Adrian Nier Code

Back to overview

Archive Mail selection

Last modification: Thursday, February 04, 2010 10:22 pm

This script will move selected Mail messages to an Archive mailbox, creating it if it doesn't already exist.

Implementation

on run
   -- Do not allow execution if "Mail" is not running
   tell application "System Events" to if (exists process "Mail") is false then return false
   
   -- Get selection
   set _selectedItems to mailSelection()
   
   -- Ask the user for permission to begin processing
   if askUserForPermissionToContinue(_selectedItems) is false then return false
   
   -- Move the selected messages or all messages contained by selected mailboxes
   set _movedMessages to moveSelectionToArchive(_selectedItems)
   
   -- BUG: If the user does not actively set another selection and runs the script again,
   -- Mail returns the old selection. Cycling the selection fixes the problem.
   if _movedMessages > 0 then cycleMailboxSelection()
   
   -- If 10 or more messages are moved, display a dialog with the result.
   if _movedMessages ≥ 10 then displayResult(_movedMessages)
   
   -- Hide LaunchBar, if it is running
   tell application "System Events" to if exists process "LaunchBar" then set visible of process "LaunchBar" to false
   
end run


on _____________________________________USER()
end _____________________________________USER

on askUserForPermissionToContinue(_selectedItems)
   -- Determine the count of messages that will be moved
   copy determineCounts() to {_messagesToMoveCount, _selectedMessageCount, _selectedMailboxCount}
   
   tell application "Mail"
      if _messagesToMoveCount = 0 then
         activate
         beep
         display alert my localizedString("nothing_selected_title", {}) message my localizedString("nothing_selected_message", {}) buttons {my localizedString("quit_button", {})} default button 1 as warning
         return false
         
      else if _messagesToMoveCount = 1 then
         
      else
         activate
         beep
         if _selectedMessageCount = 0 then
            set _alertMessage to my localizedString("about_to_move_mailbox_message", {_messagesToMoveCount, _selectedMailboxCount})
         else
            set _alertMessage to my localizedString("about_to_move_message", {_messagesToMoveCount, _selectedMailboxCount})
         end if
         
         set _button to button returned of (display alert my localizedString("about_to_move_title", {_messagesToMoveCount}) message _alertMessage buttons {my localizedString("cancel_button", {}), my localizedString("archive_button", {})} default button 2)
         
         if _button = my localizedString("cancel_button", {}) then return false
      end if
      return true
   end tell
end askUserForPermissionToContinue

on displayResult(_movedMessages)
   tell application "Mail"
      try
         display alert my localizedString("processing_done_title", {_movedMessages}) message my localizedString("processing_done_message", {_movedMessages}) buttons {my localizedString("quit_button", {})} default button 1
      end try
   end tell
end displayResult

on _____________________________________MAIL()
end _____________________________________MAIL

on moveSelectionToArchive(_selectedItems)
   -- Move the selected messages or all messages contained by selected mailboxes
   set _movedMessages to 0
   
   tell application "Mail"
      repeat with _selectedItemNumber from 1 to count of _selectedItems
         
         if class of (item _selectedItemNumber of _selectedItems) is mailbox then
            
            -- Process a selected mailbox
            set _selectedItems to messages of (item _selectedItemNumber of _selectedItems)
            repeat with _selectedItemNumber from 1 to count of _selectedItems
               if my moveMessageToArchive(item _selectedItemNumber of _selectedItems) is true then set _movedMessages to _movedMessages + 1
            end repeat
            
         else if class of (item _selectedItemNumber of _selectedItems) is message then
            
            -- Process a selected message
            if my moveMessageToArchive(item _selectedItemNumber of _selectedItems) is true then set _movedMessages to _movedMessages + 1
            
         end if
         
      end repeat
   end tell
   
   return _movedMessages
end moveSelectionToArchive

on moveMessageToArchive(_message)
   
   tell application "Mail"
      set _date to date received of _message
      
      -- Do not archive flagged messages
      --if flagged status of _message is true or read status of _message is false or junk mail status of _message is true then return false
      
      try
         set _box to (first mailbox whose name contains ((year of _date) as string) and name contains "Archiv" and name contains ("Q" & (my quartal(_date) as string)))
      on error
         set _box to my createMailboxForDate(_date)
      end try
      
      move _message to _box
      
   end tell
   return true
   
end moveMessageToArchive

on determineCounts()
   tell application "Mail"
      set _messagesToMoveCount to 0
      set _selectedMessageCount to count of selected messages of message viewer 1
      set _selectedMailboxCount to count of selected mailboxes of message viewer 1
      
      if _selectedMessageCount ≠ 0 then
         return {_selectedMessageCount, _selectedMessageCount, _selectedMailboxCount}
      else
         set _selectedMailboxes to selected mailboxes of message viewer 1
         repeat with _selectedMailbox in _selectedMailboxes
            set _messagesToMoveCount to _messagesToMoveCount + (count of messages of _selectedMailbox)
         end repeat
         return {_messagesToMoveCount, _selectedMessageCount, _selectedMailboxCount}
      end if
   end tell
end determineCounts

on createMailboxWithPath(_path)
   tell application "Mail"
      try
         set _box to mailbox _path
         get _box
      on error
         try
            make new mailbox with properties {name:_path}
         on error _eMsg number _eNum
            error "createMailboxWithPath(" & _path & "): " & _eMsg number _eNum
         end try
         set _box to mailbox _path
      end try
      return _box
   end tell
end createMailboxWithPath

on createMailboxForDate(_date)
   
   set _quartalString to (year of _date as string) & "-Q" & quartal(_date)
   set _archiveBoxName to localizedString("archive_multiple", {})
   set _yearBoxName to _archiveBoxName & "/" & (year of _date as string)
   set _quartalBoxName to _yearBoxName & "/" & localizedString("archive_single", {}) & " " & _quartalString
   
   tell application "Mail"
      set _archiveBox to my createMailboxWithPath(_archiveBoxName)
      set _yearBox to my createMailboxWithPath(_yearBoxName)
      set _quartalBox to my createMailboxWithPath(_quartalBoxName)
      return _quartalBox
   end tell
end createMailboxForDate

on mailSelection()
   tell application "Mail"
      try
         set _selectedItems to selected messages of message viewer 1
         if _selectedItems is {} then error 1
      on error
         set _selectedItems to selected mailboxes of message viewer 1
      end try
   end tell
   return _selectedItems
end mailSelection

on cycleMailboxSelection()
   tell application "Mail"
      set _selectedMailboxes to selected mailboxes of message viewer 1
      set selected mailboxes of message viewer 1 to {}
      set selected mailboxes of message viewer 1 to _selectedMailboxes
   end tell
end cycleMailboxSelection



on _____________________________________STRINGS()
end _____________________________________STRINGS

on localizedString(_string, _vars)
   set _stringKey to _string & "/" & systemLanguage()
   
   if _stringKey is "archive_single/en" then return "Archive"
   if _stringKey is "archive_single/de" then return "Archiv"
   
   if _stringKey is "archive_multiple/en" then return "Archives"
   if _stringKey is "archive_multiple/de" then return "Archive"
   
   if _stringKey is "quit_button/en" then return "Quit"
   if _stringKey is "quit_button/de" then return "Beenden"
   
   if _stringKey is "cancel_button/en" then return "Cancel"
   if _stringKey is "cancel_button/de" then return "Abbrechen"
   
   if _stringKey is "archive_button/en" then return "Archive"
   if _stringKey is "archive_button/de" then return "Archivieren"
   
   if _stringKey is "nothing_selected_title/en" then return "Nothing selected"
   if _stringKey is "nothing_selected_title/de" then return "Nichts ausgew" & (ASCII character 138) & "hlt"
   
   if _stringKey is "nothing_selected_message/en" then return "Please select at least one message or a mailbox that contains messages."
   if _stringKey is "nothing_selected_message/de" then return "Bitte w" & (ASCII character 138) & "hlen Sie mindestens eine Nachricht oder ein Postfach, welches eine oder mehrere Nachrichten enth" & (ASCII character 138) & "lt."
   
   if _stringKey is "about_to_move_title/en" then
      if (item 1 of _vars) is 1 then return "Archiving " & ((item 1 of _vars) as string) & " message"
      return "Archiving " & ((item 1 of _vars) as string) & " messages"
   end if
   
   if _stringKey is "about_to_move_title/de" then
      if (item 1 of _vars) is 1 then return ((item 1 of _vars) as string) & " Nachricht archivieren"
      return ((item 1 of _vars) as string) & " Nachrichten archivieren"
   end if
   
   if _stringKey is "about_to_move_message/en" then
      if (item 1 of _vars) is 1 then return "If you press the " & (ASCII character 210) & "Archive" & (ASCII character 211) & " button the selected message will be archived." & return & return & "This action is not undoable."
      return "If you press the " & (ASCII character 210) & "Archive" & (ASCII character 211) & " button the selected messages will be archived." & return & return & "This action is not undoable."
   end if
   
   if _stringKey is "about_to_move_message/de" then
      if (item 1 of _vars) is 1 then return "Wenn Sie die " & (ASCII character 200) & "Archivieren" & (ASCII character 199) & " Taste bet" & (ASCII character 138) & "tigen, wird die gerade ausgew" & (ASCII character 138) & "hlte Nachricht in das Archiv verschoben." & return & return & "Dieser Vorgang ist nicht wiederrufbar."
      return "Wenn Sie die " & (ASCII character 200) & "Archivieren" & (ASCII character 199) & " Taste bet" & (ASCII character 138) & "tigen, werden die gerade ausgew" & (ASCII character 138) & "hlten Nachrichten in das Archiv verschoben." & return & return & "Dieser Vorgang ist nicht wiederrufbar."
   end if
   
   if _stringKey is "about_to_move_mailbox_message/en" then
      if (item 1 of _vars) is 1 then
         if (item 2 of _vars) is 1 then
            return "If you press the " & (ASCII character 210) & "Archive" & (ASCII character 211) & " button one message from the selected mailbox will be archived." & return & return & "This action is not undoable."
         else
            return "If you press the " & (ASCII character 210) & "Archive" & (ASCII character 211) & " button one message contained by one of the selected mailboxes will be archived." & return & return & "This action is not undoable."
         end if
      else
         if (item 2 of _vars) is 1 then
            return "If you press the " & (ASCII character 210) & "Archive" & (ASCII character 211) & " button the messages from the selected mailbox will be archived." & return & return & "This action is not undoable."
         else
            return "If you press the " & (ASCII character 210) & "Archive" & (ASCII character 211) & " button the messages from the selected mailboxes will be archived." & return & return & "This action is not undoable."
         end if
      end if
      
      
   end if
   
   if _stringKey is "about_to_move_mailbox_message/de" then
      if (item 1 of _vars) is 1 then
         if (item 2 of _vars) is 1 then
            return "Wenn Sie die " & (ASCII character 200) & "Archivieren" & (ASCII character 199) & " Taste bet" & (ASCII character 138) & "tigen, wird die Nachricht des gerade ausgew" & (ASCII character 138) & "hlten Postfachs in das Archiv verschoben." & return & return & "Dieser Vorgang ist nicht wiederrufbar."
         else
            return "Wenn Sie die " & (ASCII character 200) & "Archivieren" & (ASCII character 199) & " Taste bet" & (ASCII character 138) & "tigen, wird die Nachricht, die sich in einem der gerade ausgew" & (ASCII character 138) & "hlten Postf" & (ASCII character 138) & "cher befindet, in das Archiv verschoben." & return & return & "Dieser Vorgang ist nicht wiederrufbar."
         end if
      else
         if (item 2 of _vars) is 1 then
            return "Wenn Sie die " & (ASCII character 200) & "Archivieren" & (ASCII character 199) & " Taste bet" & (ASCII character 138) & "tigen, werden die Nachrichten des gerade ausgew" & (ASCII character 138) & "hlten Postfachs in das Archiv verschoben." & return & return & "Dieser Vorgang ist nicht wiederrufbar."
         else
            return "Wenn Sie die " & (ASCII character 200) & "Archivieren" & (ASCII character 199) & " Taste bet" & (ASCII character 138) & "tigen, werden die Nachrichten, die sich in den gerade ausgew" & (ASCII character 138) & "hlten Postf" & (ASCII character 138) & "chern befinden, in das Archiv verschoben." & return & return & "Dieser Vorgang ist nicht wiederrufbar."
         end if
         
      end if
   end if
   
   
   if _stringKey is "processing_done_title/en" then return "Done archiving."
   if _stringKey is "processing_done_title/de" then return "Archivierung abgeschlossen"
   
   if _stringKey is "processing_done_message/en" then
      if (item 1 of _vars) is 1 then return "1 message was transferred to the archive."
      return (item 1 of _vars as string) & " messages were transferred to the archive."
   end if
   
   if _stringKey is "processing_done_message/de" then
      if (item 1 of _vars) is 1 then return "1 Nachricht wurde in das Archiv verschoben."
      return (item 1 of _vars as string) & " Nachrichten wurden in das Archiv verschoben."
   end if
   
   
   
   return _string
end localizedString

on _____________________________________TOOLS()
end _____________________________________TOOLS

on systemLanguage()
   try
      return first word of (do shell script "defaults read NSGlobalDomain AppleLanguages")
   on error
      return "en"
   end try
end systemLanguage

on quartal(_d)
   set _m to month of _d as integer
   set _q to 1
   repeat with _i from 1 to 12
      if _i = _m then return _q
      if _i is 3 or _i is 6 or _i is 9 then set _q to _q + 1
   end repeat
end quartal