1 votos

Ayuda de AppleScript con regla de Correo para mantener más reciente

He creado una regla para mover el correo de remitentes especificados para un buzón de correo nuevo llamado "Noticias". Me gustaría que mis AppleScript para ir a través de la "Noticia" de la carpeta y mantener sólo la más reciente emaisa de esos remitentes, la eliminación de los mensajes anteriores. (Esta es una de las funciones de Barrido en MSLive/Outlook). He tratado de escribir una secuencia de comandos de la siguiente manera, que es invocado por la regla:

using terms from application "Mail"
    on perform mail action with messages these_messages for rule this_rule
        tell application "Mail"
            set dateToday to current date
            set TargetInbox to mailbox "News" of account "iCloud"
            set EveryMessage to every message of TargetInbox
            repeat with eachMessage in these_messages
                repeat with this_message in EveryMessage
                    set eachSender to the sender of eachMessage
                    set this_sender to the sender of this_message
                    set messageDate to date received of EveryMessage
                    if messageDate < dateToday and eachSender = this_sender then
                        delete this_message
                    end if
                end repeat
            end repeat
        end tell
    end perform mail action with messages
end using terms from

Veo que el script es llamado por la regla, porque de el engranaje de giro en la barra de menú, pero ninguno de los que desee eliminar se produce, y el guión parece que se bloquea en algún tipo de bucle.

Soy un AppleScript n00b, hacer mucho mejor con JavaScript. Agradecería cualquier ayuda.

Gracias, Betalantz

macos 10.13.5 | Correo 11.4 | AppleScript 2.7

3voto

qarma Puntos 71

Yo no uso el Correo.aplicación y no mucha experiencia en la implementación de acciones de Correo, por lo que no estoy en la posición de prueba de su guión. Sin embargo, de la lectura a través de él, hay lugares en los que puedan ser motivo de preocupación que desearía a buscar a primera hora de depurar.

¿Qué tan grande es su "Noticias" buzón ?

Hay dos características en su secuencia de comandos que amenazan a colgar o tiempo de espera:

1. set EveryMessage to every message of TargetInbox

Si el buzón tiene miles o incluso cientos de correos electrónicos en ella, recuperando every message como una lista de forma individual hace referencia message objetos (que es lo que esta declaración está haciendo) podría tomar algún tiempo. Es casi siempre de manera más eficiente y menos intensivo del procesador y el uso de memoria para almacenar a reference to el every message objeto (colección):

set EveryMessage to a reference to every message of the TargetInbox

Tiene otra característica beneficiosa de la que me ocuparé más adelante.

2. Potencialmente exigentes anidada repeat de bucles

Bucles anidados son un mal necesario a veces, pero la consulta sobre el tamaño del buzón de correo es, de nuevo, una fuente de ansiedad para mí, sobre todo porque con su llamado en el corazón de el nido, donde el grueso de las operaciones se realicen. Esto significa que, para cada nuevo mensaje que desencadena la secuencia de comandos, cada uno de los mensajes en el buzón de correo tiene que ser revisado y comparado con el gatillo mensaje.

Estos son dos ramas de un problema, la verdad, porque si su buzón de correo sólo tiene 5 mensajes en ella, nada de esto es particularmente molestos. De lo contrario, está en primer lugar llegar a AppleScript para recuperar todos los mensajes del buzón de correo y almacenarlos en una variable; y luego en bicicleta a través de este potencialmente de carga pesada y de la comparación de cada elemento a otro.

Si usted no tuvo más remedio que usar un repeat de bucle, mientras que a sabiendas de que tendría que recorrer un montón de elementos de la lista (una vez que se superan los 500 de nada, AppleScript puede comenzar a hebilla) puede ayudar, una vez más, para pasar de AppleScript una referencia a la lista de artículos en lugar de la lista. Transmitir cualquier tipo de referencia a través de un objeto de secuencia de comandos (que es lo a reference to hace esencialmente), es mucho, mucho más rápido que hacer AppleScript acceso a un objeto por otros medios. He aquí un excelente explicación y demostración de estos principios.

Simples cambios y correcciones de errores

Después de ocuparse de los pesados problema anterior, que podría llegar a ser de poca relevancia para su caso en particular, aquí hay uno o dos de facto de los elementos que se pueden cambiar fácilmente para mejorar la eficiencia de la secuencia de comandos, o evitar que tirar un error:

1. La colocación de las declaraciones de variables

set eachSender to the sender of eachMessage

Esta línea está declarado en el interior el interior de la repeat de bucle, que también pasa a ser el más carnoso de los dos, en general en términos hipotéticos. Sin embargo, lo que esto hace es establecer el valor de la variable eachSender para el mismo valor para todos los mensajes que tienes en tu buzón de correo. Que es un gran desperdicio de operaciones para AppleScript (un total de número de these_messages multplied por el número de EveryMessage).

En cambio, mover de aquí:

repeat with eachMessage in these_messages
    set eachSender to the sender of eachMessage  # ...now it's here
    repeat with this_message in EveryMessage
        # It was here...
        .
        .
        .
    end repeat
end repeat

Ahora AppleScript sólo tiene que establecer la variable de una vez por eachMessage en these_message. Eso es una mejora de la eficiencia del polinomio tiempo al tiempo lineal!

2. set messageDate to date received of EveryMessage

En un principio, pensé que estaba tratando de acceder a la EveryMessage objeto como una referencia a la colección de la que hablé antes, y simplemente no se dio cuenta que no podía hacer eso en la forma en que usted declara EveryMessage.

Pero, ahora me doy cuenta de que era más probable es que sólo las manos de escribir más rápido que sus pensamientos, y la introducción de un molesto error tipográfico. EveryMessage aquí debería serthis_message, es decir:

set messageDate to date received of this_message

Esto me lleva bastante bien a mi punto final, que he insinuado anteriormente, en relación a los otros en beneficio de la declaración de una variable a una colección de objetos como una referencia.

Había que hacer esto:

set EveryMessage to a reference to every message of the TargetInbox

entonces este:

set messageDate to date received of EveryMessage

sería perfectamente válido pieza de AppleScript, que le permite acceder a la propiedad de cada elemento en una lista IFF lo hicieron a través de una referencia a la lista antes de cualquier tipo de desreferenciado ha tenido lugar. Una vez que se eliminan las referencias, la lista se evalúa en las referencias de objeto, y que ya no le dará los medios para enumerar sus propiedades de esa manera.

Lo que se obtiene si se hace correctamente es la lista que contiene los valores de la date received de la propiedad de every message of the TargetInbox, todo a través de una sola línea de AppleScript.

En la actualidad, ya que esto no era cómo se implementó, la declaración de set messageDate será sin duda producirá un error.

Esto explica por qué ninguna de las eliminaciones se producen, debido a que el script nunca va a llegar a esa parte. Sin embargo, ocurrir el error, de inmediato, así que mi sensación es que el script no es ni siquiera llegar a esa línea, ni siquiera una vez. Por lo tanto, el problema debe originarse a partir de un punto en la secuencia de comandos antes de que cada vez con éxito entra en el interior de la repeat de bucle. Y ya sabes mi corazonada acerca de eso.

Ahora para una posible solución

Siento que realmente no puedo probar mi script para comprobar que esto definitivamente va a trabajar el primer momento sin ningún tipo de retoques, así que me diga como le va con este:

    using terms from application "Mail"
        on perform mail action with messages these_messages
            tell application "Mail"
                set everyMessage to a reference to messages in mailbox "News" of account "iCloud"
                repeat with eachMessage in these_messages
                    delete (everyMessage where ¬
                        the date received is not the (current date) ¬
                        and its sender is the sender of eachMessage)
                end repeat
            end tell
        end perform mail action with messages
    end using terms from

Como se puede ver, he hecho completamente con el interior de la mayoría de repeat bucle gracias a la utilización de la a reference to operador. Como ya he dicho everyMessage de esa manera, yo soy (con suerte) capaz de enumerar las propiedades de todos los elementos de la lista contiene una sola vez, la cual debe ser de aproximadamente infinito de veces más rápido que tener que comprobar la propiedad de cada elemento de forma individual.

1voto

Lantz Warrick Puntos 8

Muchas gracias a @CJK para una respuesta exhaustiva. La solución funciona con un solo ajuste, y también he aprendido algunos conceptos básicos para AppleScript. El trabajo siguiente secuencia de comandos ahora se ejecuta muy rápidamente:

using terms from application "Mail"
    on perform mail action with messages these_messages for rule this_rule
        tell application "Mail"
            set everyMessage to a reference to messages in mailbox "News" of account "iCloud"
            repeat with eachMessage in these_messages
                delete (everyMessage where ¬
                    the date received is not the (current date) ¬
                    and its reply to is the reply to of eachMessage)
            end repeat
        end tell
    end perform mail action with messages
end using terms from

El guión parecía que no ejecute sin la adición de la línea 2 de for rule this_rule y me imagino que es necesaria para pasar a la these_messages objeto que es el resultado de la filtración se define en el padre de correo.aplicación de la regla que está invocando a la secuencia de comandos.

(Al final de la repeat de bucle, he cambiado sender a reply to a manejar casos en los que el remitente había cambiado su propia cadena de identificador de la cuenta de envío, incluso a pesar de que la dirección real sigue siendo la misma, causando la secuencia de comandos para perder los mensajes más antiguos de la misma dirección).

La clave de la comprensión de que me faltaba es que el EveryMessage objeto no era automáticamente se pasa por referencia. Vengo de JavaScript, en donde los objetos, matrices, variables y automáticamente se pasa por referencia, mientras que en AppleScript uno debe declarar como objeto de referencia.

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