Created
January 18, 2016 04:34
-
-
Save IskenHuang/bdd9a7c4f00642187a32 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
Export Evernote notes to Apple Notes | |
Copyright (C) 2015 Lawrence A. Salibra, III | |
This program is free software: you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation, either version 3 of the License, or | |
(at your option) any later version. | |
This program is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with this program. If not, see <http://www.gnu.org/licenses/>. | |
====== | |
Read https://www.larrysalibra.com/evernote-to-apple-notes/ and then | |
https://www.larrysalibra.com/can-apple-notes-replace-evernote/ *before* | |
you run this. You have been warned. | |
====== | |
This worked on Evernote Version 6.1.1 (452254 App Store) | |
and Apple Notes Version 4.0 (535) on OS X 10.11 (15A284) | |
It might not work on yours. | |
Known Issue: Migrating too many notes at one time may cause Evernote to time out. | |
Workaround: Migrate notes in smaller batches. | |
*) | |
---------- | |
-- User configurable settings | |
---------- | |
(* | |
Appends Evernote data that can't be set in Apple Notes such as | |
creation date & location in JSON structured text at end of note | |
*) | |
set includeEvernoteData to true | |
set timeoutInMinutes to 120 | |
---------- | |
-- Nothing user configurable below this line | |
---------- | |
with timeout of (timeoutInMinutes * 60) seconds | |
set homeFolderPosix to (system attribute "HOME") | |
-- Sandboxing limits access to apps' own containers | |
set exportFolderPosix to homeFolderPosix & "/Library/Containers/com.evernote.Evernote/Data/export_to_icloud/" as string | |
set importFolderPosix to homeFolderPosix & "/Library/Containers/com.apple.Notes.HTMLConverter/Data/import_from_evernote/" as string | |
set exportFolder to ((exportFolderPosix as POSIX file) as string) | |
set importFolder to ((importFolderPosix as POSIX file) as string) | |
set notesWithProblems to {} | |
do shell script "mkdir -p " & quoted form of exportFolderPosix | |
do shell script "mkdir -p " & quoted form of importFolderPosix | |
-- Clean out any attachments that may be left over from previous failed run | |
do shell script "rm -f " & quoted form of importFolderPosix & "*" | |
do shell script "rm -f " & quoted form of exportFolderPosix & "*" | |
tell application "Evernote" | |
set selectedNotes to selection | |
if (count of selectedNotes) is equal to 0 then | |
error "Looks like you didn't select any notes in Evernote. Please select some notes and run this script again!" | |
else | |
set notesString to " notes" | |
if (count of selectedNotes) is equal to 1 then | |
set notesString to " note" | |
end if | |
display dialog "You've selected " & (count of selectedNotes) & notesString & " in Evernote which I will try to migrate to your Apple Notes iCloud account. This might take a while! 🕒" | |
end if | |
set migratedNoteCount to 0 | |
repeat with theNote in selectedNotes | |
set noteName to title of theNote | |
set noteBody to HTML content of theNote | |
set noteNotebookName to name of notebook of theNote | |
set noteCreated to (creation date of theNote) | |
set noteModified to (modification date of theNote) | |
-- data that we can't use directly in Apple Notes | |
set noteSource to (source URL of theNote) | |
set noteTags to (tags of theNote) | |
set noteAltitude to (altitude of theNote) | |
set noteLat to (latitude of theNote) | |
set noteLong to (longitude of theNote) | |
set unnamedCounter to 1 | |
try | |
repeat with theAttachment in (attachments of theNote) | |
do shell script "rm -f " & quoted form of importFolderPosix & "*" | |
set theFilename to theAttachment's filename | |
if theFilename is equal to missing value then | |
--assume attachments without filenames are jpg photos take with evernote ios app | |
set theFilename to "photo-" & unnamedCounter & ".jpg" | |
set unnamedCounter to unnamedCounter + 1 | |
end if | |
set fileExists to false | |
tell application "System Events" | |
if exists file (exportFolder & theFilename) then | |
set fileExists to true | |
end if | |
end tell | |
if not fileExists then | |
write theAttachment to (exportFolder & theFilename) | |
else | |
-- prepend a random number to avoid filename collisions | |
set theFilename to (random number from 1 to 100) & "-" & theFilename | |
write theAttachment to (exportFolder & theFilename) | |
end if | |
-- Evernote references every attachment with a img or embed tag | |
-- where src=?hash=<md5 hash of the attachment> | |
set evernoteProvidedHash to hash of theAttachment | |
set attachmentHash to do shell script ("md5 -q " & quoted form of (exportFolderPosix & theFilename)) | |
if evernoteProvidedHash is not equal to attachmentHash then | |
display dialog "Uh oh! There appears to be data corruption while exporting the attachment: " & theFilename | |
end if | |
set evernoteSrc to "?hash=" & attachmentHash | |
set notesSrc to "file://" & importFolderPosix & theFilename | |
set sedEscapeReplaceComand to "sed -e 's/[\\/&]/\\\\&/g'" | |
set notesSrc to do shell script "echo " & (quoted form of notesSrc) & " | " & sedEscapeReplaceComand | |
set shellText to "echo " & (quoted form of noteBody) & " | sed 's/?hash=" & attachmentHash & "/" & notesSrc & "/g'" | |
set noteBody to do shell script shellText | |
-- Replace Evernote embed tags with img | |
-- Apple Notes treats any file referenced in img tag as attachment | |
set shellText to "echo " & (quoted form of noteBody) & " | sed 's,<embed,<img,g'" | |
set noteBody to do shell script shellText | |
end repeat | |
if includeEvernoteData is equal to true then | |
set evernoteData to "<pre>{" | |
set evernoteData to evernoteData & "\"source\": \"" & noteSource & "\", " | |
set noteTagsText to "" | |
set tagCounter to 0 | |
repeat with noteTag in noteTags | |
set tagCounter to tagCounter + 1 | |
if tagCounter is equal to (count of noteTags) then | |
-- don't add a common after last tag | |
set noteTagsText to noteTagsText & (name of noteTag) | |
else | |
set noteTagsText to noteTagsText & (name of noteTag & ", ") | |
end if | |
end repeat | |
set evernoteData to evernoteData & "\"tags\": \"" & noteTagsText & "\", " | |
set evernoteData to evernoteData & "\"altitude\": \"" & noteAltitude & "\", " | |
set evernoteData to evernoteData & "\"latitude\": \"" & noteLat & "\", " | |
set evernoteData to evernoteData & "\"longitude\": \"" & noteLong & "\" }" | |
set noteBody to noteBody & "<br><h3>Evernote Data:</h3>" & evernoteData | |
end if | |
if (count of attachments of theNote) is not equal to 0 then | |
do shell script "mv " & quoted form of exportFolderPosix & "* " & quoted form of importFolderPosix | |
end if | |
on error | |
set end of notesWithProblems to theNote | |
end try | |
tell application "Notes" | |
set theAccount to ¬ | |
(my getICloudAccount()) | |
if not (exists folder noteNotebookName) then | |
make new folder with properties {name:noteNotebookName} at theAccount | |
end if | |
set newNote to make new note at folder noteNotebookName with properties {name:noteName, body:noteBody, creation date:noteCreated, modification date:noteModified} | |
end tell | |
set migratedNoteCount to migratedNoteCount + 1 | |
end repeat | |
if migratedNoteCount is equal to 1 then | |
display dialog "Migrated 1 note to Apple Notes!" buttons {"Great! 😁"} | |
else | |
if migratedNoteCount is equal to 0 then | |
error "Looks like you didn't select any notes in Evernote. Please select some notes and run this script again!" | |
else | |
display dialog "Migrated " & migratedNoteCount & " notes to Apple Notes!" buttons {"Great! 😁"} | |
end if | |
end if | |
if (count of notesWithProblems) is not equal to 0 then | |
set failedNotes to "I had trouble moving the following notes: | |
" | |
repeat with theNote in notesWithProblems | |
set failedNotes to failedNotes & (title of theNote) & " | |
" | |
end repeat | |
display dialog failedNotes | |
end if | |
set answer to the button returned of (display dialog "Wow! I'm so glad Larry wrote this free software! I want to tell the world by..." buttons {"Sharing on Twitter 😃", "Sharing on Facebook ☺️", "Doing nothing 😒"} default button 1) | |
if answer is equal to "Sharing on Twitter 😃" then | |
set tweetLink to "https://twitter.com/intent/tweet?related=larrysalibra&text=I just moved from Evernote to Apple Notes with @larrysalibra's help!&url=https://www.larrysalibra.com/evernote-to-apple-notes/" | |
do shell script "open " & quoted form of tweetLink | |
end if | |
if answer is equal to "Sharing on Facebook ☺️" then | |
set faceLink to "https://www.facebook.com/sharer/sharer.php?u= | |
https://www.larrysalibra.com/evernote-to-apple-notes/" | |
do shell script "open " & quoted form of faceLink | |
end if | |
end tell | |
end timeout | |
on getICloudAccount() | |
tell application "Notes" | |
repeat with theAccount in every account | |
if name of theAccount as string is equal to "iCloud" then | |
return theAccount | |
end if | |
end repeat | |
display dialog "I can't find your iCloud account! Perhaps your Apple Notes iCloud account isn't called iCloud or you've disabled it? I give up! 😧" | |
error number -128 | |
end tell | |
end getICloudAccount |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How to use