Skip to content

Instantly share code, notes, and snippets.

@monperrus
Last active August 2, 2024 06:00
Show Gist options
  • Save monperrus/93b5fe05025a726b13f64a971e9127c2 to your computer and use it in GitHub Desktop.
Save monperrus/93b5fe05025a726b13f64a971e9127c2 to your computer and use it in GitHub Desktop.
export Nextcloud Notes to the Enex file format for importing into Evernote or Joplin
#!/usr/bin/python3
# export Nextcloud Notes to the Enex file format for importing into Evernote or Joplin
#
# in Joplin use File > Import > ENEX - EverNote Export File (as Markdown)
#
# reference documentation about ENEX file format: https://evernote.com/blog/how-evernotes-xml-export-format-works
#
# Author: Martin Monperrus
# License: Public domain
# URL: https://gist.github.com/monperrus/93b5fe05025a726b13f64a971e9127c2
import os
import sys
from xml.sax.saxutils import escape
from lxml import etree
from datetime import datetime
# check if the user has provided the path to the Nextcloud Notes directory
if len(sys.argv) != 2:
print("Usage: python3 export-nextcloud-notes-to-enex.py /path/to/Nextcloud/Notes")
sys.exit(1)
# get the path to the Nextcloud Notes directory
notes_dir = sys.argv[1]
# check if the path is valid
if not os.path.exists(notes_dir):
print(f"Error: {notes_dir} does not exist.")
sys.exit(1)
# create a new XML file
root = etree.Element("en-export")
root.set("export-date", datetime.now().strftime("%Y%m%dT%H%M%SZ"))
root.set("application", "export-nextcloud-notes-to-enex.py")
root.set("version", "1.0")
def ncmd_to_joplin_md(content):
# add line break after markdown header
final = ""
lines = content.split("\n")
lines.append("")
for idx in range(len(lines)-1):
line = lines[idx]
next_line = lines[idx + 1]
if line.startswith("#") and not len(next_line.strip())==0:
final += line + "\n\n"
# joplin needs two line breaks to not concatenate the lines
elif not len(line.strip())==0 and not len(next_line.strip())==0:
final += line + "\n\n"
else:
final += line+"\n"
return final
# iterate over all the files in the Nextcloud Notes directory
for filename in os.listdir(notes_dir):
if filename.endswith(".md") or filename.endswith(".txt"):
# read the content of the file
with open(os.path.join(notes_dir, filename), "r") as f:
content = f.read()
# create a new note
note = etree.SubElement(root, "note")
title = etree.SubElement(note, "title")
title.text = content.split("\n")[0].strip()
cdata = "<![CDATA[{content}]]>".format(content=ncmd_to_joplin_md(content))
parser = etree.XMLParser(strip_cdata=False)
contentnode = etree.XML("<content>{cdata}</content>".format(cdata=cdata), parser)
note.append(contentnode)
# write the XML file to disk
tree = etree.ElementTree(root)
tree.write("NextcloudNotes.enex", encoding="utf-8", xml_declaration=True)
# log
print("Exported Nextcloud Notes to NextcloudNotes.enex")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment