(*
warning! use this script at your own risk. i worked on it just enough to get it to do what i needed and never got around to testing it much, so it might not work for you. and it's not very elegant, kind of simpleton brute force in approach. in fact, i could only get it to work in OS X (10.2 in fact). it seemed to work in OS9, but it didn't actually get all of the email from the filing cabinet, but i don't know why (it got a slightly different number of emails each time i ran it on the same filing cabinet).
in osx, i got it to work on filing cabinets from AOL 4 and AOL 5. After that, they changed their format.
the file it produces is a text file (i think it's close to mbox format, but i've never checked actual specs) which you can read in textedit, or bbedit, or whatever, and you should be able to import it into various email applications. I have only actually tried it on Eudora, so if necessary, you could download Eudora for free, then maybe export from it to something else, if you so require.
here are my notes on the america online filing cabinet format (probably not much use)
*)
global filePath
global totalCount
global theAuthorOwner
global theKind
global emailStartPattern1
set totalCount to 0
set sampleReadLength to 3000
set startSample to 0
--set startSample to 80000
--set rPointer to startSample
--set theAuthorOwner to "me@aol.com"
set theAuthorOwner to ""
set authorQuery to "Enter the email address of the owner of the Filing Cabinet. For example: tom@aol.com
This address will be the 'To:' address for incoming email, and the 'From:' address of sent mail"
repeat
set theAnswer to text returned of (display dialog authorQuery default answer theAuthorOwner)
if theAnswer = theAuthorOwner and theAuthorOwner ≠ "" then
exit repeat
else if theAnswer = "" then
set authorQuery to "Please enter the email address of the owner of the Filing Cabinet, e.g. dick@aol.com"
else
set theAuthorOwner to theAnswer
set authorQuery to "Are you certain that '" & theAnswer & "' is the email address you wish to use as Author of Sent mail and Destination of Incoming Saved Mail?"
if ((offset of "@" in theAnswer) = 0) then
set authorQuery to authorQuery & return & "I recommend using a standard internet email address with '@' and the domain name, such as harry@aol.com"
end if
end if
end repeat
set theKind to button returned of (display dialog "Which kind of email to look for?" buttons {"Cancel", "Sent", "Incoming"} default button 3)
if theKind = "Incoming" then
set emailStartPattern1 to (ASCII character 0) & (ASCII character 0) & (ASCII character 0) & (ASCII character 0)
set emailStartPattern2 to (ASCII character 0) & (ASCII character 4) & (ASCII character 0) & (ASCII character 0) & (ASCII character 0)
--adding a null to the end of the emailStartPattern2 above assumes subject limit of 255 char, but gets rid of false positives
set emailStartPattern to emailStartPattern1 & emailStartPattern2 as string
else if theKind = "Sent" then
set emailStartPattern1 to (ASCII character 0) & (ASCII character 0) & (ASCII character 0) & (ASCII character 1)
set emailStartPattern2 to (ASCII character 0) & (ASCII character 4) & (ASCII character 0) & (ASCII character 0) & (ASCII character 0)
--adding a null to the end of the emailStartPattern2 above assumes subject limit of 255 char, but gets rid of false positives
set emailStartPattern to emailStartPattern1 & emailStartPattern2 as string
end if
set badPattern to (ASCII character 0) & (ASCII character 1) & (ASCII character 0) & (ASCII character 4) & (ASCII character 0) & (ASCII character 0)
set staticFolderName to "Receptacle"
--set thisUserName to do shell script "whoami"
set filePathread to choose file with prompt "Select the file cabinet to munge:"
set filePath to choose file name with prompt "Where to save the text formatted email?"
--set filePath to staticFolderPath & "email.txt" as string
set gotOne to false
set myFileReference to open for access filePathread
repeat
try
repeat until gotOne
set sampleRead to read myFileReference from startSample for sampleReadLength
--set rPointer to rPointer + sampleReadLength
set sampleReadTest to my list_proc(sampleRead, emailStartPattern, "", "")
--display dialog sampleReadTest as string
if (number of items in sampleReadTest) > 1 then
set gotOne to true
set startDiff to number of characters of item 1 of sampleReadTest
set startSample to startSample + startDiff
--display dialog startSample as string
else
set startSample to startSample + sampleReadLength - 10
end if
-- back it off ten bytes in case a read chopped a pattern in two
end repeat
set gotOne to false
set emailReadSize to my readEmail(myFileReference, startSample)
set startSample to startSample + emailReadSize
on error errText number errNum
if errNum = -39 then
display dialog "Read to end of file. " & totalCount & " emails read and written." buttons {"OK"} default button 1
close access myFileReference
return
end if
display dialog errText & " | error num:" & errNum buttons {"OK"} default button 1
close access myFileReference
end try
end repeat
on readEmail(myFileReference, startRead)
set valList to {}
set attachName to ""
set attachNameSent to ""
set separator to "" -- for attachNameSent
set emailReadSize to 0
--set myFileReference to open for access filePathread
set newRead to read myFileReference from startRead for 4 --as data
set emailReadSize to emailReadSize + 4
if newRead ≠ emailStartPattern1 then
return -7
--this is not a very good fix
end if
--set theReport to (ASCII number of text 1 through 1 of newRead) & ":" & (ASCII number of text 2 through 2 of newRead) & ":" & (ASCII number of text 3 through 3 of newRead) & ":" & (ASCII number of text 4 through 4 of newRead) as string
--display dialog theReport
(*
if newRead = (ASCII character 0) & (ASCII character 0) & (ASCII character 0) & (ASCII character 0) then
--say "nulls"
end if
*)
--set theSize to get eof of myFileReference
repeat
try
set newRead to read myFileReference for 4
set emailReadSize to emailReadSize + 4
set readTag to ASCII number of character 2 of newRead
set valList to valList & readTag as list
set newReadlen to read myFileReference for 2
set emailReadSize to emailReadSize + 2
set readLenDec to ((ASCII number of character 1 of newReadlen) * 256) + (ASCII number of character 2 of newReadlen)
set valueRead to read myFileReference for readLenDec
set emailReadSize to emailReadSize + readLenDec
set valList to valList & valueRead as list
if readTag = 10 then
set readStop to false
set messageBody to ""
set bigText to valueRead
repeat until readStop
set messagebegin to my list_proc(bigText, ",", "", 1)
set messagebeginlength to number of characters of messagebegin
set messageLength to my list_proc(messagebegin, ASCII character 0, "", -1)
set messageLengthDec to my numconvert(messageLength, "ascii2hex")
set messageEnd to (messagebeginlength + 1 + messageLengthDec)
set messageBody to messageBody & (text (messagebeginlength + 2) through messageEnd of bigText) as string
set theMultTest to text (messageEnd + 1) through (messageEnd + 22) of bigText
set theMultTest1 to ASCII number of (text -1 through -1 of theMultTest)
set bigText to text (messageEnd) through -1 of bigText
if theMultTest1 ≠ 0 then
set readStop to true
end if
--display dialog theMultTest & " | " & theMultTest1 as string
end repeat
exit repeat
--error "got 10, done reading"
--display dialog messageLengthDec & ": " & messageBody as string
else if readTag = 12 then
--attachment in incoming email, assuming only one?
set messageLength to my numconvert((text 13 through 13 of valueRead as string), "asciinum2hex")
set attachFileName to text 14 through (13 + messageLength) of valueRead as string
set attachName to "Attachment converted: " & attachFileName & return & return as string
--display dialog attachName
else if readTag = 13 then
--attachment in sent mail, can be more than one
set messageLength to my numconvert((text 7 through 7 of valueRead as string), "asciinum2hex")
set attachFileName to text 8 through (7 + messageLength) of valueRead as string
--display dialog attachFileName
set attachNameSent to attachNameSent & separator & ":" & attachFileName & ":" as string
set separator to space as string
else if readTag = 4 and (offset of (ASCII character 0) in valueRead) ≠ 0 then
--display dialog "got nil" & valueRead
return 8
end if
--display dialog (readTag & " (" & readLenDec & ") = " & valueRead) as string
on error errText number errNum
display dialog errText buttons {"OK"} default button 1
set valItemNum to (number of items of valList) / 2
close access myFileReference
display dialog (valItemNum & " items read") as string
exit repeat
end try
end repeat
set valItemNum to (number of items of valList) / 2
repeat with z from 1 to (2 * valItemNum) by 2
if item z of valList = 4 then
set theSubject to item (z + 1) of valList
end if
if item z of valList = 5 then
set theAuthor to item (z + 1) of valList
end if
if item z of valList = 6 then
set secVal to my numconvert((item (z + 1) of valList), "asciinum2hex")
set theDate to (date "Friday, January 1, 1904 12:00:00") + (secVal / 60) * minutes
end if
if item z of valList = 9 then
set sendDestination to item (z + 1) of valList
--for some reason, the destination leads with a null?
set sendDestination to (my list_proc(sendDestination, ASCII character 0, "", "")) as string
end if
end repeat
set theBody to messageBody
if theKind = "Sent" then
set theAuthor to theAuthorOwner
end if
set theHeader to ""
if theKind = "Incoming" then
set theBodyList to my list_proc(theBody, return, "", "") as list
if theBodyList contains "----------------------- Headers --------------------------------" then
set theListCount to the number of items in theBodyList
-- display dialog theListCount
set theHeaderList to {}
-- display dialog item 1 of theBodyList
set headGo to true
repeat with m from theListCount to 1 by -1
if headGo then
if item m of theBodyList ≠ "----------------------- Headers --------------------------------" then
set theHeaderList to {(item m of theBodyList)} & theHeaderList as list
else
set bodyEnd to m - 1
set m to 2
set headGo to false
end if
end if
end repeat
--display dialog theHeaderList
set theBodyListUse to items 1 through bodyEnd of theBodyList
set AppleScript's text item delimiters to return
set theBody to the theBodyListUse as string
set theHeader to the theHeaderList as string
set AppleScript's text item delimiters to ""
end if
end if
--display dialog theAuthor & " " & theDate
--display dialog theBody
set theDay to the day of theDate as string
if the number of characters of theDay < 2 then
set theDay to "0" & theDay as string
end if
set theDayofWeek to the weekday of theDate
set theDayofWeek3 to text 1 through 3 of (theDayofWeek as string)
set theYear to the year of theDate
set theMonth to the month of theDate
set theMonth3 to text 1 through 3 of (theMonth as string)
set theDateString to the date string of theDate
set theTimeString to the time string of theDate
if (offset of ":" in theTimeString) ≠ 3 then
set theTimeString to "0" & theTimeString
end if
set theFromBegin to "From ???@??? " & theDayofWeek3 & " " & theMonth3 & " " & theDay & " " & theTimeString & " " & theYear as string
if theHeader = "" then
if (offset of "@" in theAuthor) = 0 then
set theAuthor to theAuthor & "@aol.com" as string
end if
set theFromLine to "From: " & theAuthor as string
if theKind = "Incoming" then
set theDateLine to "Date: " & theDayofWeek3 & ", " & theDay & " " & theMonth3 & " " & theYear & " " & theTimeString & " -0500" as string
set theReturnPath to "Return-Path: <" & theAuthor & ">" & return as string
set sendDestination to theAuthorOwner
set theBody to return & theBody & return as string
else if theKind = "Sent" then
set theDateLine to ""
set theReturnPath to ""
if (offset of "@" in sendDestination) = 0 then
set sendDestination to sendDestination & "@aol.com" as string
end if
set theBody to theBody & return as string
end if
set theToLine to "To: " & sendDestination as string
set theSubjectLine to "Subject: " & theSubject as string
if theKind = "Incoming" then
set toFrom to theFromLine & return & theToLine & return
set sentTags to ""
else if theKind = "Sent" then
set toFrom to theToLine & return & theFromLine & return
set sentTags to return & "Cc: " & return & "Bcc: " & return & "X-Attachments: " & attachNameSent & return
end if
set theHeader to theReturnPath & toFrom & theSubjectLine & sentTags & return & theDateLine
end if
--display dialog theFromBegin & return & theReturnPath & return & theFromLine & return & theDateLine
set theWrite to theFromBegin & return & theHeader & return & theBody & return & attachName as string
writeIt(theWrite) of me
set totalCount to totalCount + 1
return emailReadSize
end readEmail
--display dialog theAuthor & " | " & theDate & " | " & theSubject
--display dialog theBody
-- close access myFileReference
--display dialog valueRead
on list_proc(searchList, search_string, replace_string, item_return)
set AppleScript's text item delimiters to the search_string
set searchListlist to every text item of searchList
set AppleScript's text item delimiters to replace_string
set searchList to the searchListlist as string
set AppleScript's text item delimiters to ""
if replace_string = "" then
if item_return ≠ "" then
return item item_return of searchListlist
end if
return searchListlist
else
return searchList
end if
end list_proc
on numconvert(num, convtype)
set total to 0
if convtype = "ascii2hex" then
set numBase to 16
else if convtype = "asciinum2hex" then
set numBase to 256
end if
set numNum to the number of characters of num
set digitCount to 0
repeat with i from numNum to 1 by -1
set aChar to character i of num
if convtype = "ascii2hex" then
try
set aChar to aChar as integer
on error
set aChar to (ASCII number aChar) - 55
end try
else if convtype = "asciinum2hex" then
set aChar to ASCII number of aChar
end if
set aChar to aChar * (numBase ^ digitCount)
set total to total + aChar
set digitCount to digitCount + 1
end repeat
return total
end numconvert
on writeIt(theWrite)
--set theHTMLalias to staticFolderPath & fileName as string
set myFileReference to open for access filePath with write permission
set theSize to get eof of myFileReference
write theWrite to myFileReference starting at (theSize + 1)
close access myFileReference
set filePathType to class of filePath
if filePathType ≠ alias then
set filePath to alias filePath
end if
end writeIt
-- applescript page