Simplenote to Bear importer
With Bear 2 seemingly around the corner and the beta being great (though still very much a beta), I decided it was time to move from Simplenote.
Exporting from Simplenote gives you two things, neither of which is directly usable by Bear:
- A file for each note with correct creation and modification dates and tags appended at the end as not-hashtags
- A JSON file containing each note and its metadata (UUID, tags, creation date, and modification date)
What I needed for Bear was a file for each note with correct creation and modification dates and tags at the end as hashtags. So I wrote a quick Python script that reads in the JSON file and — with some help from SetFile — outputs a file in the format I needed.
from subprocess import run
import os
import json
from datetime import datetime
# path to input JSON
in_path = os.path.join(os.environ['HOME'], 'Downloads/notes/source/notes.json')
# path to output directory. it must exist.
out_path = os.path.join(os.environ['HOME'], 'Downloads/for-bear')
# read the data
with open(in_path) as f:
note_data = json.load(f)
datetime_format = '%m/%d/%Y %H:%M:%S.%f'
def create_note_file(datum):
# the note text
content = datum['content']
# if there are tags, append them as space-separated hashtags at the end of the text
if 'tags' in datum:
tags_string = '\n\n'
tags_string += ' '.join(['#' + tag for tag in datum['tags']])
content += tags_string
# convert times to local timezone (Simplenote is in UTC) and format for SetFile
creation_date = datetime.fromisoformat(datum['creationDate']).astimezone()
creation_date_str = creation_date.strftime(datetime_format)
modification_date = datetime.fromisoformat(datum['lastModified']).astimezone()
modification_date_str = modification_date.strftime(datetime_format)
# write out the file
outfile_path = os.path.join(out_path, datum['id'] + '.md')
with open(outfile_path, 'w+') as outfile:
outfile.write(content)
# set the creation and modification dates
run(['SetFile', '-d', creation_date_str, outfile_path])
run(['SetFile', '-m', modification_date_str, outfile_path])
# iterate through the notes
for note in note_data['activeNotes']:
create_note_file(note)
Note: Using datetime.fromisoformat()
with the date format Simplenote uses requires Python 3.11+.
After running the script, import them into Bear with these settings:
- ☑️ Keep original creation and modification date
- ☑️ Use first line as title (txt, md, textbundle)
- 🔲 Use filename as title (txt, md, textbundle)
- 🔲 Escape involuntary tags
Possible improvements
It would be nice to \
escape all incidental hashtags, but it wouldn’t be trivial. For example, you shouldn’t escape #
followed by a non-space character inside a Markdown `#code block`.