Last active
August 2, 2024 06:00
-
-
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
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/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