Mich hat heute eine Email erreicht, in der mir folgende Aufgabe beschrieben wurde (Ich hoffe mal Udo ist mit der Veröffentlichung einverstanden, hätte ich selber nicht besser formulieren können.):
Ich möchte eine Mail in Mail.app anklicken, danach sollte die Mail als pdf (wie unter Ablage Drucken PDF Als PDF sichern) in einem speziellen Ordner auf dem Schreibtisch mit folgendem Namen (Sendedatum, E-Mail-Adresse und Betreff aus Mail) gesichert werden. Der eventuelle Anhang sollte ebenfalls in diesem Ordner gesichert werden. Die Mail kann danach gelöscht werden.
zusammen mit dieser Aufgabenstellung und den ersten Code-Zeilen von Udo ist dann das hier entstanden (ich mag zwar GUI-Scripting nicht, aber das hier ROCKT ;-) ):
-- Save Mail as PDF and it's attachments to folder
-- Created by hubionmac (22.03.2010) requested by Udo
global frontmost_message_viewer
--this is the posix (unix) path of the folder you would like to store the messages in
tell application "Finder" to set mymailboxpath to POSIX path of ((desktop) as alias) & "mail_box/"
tell application "Mail"
set myselection to my check_message_viewer_and_return_selection()
--works only with one selected message for many reasons...
if (count of myselection) = 1 then
repeat with currentMail in myselection
set currentSender to my (getEmail(sender of currentMail))
set currentDateSent to my getDatestring(date sent of currentMail)
set currentSubject to my replace_chars(my replace_chars(subject of currentMail, ":", "-"), "/", ":") --Doppelpunkte kommen bei Dateinamen nicht so gut
set currentFolder2Store to mymailboxpath & currentDateSent & " " & currentSender & " " & currentSubject & "/" as rich text
my create_messagefolder(currentFolder2Store)
repeat with a in (every mail attachment of currentMail)
set current_a_name to name of a
set current_a_name to my checkname_with_pdf_suffix(current_a_name, (POSIX file currentFolder2Store) as alias, false)
save a in (((POSIX file currentFolder2Store) as rich text) & current_a_name) as rich text
end repeat
set desktop_pdf_name to my checkname_with_pdf_suffix("1.pdf", path to desktop, false)
set the clipboard to desktop_pdf_name
my print_current_mail_as_pdf()
repeat until (index of window of frontmost_message_viewer) is 1
delay 1
end repeat
my move_desktop_pdf(desktop_pdf_name, currentFolder2Store)
--open destination folder in finder ( did it really work? YES!! =))
do shell script "open " & quoted form of currentFolder2Store
end repeat
else
error "Sorry, ich kann zur Zeit nur mit einer ausgewählten Email hantieren"
end if
end tell
to move_desktop_pdf(desktop_pdf_name, currentFolder2Store)
--used to move the printed pdf to it's final destination
set finalname to checkname_with_pdf_suffix("__message.pdf", (POSIX file currentFolder2Store) as alias, false)
try
tell application "Finder" to do shell script "mv " & POSIX path of ((desktop) as alias) & quoted form of desktop_pdf_name & " " & quoted form of currentFolder2Store & quoted form of finalname
on error msg
error "Fehler beim Bewegen der gedruckten Nachricht: " & msg as text
end try
end move_desktop_pdf
to getEmail(mailstring)
-- if an email contains the senders name like "Mr.Bla <bla@bla.com>" then returns just the email not leaves the name
if mailstring contains "<" then
return (characters ((offset of "<" in mailstring) + 1) through ((offset of ">" in mailstring) - 1) of mailstring) as text
else
return mailstring
end if
end getEmail
to getDatestring(thedate)
--format a date to a string like 2010-03-22
set monthnum to characters -2 through -1 of ("0" & ((month of thedate) as integer)) as text
set daynum to characters -2 through -1 of ("0" & ((day of thedate) as integer)) as text
set yearnum to year of the thedate
return yearnum & "-" & monthnum & "-" & daynum as text
end getDatestring
to create_messagefolder(thepath_posix)
--I love mkdir -p, simple, short, easy to use
try
do shell script "mkdir -p " & quoted form of thepath_posix
on error msg
error msg
end try
end create_messagefolder
to replace_chars(this_text, search_string, replacement_string)
--this replaces characters
--used for folder and filenames, since a : must not be used for that
if this_text contains the search_string then
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to ""
end if
return this_text
end replace_chars
to checkname_with_pdf_suffix(n, D, looped)
--check if filename exists in D
-- so if "A File.pdf" exists it names it "A File 1.pdf","A File 2.pdf",...
tell application "Finder"
set thefiles to name of every item of (D as alias)
end tell
if thefiles contains n then
if looped = false then
set n to ((characters 1 through -5 of n) & " 1" & (characters -4 through -1 of n)) as text
my checkname_with_pdf_suffix(n, D, true)
else
set tmp to (last word of ((characters 1 through -5 of n) as text) as integer)
set tmpcount to (count of characters of (tmp as text)) + 5
set tmp to tmp + 1
set n to ((characters 1 through (-1 * tmpcount) of n) & tmp & (characters -4 through -1 of n)) as text
my checkname_with_pdf_suffix(n, D, true)
end if
else
return n
end if
end checkname_with_pdf_suffix
to print_current_mail_as_pdf()
--hopefully works on every mac in every language =)
-- GUI-Scripting is not the best way, but somehow the only way at the moment :-/
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
keystroke "p" using command down
set p to "false"
repeat with i from 1 to 10
if (count of every sheet of window 1) > 0 then
set p to "ready"
exit repeat
end if
delay 1
end repeat
if p = "ready" then
click menu button 1 of sheet 1 of window 1
delay 0.25
key code 125
key code 125
delay 0.25
keystroke return
delay 1
click text field 1 of window 1
keystroke "a" using command down
keystroke "v" using command down
keystroke "d" using command down
keystroke return
else
error "timeout"
end if
end tell
end tell
end tell
end print_current_mail_as_pdf
to check_message_viewer_and_return_selection()
-- check if frontmost window is a message viewer, otherwhise tell the user to RTFM!... wait there is no manual... don't care error change user!
tell application "Mail"
set frontmost_message_viewer to {}
repeat with i from 1 to count of every message viewer
if index of window of message viewer i = 1 then
set frontmost_message_viewer to message viewer i
exit repeat
end if
end repeat
if frontmost_message_viewer = {} then
error "Ist ja gar kein Message Viewer im Vordergrund, so kann ich einfach nicht arbeiten!"
else
return selection
end if
end tell
end check_message_viewer_and_return_selection
In habe mal auf das Löschen der Email verzichtet (das soll mal jeder lieber alleine rein schreiben), aber es scheint wunderbar zu funktionieren. Bin mal gespannt ob es auch bei anderen läuft…
Updates vom 29.09.2010 und 27.09.2011:
- Auswahl von mehren Emails wird nun auch möglich
- Abgesendete Emails werden als solche erkannt und in einem anderen Verzeichnis mit Empfänger-Adresse im Ordnernamen gespeichert (req. by Andreas)
- Lokale Email-Ordner funktionieren nun auch mit dem Skript
-- Save Mail as PDF and it's attachments to folder
-- Created by hubionmac (29.09.2010)
-- 29.09.2010
-- -Auswahl von mehren Emails wird nun auch möglich
-- -Abgesendete Emails werden als solche erkannt und in einem anderen Verzeichnis mit Empfänger-Adresse im Ordnernamen gespeichert (req. by Andreas)
-- 27.09.2011 made it work with local mailboxes, too
global frontmost_message_viewer
--this is the posix (unix) path of the folder you would like to store the messages in
tell application "Finder" to set mymailboxpath to POSIX path of ((desktop) as alias) & "received_mail_box/"
tell application "Finder" to set mysentmailboxpath to POSIX path of ((desktop) as alias) & "sent_mail_box/"
tell application "Mail"
set myselection to my check_message_viewer_and_return_selection()
repeat with currentMail in myselection
open currentMail
set currentSender to my (getEmail(sender of currentMail))
set currentDateSent to my getDatestring(date sent of currentMail)
set currentSubject to my replace_chars(my replace_chars(subject of currentMail, ":", "-"), "/", "--") --Doppelpunkte kommen bei Dateinamen nicht so gut
if my is_in_sent_mail(currentMail) is true then
--if the file was sent FROM this email account
set sentToEmail to address of item 1 of to recipient of currentMail
set currentFolder2Store to mysentmailboxpath & sentToEmail & " " & currentDateSent & " " & currentSubject & "/" as rich text
else
--if the email was sent TO this email account
try
set myemail to item 1 of (get email addresses of account of mailbox of currentMail)
on error
--27.09.2011 added to make it work with local mailboxes, too
set myemail to item 1 of (get address of to recipient of currentMail)
end try
set currentFolder2Store to mymailboxpath & currentDateSent & " " & currentSender & " " & currentSubject & " send to" & myemail & "/" as rich text
end if
my create_messagefolder(currentFolder2Store)
repeat with a in (every mail attachment of currentMail)
set current_a_name to name of a
set current_a_name to my checkname_with_pdf_suffix(current_a_name, (POSIX file currentFolder2Store) as alias, false)
save a in (((POSIX file currentFolder2Store) as rich text) & current_a_name) as rich text
end repeat
set desktop_pdf_name to my checkname_with_pdf_suffix("1.pdf", path to desktop, false)
set the clipboard to desktop_pdf_name
tell application "System Events"
tell process "Mail"
set wc to count of every window
end tell
end tell
my print_current_mail_as_pdf()
tell application "System Events"
tell process "Mail"
repeat until (count of every window) is wc
end repeat
end tell
end tell
my move_desktop_pdf(desktop_pdf_name, currentFolder2Store)
--close last_message window
activate
tell application "System Events"
tell process "Mail"
keystroke "w" using command down
end tell
end tell
--open destination folder in finder ( did it really work? YES!! =))
--do shell script "open " & quoted form of currentFolder2Store
end repeat
end tell
to move_desktop_pdf(desktop_pdf_name, currentFolder2Store)
--used to move the printed pdf to it's final destination
set finalname to checkname_with_pdf_suffix("__message.pdf", (POSIX file currentFolder2Store) as alias, false)
try
tell application "Finder" to do shell script "mv " & POSIX path of ((desktop) as alias) & quoted form of desktop_pdf_name & " " & quoted form of currentFolder2Store & quoted form of finalname
on error msg
error "Fehler beim Bewegen der gedruckten Nachricht: " & msg as text
end try
end move_desktop_pdf
to getEmail(mailstring)
-- if an email contains the senders name like "Mr.Bla <bla@bla.com>" then returns just the email not leaves the name
if mailstring contains "<" then
return (characters ((offset of "<" in mailstring) + 1) through ((offset of ">" in mailstring) - 1) of mailstring) as text
else
return mailstring
end if
end getEmail
to getDatestring(thedate)
--format a date to a string like 2010-03-22
set monthnum to characters -2 through -1 of ("0" & ((month of thedate) as integer)) as text
set daynum to characters -2 through -1 of ("0" & ((day of thedate) as integer)) as text
set yearnum to year of the thedate
return yearnum & "-" & monthnum & "-" & daynum as text
end getDatestring
to create_messagefolder(thepath_posix)
--I love mkdir -p, simple, short, easy to use
try
do shell script "mkdir -p " & quoted form of thepath_posix
on error msg
error msg
end try
end create_messagefolder
to replace_chars(this_text, search_string, replacement_string)
--this replaces characters
--used for folder and filenames, since a : must not be used for that
if this_text contains the search_string then
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to ""
end if
return this_text
end replace_chars
to checkname_with_pdf_suffix(n, D, looped)
--check if filename exists in D
-- so if "A File.pdf" exists it names it "A File 1.pdf","A File 2.pdf",...
tell application "Finder"
set thefiles to name of every item of (D as alias)
end tell
if thefiles contains n then
if looped = false then
set n to ((characters 1 through -5 of n) & " 1" & (characters -4 through -1 of n)) as text
my checkname_with_pdf_suffix(n, D, true)
else
set tmp to (last word of ((characters 1 through -5 of n) as text) as integer)
set tmpcount to (count of characters of (tmp as text)) + 5
set tmp to tmp + 1
set n to ((characters 1 through (-1 * tmpcount) of n) & tmp & (characters -4 through -1 of n)) as text
my checkname_with_pdf_suffix(n, D, true)
end if
else
return n
end if
end checkname_with_pdf_suffix
to print_current_mail_as_pdf()
--hopefully works on every mac in every language =)
-- GUI-Scripting is not the best way, but somehow the only way at the moment :-/
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
keystroke "p" using command down
set p to "false"
repeat until 0 = 1
if (count of every sheet of window 1) > 0 then
set p to "ready"
exit repeat
end if
end repeat
if p = "ready" then
click menu button 1 of sheet 1 of window 1
delay 0.25
key code 125
key code 125
delay 0.25
set cwc to count of every window
keystroke return
repeat until 1 = 0
if (cwc + 1) = (count of every window) then
exit repeat
end if
end repeat
click text field 1 of window 1
keystroke "a" using command down
keystroke "v" using command down
keystroke "d" using command down
keystroke return
else
error "timeout"
end if
end tell
end tell
end tell
end print_current_mail_as_pdf
to check_message_viewer_and_return_selection()
-- check if frontmost window is a message viewer, otherwhise tell the user to RTFM!... wait there is no manual... don't care error change user!
tell application "Mail"
set frontmost_message_viewer to {}
repeat with i from 1 to count of every message viewer
if index of window of message viewer i = 1 then
set frontmost_message_viewer to message viewer i
exit repeat
end if
end repeat
if frontmost_message_viewer = {} then
error "Ist ja gar kein Message Viewer im Vordergrund, so kann ich einfach nicht arbeiten!"
else
return selection
end if
end tell
end check_message_viewer_and_return_selection
on is_in_sent_mail(amessage)
tell application "Mail"
set sentmailboxes to every mailbox of sent mailbox
set currentmailbox to mailbox of amessage
repeat with i from 1 to (count of sentmailboxes)
if item i of sentmailboxes = currentmailbox then
return true
end if
end repeat
return false
end tell
end is_in_sent_mail
Update vom 17.04.2012:
Das Skript funktionierte leider nicht mehr unter 10.7… tja jetzt schon wieder… dazu mussten die Pfade etwas angepasst werden
-- Save Mail as PDF and it's attachments to folder
-- Created by hubionmac (29.09.2010)
-- 29.09.2010
-- -Auswahl von mehren Emails wird nun auch möglich
-- -Abgesendete Emails werden als solche erkannt und in einem anderen Verzeichnis mit Empfänger-Adresse im Ordnernamen gespeichert (req. by Andreas)
-- 27.09.2011 made it work with local mailboxes, too
##2012-04-17 changed the way paths are formated (posix/mac) and now the script runs on 10.7 again =)
global frontmost_message_viewer
--this is the posix (unix) path of the folder you would like to store the messages in
set mymailboxpath to (path to "desk") & "received_mail_box:" as text
set mysentmailboxpath to (path to "desk") & "sent_mail_box:" as text
tell application "Mail"
set myselection to my check_message_viewer_and_return_selection()
repeat with currentMail in myselection
open currentMail
set currentSender to my (getEmail(sender of currentMail))
set currentDateSent to my getDatestring(date sent of currentMail)
set currentSubject to my replace_chars(my replace_chars(subject of currentMail, ":", "-"), "/", "--") --Doppelpunkte kommen bei Dateinamen nicht so gut
if my is_in_sent_mail(currentMail) is true then
--if the file was sent FROM this email account
set sentToEmail to address of item 1 of to recipient of currentMail
set currentFolder2Store to mysentmailboxpath & sentToEmail & " " & currentDateSent & " " & currentSubject & ":" as rich text
else
--if the email was sent TO this email account
try
set myemail to item 1 of (get email addresses of account of mailbox of currentMail)
on error
--27.09.2011 added to make it work with local mailboxes, too
set myemail to item 1 of (get address of to recipient of currentMail)
end try
set currentFolder2Store to mymailboxpath & currentDateSent & " " & currentSender & " " & currentSubject & " send to " & myemail & ":" as rich text
end if
my create_messagefolder(currentFolder2Store)
repeat with a in (every mail attachment of currentMail)
set current_a_name to name of a
set current_a_name to my checkname_with_pdf_suffix(current_a_name, currentFolder2Store, false)
display dialog (currentFolder2Store & current_a_name) as rich text
save a in (currentFolder2Store & current_a_name as rich text)
end repeat
set desktop_pdf_name to my checkname_with_pdf_suffix("1.pdf", path to desktop, false)
set the clipboard to desktop_pdf_name
tell application "System Events"
tell process "Mail"
set wc to count of every window
end tell
end tell
my print_current_mail_as_pdf()
tell application "System Events"
tell process "Mail"
repeat until (count of every window) is wc
end repeat
end tell
end tell
my move_desktop_pdf(desktop_pdf_name, currentFolder2Store)
--close last_message window
activate
tell application "System Events"
tell process "Mail"
keystroke "w" using command down
end tell
end tell
--open destination folder in finder ( did it really work? YES!! =))
--do shell script "open " & quoted form of currentFolder2Store
end repeat
end tell
to move_desktop_pdf(desktop_pdf_name, currentFolder2Store)
--used to move the printed pdf to it's final destination
set finalname to checkname_with_pdf_suffix("__message.pdf", currentFolder2Store, false)
try
do shell script "mv " & POSIX path of (path to "desk") & quoted form of desktop_pdf_name & " " & quoted form of POSIX path of currentFolder2Store & quoted form of finalname
on error msg
error "Fehler beim Bewegen der gedruckten Nachricht: " & msg as text
end try
end move_desktop_pdf
to getEmail(mailstring)
-- if an email contains the senders name like "Mr.Bla <bla@bla.com>" then returns just the email not leaves the name
if mailstring contains "<" then
return (characters ((offset of "<" in mailstring) + 1) through ((offset of ">" in mailstring) - 1) of mailstring) as text
else
return mailstring
end if
end getEmail
to getDatestring(thedate)
--format a date to a string like 2010-03-22
set monthnum to characters -2 through -1 of ("0" & ((month of thedate) as integer)) as text
set daynum to characters -2 through -1 of ("0" & ((day of thedate) as integer)) as text
set yearnum to year of the thedate
return yearnum & "-" & monthnum & "-" & daynum as text
end getDatestring
to create_messagefolder(thepath)
--I love mkdir -p, simple, short, easy to use
try
do shell script "mkdir -p " & quoted form of POSIX path of thepath
on error msg
error msg
end try
end create_messagefolder
to replace_chars(this_text, search_string, replacement_string)
--this replaces characters
--used for folder and filenames, since a : must not be used for that
if this_text contains the search_string then
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to ""
end if
return this_text
end replace_chars
to checkname_with_pdf_suffix(n, D, looped)
--check if filename exists in D
-- so if "A File.pdf" exists it names it "A File 1.pdf","A File 2.pdf",...
tell application "Finder"
set thefiles to name of every item of (D as alias)
end tell
if thefiles contains n then
if looped = false then
set n to ((characters 1 through -5 of n) & " 1" & (characters -4 through -1 of n)) as text
my checkname_with_pdf_suffix(n, D, true)
else
set tmp to (last word of ((characters 1 through -5 of n) as text) as integer)
set tmpcount to (count of characters of (tmp as text)) + 5
set tmp to tmp + 1
set n to ((characters 1 through (-1 * tmpcount) of n) & tmp & (characters -4 through -1 of n)) as text
my checkname_with_pdf_suffix(n, D, true)
end if
else
return n
end if
end checkname_with_pdf_suffix
to print_current_mail_as_pdf()
--hopefully works on every mac in every language =)
-- GUI-Scripting is not the best way, but somehow the only way at the moment :-/
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
keystroke "p" using command down
set p to "false"
repeat until 0 = 1
if (count of every sheet of window 1) > 0 then
set p to "ready"
exit repeat
end if
end repeat
if p = "ready" then
click menu button 1 of sheet 1 of window 1
delay 0.25
key code 125
key code 125
delay 0.25
set cwc to count of every window
keystroke return
repeat until 1 = 0
if (cwc + 1) = (count of every window) then
exit repeat
end if
end repeat
click text field 1 of window 1
keystroke "a" using command down
keystroke "v" using command down
keystroke "d" using command down
keystroke return
else
error "timeout"
end if
end tell
end tell
end tell
end print_current_mail_as_pdf
to check_message_viewer_and_return_selection()
-- check if frontmost window is a message viewer, otherwhise tell the user to RTFM!... wait there is no manual... don't care error change user!
tell application "Mail"
set frontmost_message_viewer to {}
repeat with i from 1 to count of every message viewer
if index of window of message viewer i = 1 then
set frontmost_message_viewer to message viewer i
exit repeat
end if
end repeat
if frontmost_message_viewer = {} then
error "Ist ja gar kein Message Viewer im Vordergrund, so kann ich einfach nicht arbeiten!"
else
return selection
end if
end tell
end check_message_viewer_and_return_selection
on is_in_sent_mail(amessage)
tell application "Mail"
set sentmailboxes to every mailbox of sent mailbox
set currentmailbox to mailbox of amessage
repeat with i from 1 to (count of sentmailboxes)
if item i of sentmailboxes = currentmailbox then
return true
end if
end repeat
return false
end tell
end is_in_sent_mail
Update vom 18.02.2013:
Das Skript funktionierte leider nicht mehr unter 10.8… tja jetzt schon wieder… habe ich schon mal gesagt, dass GUI-Scripting doof ist? Ok, zudem spielte da auch noch Gatekeeper mit rein. Man darf Attachments nur noch im dafür ausgewiesenen Download-Order per Skript speichern. Anschließend darf man diese aber auch wieder verschieben, nervig, aber nicht sicher ;-)
-- Save Mail as PDF and it's attachments to folder
-- Created by hubionmac (29.09.2010)
-- 29.09.2010
-- -Auswahl von mehren Emails wird nun auch möglich
-- -Abgesendete Emails werden als solche erkannt und in einem anderen Verzeichnis mit Empfänger-Adresse im Ordnernamen gespeichert (req. by Andreas)
-- 27.09.2011 made it work with local mailboxes, too
##2012-04-17 changed the way paths are formated (posix/mac) and now the script runs on 10.7 again =)
##2013-02-18 Updated code so that it works using 10.8.3 (new dialogs and new gatekeeper made this necessary)
global frontmost_message_viewer
--this is the posix (unix) path of the folder you would like to store the messages in
set mymailboxpath to (path to "desk") & "received_mail_box:" as text
set mysentmailboxpath to (path to "desk") & "sent_mail_box:" as text
my checkIfUIElementsAreEnabled()
tell application "Finder"
set os_version to version
end tell
if os_version does not start with "10.8" then
error "This Script was only tested using 10.8… I quit here…"
end if
tell application "Mail"
set downloadFolder to ((path to home folder) as rich text) & "Downloads:"
set myselection to my check_message_viewer_and_return_selection()
repeat with currentMail in myselection
open currentMail
set currentSender to my (getEmail(sender of currentMail))
set currentDateSent to my getDatestring(date sent of currentMail)
set currentSubject to my replace_chars(my replace_chars(subject of currentMail, ":", "-"), "/", "--") --Doppelpunkte kommen bei Dateinamen nicht so gut
if my is_in_sent_mail(currentMail) is true then
--if the file was sent FROM this email account
set sentToEmail to address of item 1 of to recipient of currentMail
set currentFolder2Store to mysentmailboxpath & sentToEmail & " " & currentDateSent & " " & currentSubject & ":" as rich text
else
--if the email was sent TO this email account
try
set myemail to item 1 of (get email addresses of account of mailbox of currentMail)
on error
--27.09.2011 added to make it work with local mailboxes, too
set myemail to item 1 of (get address of to recipient of currentMail)
end try
set currentFolder2Store to mymailboxpath & currentDateSent & " " & currentSender & " " & currentSubject & " send to " & myemail & ":" as rich text
end if
my create_messagefolder(currentFolder2Store)
repeat with a in (every mail attachment of currentMail)
set current_a_name to name of a
set current_a_name to my checkname_with_pdf_suffix(current_a_name, currentFolder2Store, false)
##10.8 fix… you may only save attachments in the download folder… this does not mean you cannot move it afterwards ;-)
save a in downloadFolder & current_a_name
set thefile to quoted form of POSIX path of (downloadFolder & current_a_name as alias)
set mypath to quoted form of POSIX path of currentFolder2Store
do shell script "mv -f " & thefile & " " & mypath
end repeat
set desktop_pdf_name to my checkname_with_pdf_suffix("1.pdf", path to desktop, false)
tell application "System Events"
tell process "Mail"
set wc to count of every window
end tell
end tell
my print_current_mail_as_pdf(desktop_pdf_name)
tell application "System Events"
tell process "Mail"
repeat until (count of every window) is wc
end repeat
end tell
end tell
my move_desktop_pdf(desktop_pdf_name, currentFolder2Store)
--close last_message window
activate
tell application "System Events"
tell process "Mail"
keystroke "w" using command down
end tell
end tell
--open destination folder in finder ( did it really work? YES!! =))
--do shell script "open " & quoted form of currentFolder2Store
end repeat
end tell
to move_desktop_pdf(desktop_pdf_name, currentFolder2Store)
--used to move the printed pdf to it's final destination
set finalname to checkname_with_pdf_suffix("__message.pdf", currentFolder2Store, false)
set movedIt to false
repeat with i from 1 to 10
try
do shell script "mv " & POSIX path of (path to "desk") & quoted form of desktop_pdf_name & " " & quoted form of POSIX path of currentFolder2Store & quoted form of finalname
set movedIt to true
exit repeat
end try
delay 1
end repeat
if movedIt is false then error "Fehler beim Bewegen der gedruckten Nachricht: " & msg as text
end move_desktop_pdf
to getEmail(mailstring)
-- if an email contains the senders name like "Mr.Bla <bla@bla.com>" then returns just the email not leaves the name
if mailstring contains "<" then
return (characters ((offset of "<" in mailstring) + 1) through ((offset of ">" in mailstring) - 1) of mailstring) as text
else
return mailstring
end if
end getEmail
to getDatestring(thedate)
--format a date to a string like 2010-03-22
set monthnum to characters -2 through -1 of ("0" & ((month of thedate) as integer)) as text
set daynum to characters -2 through -1 of ("0" & ((day of thedate) as integer)) as text
set yearnum to year of the thedate
return yearnum & "-" & monthnum & "-" & daynum as text
end getDatestring
to create_messagefolder(thepath)
--I love mkdir -p, simple, short, easy to use
try
do shell script "mkdir -p " & quoted form of POSIX path of thepath
on error msg
error msg
end try
end create_messagefolder
to replace_chars(this_text, search_string, replacement_string)
--this replaces characters
--used for folder and filenames, since a : must not be used for that
if this_text contains the search_string then
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to ""
end if
return this_text
end replace_chars
to checkname_with_pdf_suffix(n, D, looped)
--check if filename exists in D
-- so if "A File.pdf" exists it names it "A File 1.pdf","A File 2.pdf",...
tell application "Finder"
set thefiles to name of every item of (D as alias)
end tell
if thefiles contains n then
if looped = false then
set n to ((characters 1 through -5 of n) & " 1" & (characters -4 through -1 of n)) as text
my checkname_with_pdf_suffix(n, D, true)
else
set tmp to (last word of ((characters 1 through -5 of n) as text) as integer)
set tmpcount to (count of characters of (tmp as text)) + 5
set tmp to tmp + 1
set n to ((characters 1 through (-1 * tmpcount) of n) & tmp & (characters -4 through -1 of n)) as text
my checkname_with_pdf_suffix(n, D, true)
end if
else
return n
end if
end checkname_with_pdf_suffix
to print_current_mail_as_pdf(pdfname)
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
keystroke "p" using command down
set p to "false"
repeat until 0 = 1
if (count of every sheet of window 1) > 0 then
set p to "ready"
exit repeat
end if
end repeat
if p = "ready" then
click menu button 1 of sheet 1 of window 1
delay 0.25
key code 125
key code 125
delay 0.25
keystroke return
##wait until second sheet opened
delay 1
set value of text field 1 of sheet 1 of sheet 1 of window 1 to pdfname
keystroke "d" using command down
delay 0.25
keystroke return
else
error "timeout"
end if
end tell
end tell
end tell
end print_current_mail_as_pdf
to check_message_viewer_and_return_selection()
-- check if frontmost window is a message viewer, otherwhise tell the user to RTFM!... wait there is no manual... don't care error change user!
tell application "Mail"
set frontmost_message_viewer to {}
repeat with i from 1 to count of every message viewer
if index of window of message viewer i = 1 then
set frontmost_message_viewer to message viewer i
exit repeat
end if
end repeat
if frontmost_message_viewer = {} then
error "Ist ja gar kein Message Viewer im Vordergrund, so kann ich einfach nicht arbeiten!"
else
return selection
end if
end tell
end check_message_viewer_and_return_selection
on is_in_sent_mail(amessage)
##Just Try
try
tell application "Mail"
set sentmailboxes to every mailbox of sent mailbox
set currentmailbox to mailbox of amessage
repeat with i from 1 to (count of sentmailboxes)
if item i of sentmailboxes = currentmailbox then
return true
end if
end repeat
return false
end tell
end try
return false
end is_in_sent_mail
on checkIfUIElementsAreEnabled()
tell application "System Events"
get system attribute "sysv"
if result is greater than or equal to 4144 then -- Mac OS X 10.3.0
if UI elements enabled then
return true
else
beep
aktivate
display dialog "GUI Scripting is not enabled" & return & return & "Open System Preferences and check Enable Access for Assistive Devices in the Accessibility (or Universal Access) preference pane, then run this script again." with icon stop
if button returned of result is "OK" then
tell application "System Preferences"
activate
set current pane to pane "com.apple.preference.universalaccess"
end tell
end if
end if
else
beep
display dialog "This computer cannot run this script" & return & return & "The script uses GUI Scripting technology, which requires an upgrade to Mac OS X 10.3 Panther or newer." with icon caution buttons {"Quit"} default button "Quit"
end if
end tell
end checkIfUIElementsAreEnabled
Update vom 23.03.2014:
Das Skript funktioniert nun auch unter 10.9.2 (habe nun gewagt selber zu aktualisieren). Dabei hat sich in Mail selbst nichts geändert, aber nun muss jede Anwendung einzeln die Erlaubnis erteilt bekommen GUI-Scriping durchzuführen. Das Script also ab besten über ein richtiges Programm wie FastScripts ausführen, den Dialog abwarten und dann bei FastScripts das Häckchen setzen…
-- Save Mail as PDF and it's attachments to folder
-- Created by hubionmac (29.09.2010)
-- 29.09.2010
-- -Auswahl von mehren Emails wird nun auch möglich
-- -Abgesendete Emails werden als solche erkannt und in einem anderen Verzeichnis mit Empfänger-Adresse im Ordnernamen gespeichert (req. by Andreas)
-- 27.09.2011 made it work with local mailboxes, too
##2012-04-17 changed the way paths are formated (posix/mac) and now the script runs on 10.7 again =)
##2013-02-18 Updated code so that it works using 10.8.3 (new dialogs and new gatekeeper made this necessary)
## 2014-03-23 Updated code so that it works using 10.9.2 The Dialogs have not changed, but handling GUI Scripting made this necessary. Now you will have to enable GUI Access for each single app that whats access... so this script app or the app running this script (e.g. FastScripts)
global frontmost_message_viewer
--this is the posix (unix) path of the folder you would like to store the messages in
set mymailboxpath to (path to "desk") & "received_mail_box:" as text
set mysentmailboxpath to (path to "desk") & "sent_mail_box:" as text
my enabledGUIScripting(true)
tell application "Finder"
set os_version to version
end tell
if os_version does not start with "10.9" then
error "This Script was only tested using 10.9… I quit here…"
end if
tell application "Mail"
set downloadFolder to ((path to home folder) as rich text) & "Downloads:"
set myselection to my check_message_viewer_and_return_selection()
repeat with currentMail in myselection
open currentMail
set currentSender to my (getEmail(sender of currentMail))
set currentDateSent to my getDatestring(date sent of currentMail)
set currentSubject to my replace_chars(my replace_chars(subject of currentMail, ":", "-"), "/", "--") --Doppelpunkte kommen bei Dateinamen nicht so gut
if my is_in_sent_mail(currentMail) is true then
--if the file was sent FROM this email account
set sentToEmail to address of item 1 of to recipient of currentMail
set currentFolder2Store to mysentmailboxpath & sentToEmail & " " & currentDateSent & " " & currentSubject & ":" as rich text
else
--if the email was sent TO this email account
try
set myemail to item 1 of (get email addresses of account of mailbox of currentMail)
on error
--27.09.2011 added to make it work with local mailboxes, too
set myemail to item 1 of (get address of to recipient of currentMail)
end try
set currentFolder2Store to mymailboxpath & currentDateSent & " " & currentSender & " " & currentSubject & " send to " & myemail & ":" as rich text
end if
my create_messagefolder(currentFolder2Store)
repeat with a in (every mail attachment of currentMail)
set current_a_name to name of a
set current_a_name to my checkname_with_pdf_suffix(current_a_name, currentFolder2Store, false)
##10.8 fix… you may only save attachments in the download folder… this does not mean you cannot move it afterwards ;-)
save a in downloadFolder & current_a_name
set thefile to quoted form of POSIX path of (downloadFolder & current_a_name as alias)
set mypath to quoted form of POSIX path of currentFolder2Store
do shell script "mv -f " & thefile & " " & mypath
end repeat
set desktop_pdf_name to my checkname_with_pdf_suffix("1.pdf", path to desktop, false)
tell application "System Events"
tell process "Mail"
set wc to count of every window
end tell
end tell
my print_current_mail_as_pdf(desktop_pdf_name)
tell application "System Events"
tell process "Mail"
repeat until (count of every window) is wc
end repeat
end tell
end tell
my move_desktop_pdf(desktop_pdf_name, currentFolder2Store)
--close last_message window
activate
tell application "System Events"
tell process "Mail"
keystroke "w" using command down
end tell
end tell
--open destination folder in finder ( did it really work? YES!! =))
--do shell script "open " & quoted form of currentFolder2Store
end repeat
end tell
to move_desktop_pdf(desktop_pdf_name, currentFolder2Store)
--used to move the printed pdf to it's final destination
set finalname to checkname_with_pdf_suffix("__message.pdf", currentFolder2Store, false)
set movedIt to false
repeat with i from 1 to 10
try
do shell script "mv " & POSIX path of (path to "desk") & quoted form of desktop_pdf_name & " " & quoted form of POSIX path of currentFolder2Store & quoted form of finalname
set movedIt to true
exit repeat
end try
delay 1
end repeat
if movedIt is false then error "Fehler beim Bewegen der gedruckten Nachricht: " & msg as text
end move_desktop_pdf
to getEmail(mailstring)
-- if an email contains the senders name like "Mr.Bla <bla@bla.com>" then returns just the email not leaves the name
if mailstring contains "<" then
return (characters ((offset of "<" in mailstring) + 1) through ((offset of ">" in mailstring) - 1) of mailstring) as text
else
return mailstring
end if
end getEmail
to getDatestring(thedate)
--format a date to a string like 2010-03-22
set monthnum to characters -2 through -1 of ("0" & ((month of thedate) as integer)) as text
set daynum to characters -2 through -1 of ("0" & ((day of thedate) as integer)) as text
set yearnum to year of the thedate
return yearnum & "-" & monthnum & "-" & daynum as text
end getDatestring
to create_messagefolder(thepath)
--I love mkdir -p, simple, short, easy to use
try
do shell script "mkdir -p " & quoted form of POSIX path of thepath
on error msg
error msg
end try
end create_messagefolder
to replace_chars(this_text, search_string, replacement_string)
--this replaces characters
--used for folder and filenames, since a : must not be used for that
if this_text contains the search_string then
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to ""
end if
return this_text
end replace_chars
to checkname_with_pdf_suffix(n, D, looped)
--check if filename exists in D
-- so if "A File.pdf" exists it names it "A File 1.pdf","A File 2.pdf",...
tell application "Finder"
set thefiles to name of every item of (D as alias)
end tell
if thefiles contains n then
if looped = false then
set n to ((characters 1 through -5 of n) & " 1" & (characters -4 through -1 of n)) as text
my checkname_with_pdf_suffix(n, D, true)
else
set tmp to (last word of ((characters 1 through -5 of n) as text) as integer)
set tmpcount to (count of characters of (tmp as text)) + 5
set tmp to tmp + 1
set n to ((characters 1 through (-1 * tmpcount) of n) & tmp & (characters -4 through -1 of n)) as text
my checkname_with_pdf_suffix(n, D, true)
end if
else
return n
end if
end checkname_with_pdf_suffix
to print_current_mail_as_pdf(pdfname)
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
keystroke "p" using command down
set p to "false"
repeat until 0 = 1
if (count of every sheet of window 1) > 0 then
set p to "ready"
exit repeat
end if
end repeat
if p = "ready" then
click menu button 1 of sheet 1 of window 1
delay 0.25
key code 125
key code 125
delay 0.25
keystroke return
##wait until second sheet opened
delay 1
set value of text field 1 of sheet 1 of sheet 1 of window 1 to pdfname
keystroke "d" using command down
delay 0.25
keystroke return
else
error "timeout"
end if
end tell
end tell
end tell
end print_current_mail_as_pdf
to check_message_viewer_and_return_selection()
-- check if frontmost window is a message viewer, otherwhise tell the user to RTFM!... wait there is no manual... don't care error change user!
tell application "Mail"
set frontmost_message_viewer to {}
repeat with i from 1 to count of every message viewer
if index of window of message viewer i = 1 then
set frontmost_message_viewer to message viewer i
exit repeat
end if
end repeat
if frontmost_message_viewer = {} then
error "Ist ja gar kein Message Viewer im Vordergrund, so kann ich einfach nicht arbeiten!"
else
return selection
end if
end tell
end check_message_viewer_and_return_selection
on is_in_sent_mail(amessage)
##Just Try
try
tell application "Mail"
set sentmailboxes to every mailbox of sent mailbox
set currentmailbox to mailbox of amessage
repeat with i from 1 to (count of sentmailboxes)
if item i of sentmailboxes = currentmailbox then
return true
end if
end repeat
return false
end tell
end try
return false
end is_in_sent_mail
on enabledGUIScripting(flag)
get system attribute "sysv"
if result is less than 4240 then -- 4240 is OS X 10.9.0 Mavericks
-- In OS X 10.8 Mountain Lion and older, enable GUI Scripting globally by calling this handler and passing 'true' in the flag parameter before your script executes any GUI Scripting commands, or pass 'false' to disable GUI Scripting. Authentication is required only if the value of the 'UI elements enabled' property will be changed. Returns the final setting of 'UI elements enabled' even if unchanged.
tell application "System Events"
activate -- brings System Events authentication dialog to front
set UI elements enabled to flag
return UI elements enabled
end tell
else
-- In OS X 10.9 Mavericks, global access is no longer available and GUI Scripting can only be enabled manually on a per-application basis. Pass true to present an alert with a button to open System Preferences and telling the user to select the current application (the application running the script) in the Accessibility list in the Security & Privacy preference's Privacy pane. Authentication is required to unlock the preference. Returns the current setting of 'UI elements enabled' asynchronously, without waiting for System Preferences to open, and tells the user to run the script again.
tell application "System Events" to set GUIScriptingEnabled to UI elements enabled -- read-only in OS X 10.9 Mavericks
if flag is true then
if not GUIScriptingEnabled then
activate
set scriptRunner to name of current application
display alert "GUI Scripting is not enabled for " & scriptRunner & "." message "Open System Preferences, unlock the Security & Privacy preference, select " & scriptRunner & " in the Privacy Pane's Accessibility list, and then run this script again." buttons {"Open System Preferences", "Cancel"} default button "Cancel"
if button returned of result is "Open System Preferences" then
tell application "System Preferences"
tell pane id "com.apple.preference.security" to reveal anchor "Privacy_Accessibility"
activate
end tell
end if
end if
end if
return GUIScriptingEnabled
end if
end enabledGUIScripting
Erst mal vielen Dank für das tolle Script.
Ich finde die Möglichkeit in osx beim Öffnen/ Speicherndialog den Zielordner durch ziehen eines Objektes aus dem Zielordner auf das Dialogfenster extrem praktisch.
Bei dem Dialog zur Auswahl des Zielordners im Script funktioniert das leider nicht.
Kann man das irgendwie einstellen, ändern?
Servus Franz,
welchen Dialog meinst Du denn? Den Zielordner gibst Du im Quellcode an, der Datei-Dialog, den das Skript öffnet, nutzt es selbst via GUI-Skripting zum Speichern des PDFs…
Hallo,
leider bin ich ein blutiger Laie, aber ich suche diese funktion schon lange.
Kann mir jemand helfen?
Wo gebe ich den Script-Code ein beim Mac und wie bekomme ich das Script im Mail zum Laufen? Optimal über einen Shortcode, das ich anwende und dann werden E-Mail als PDF und die Anhänge in einem Ordner auf dem Schreibtisch gespeichert, wie beschrieben.
Danke!
VG
Sameer
Hallo Sameer,
also den Script-Code kopierst Du Dir in die Zwischenablage und speicherst Ihn in ein neues AppleScript. Dazu öffnest Du den AppleScript Editor (findest Du in den Programmen bzw. Dienstprogrammen).
Und wenn Du das Skript dann später über einen Shortcut abrufen möchtest, schaust Du dir mal FastScripts (ist im Posting verlinkt) an. Die haben bestimmt auch ein Handbuch, in dem Dir erklärt wird, wo Du dann das Skript abspeichern musst, damit Du es darüber aufrufen kannst.
Gruß Hubi
Hallo Sameer,
das Aufrufen über shortcut kannst du auch über eine Automator-Script lösen.
Dazu einfach das Apple-Script in einen Automator-workflow einbetten und in ~/Library/Services/ ablegen. Danach über die Systemeinstellung “Tastatur” dem Dienst ein Shortcut zuweisen.
Bei mir zickt die Lösung hin und wieder. Deshalb hab ich das Apple-Script zusätzlich mit installiert. Keine Ahnung warum.
Gruß Franz
Hallo Hubi, hallo Franz,
danke für Eure Hinweise.
Ich habe leider folgendes Problem:
This Script was only tested using 10.9… I quit here…
Diese Meldung kommt wenn ich im Script Editor auf Ausführen gehe.
Ich nutze noch 10.8.5
Ein Update wir über die IT gemacht, aber noch nicht jetzt.
Muss ich warten bis dahin?
Danke!
Gruß,
Sameer
Servus Sameer,
versuche es doch mal mit der vorherigen Version, die hatte ich für 10.8 angepasst.
Wegen des GUI-Scripting Parts gibt es da immer wieder Neuerungen, das Skript selbst dürfte sich aber von der Funktion kaum ändern.
Gruß Hubi
Hallo
Ich habe das letzte Skript in AppleScript-Editor eingefügt und die Routine funktioniert einwandfrei. Jedoch habe ich festgestellt, dass in den Ordnern der einzelnen Mails immer die gleiche Email abgespeichert wird. Nämliche jeweils die ersten der markierten Reihe.
Woran kann das liegen? Ich hatte auch schon Durchgänge wo das nicht so war…
Ich bin ebenfalls Laie und führe das Skript aus in dem ich die betreffenden Mails markiere und dann auf ausführen im Editor klicke.
Besten Dank für eine Rückmeldung.
Grüsse
Simon
Hallo zusammen,
der Fehler, den Simon beschreibt, tritt bei mir auch auf. Wenn man mehrere E-Mails anwählt und das Script startet, werden zwar die Ordner richtig angelegt und auch die Attachments richtig abgelegt, aber die Mail selbst ist immer dieselbe.
Bitte, bitte, lieber Hubi, kann man das korrigieren?
Eine weitere Neuheit (seit ich von OS10.6.8 auf OS10.9.5 umgestiegen bin) ist die Fehlermeldung “… kein Message Viewer im Vordergrund …”. Dann muss man erst in das Voransichtsfenster hineinklicken. Damit kann man allerdings leben.
Vielen Dank und beste Grüße
Kerstin
Komisch… muss ich mal bei Gelegenheit prüfen, woran das liegt.
Ggf. könnt Ihr euch damit behelfen, dass Ihr die Emails nicht nach Konversationen ordnen lasst (Menü Darstellung).
Ihr benutzt auch die neuste Script-Version?
Lieber Hubi, frohes neues Jahr!
Ich habe eben nochmals das letzte Skript vom 23.03.14 in den Editor kopiert und verschiedene Darstellungsoptionen bei Mail getestet. Ausserdem habe ich die Routine in unterschiedlich grossen Postfächern (lokal und exchange) ausprobiert. Leider noch immer mit dem beschriebenen Resultat. Mir ist aufgefallen, dass zu beginn immer die erste Mail geöffnet wird und dann jeweils auch sichtbar bleibt während die weiteren Mails (resp. immer die gleiche) abgelegt werden. Evtl. ein Hinweis…? Wäre toll wenn es eine Lösung gäbe.
LG
Simon
Hallo Hubi, hallo Kerstin, hallo Simon,
das Problem bei den Mehrfachdrucken lässt sich beheben, wenn eine Pause nach dem Schließen des Fensters eingefügt wird.
So in etwa:
“tell application “System Events”
tell process “Mail”
keystroke “w” using command down
delay 0.25
end tell
end tell
”
Att Hubi:
Beim Ausprobieren bin ich über die beiden Abschnitte gestolpert:
“tell application “System Events”
tell process “Mail”
set wc to count of every window
end tell
end tell
” und
“tell application “System Events”
tell process “Mail”
repeat until (count of every window) is wc
end repeat
end tell
end tell
”
Was haben diese für eine Funktion?
Viele Grüße
Franz
Hallo Franz,
super, jetzt geht’s!! Vielen, vielen Dank für den Tipp.
Es ist mit Abstand das nützlichste Script auf meinem Rechner (hier mal großen Dank an Hubi!). Bin froh, dass es wieder läuft.
Schöne Grüße an alle
Kerstin
Hi there, I believe your website may be having web browser compatibility issues.
Whenever I take a look at your site in Safari, it looks fine however, if opening in Internet Explorer, it has some overlapping issues.
I merely wanted to give you a quick heads up! Apart from that,
wonderful website!
[url=http://paydayloansonlinetop.com/]payday loans[/url] payday loans