31 votos

¿Cómo se establecen los metadatos de "fecha añadida" en Mac OS X 10.7 Lion?

El Finder de Mac OS X 10.7 Lion muestra una nueva pieza de metadatos de archivo, "Fecha de adición", que rastrea la fecha en que un elemento se añadió a una carpeta. Después de actualizar a 10.7, ninguno de los elementos de mi ~/Downloads tienen valores de "Fecha de adición". Me gustaría establecer todos los valores vacíos de "Fecha de adición" para que coincidan con los valores de "Fecha de modificación", pero no puedo averiguar cómo establecer el atributo "Fecha de adición" a un valor específico.

Mi primera suposición fue esta:

xattr -w com.apple.metadata:kMDItemDateAdded "2012-02-19 16:34:47 +0000" myfile

Pero eso no parece funcionar (aunque tampoco informa de un error).

0 votos

¿Ha acabado encontrando una solución?

1 votos

La respuesta aceptada funcionó cuando la probé (por disparatada que sea).

10voto

TraFoO Puntos 11

Cuando corro xattr -l en los elementos de mi carpeta de descargas, obtengo un campo que se parece a esto:

com.apple.metadata:kMDItemDownloadedDate:
00000000  62 70 6C 69 73 74 30 30 A1 01 33 41 B4 83 4D BF  |bplist00..3A..M.|
00000010  4C 4F E3 08 0A 00 00 00 00 00 00 01 01 00 00 00  |LO..............|
00000020  00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 13                                   |.....|
00000035

Este es un plist binario. Cuando uso HexFiend para crear un archivo con esos bytes (sí, los introduje manualmente; una explosión del pasado como introducir código ensamblador de una revista en mi Apple ][GS), y luego lo guardo como un archivo .plist, abrí el archivo en TextWrangler y obtuve el siguiente xml sin compilar:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <date>2011-11-28T05:03:59Z</date>
</array>
</plist>

Dicho esto, aunque Apple parece almacenar las fechas en XML compilado, el texto plano parece funcionar.

En otras palabras, si puede obtener la fecha de modificación del archivo en forma de cadena, puede ejecutar el comando xattr -w com.apple.metadata:kMDItemDownloadedDate "2012-02-19 16:34:47 +0000" file para cambiar la "fecha de descarga", que parece ser el campo realmente ordenado, no la fecha real de adición.

Finalmente no tienes ningún error al añadir el (no usado) kMDItemDateAdded campo porque, como aprendí en este artículo , xattr establecerá felizmente cualquier campo de metadatos que desee, utilizado o no.

Ese es el núcleo de la respuesta. Voy a trabajar en la escritura de un AppleScript para obtener la fecha de modificación de cada archivo, comprobar para ver si kMDItemDownloadedDate y, si no lo está, establecer kMDItemDownloadedDate a la fecha de modificación, pero quería obtener el núcleo de la respuesta publicada.

1 votos

Ejecute mdls en los archivos de su carpeta Descargas y verá los valores kMDItemDateAdded. Eso es lo que muestra la columna "Fecha Añadida" en la vista Lista del Finder.

0 votos

Por cierto, si quieres mostrar el kMDItemDownloadedDate como información plist sin pasar por HexFiend y TextWrangler, prueba con xattr -p com.apple.metadata:kMDItemDownloadedDate FILENAME_HERE | xxd -r -p | plutil -convert xml1 - -o - . El xxd convierte a datos binarios plist, entonces el plutil convierte a XML plist y lo imprime.

0 votos

OK, estoy en mi cabeza, me temo que decir. kMDItemDateAdded no aparece en xattr -l y kMDItemDownloadedDate no aparece con mdls . Cada vez más curioso. El campo Fecha de adición tampoco se almacena en un xattr para el campo directorio . ¿Dónde viven estos metadatos?

9voto

TraFoO Puntos 11

OK, nuevo enfoque aquí. Precaución: No tengo un sistema actualizado a Lion (mi ordenador venía con Lion instalado) así que no puedo probar esto. Código no probado; ¡haz una copia de seguridad antes de probar este código!

Mi respuesta anterior se basaba en el orden de clasificación utilizado por la pila de descargas en el Dock. El campo Fecha de adición en el Finder parece basarse en la información de Spotlight, que es difícil de piratear. Tampoco es accesible a través de AppleScript. Pero, parece que hay una solución.

  1. Cree un nuevo flujo de trabajo en Automator.

  2. Configure el flujo de trabajo para que acepte archivos o carpetas del Finder añadiendo la acción "Pedir elementos del Finder".

  3. Haga que el flujo de trabajo ejecute un AppleScript añadiendo la acción "Ejecutar AppleScript".

Utilice este AppleScript:

on run {input, parameters}
    do shell script "sudo /usr/sbin/systemsetup -setusingnetworktime Off" with administrator privileges
    tell application "Finder"
        repeat with x in input
            set myfile to POSIX path of x
            set nm to name of x
            set d to modification date of x
            set yr to (character 3 of (year of d as string)) & (character 4 of (year of d as string))
            set mth to (month of d as number) as string
            if length of mth is 1 then set mth to "0" & mth
            set dy to day of d as string
            if length of dy is 1 then set dy to "0" & dy
            set h to hours of d as string
            if length of h is 1 then set h to "0" & h
            set m to minutes of d as string
            if length of m is 1 then set m to "0" & m
            set s to seconds of d as string
            if length of s is 1 then set s to "0" & s
            set dt to mth & ":" & dy & ":" & yr as string
            set tm to h & ":" & m & ":" & s as string
            do shell script "sudo /usr/sbin/systemsetup -setdate '" & dt & "'" with administrator privileges
            do shell script "sudo /usr/sbin/systemsetup -settime '" & tm & "'" with administrator privileges
            do shell script "mv \"" & myfile & "\" /var/tmp/clobber"
            do shell script "mv /var/tmp/clobber \"" & myfile & "\""
        end repeat
    end tell
    do shell script "sudo /usr/sbin/systemsetup -setusingnetworktime On" with administrator privileges
    return input
end run

Seleccione los archivos que aún no tienen una fecha de adición (ordene por fecha de adición en el Finder, luego seleccione la parte de la lista sin fecha de adición) y ejecute este servicio.

screenshot of the workflow in Automator

2 votos

Eso es horrible ¿en el buen sentido, quizás?

1 votos

Bueno, definitivamente es un hack. Pero parece que esa pieza en particular de metadatos se calcula a partir de Spotlight, y sin hackear el oscuro misterio conocido como /.Spotlight-V100 esto podría ser tan bueno como se pone. Pero yo amor para ver una respuesta limpia.

0 votos

Estoy recibiendo un extraño error de este script? sh: -c línea 0: inesperado EOF mientras buscaba coincidencia `"

4voto

sdfx Puntos 6428

No encuentro la forma de configurar la "Fecha de adición" que aparece en el Finder.

Creo que tienes razón en que se recupera del índice de Spotlight kMDItemDateAdded atributo de metadatos. Sin embargo, Spotlight parece derivar esto por sí mismo de alguna manera.

He intentado establecer un atributo de archivo extendido llamado com.apple.metadata:kMDItemDateAdded a un valor de fecha en uno de varios formatos diferentes, incluyendo el formato utilizado por kMDItemDateAdded y ninguno de ellos fue recogido por el índice Spotlight, es decir, sin importar el valor mostrado por xattr el valor mostrado por mdls no fue cambiado.

Me gustaría adivinar Aunque no lo sé con certeza, Spotlight simplemente establece esta fecha basándose en la primera vez que indexa un archivo en una ubicación determinada, y no comprueba ningún otro metadato para generarla. Si usted mv un archivo fuera de Descargas y lo vuelvo a meter, la Fecha de adición se actualiza a la fecha en que se volvió a meter, pero ninguno de los archivo parecen estar afectados, sólo los metadatos de Spotlight.

Así que, en resumen, creo que la fecha de adición sólo se almacena en algún lugar en las tripas más bien crípticas de /.Spotlight-V100, y a menos que alguien puede llegar a una manera de decirle a Spotlight para actualizar una entrada de metadatos a un valor arbitrario, no puedo ver una manera de hacer esto.

0 votos

¡Foco de atención! Bien hecho.

4voto

smci Puntos 159

Gracias a Daniel Lawson por la solución. Sigue funcionando bien, incluso dos años después.

Tengo dos adiciones:

1) Tenga en cuenta que hay un pequeño error en el código de la respuesta aceptada.

Esta línea:

do shell script "/usr/sbin/systemsetup -settime ''" & tm & "'"

...tiene un apóstrofe de más, provocando un error de "EOF inesperado". Debería decir:

do shell script "/usr/sbin/systemsetup -settime '" & tm & "'"

2) Más importante, a partir de Mavericks 10.9.2, el systemsetup requiere derechos de administrador. Así que cada llamada al shell script debe seguir esta fórmula:

do shell script "sudo /usr/sbin/systemsetup -setusingnetworktime Off" with administrator privileges

Aquí está la versión completa modificada del AppleScript, confirmada para funcionar en 10.9.3:

on run {input, parameters}
    do shell script "sudo /usr/sbin/systemsetup -setusingnetworktime Off" with administrator privileges

    tell application "Finder"
        repeat with x in input
            set myfile to POSIX path of x
            set nm to name of x

            set d to modification date of x
            set yr to (character 3 of (year of d as string)) & (character 4 of (year of d as string))
            set mth to (month of d as number) as string
            if length of mth is 1 then set mth to "0" & mth
            set dy to day of d as string
            if length of dy is 1 then set dy to "0" & dy
            set h to hours of d as string
            if length of h is 1 then set h to "0" & h
            set m to minutes of d as string
            if length of m is 1 then set m to "0" & m
            set s to seconds of d as string
            if length of s is 1 then set s to "0" & s

            set dt to mth & ":" & dy & ":" & yr as string
            set tm to h & ":" & m & ":" & s as string
            do shell script "sudo /usr/sbin/systemsetup -setdate '" & dt & "'" with administrator privileges
            do shell script "sudo /usr/sbin/systemsetup -settime '" & tm & "'" with administrator privileges

            do shell script "mv \"" & myfile & "\" /var/tmp/clobber"
            do shell script "mv /var/tmp/clobber \"" & myfile & "\""
        end repeat
    end tell

    do shell script "sudo /usr/sbin/systemsetup -setusingnetworktime On" with administrator privileges

    return input
end run

1 votos

¡Bienvenido a Ask Different! En lugar de escribir una respuesta para editar la respuesta de otra persona, simplemente haz clic en el botón editar o mejorar esta respuesta botón debajo del puesto que desea mejorar .

2 votos

Respuesta de Daniel tiene editado para incluir estos cambios.

2voto

Froyo Puntos 113

Si se siente cómodo compilando algo de código C, entonces, como señalado por Ken Thomases estos datos se pueden recuperar en getattrlist(2) . Y aunque parezca que el correspondiente settralist(2) no funcionaba para la fecha añadida en versiones antiguas de MacOS, el siguiente código me funciona en MacOS Monterey 12.5.1, ajustando la fecha mostrada en Finder.

Es sólo conseguir y establecer el ATTR_CMN_ADDEDTIME que el manual describe como

el momento en que el archivo fue creado o renombrado en su directorio que lo contiene. Tenga en cuenta que inconsistente cuando este atributo se en elementos hard-linked

#include <stdlib.h>
#include <string.h>
#include <sys/attr.h>
#include <unistd.h>

/*
 * Get kMDItemDateAdded of path.
 *
 * Returns:
 *   • 0 on success
 *   • 1 if a system call failed: check errno
 *   • 2 if something else went wrong
 */
int get_date_added(const char* path, struct timespec * out) {
    attrgroup_t request_attrs = ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_ADDEDTIME;

    struct attrlist request;
    memset(&request, 0, sizeof(request));
    request.bitmapcount = ATTR_BIT_MAP_COUNT;
    request.commonattr = request_attrs;

    typedef struct {
        u_int32_t length;
        attribute_set_t returned;
        struct timespec added;
    } __attribute__((aligned(4), packed)) response_buf_t;

    response_buf_t response;

    int err = getattrlist(path, &request, &response, sizeof(response), 0);
    if (err != 0) {
        return 1;
    }
    if (response.length != sizeof(response)) {
        // Need a different-sized buffer; but provided one of exactly required
        // size?!
        return 2;
    }
    if (response.returned.commonattr != request_attrs) {
        // Didn’t get back all requested common attributes
        return 2;
    }

    out->tv_sec = response.added.tv_sec;
    out->tv_nsec = response.added.tv_nsec;

    return 0;
}

/*
 * Set kMDItemDateAdded of path.
 *
 * Returns:
 *   • 0 on success
 *   • 1 if a system call failed: check errno
 */
int set_date_added(const char* path, struct timespec in) {
    attrgroup_t request_attrs = ATTR_CMN_ADDEDTIME;

    struct attrlist request;
    memset(&request, 0, sizeof(request));
    request.bitmapcount = ATTR_BIT_MAP_COUNT;
    request.commonattr = request_attrs;

    typedef struct {
        struct timespec added;
    } __attribute__((aligned(4), packed)) request_buf_t;

    request_buf_t request_buf;
    request_buf.added.tv_sec = in.tv_sec;
    request_buf.added.tv_nsec = in.tv_nsec;

    int err = setattrlist(path, &request, &request_buf, sizeof(request_buf), 0);
    if (err != 0) {
        return 1;
    }

    return 0;
}

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X