Thursday, July 9, 2020

#1 2020-06-27 02:29:32 pm

dtomasch
Member
Registered: 2007-05-31
Posts: 16

Speeding Up a repeat loop — Working with Mail.app and emails

Hey, everyone!

Can anyone suggest how I could speed up / improve this script?

--

I needed to solve a problem for a client.

They use the colored flags on Mail.app extensively for their business workflow. Different colors mean different things.

However, Mail.app colored flags aren't visible in any environment other than a Mac. If anyone wants to use a PC or look at their emails in Webmail, the workflow is totally broken.

So I wrote a script that takes all flagged items and sorts them into corresponding folders on the server (Red, Green, Blue, etc). It then looks at those same folders, and removes anything that's no longer flagged).

With this, the Mail.app colored flags are always synced up with a corresponding folder on the server.

However, they have a ton of emails, often with large attachments.

When the script runs, it can often slow down Mail.app, which I would like to avoid.

Any suggestions?

Applescript:


-- These are the account and folder names we need
set _account to "Jimthehandyman"
set _mailboxlistUNSET to {"INBOX/Red", "INBOX/Orange", "INBOX/Yellow", "INBOX/Green", "INBOX/Blue", "INBOX/Purple", "INBOX/Gray"}
set _mailboxlist to {"INBOX", "Sent Items"}


-- These are the color and index pairs so we can just iterate thru all of these with the same function
set _FlagRecord to {{index:"0", color:"Red"}, {index:"1", color:"Orange"}, {index:"2", color:"Yellow"}, {index:"3", color:"Green"}, {index:"4", color:"Blue"}, {index:"5", color:"Purple"}, {index:"6", color:"Gray"}}


-- Search thru each flag-folder, find any message without a flag, and move it into the inbox.
tell application "Mail"
   repeat with _m in _mailboxlistUNSET
       set allMessage to (every message of mailbox _m of account _account whose flag index is -1)
       repeat with MyMessage in allMessage
           move MyMessage to mailbox "INBOX" of account _account
       end repeat
   end repeat
end tell


-- Search through each color/flag pair and move flagged items into the flag-folder
tell application "Mail"
   repeat with i in _FlagRecord
       repeat with box in _mailboxlist
           
           -- here for testing
           -- display dialog (index of i) & (color of i)
           -- set _mailbox to box
           -- display dialog box
           
           set allMessage to (every message of mailbox _mailbox of account _account whose flag index is index of i)
           try
               repeat with MyMessage in allMessage
                   move MyMessage to (first mailbox whose name is color of i) of account _account
               end repeat
           end try
       end repeat
   end repeat
end tell


Filed under: repeat, mail, email, loop

Offline

 

#2 2020-06-27 03:27:43 pm

robertfern
Member
Registered: 2011-11-29
Posts: 63

Re: Speeding Up a repeat loop — Working with Mail.app and emails

I could only find one place that might be able to be sped up.
It is in the last inner-most repeat loop where you are moving emails to the "Color" mailbox.
Each time thru the repeat loop, you have the Mail program search for the box based on the name.
I added a variable "mbox" to the colored mailbox once before the loop starts.

Applescript:


-- These are the account and folder names we need
set _account to "Jimthehandyman"
set _mailboxlistUNSET to {"INBOX/Red", "INBOX/Orange", "INBOX/Yellow", "INBOX/Green", "INBOX/Blue", "INBOX/Purple", "INBOX/Gray"}
set _mailboxlist to {"INBOX", "Sent Items"}


-- These are the color and index pairs so we can just iterate thru all of these with the same function
set _FlagRecord to {{index:"0", color:"Red"}, {index:"1", color:"Orange"}, {index:"2", color:"Yellow"}, {index:"3", color:"Green"}, {index:"4", color:"Blue"}, {index:"5", color:"Purple"}, {index:"6", color:"Gray"}}


-- Search thru each flag-folder, find any message without a flag, and move it into the inbox.
tell application "Mail"
   repeat with _m in _mailboxlistUNSET
       set allMessage to (every message of mailbox _m of account _account whose flag index is -1)
       repeat with MyMessage in allMessage
           move MyMessage to mailbox "INBOX" of account _account
       end repeat
   end repeat
end tell


-- Search through each color/flag pair and move flagged items into the flag-folder
tell application "Mail"
   repeat with i in _FlagRecord
       repeat with box in _mailboxlist
           
           -- here for testing
           -- display dialog (index of i) & (color of i)
           -- set _mailbox to box
           -- display dialog box
           
           set allMessage to (every message of mailbox _mailbox of account _account whose flag index is index of i)
           try
               -- I added this below
               set mbox to (first mailbox whose name is color of i) of account _account
               repeat with MyMessage in allMessage
                   move MyMessage to mbox -- now it doesn't have to search for each email
               end repeat
           end try
       end repeat
   end repeat
end tell

Last edited by robertfern (2020-06-27 05:04:47 pm)

Offline

 

#3 2020-06-28 09:18:14 am

Marc Anthony
Member
From:: Dallas, TX
Registered: 2006-04-27
Posts: 950

Re: Speeding Up a repeat loop — Working with Mail.app and emails

Since your request is commercial in nature, I'll abstain from writing code samples, however, you should know that whose clauses tend to be less efficient with large file volumes than standard loops with nested if considerations, and you may want to experiment with a ground-up rewrite that removes them. As the messages' flag index parallels the messages' list position, there is little need to obtain the actual messages in a giant list, which is computationally expensive; they can simply be positionally (re)moved by index.

Offline

 

#4 2020-06-28 10:37:54 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 4544

Re: Speeding Up a repeat loop — Working with Mail.app and emails

I didn't tested because I don't want to change my Mail's datas but I assume that this edited version may do the job correctly.

Applescript:


-- These are the account and folder names we need
set _account to "Jimthehandyman"
set _mailboxlistUNSET to {"INBOX/Red", "INBOX/Orange", "INBOX/Yellow", "INBOX/Green", "INBOX/Blue", "INBOX/Purple", "INBOX/Gray"}
set _mailboxlist to {"INBOX", "Sent Items"}


set _colorNames to {"Red", "Orange", "Yellow", "Green", "Blue", "Purple", "Gray"}

-- Search thru each flag-folder, find any message without a flag, and move it into the inbox.
tell application "Mail" to tell account _account
   repeat with _m in _mailboxlistUNSET
       repeat with MyMessage in (every message of mailbox _m whose flag index is -1)
           move MyMessage to mailbox "INBOX"
       end repeat
   end repeat

-- Search through each color/flag pair and move flagged items into the flag-folder

   repeat with box in _mailboxlist
       repeat with MyMessage in (every message of mailbox box)
           set colorName to _colorNames's item (1 + (flag index of MyMessage))
           move MyMessage to (first mailbox whose name is _colorName)
       end repeat
   end repeat
end tell

As _mailboxlistUNSET, _mailboxlist and _colorNames are very short lists I assume that there is no need to try to fasten using the brave old property tip.
But as we aren't changing these lists, it costs nothing to try to use such objects.

Applescript:


-- These are the account and folder names we need

property _mailboxlistUNSET : {"INBOX/Red", "INBOX/Orange", "INBOX/Yellow", "INBOX/Green", "INBOX/Blue", "INBOX/Purple", "INBOX/Gray"}
property _mailboxlist : {"INBOX", "Sent Items"}
property _colorNames : {"Red", "Orange", "Yellow", "Green", "Blue", "Purple", "Gray"}

set _account to "Jimthehandyman"

-- Search thru each flag-folder, find any message without a flag, and move it into the inbox.
tell application "Mail" to tell account _account
   repeat with _m in my _mailboxlistUNSET
       repeat with MyMessage in (every message of mailbox _m whose flag index is -1)
           move MyMessage to mailbox "INBOX"
       end repeat
   end repeat
   
   -- Search through each color/flag pair and move flagged items into the flag-folder
   
   repeat with box in my _mailboxlist
       repeat with MyMessage in (every message of mailbox box)
           set colorName to my _colorNames's item (1 + (flag index of MyMessage))
           move MyMessage to (first mailbox whose name is _colorName)
       end repeat
   end repeat
end tell

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 28 juin 2020 18:31:02

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)