From cfaadb06025da34562d5443b9dcaaf79cda0198b Mon Sep 17 00:00:00 2001 From: Arne Tarara Date: Thu, 4 Jun 2020 15:47:30 +0200 Subject: [PATCH 1/9] Removed all commented lines and annotations that were optional --- standard-notes-to-enex.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/standard-notes-to-enex.py b/standard-notes-to-enex.py index 6a565e6..ab39ff2 100755 --- a/standard-notes-to-enex.py +++ b/standard-notes-to-enex.py @@ -24,7 +24,6 @@ final_file = ''' ''' tag_notes_links = {} -# first we build the tag hash for key, item in enumerate(data['items']): if item['content_type'] == 'Tag': for inner_key, reference in enumerate(item['content']['references']): @@ -36,26 +35,17 @@ for key, item in enumerate(data['items']): else: tag_notes_links[reference['uuid']] = [html.escape(item['content']['title'])] - -#print (json.dumps(tag_notes_links, indent=2)) -#quit() - -counter = 0 for key, item in enumerate(data['items']): if item['content_type'] == 'Note': -# if 'title' in item['content'] and 'text' in item['content']: # tís this if really needed? - if 'title' in item['content']: title = item['content']['title'] title = html.escape(title) - # title = re.sub(r'\\([^\w])', r'\1', title) # if you have mal-imported notes from earliner in SN, then this de-escaping may help you else: title = "empty title" text = item['content']['text'] text = text_from_html(title, text) - #text = re.sub(r'\\([^\w])', r'\1', text) # if you have mal-imported notes from earliner in SN, then this de-escaping may help you if item['uuid'] not in tag_notes_links: print(f"Whoops .... {title} had no tag ... if this is expected, then safely ignore ... Setting tag: 'Missing-Standard-Notes-Tag'.") @@ -71,10 +61,6 @@ for key, item in enumerate(data['items']): final_file += '''{title}{text}]]>{created_at}{updated_at}{tag}0'''.format(title=title, text=text, tag=tag, created_at=created_at, updated_at=updated_at) - counter += 1 # uncommet following lines if you want to limit import - #if counter > 500: # only process 500 notes - # break - final_file += '''''' # close root tag -- 2.54.0 From 599b3d58b003a716cf0b1ea6016ee339ef14be99 Mon Sep 17 00:00:00 2001 From: Arne Tarara Date: Thu, 4 Jun 2020 15:48:50 +0200 Subject: [PATCH 2/9] put the string replacement back in. Just for my codebase. Also removed uneeded commented lines --- standard-notes-to-enex.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/standard-notes-to-enex.py b/standard-notes-to-enex.py index 6a565e6..5325d43 100755 --- a/standard-notes-to-enex.py +++ b/standard-notes-to-enex.py @@ -24,7 +24,6 @@ final_file = ''' ''' tag_notes_links = {} -# first we build the tag hash for key, item in enumerate(data['items']): if item['content_type'] == 'Tag': for inner_key, reference in enumerate(item['content']['references']): @@ -44,18 +43,16 @@ counter = 0 for key, item in enumerate(data['items']): if item['content_type'] == 'Note': -# if 'title' in item['content'] and 'text' in item['content']: # tís this if really needed? - if 'title' in item['content']: title = item['content']['title'] title = html.escape(title) - # title = re.sub(r'\\([^\w])', r'\1', title) # if you have mal-imported notes from earliner in SN, then this de-escaping may help you + title = re.sub(r'\\([^\w])', r'\1', title) # if you have mal-imported notes from earliner in SN, then this de-escaping may help you else: title = "empty title" text = item['content']['text'] text = text_from_html(title, text) - #text = re.sub(r'\\([^\w])', r'\1', text) # if you have mal-imported notes from earliner in SN, then this de-escaping may help you + text = re.sub(r'\\([^\w])', r'\1', text) # if you have mal-imported notes from earliner in SN, then this de-escaping may help you if item['uuid'] not in tag_notes_links: print(f"Whoops .... {title} had no tag ... if this is expected, then safely ignore ... Setting tag: 'Missing-Standard-Notes-Tag'.") -- 2.54.0 From 3a068ede6f24013d9712081a7f7fbeeb2fc42d59 Mon Sep 17 00:00:00 2001 From: Arne Tarara Date: Thu, 4 Jun 2020 15:59:22 +0200 Subject: [PATCH 3/9] Fixed indentation --- standard-notes-to-enex.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/standard-notes-to-enex.py b/standard-notes-to-enex.py index ab39ff2..5b270f6 100755 --- a/standard-notes-to-enex.py +++ b/standard-notes-to-enex.py @@ -36,30 +36,30 @@ for key, item in enumerate(data['items']): tag_notes_links[reference['uuid']] = [html.escape(item['content']['title'])] for key, item in enumerate(data['items']): - if item['content_type'] == 'Note': + if item['content_type'] == 'Note': - if 'title' in item['content']: - title = item['content']['title'] - title = html.escape(title) - else: - title = "empty title" + if 'title' in item['content']: + title = item['content']['title'] + title = html.escape(title) + else: + title = "empty title" - text = item['content']['text'] - text = text_from_html(title, text) + text = item['content']['text'] + text = text_from_html(title, text) - if item['uuid'] not in tag_notes_links: - print(f"Whoops .... {title} had no tag ... if this is expected, then safely ignore ... Setting tag: 'Missing-Standard-Notes-Tag'.") - tag = 'Missing-Standard-Notes-Tag' - else: - tag = ''.join(tag_notes_links[item['uuid']]) + if item['uuid'] not in tag_notes_links: + print(f"Whoops .... {title} had no tag ... if this is expected, then safely ignore ... Setting tag: 'Missing-Standard-Notes-Tag'.") + tag = 'Missing-Standard-Notes-Tag' + else: + tag = ''.join(tag_notes_links[item['uuid']]) - # remove miliseconds and timezone ... example: 2020-04-14T14:30:09.256Z => 2020-04-14T14:30:09 - # we assume zulu time for all dates (UTC) - created_at = datetime.datetime.strptime(item['created_at'][0:19], '%Y-%m-%dT%H:%M:%S').strftime('%Y%m%dT%H%M%SZ') - updated_at = datetime.datetime.strptime(item['updated_at'][0:19], '%Y-%m-%dT%H:%M:%S').strftime('%Y%m%dT%H%M%SZ') + # remove miliseconds and timezone ... example: 2020-04-14T14:30:09.256Z => 2020-04-14T14:30:09 + # we assume zulu time for all dates (UTC) + created_at = datetime.datetime.strptime(item['created_at'][0:19], '%Y-%m-%dT%H:%M:%S').strftime('%Y%m%dT%H%M%SZ') + updated_at = datetime.datetime.strptime(item['updated_at'][0:19], '%Y-%m-%dT%H:%M:%S').strftime('%Y%m%dT%H%M%SZ') - final_file += '''{title}{text}]]>{created_at}{updated_at}{tag}0'''.format(title=title, text=text, tag=tag, created_at=created_at, updated_at=updated_at) + final_file += '''{title}{text}]]>{created_at}{updated_at}{tag}0'''.format(title=title, text=text, tag=tag, created_at=created_at, updated_at=updated_at) final_file += '''''' # close root tag -- 2.54.0 From 3ddc5ac7306b31b115c3982ef3a279caa66617f2 Mon Sep 17 00:00:00 2001 From: KC Maddever Date: Mon, 23 Nov 2020 12:26:44 +0800 Subject: [PATCH 4/9] Fix issue with notes with newlines not being imported to Evernote --- standard-notes-to-enex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard-notes-to-enex.py b/standard-notes-to-enex.py index 5b270f6..5d93af9 100755 --- a/standard-notes-to-enex.py +++ b/standard-notes-to-enex.py @@ -14,7 +14,7 @@ def text_from_html(title, text): temp_text = text.replace(title + '\n\n \n\n', '') # Parse to html temp_text = html.escape(temp_text) - temp_text = temp_text.replace('\n', '
') + temp_text = temp_text.replace('\n', '
') return temp_text final_file = ''' -- 2.54.0 From c32cec263a7df80495b2590089b461679cabceb9 Mon Sep 17 00:00:00 2001 From: Andros Fenollosa Date: Wed, 19 May 2021 15:30:21 +0200 Subject: [PATCH 5/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c051fa..d4bb342 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,6 @@ python3 standard-notes-to-enex.py SN_Archive.txt ``` If a name like `SN_Archive.txt` is not provided, the script will assume your file is called `notes.txt`. -## Tutorial +## Tutorial (Outdated) [Migrate notes from Standard Notes to Joplin](https://programadorwebvalencia.com/migrate-notes-from-standard-notes-to-joplin/) -- 2.54.0 From 50d780dba10832dc8a8bfc8c2ce1adfee8b7b9d7 Mon Sep 17 00:00:00 2001 From: Andros Fenollosa Date: Wed, 19 May 2021 15:33:35 +0200 Subject: [PATCH 6/9] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d4bb342..1c7b3a2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Standard Notes to Evernote or Joplin +# Attention: It has been reported that the following methodology is no longer valid as it exports Starndard Notes in a new format. A pull request is needed to fix it. ## Usage: @@ -7,6 +7,6 @@ python3 standard-notes-to-enex.py SN_Archive.txt ``` If a name like `SN_Archive.txt` is not provided, the script will assume your file is called `notes.txt`. -## Tutorial (Outdated) +## Tutorial [Migrate notes from Standard Notes to Joplin](https://programadorwebvalencia.com/migrate-notes-from-standard-notes-to-joplin/) -- 2.54.0 From c2a7416652a887dc67df0f20bd5ca6ed94e7ebd8 Mon Sep 17 00:00:00 2001 From: Jay Cady Date: Sat, 22 May 2021 17:01:05 -0700 Subject: [PATCH 7/9] Fix for new standard notes archives using zip files. --- README.md | 6 ++---- standard-notes-to-enex.py | 9 +++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1c7b3a2..af3bc34 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ -# Attention: It has been reported that the following methodology is no longer valid as it exports Starndard Notes in a new format. A pull request is needed to fix it. - ## Usage: ```bash -python3 standard-notes-to-enex.py SN_Archive.txt +python3 standard-notes-to-enex.py SN_Archive.zip ``` -If a name like `SN_Archive.txt` is not provided, the script will assume your file is called `notes.txt`. +If a name like `SN_Archive.zip` is not provided, the script will assume your file is called `notes.zip`. ## Tutorial diff --git a/standard-notes-to-enex.py b/standard-notes-to-enex.py index 5d93af9..7cac455 100755 --- a/standard-notes-to-enex.py +++ b/standard-notes-to-enex.py @@ -3,11 +3,12 @@ import html import datetime import re from sys import argv +import zipfile -source = argv[1] if len(argv) > 1 else 'notes.txt' - -data = json.load(open(source)) +source = argv[1] if len(argv) > 1 else 'notes.zip' +with zipfile.ZipFile(source, 'r') as zip_ref: + data = json.loads(zip_ref.read('Standard Notes Backup and Import File txt.txt').decode('utf-8')) def text_from_html(title, text): # Clear title @@ -65,6 +66,6 @@ final_file += '''''' # close root tag # Save -with open("notes.enex", "w") as text_file: +with open("notes.enex", "w", encoding='utf-8') as text_file: text_file.write(final_file) -- 2.54.0 From dbe01c8bd6c3a8111abc3eb74585e3e8c5bf2465 Mon Sep 17 00:00:00 2001 From: Kole McRae Date: Wed, 16 Jun 2021 09:37:27 -0400 Subject: [PATCH 8/9] Fixed typo that caused this to stop working Once I removed txt.txt from the required file name the script runs as expected. --- standard-notes-to-enex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standard-notes-to-enex.py b/standard-notes-to-enex.py index 7cac455..54da245 100755 --- a/standard-notes-to-enex.py +++ b/standard-notes-to-enex.py @@ -8,7 +8,7 @@ import zipfile source = argv[1] if len(argv) > 1 else 'notes.zip' with zipfile.ZipFile(source, 'r') as zip_ref: - data = json.loads(zip_ref.read('Standard Notes Backup and Import File txt.txt').decode('utf-8')) + data = json.loads(zip_ref.read('Standard Notes Backup and Import File.txt').decode('utf-8')) def text_from_html(title, text): # Clear title -- 2.54.0 From 8b93a6d6708387e81dd42760aa93047b226052ae Mon Sep 17 00:00:00 2001 From: Andros Fenollosa Date: Fri, 14 Aug 2026 16:36:15 +0200 Subject: [PATCH 9/9] Add contribution guidelines to the README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index af3bc34..6d03022 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,7 @@ If a name like `SN_Archive.zip` is not provided, the script will assume your fil ## Tutorial [Migrate notes from Standard Notes to Joplin](https://programadorwebvalencia.com/migrate-notes-from-standard-notes-to-joplin/) + +## Contributing + +Contributions are welcome! Please see the [contribution guidelines](https://git.andros.dev/andros/contribute) for instructions on how to submit issues or pull requests. -- 2.54.0