-
Notifications
You must be signed in to change notification settings - Fork 559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Importer: Add core Simplenote format support #922
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you Dan! 🙂
Two things I noticed that are missing:
- Is there a reason why the
markdown
systemTag was not included in the original export json? Seems like something that could/should be included like thepinned
prop. - We also need to add the tags to the tagBucket.
lib/utils/import/index.js
Outdated
throw new Error('No notes to import.'); | ||
} | ||
|
||
if (!get(notes, 'activeNotes') || !get(notes, 'trashedNotes')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!get(notes, 'activeNotes') || !get(notes, 'trashedNotes')) { | |
if (!notes.activeNotes || !notes.trashedNotes) { |
I’m wondering if this would be more readable and functionally equivalent in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this should be an &&
not an ||
😬. Will fix!
lib/utils/import/index.js
Outdated
}; | ||
|
||
get(notes, 'activeNotes', []).map(note => importNote(note)); | ||
get(notes, 'trashedNotes', []).map(note => importNote(note)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think .map(importNote)
would be equivalent here.
lib/utils/import/index.js
Outdated
importedNote.shareURL = ''; | ||
importedNote.systemTags = []; | ||
|
||
importedNote.deleted = get(importedNote, 'deleted', false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The deleted
prop isn’t set on trashed notes in the export json, so nothing is being set to true
here. We will have to explicitly set this prop to true
with each note in trashedNotes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add deleted
prop to the export?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The deleted
property is required, or else Simperium will reject it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm guessing that the deleted
prop was not in the export because having that and also keeping a trashedNotes array would be redundant. We could flatten the export structure, but that would be disruptive for users who have export files with the old structure.
Explicitly setting back the deleted
prop in the importer side should be ok, I think.
lib/utils/import/README.MD
Outdated
|
||
This is the core importer for Simplenote. It expects a JSON object of notes in the same format as the `import` module. It is aggressive about only allowing certain properties, and converts dates into timestamps where appropriate. Importing specific export files (Such as Evernote .enex) should use a separate conversion script and then pass the resulting JSON object to `importNotes()`. | ||
|
||
Example JSON: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the “Example JSON” should be “Example JSON with allowed properties”, and then remove the id
prop?
lib/utils/import/test.js
Outdated
|
||
it('should throw when invalid json is passed', () => { | ||
const bogusNotes = { actveNotes: [] }; | ||
expect(importNotes.bind(importNotes, bogusNotes)).toThrow( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, are these bind
statements intended to do anything more than a simple expect(() => importNotes(null))
? It had me wondering why a bind was necessary here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it was executing the function during the test instead of evaluating it for the result. Hope that makes sense :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, if it's just to avoid the immediate call, then simply wrapping the call in a function (e.g. expect(() => importNotes(null))
) should be sufficient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Thanks.
How about we add some tag to indicate which import the notes came from? even if we leave it as a user-facing tag the customer could remove them if they wanted. could make mess-ups significantly easier to deal with, like when dealing with duplicate notes or partial imports. |
Good call! |
Hmm. How about we add a |
Seems just as good. I bet some people want to see it, others don't. System tag seems fine. |
Cleaner (and fixed!) check for no activeNotes or trashedNotes props.
… be marked deleted. Probably a better way to do this?
…r the note came from.
…it. Fixed bug where creationDate could be `NaN`.
ToDo:
|
Fixed date parsing to get correct timestamp.
…stead of throwing.
Sorry I didn't catch this on the first pass, but this CoreImporter is actually not dealing with JSON at all (it just takes JavaScript objects as input), so we should probably remove mentions of JSON in the readme. (So why is the To allow users to import their JSON files, we're going to need a separate SimplenoteImporter to read from |
Oh yeah, lol! I think I can change |
@roundhill I added some fixes to the tests and readme so this can be merged. Anything left on your side? |
I'm good! |
Here's the first step towards getting an importer going. This module expects to receive a JSON object that contains note data in the same format as when you export your notes from the app (the
notes.json
file).I'm slightly concerned about performance here with large imports, perhaps we could use a web worker? The exporter is crazy fast with thousands of notes, however, so maybe we don't need to worry about it.
To Test
npm run test
passes (I added some very basic tests)notes.json
file and put it in the source code in the same folder asapp.jsx
.import exportedJSON from './notes.json'
andimport importNotes from './utils/import';
to the top of app.jsx.render()
ofapp.jsx
(or anywhere you'd like) runimportNotes(exportedJSON, this.props.noteBucket);
Refs: #916
cc @dmsnell!