Import From Apple Mail
Summary: Imports the selected or rule-processed messages from Apple Mail as .eml files.
Requires: EagleFiler
Install Location: ~/Library/Application Scripts/com.apple.mail or ~/Library/Scripts/Applications/Mail/
Last Modified: 2022-08-25
Description
The recommended way to import from Apple Mail is to select some messages and press the capture key. That will import the messages as a new mailbox file. This script is for situations where you want to:
- Import messages as individual .eml files instead of as a mailbox. You can import them into an existing folder if desired. This is less efficient than the normal way that EagleFiler stores messages in a mailbox, but for smaller numbers of messages you may find it more convenient.
- Automate importing the selected messages.
- Import the messages that are being processed by a Mail rule. (Note that, on macOS 10.13, if the message contains attachments, Mail might not download them before applying the rule, so they will not be included in the message source sent to EagleFiler.)
Unlike when using the capture key, the unread/flagged status and MailTags are not preserved.
If you want the script to bring up the options window asking you where import the messages, remove the --
before with asking for options
.
Installation Instructions · Download in Compiled Format · Download in Text Format
Script
on
run
tell
application
"Mail"
if
my
isLionOrBetter()
and
(
count
of
message viewers
)
is
1
then
-- If there's more than one, and full screen mode is active, we can't tell which is frontmost
return
my
importFromViewer(
message viewer
1)
else
repeat
with
_viewer
in
message viewers
if
index
of
_viewer's
window
is
1
then
my
importFromViewer(
_viewer)
end
if
end
repeat
end
if
end
tell
end
run
on
isLionOrBetter()
considering
numeric strings
return
(
system version
of
(
system info
)) ≥ "10.7"
end
considering
end
isLionOrBetter
using terms from
application
"Mail"
on
perform mail action with messages
_messages
my
importMessages(
_messages)
end
perform mail action with messages
end
using terms from
on
importFromViewer(
_viewer)
tell
application
"Mail"
set
_messages
to
(
get
selected messages
of
_viewer)
my
importMessages(
_messages)
end
tell
end
importFromViewer
on
importMessages(
_messages)
set
_paths
to
{}
repeat
with
_message
in
_messages
tell
application
"Mail"
set
_subject
to
subject
of
_message
set
_source
to
source
of
_message
end
tell
set
_inflatedPath
to
my
createTempFolder() & "/" & "Inflated"
my
writeInflatedUnicode(
_inflatedPath,
_source)
set
_path
to
my
createTempFolder() & "/" &
my
makeFileName(
_subject)
my
deflate(
_inflatedPath,
_path)
copy
_path
to
end
of
_paths
end
repeat
tell
application
"EagleFiler"
import
files
_paths
-- with asking for options
end
tell
end
importMessages
on
writeInflatedUnicode(
_path,
_string)
set
_file
to
POSIX file
_path
set
_fd
to
open for access
_file
with
write permission
write
_string
to
_fd
as
Unicode text
-- UTF-16; byte order doesn't matter since will ignore nil bytes
close access
_fd
end
writeInflatedUnicode
on
deflate(
_inflatedPath,
_deflatedPath)
-- cat u.eml | tr -d '\000' > out.eml
set
_script
to
"cat " &
_inflatedPath's
quoted form & " | "
# https://unix.stackexchange.com/questions/45404/why-cant-tr-read-from-dev-urandom-on-osx
set
_script
to
_script & "LC_CTYPE=C tr -d '\\000'"
set
_script
to
_script & " > " &
_deflatedPath's
quoted form
do shell script
_script
end
deflate
on
createTempFolder()
set
_tempFolder
to
do shell script
"mktemp -d -t 'EFImportAppleMail'"
return
_tempFolder
end
createTempFolder
on
makeFileName(
_subject)
set
_clean
to
my
replace(
_subject, "/", ":")
set
_clean
to
my
replace(
_clean, ":", "-")
set
_extension
to
".eml"
set
_hfsPlusLimit
to
255
set
_max
to
_hfsPlusLimit - (
length
of
_extension)
set
_shortened
to
my
substringToIndex(
_clean,
_max)
return
_shortened &
_extension
end
makeFileName
on
substringToIndex(
_string,
_index)
if
length
of
_string >
_index
then
set
_end
to
_index
else
set
_end
to
length
of
_string
end
if
return
my
join(
characters
1
thru
_end
of
_string, "")
end
substringToIndex
on
replace(
_string,
_source,
_replacement)
return
my
join(
my
split(
_string,
_source),
_replacement)
end
replace
on
join(
_list,
_sep)
set
_temp
to
AppleScript's
text item delimiters
set
AppleScript's
text item delimiters
to
_sep
set
_result
to
_list
as
string
set
AppleScript's
text item delimiters
to
_temp
return
_result
end
join
on
split(
_string,
_sep)
set
_temp
to
AppleScript's
text item delimiters
set
AppleScript's
text item delimiters
to
_sep
set
_result
to
text items
of
_string
set
AppleScript's
text item delimiters
to
_temp
return
_result
end
split