Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (*
- Requirements:
- https://discussions.apple.com/thread/8480829
- Quick hints
- 1) Apple hids the User's library folder. You will want to make it visible.
- http://osxdaily.com/2013/10/28/show-user-library-folder-os-x-mavericks/
- 2) Place this Applescript in this folder with name ShortMailDownload.scpt. You may not use the App extension.
- "/Users/mac/Library/Application Scripts/com.apple.mail"
- 2) The first "on" statement needs to be
- on perform mail action with messages theMessages
- 3) Mail > Preferences... > Rules > Add Rule
- "Perform the following actions" [ buttons should be ]
- "Run AppleScript" "ShortMailDownload"
- 4) When saving you may get a warning message that some other app, Mail, has made changes to the script. When ever the script is run, the script changes a global variable which modifies the script. Ignore and save any way.
- Limitation: Yosemite, 10.10.5, Mail Version 8.2 (2104) only supports extracting one attachment. No problem in High Sierra, 10.13.6.
- off topic. Clicking on menu item:
- tell application "System Events" to click menu item "Date" of menu "Sort By" of menu item "Sort By" of menu "View" of menu bar item "View" of menu bar 1 of process "Mail"
- Based on the example " Sample Rule Action Script.scpt" script in macOS 10.6.8 found in folder
- "/Library/Scripts /Library/Scripts/Mail Scripts/Rule Actions"
- Sample Rule Action Script.scpt
- I think "on perform mail action" needs to be the first "on" routine.
- -- If run as an ordinary script, instead of directly from the Scripts
- -- menu, it will call the default handler instead.
- on r u n
- tell application "Mail" to set selectedMessages to selection
- tell me to perform mail action with messages (selectedMessages)
- end r u n
- http://hints.macworld.com/article.php?story=20070215145127300
- There is lots of outdated advice on download attachments found by Google.
- https://stackoverflow.com/questions/39882312/how-to-download-an-attachment-from-mail-via-applescript-and-mail-rules
- Copyright 2018 rccharles
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- *)
- (* Uncomment when you want to debug this script in the Script Editor. Go into Mail and select a message. Run this script. *)
- (*
- on run
- tell application "Mail"
- try
- set theSelectedMessages to selection
- log "class of theSelectedMessages is " & class of theSelectedMessages
- log "count of theSelectedMessages is " & (count of theSelectedMessages)
- on error errMsg number n
- display dialog "Silly, you need to select a message in Mail." & return & "on error the errMsg is " & errMsg & " number is " & n giving up after 8
- return
- end try
- -- not used, don't know how to pass to perform ...
- set theRule to {name:"dummyRule"}
- tell me to perform mail action with messages theSelectedMessages -- for theRule
- end tell -- app "Mail"
- end run
- *)
- (**)
- using terms from application "Mail"
- on perform mail action with messages theMessages --for rule theRule
- -- Suggest this code be the first "on" in file, no on r u n & no assumed on r u n either
- -- Required by debug routine.
- global debugRunning
- set debugRunning to ""
- -- debug status for displaying messages in this routine.
- set debugSwitch to true
- log "debugSwitch is " & debugSwitch
- -- initialize
- set longWait to 20
- (*
- Where to place files
- *)
- -- intermediate folder in Home folder
- -- must be Downloads for later version of macOS
- set intermediateDownloadFolder to "Downloads:"
- -- Folder inside of Downloads folder
- set intermediateSubFolder to "subFolderForMailDownload"
- -- final destination folder in Home folder
- set finalDestination to "Students"
- set startMsg to "perform mail with " & getMyName() & " ====== " & ((current date) as string) & " ====== perform mail "
- my debugLog(startMsg)
- --display dialog startMsg giving up after 2
- set intermediateFolder to intermediateDownloadFolder & intermediateSubFolder
- log "intermediateFolder is " & intermediateFolder
- if (count of theMessages) = 0 then
- log "odd no messages to process."
- display dialog "Odd, no messages to process." giving up after longWait
- return 1
- end if
- -- mail requires download to the Downloads or subfolders of Downloads
- -- for some reason, this gets the path to this app when invoked by mail.
- set pathToHome to (path to home folder) as string
- log ("pathToHome is " & pathToHome)
- set listOfPathToHome to textToList(pathToHome, ":")
- set pathToHome to item 1 of listOfPathToHome & ":" & item 2 of listOfPathToHome & ":" & item 3 of listOfPathToHome & ":"
- log ("revised pathToHome is " & pathToHome)
- -- make intermediate folder
- try
- tell application "Finder"
- set newfolder to make new folder at (pathToHome & intermediateDownloadFolder) with properties {name:intermediateSubFolder}
- my debugLog("Created folder " & pathToHome & intermediateDownloadFolder & intermediateSubFolder)
- end tell
- on error errMsg number n
- -- It's ok if the folder already exits [ -48 ]. Put out warning for all other errors.
- if n is not -48 then
- set commonError to "on error " & intermediateSubFolder & " the errMsg is " & errMsg & " number is " & n
- display dialog commonError giving up after longWait
- my debugLog(commonError)
- return 2
- end if
- end try
- -- make final destination folder
- try
- tell application "Finder"
- set newfolder to make new folder at pathToHome with properties {name:finalDestination}
- my debugLog("Created final destination folder " & pathToHome & finalDestination)
- end tell
- on error errMsg number n
- -- It's ok if the folder already exits [ -48 ]. Put out warning for all other errors.
- if n is not -48 then
- set commonError to "on error " & finalDestination & " errMsg is " & errMsg & " number is " & n
- display dialog commonError giving up after longWait
- my debugLog(commonError)
- return 3
- end if
- end try
- tell application "Mail"
- --activate
- log "was activated"
- -- look throught the messages we selected.
- repeat with aMessage in theMessages -- loop through each message
- log "class of aMessage is " & class of aMessage
- -- get the senders email address
- set fromMail to aMessage's sender
- my debugLog("fromMail is " & fromMail)
- -- Create folder for the individual student.
- -- ---- Set final target folder ---->
- set pathToStudents to pathToHome & finalDestination & ":"
- my debugLog("pathToStudents is " & pathToStudents)
- repeat 1 times -- sinulate continue
- try
- tell application "Finder"
- set newStudent to make new folder at pathToStudents with properties {name:fromMail}
- my debugLog("Created final destination subfolder " & pathToStudents & fromMail)
- end tell
- on error errMsg number n
- -- It's ok if the folder already exits [-48 ]. Put out warning for all other errors.
- if n is not -48 then
- set commonError to "attempting to create " & pathToStudents & fromMail & return & " on error the errMsg is " & errMsg & " number is " & n
- display dialog commonError giving up after longWait
- my debugLog(commonError)
- exit repeat -- look at next message. simulate iterate here.
- end if
- end try
- set pathToTheStudent to pathToStudents & fromMail & ":"
- my debugLog("pathToTheStudent is " & pathToTheStudent)
- -- repeat with aFile in aMessage's mail attachments
- -- set ourList to every mail attachment of aMessage
- repeat with aFile in (mail attachments of aMessage)
- log "save aFile"
- repeat 1 times -- sinulate continue
- --if (downloaded of aFile) then -- check if file is already downloaded
- set attachmentName to name of aFile
- my debugLog("attachmentName is " & attachmentName)
- set {fileName, fileExt} to my getNameExt(attachmentName)
- log "fileName is " & fileName & " fileExt is " & fileExt
- -- ---- Intermediate folder target ---->
- -- apple changed mail to require the download to be in the downloads folder :-(
- set pathForDownload to pathToHome & intermediateFolder & ":"
- set clearCount to 0
- set destPath to pathForDownload & attachmentName
- set finalDestPath to pathToStudents & fromMail & ":" & attachmentName
- log "check for free name. clearCount is " & clearCount & return & " destPath is " & destPath & return & " finalDestPath is " & finalDestPath
- try
- repeat while my fileExists(destPath) or my fileExists(finalDestPath)
- if clearCount > 300 then
- set commonError to "could not find free name when searching for free name. clearCount is " & clearCount & " clean up intermediate and final foldrs. " & return & destPath & return & finalDestPath
- my debugLog(commonError)
- -- have to throw an error to get out of this repeat. Could have set a switch I guess.
- display dialog commonError giving up after longWait
- error "cannot find free file name" number 8110
- end if
- set clearCount to clearCount + 1
- log "clearCount is " & clearCount
- set destPath to pathForDownload & fileName & "#" & clearCount & "." & fileExt
- set finalDestPath to pathToStudents & fromMail & ":" & fileName & "#" & clearCount & "." & fileExt
- my debugLog("searching for free name. clearCount is " & clearCount & return & " destPath is " & destPath & return & " finalDestPath is " & finalDestPath)
- end repeat -- while
- on error errMsg number n
- if n is not 8110 then
- set commonError to "attempting to create free filename " & return & " on error the errMsg is " & errMsg & " number is " & n
- display dialog commonError giving up after longWait
- my debugLog(commonError)
- end if
- exit repeat -- look at next message. simulate iterate here.
- end try
- my debugLog("found usable name. destPath is " & destPath)
- save aFile in destPath as native format
- log "file was saved."
- -- move it right on to file location.
- -- debuggin to see if we got the right name
- my debugLog("Saved to intermediate. destPath is " & destPath)
- if my fileExists(destPath) then
- tell application "Finder"
- try
- -- from file filename path to full folder name path :-(.
- move destPath to pathToTheStudent
- my debugLog("saved to final folder pathToTheStudent is " & pathToTheStudent)
- on error msg number n
- set outMsg to "Got error message while moving " & destPath & " to " & pathToTheStudent & return & "message is " & msg & return & "number is " & n
- my debugLog(outMsg)
- display dialog outMsg giving up after longWait
- -- might as well try the next attachment
- exit repeat -- look at next message. simulate iterate here.
- end try
- end tell
- else
- -- very bad, folder doesn't exist as expected.
- my debugLog("very bad, folder " & destPath & " doesn't exist as expected.")
- exit repeat -- look at next message. simulate iterate here.
- end if
- end repeat -- one time to make like a continue statment
- end repeat -- next attached file
- end repeat -- continue
- end repeat -- next message
- end tell --tell app "Mail"
- return 0
- end perform mail action with messages
- end using terms from
- (* ======================== Subroutines ======================= *)
- -- ------------------------------------------------------
- (*
- *)
- on appendToFile(fileId, theData)
- local theSize, writeWhere
- set theSize to (get eof fileId)
- set writeWhere to theSize + 1 as integer
- write theData to fileId starting at writeWhere
- end appendToFile
- -- ------------------------------------------------------
- (*
- debug(<string>)
- Write messages to a log file.
- -- Need to place these two lines in the calling routine.
- global debugRunning
- set debugRunning to ""
- -- references appendToFile()
- -- example:
- debug("start program. Reading from " & listOfFiles)
- found here: /Users/mac/Documents/BJ\ Prior\ Years/BJ2004/sendmailapp2\ copy
- *)
- on debug(theMessage)
- -- return
- global debugRunning
- local theSize, startupDiskName, pathToLog, fileReference
- set pathToLog to (path to home folder as text) & "tryAttachmentsLog.txt"
- -- log "pathToLog is " & pathToLog
- -- display dialog "pathToLog is " & pathToLog giving up after 4
- try
- -- Complete the path.
- set pathToLog to pathToLog as text
- set fileReference to (open for access file pathToLog ¬
- with write permission)
- if debugRunning = "" then
- set theSize to (get eof fileReference)
- if theSize > 0 then
- appendToFile(fileReference, " " & return)
- end if
- appendToFile(fileReference, " --- debug on " & ((current date) as string) & " --- " & return)
- set debugRunning to "running"
- end if
- -- log "theMessage " & theMessage
- -- display dialog "in debug..." & return & "theMessage " & theMessage giving up after 3
- appendToFile(fileReference, theMessage & return)
- close access fileReference
- tell application "Finder"
- set the creator type of the file pathToLog ¬
- to "R*ch"
- end tell
- on error mes number n
- try
- set commonErr to "error ... " & mes & " error number is " & n
- log commonErr
- close access fileReference
- display dialog commonErr giving up after 4
- end try
- end try
- -- log "end of debug"
- end debug
- (*
- write log message to script editor log and to our file log
- *)
- on debugLog(theMessage)
- log "debugLog: " & theMessage
- return debug(theMessage)
- end debugLog
- -- ------------------------------------------------------
- (*
- ideas from:
- https://stackoverflow.com/questions/3469389/applescript-testing-for-file-existence
- use the alias way.
- *)
- on fileExists(theFile) -- (String) as Boolean
- (* "System Events" and "Finder" checking for file existance revealed problems. l*)
- set debugging to false
- if debugging then log " fileExists: theFile is " & theFile
- try
- set theAlias to theFile as alias
- set theExistance to true
- on error errMsg number n
- if debugging then log " fileExists: n is " & n
- -- File or folder doesn't exist.
- if n is not -43 then
- set commonError to "on error the errMsg is " & errMsg & " number is " & n
- if debugging then log " fileExists: " & commonError
- display dialog commonError giving up after 10
- -- cause grief above.
- error "Failure of alias." number -1
- else
- set theExistance to false
- end if
- end try
- if debugging then log " fileExists: theExistance is " & theExistance
- return theExistance
- end fileExists
- (*
- Philip Regan
- https://stackoverflow.com/questions/3469389/applescript-testing-for-file-existence
- *)
- (*on fileExists(theFile) -- (String) as Boolean
- tell application "System Events"
- if exists file theFile then
- return true
- else
- return false
- end if
- end tell
- end fileExists*)
- -- ------------------------------------------------------
- (*
- Yvan Koenig
- https://macscripter.net/viewtopic.php?id=43133
- with mods for no extension present
- *)
- on getExt(theName)
- if (offset of "." in theName) is greater than 0 then
- set saveTID to AppleScript's text item delimiters
- set AppleScript's text item delimiters to {"."}
- set theExt to last text item of theName
- set AppleScript's text item delimiters to saveTID
- if theExt ends with ":" then set theExt to text 1 thru -2 of theExt
- else
- set theExt to ""
- end if
- return theExt
- end getExt
- -- ------------------------------------------------------
- (*
- Input: a file with or without an extension.
- hhas
- https://forums.macrumors.com/threads/applescript-to-get-file-name.927338/
- may not work with folders with extensions like apps.
- Test cases:
- set fileName to " "
- set fileExt to my getExt(attachmentName)
- log "fileName is " & fileName & " fileExt is " & fileExt
- set fileExt to my getExt("testfileNo")
- log "fileName is " & fileName & " fileExt is " & fileExt
- set fileExt to my getExt("path:to:testfileNo:")
- log "fileName is " & fileName & " fileExt is " & fileExt
- log ">>>>>>>>>>>>>>>>>>>>>>"
- set {fileName, fileExt} to my getNameExt(attachmentName)
- log "fileName is " & fileName & " fileExt is " & fileExt
- set {fileName, fileExt} to my getNameExt("testfileNo")
- log "fileName is " & fileName & " fileExt is " & fileExt
- set {fileName, fileExt} to my getNameExt("path:to:testfileNo:")
- log "fileName is " & fileName & " fileExt is " & fileExt
- *)
- on getNameExt(fileName)
- set saveTID to AppleScript's text item delimiters
- set AppleScript's text item delimiters to "."
- if fileName contains "." then
- set {displayName, nameExt} to {text 1 thru text item -2, text item -1} of fileName
- else
- set {displayName, nameExt} to {fileName, ""}
- end if
- set AppleScript's text item delimiters to saveTID
- return {displayName, nameExt}
- end getNameExt
- -- ------------------------------------------------------
- (*
- modified to let the extension be.
- by mklement0
- https://stackoverflow.com/questions/5770384/how-find-the-file-name-of-an-executing-applescript
- *)
- on getMyName()
- local myAlias, myName
- tell application "System Events"
- set myAlias to path to me -- alias to the file/bundle of the running script
- set myName to name of myAlias -- filename with extension, if any.
- -- leave extension alone.
- end tell
- return myName
- end getMyName
- -- ------------------------------------------------------
- (*
- ls_l is list file with options
- the format is best for debuging.
- example usage:
- set {fileExists, fromUnix} to ls_l(attachmentNamePath, "-l")
- log "attachmentNamePath fileExists is " & fileExists & return & " fromUnix is " & fromUnix
- *)
- on ls_l(attachmentNamePath, options)
- --log "ls_l"
- --log options
- set unixAttachmentNamePath to POSIX path of attachmentNamePath
- --log "unixDesktopPath = " & unixAttachmentNamePath
- set quotedUnixAttachmentNamePath to quoted form of unixAttachmentNamePath
- --log "quoted form is " & quotedUnixAttachmentNamePath
- try
- set fromUnix to do shell script "ls " & options & " " & quotedUnixAttachmentNamePath
- set fromUnix to "ls " & options & return & fromUnix
- set fileExists to true
- on error errMsg number n
- set fromUnix to "ls " & options & " error..." & errMsg & " with number " & n
- set fileExists to false
- end try
- return {fileExists, fromUnix}
- end ls_l
- -- ------------------------------------------------------
- (*
- textToList seems to be what you are trying to do
- thisText is the input string
- delim is what to split on
- returns a list of strings.
- - textToList was found here:
- - http://macscripter.net/viewtopic.php?id=15423
- *)
- on textToList(thisText, delim)
- set resultList to {}
- set {tid, my text item delimiters} to {my text item delimiters, delim}
- try
- set resultList to every text item of thisText
- set my text item delimiters to tid
- on error
- set my text item delimiters to tid
- end try
- return resultList
- end textToList
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement