Last active
August 20, 2022 12:08
-
-
Save mbafford/2c18f5c4d7b0dab673fddb1af2126680 to your computer and use it in GitHub Desktop.
Convert Journey.Cloud (Diary) JSON Export to Evernote Export (ENEX)
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
#!/usr/bin/env python3 | |
# Converts the JSON export of Journey.Cloud diary entries into an Evernote Note Export format (ENEX) for easy import back into Evernote. | |
# | |
# This was a quick and dirty script to save someone the trouble of doing this process manually. | |
# | |
# Create/update date, journal text, location, and photos are preserved in the resulting Evernote Note. | |
import sys | |
import os | |
import json | |
import base64 | |
import hashlib | |
from datetime import datetime | |
from xml.sax.saxutils import escape | |
def md5sum( file ): | |
m = hashlib.md5() | |
m.update( file ) | |
return m.hexdigest() | |
def load_photos( journal_id, files ): | |
ret = {} | |
for file in files: | |
try: | |
with open(file, "rb") as f: | |
ret[ file ] = f.read() | |
except: | |
print("Journal %s - Unable to find photo file %s" % ( journal_id, file ) ) | |
sys.exit(1) | |
return ret | |
def convert_journal( journal ): | |
created = datetime.fromtimestamp( journal['date_journal']/1000 ) | |
updated = datetime.fromtimestamp( journal['date_modified']/1000 ) | |
print("%s: Converting journal from %s (modified %s)" % ( journal['id'], created.strftime("%Y-%m-%d %H:%M:%S"), updated.strftime("%Y-%m-%d %H:%M:%S") ) ) | |
photos = load_photos( journal['id'], journal['photos'] ) | |
print("%s: Loaded: %d photos" % ( journal['id'], len(photos) ) ) | |
resources_xml = "" | |
images = "" | |
for photo in photos: | |
mime = "" | |
if photo.lower().endswith( "jpg" ): mime = "image/jpeg" | |
elif photo.lower().endswith( "sticker" ): mime = "image/gif" | |
elif photo.lower().endswith( "png" ): mime = "image/png" | |
else: | |
print("Unable to determine MIME mime from filename: %s" % photo) | |
sys.exit(1) | |
resources_xml += """ | |
<resource><data encoding="base64"> | |
%(base64)s | |
</data><mime>%(mime)s</mime> | |
<resource-attributes> | |
<source-url>file://%(filename)s</source-url> | |
<file-name>%(filename)s</file-name> | |
</resource-attributes> | |
</resource> | |
""" % { | |
"base64": base64.b64encode(photos[photo]).decode(), | |
"filename": photo, | |
"mime": mime, | |
} | |
images += """ <div><en-media hash="%(hash)s" type="%(mime)s"/></div> """ % { "hash": md5sum( photos[photo] ), "mime": mime } | |
xml = """<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export2.dtd"> | |
<en-export export-date="%(updated)s" application="Evernote/Windows" version="6.x"> | |
<note> | |
<title>%(title)s</title> | |
<content><![CDATA[<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"> | |
<en-note><div> | |
%(text)s | |
</div> | |
%(images)s | |
</en-note>]]></content> | |
<created>%(created)s</created> | |
<updated>%(updated)s</updated> | |
<note-attributes> | |
<author>AUTHOR_NAME</author> | |
<source>desktop.win</source> | |
<source-application>evernote.win32</source-application> | |
<latitude>%(latitude)s</latitude> | |
<longitude>%(longitude)s</longitude> | |
</note-attributes> | |
%(resources)s | |
</note> | |
</en-export>""" % { | |
"title": created.strftime("%Y%m%d - %d %B, %Y"), | |
"text": escape( journal['text'] ).replace("\n", "<br/>"), | |
"created": created.strftime("%Y%m%dT%H%M%%SZ"), | |
"updated": updated.strftime("%Y%m%dT%H%M%%SZ"), | |
"latitude": journal.get('lat', ""), | |
"longitude": journal.get('lon', ""), | |
"resources": resources_xml, | |
"images": images, | |
} | |
out_file = "%s.enex" % journal['id'] | |
with open( out_file, "w" ) as f: | |
f.write( xml ) | |
print("%s: Wrote %s" % ( journal['id'], out_file )) | |
def find_and_convert(): | |
for fn in [fn for fn in os.listdir() if fn.endswith(".json")]: | |
with open(fn, "r") as f: | |
journal = json.loads( f.read() ) | |
convert_journal( journal ) | |
find_and_convert() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks, it was really helpful! I improved it a bit in https://gist.github.com/rogatty/8a65ebc01062ebc48fac7473792ae993: