Jimmy: A Joplin Import Tool

jimmy is a tool to import notes in various formats to Markdown.

Which formats are supported?

  • Every format that is supported by pandoc. Additionally txt, eml, fountain, asciidoc and Textbundle.
  • Apps:
    • Anki
    • Bear
    • Cacher
    • CherryTree
    • Clipto
    • ColorNote
    • Day One
    • Dynalist
    • Facebook
    • Fusebase / Nimbus Note
    • Google Docs
    • Google Keep
    • jrnl
    • Notion
    • Obsidian
    • QOwnNotes
    • RedNotebook
    • Simplenote
    • Standard Notes
    • Synology Note Station
    • TiddlyWiki
    • Tomboy-ng / Gnote
    • vCard
    • Zettelkasten (Zkn3)
    • Zim Wiki
    • Zoho Notebook

For specific import instructions, visit the documentation.

For formats like Evernote or Onenote, Joplins built-in import should be used.

Features

  • :white_check_mark: Many input formats
  • :white_check_mark: Markdown + Frontmatter output
    • Compatible with any text editor
    • Can be imported to Joplin/Obsidian/...
    • Preserves resources, tags and note links when possible
  • :white_check_mark: Offline
  • :white_check_mark: Open Source
  • :white_check_mark: Cross-platform
  • :white_check_mark: Standalone (no python or node installation required)

What is converted (in most cases)?

  • Note content
  • Tags / Labels
  • Images / Resources / Attachments
  • External links and internal note links

Reference: Importing notes from other notebook applications

17 Likes

This seems a good way to me, but I can't figure it out how to convert Keep to markdown files.
I am on the windows 10 x64, I tried run the app from githu on cmd, it says:


D:\>jimmy-cli-windows takeout-20240920T005824Z-001.zip --format google_keep --frontmatter joplin
[09/20/24 09:48:59] INFO     Importing notes from "takeout-20240920T005824Z-001.zip"
[09/20/24 09:49:00] INFO     Start parsing
Traceback (most recent call last):
  File "jimmy_cli.py", line 103, in <module>
  File "jimmy_cli.py", line 99, in main
  File "jimmy.py", line 94, in jimmy
  File "jimmy.py", line 71, in convert_all_inputs
  File "converter.py", line 53, in convert_multiple
  File "formats\google_keep.py", line 35, in convert
KeyError: 'textContent'
[PYI-12092:ERROR] Failed to execute script 'jimmy_cli' due to unhandled exception!

What am I supposed to do

1 Like

That's an error in the script (likely the note is empty, but the script doesn't handle it correctly). I can provide a fixed version later today or tomorrow. Thanks for reporting!

Edit: I couldn't reproduce this with an empty note, but the script is now more robust. I hope this fixes the issue. Here is the new release: v0.0.13

2 Likes

:+1: I have tried and successfully converted 600+ notes. Everything is fine. It works perfectly as expected.
I am so happy.
I previously tried similar app, which needs Google account tokens, I couldn't do that.

Thank YOU for this helpful tool

2 Likes

I have tried Jimmy several times but keep running into the same "Unhandled exception" error. (5,5GB, ca. 1500 notes Synology Note Station NSX file, conversion on Win 10). My DEBUG-level export looks like this:

                    INFO     Finished parsing: 31 notebooks, 1032 notes, 1581 resources, 1065 tags
                    INFO     Start filtering
                    INFO     Finished filtering: 31 notebooks, 1032 notes, 1581 resources, 1065 tags
                    INFO     Start writing to file system
Traceback (most recent call last):
  File "jimmy_cli.py", line 108, in <module>
  File "jimmy_cli.py", line 104, in main
  File "jimmy.py", line 113, in jimmy
  File "importer.py", line 274, in import_notebook
  File "importer.py", line 271, in import_notebook
  File "importer.py", line 243, in import_note
  File "importer.py", line 160, in import_resources
  File "puremagic\main.py", line 271, in from_file
  File "puremagic\main.py", line 202, in _magic
ValueError: Input was empty
[PYI-8384:ERROR] Failed to execute script 'jimmy_cli' due to unhandled exception!

Notebooks   19%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ |  6/31 [00:03<00:12]
Notes       17%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Œ|  174/1032 [00:03<00:14]
Resources   29%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  |  458/1581 [00:03<00:07]
Tags        17%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ |  181/1065 [00:03<00:13]

The conversion itself seems to complete fine, but the script runs into problems when writing the data. I was unable to pinpoint why. Anything I can do here?

Thanks for the report! I can provide a fix later today. You can try it.

Background: The binary files (like images, PDFs, ...) in the export archive don't have an extension. That's why the script tries to guess the extension. In this case, the file seems to be empty and the corresponding error isn't catched properly.

1 Like

Many thanks, that would be very helpful! It's an excellent tool!

1 Like

The error should be fixed now: v0.0.21.

Feel free to post again if something doesn't work. I never tried such a big export :smiley:

1 Like

Many thanks! It's better -- but not quite there yet. This happens:

[10/04/24 17:17:04] DEBUG    Converting note "Root Causes vs. Facebook Causes"
                    DEBUG    Found too less or too many resources: 0 (note: "Root Causes vs. Facebook Causes", original
                             link: "![](webman/3rdparty/NoteStation/images/transparent.gif)")
                    DEBUG    Converting note "FIU-Verlag"
                    DEBUG    Converting note "beuys, Erweiterter Kunstbegriff"
[10/04/24 17:17:05] INFO     Finished parsing: 31 notebooks, 1032 notes, 1581 resources, 1065 tags
                    INFO     Start filtering
                    INFO     Finished filtering: 31 notebooks, 1032 notes, 1581 resources, 1065 tags
                    INFO     Start writing to file system
Traceback (most recent call last):
  File "jimmy_cli.py", line 125, in <module>
  File "jimmy_cli.py", line 121, in main
  File "jimmy.py", line 113, in jimmy
  File "importer.py", line 290, in import_notebook
  File "importer.py", line 287, in import_notebook
  File "importer.py", line 270, in import_note
  File "importer.py", line 238, in write_note
  File "frontmatter\__init__.py", line 238, in dump
  File "<frozen codecs>", line 918, in open
FileNotFoundError: [Errno 2] No such file or directory: '20241004T151103Z - Jimmy Import from synology_note_station\\Kleidung\\1926 c. Green chiffon web-pattern cocktail dress over it’s original silk slip. The dress is beaded in crystal silver glass seed beads, tiny white glass beads and crystal rhinestones. From 1st Dibs_.md'
[PYI-8820:ERROR] Failed to execute script 'jimmy_cli' due to unhandled exception!

Notebooks   42%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ | 13/31 [00:04<00:06]
Notes       30%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Œ |  307/1032 [00:04<00:11]
Resources   38%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  |  598/1581 [00:04<00:07]
Tags        33%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  |  351/1065 [00:04<00:09]
C:\notes_to_joplin\src>

In this case, it seems to be stuck on a very long file name, maybe including problematic characters?

And because you asked: I noticed that I see plenty of DEBUG messages (not WARNING) saying:

Found too less or too many resources: 0 (note: "Root Causes vs. Facebook Causes", original
                             link: "![](webman/3rdparty/NoteStation/images/transparent.gif)")

In each and every case, the same "transparent.gif" reappears. This affects at least some hundred notes.

The only potentially problematic character is ’, but I'm not sure if it's really causing the error. It could be the long path (270 characters), too. I think windows has a limit at 260 (?) characters. I will investigate.

It should be ok to ignore this. I guess it's an image added by Synology and not contained in the export. And probably it's transparent anyway :smiley:

It's most likely the path length. For now, I hardcoded a limit of 50 characters for the filename: v0.0.22

I went ahead and gave it a shot by renaming some notes in Note Station and it worked. The issue is the long filenames. I had to rename about 20 notes or so and the script went through fine.

However, that wasn't the end of the story. Upon importing using "MD+Frontmatter (Folder)" I ran into tons of other issues.

  • First off, the Joplin importer seems to have issues with tags that contain umlauts, e.g. "Γ–konomie". It gives me an error message reading "The MD file could not be imported. The tag 'Γ–konomie' already exists." (which it doesn't). If I edit the MD file to read "Oekonomie", the file imports fine.
  • Then, the import process eventually broke off with the error message "Malformed URI" – which is unfortunate as it does not give me a pointer to where the source of the issue lies. It is clear that most of the import is missing.
  • And then, finally, in the parts successfully imported, there are no images. As far as I can say, all notes that should contain images either show only

"![](webman/3rdparty/NoteStation/images/transparent.gif)"

if I look at them in markdown view and show as empty in the rich-text editor view. Or they do contain some sort of link to a file, but the file does not seem to be there and rich-text view shows only a "broken image icon" with the name of the image file:

![IMAGE-0.PNG](file_45edad5ca262e1217c8aa53294d954dd.PNG)

Any idea if these issues are related to your script or Joplin-specific?

Thanks for the detailed feedback!

I was able to reproduce your issue: Γ–konomie doesn't work, while Oekonomie and ΓΆkonomie are working. This is an issue in Joplin, but a workaround in the script can be implemented easily. I. e. converting all tags to lower case.

Edit: I opened a github issue: Tags starting with upper case special characters are not imported properly Β· Issue #11179 Β· laurent22/joplin Β· GitHub

I guess there is a problem on both sides: The script creates some odd URI and the Joplin import is not robust enough to handle it. You could try to catch the related error at the developer console ("Help > Toggle Development Tools"). Maybe it shows the name of the affected note.

That's strange. I couldn't observe this in the test files. Could you provide a example export here or send it to my email (linked at the end of the script output)? The more data it contains, the better for debugging. I guess that's the only way to find out if it's a bug in the script.

So, I figured I could dig a bit deeper. I thought that I might try importing the individual notebooks instead of the full import folder. This is what I found:

  • Regarding the tags, this affected only a handful on my end, so I quickly edited the MDs manually. All went fine then, but it would surely be nice to have this checked by the script.
  • Two out of 31 notebooks produced a "Malformed URI" error (but seemed to import anyway). I'll have to look deeper and see what I can find out. (The dev console was no help.)
  • When importing the individual notebooks, all images were there. HOWEVER, several hundred notes still lack some images and are instead peppered with the "transparent.gif" error message. This looks like this. This would be an issue I would be eager to see resolved.
  • All the notes that I had in the "Mein Notizbuch" (My Notebook) folder in Note Station got dumped into a notebook folder named "unnamed_4918c825fde249e4babf8ecc0eeed147". Not sure why. Import was no problem.

Also, I include a longer part of the DEBUG-level log here.

This is fixed, but not released yet.

Ok, then let's ignore this for now.

Unfortunately, I can't reproduce this and I would need an example export for debugging. I found another resolvable bug with images, but it's most likely not related.

Edit: Some image links and the tag issue are fixed in the latest release (v0.0.23).

This is because the export has an empty title ("title":"") and the script assigns a default title. Not sure why, but since it's only this single folder, I wouldn't implement a custom workaround.

Thanks for the tool. Does it support individual .tid (TiddlyWiki server) files?

1 Like

For now it supports only the complete backup in .json. From what I see, .tid files have the same markup, so it's a matter of extracting the (meta-)data. I will add it to the todo list.

1 Like

Awesome, thank you.

Individual .tid files are supported in v0.0.31. There are some limitations compared to the json export though, like note links and resources aren't preserved. Also Tiddlywikis WikiText can contain plenty of non-convertible stuff. But for mainly text notes with markup, the converter should be feasible.

1 Like