diff --git a/CliClient/app/import-enex.js b/CliClient/app/import-enex.js index 7c129d89fa..d5fd336978 100644 --- a/CliClient/app/import-enex.js +++ b/CliClient/app/import-enex.js @@ -86,9 +86,10 @@ async function fuzzyMatch(note) { return null; } -async function saveNoteToStorage(note) { +async function saveNoteToStorage(note, fuzzyMatching = false) { note = Note.filter(note); - let existingNote = await fuzzyMatch(note); + + let existingNote = fuzzyMatching ? await fuzzyMatch(note) : null; if (existingNote) { let diff = BaseModel.diffObjects(existingNote, note); @@ -117,11 +118,7 @@ async function saveNoteToStorage(note) { // In that case, just skip it - it means two different notes might be linked to the // same resource. let existingResource = await Resource.load(toSave.id); - if (existingResource) { - // console.warn('Trying to save: ' + JSON.stringify(toSave)); - // console.warn('But duplicate: ' + JSON.stringify(existingResource)); - continue; - } + if (existingResource) continue; await Resource.save(toSave, { isNew: true }); await filePutContents(Resource.fullPath(toSave), resource.data); @@ -134,7 +131,10 @@ async function saveNoteToStorage(note) { } } -function importEnex(parentFolderId, filePath) { +function importEnex(parentFolderId, filePath, importOptions = null) { + if (!importOptions) importOptions = {}; + if (!('fuzzyMatching' in importOptions)) importOptions.fuzzyMatching = false; + let stream = fs.createReadStream(filePath); return new Promise((resolve, reject) => { @@ -177,7 +177,7 @@ function importEnex(parentFolderId, filePath) { note.parent_id = parentFolderId; note.body = body; - return saveNoteToStorage(note); + return saveNoteToStorage(note, importOptions.fuzzyMatching); }); }); } diff --git a/CliClient/app/main.js b/CliClient/app/main.js index b2a33e419c..c11a130fc3 100644 --- a/CliClient/app/main.js +++ b/CliClient/app/main.js @@ -15,6 +15,7 @@ import { Logger } from 'lib/logger.js'; import { uuid } from 'lib/uuid.js'; import { sprintf } from 'sprintf-js'; import { importEnex } from 'import-enex'; +import { filename, basename } from 'lib/path-utils.js'; import { _ } from 'lib/locale.js'; import os from 'os'; import fs from 'fs-extra'; @@ -179,11 +180,29 @@ async function main() { }); } - function commandError(commandInstance, msg, end) { + function cmdError(commandInstance, msg, end) { commandInstance.log(msg); end(); } + function cmdPromptConfirm(commandInstance, message) { + return new Promise((resolve, reject) => { + let options = { + type: 'confirm', + name: 'ok', + default: false, // This needs to be false so that, when pressing Ctrl+C, the prompt returns false + message: message, + }; + commandInstance.prompt(options, (result) => { + if (result.ok) { + resolve(true); + } else { + resolve(false); + } + }); + }); + } + process.stdin.on('keypress', (_, key) => { if (key && key.name === 'return') { updatePrompt(); @@ -240,7 +259,7 @@ async function main() { let folderTitle = args['notebook-title']; let folder = await Folder.loadByField('title', folderTitle); - if (!folder) return commandError(this, _('Invalid folder title: %s', folderTitle), end); + if (!folder) return cmdError(this, _('Invalid folder title: %s', folderTitle), end); switchCurrentFolder(folder); end(); }, @@ -335,7 +354,7 @@ async function main() { } let item = await BaseItem.loadItemByField(itemType, 'title', title); - if (!item) return commandError(this, _('No item with title "%s" found.', title), end); + if (!item) return cmdError(this, _('No item with title "%s" found.', title), end); await BaseItem.deleteItem(itemType, item.id); if (currentFolder && currentFolder.id == item.id) { @@ -389,7 +408,7 @@ async function main() { folder = currentFolder; } - if (!folder) return commandError(this, _('Unknown notebook: "%s"', folderTitle), end); + if (!folder) return cmdError(this, _('Unknown notebook: "%s"', folderTitle), end); items = await Note.previews(folder.id, queryOptions); } @@ -424,11 +443,51 @@ async function main() { }); commands.push({ - usage: 'import-enex', - description: _('Imports a .enex file (Evernote notebook file).'), - action: function(args, end) { - - end(); + usage: 'import-enex [notebook-title]', + description: _('Imports en Evernote notebook file (.enex file).'), + options: [ + ['--fuzzy-matching', 'For debugging purposes. Do not use.'], + ], + action: async function(args, end) { + let filePath = args.file; + let folder = null; + let folderTitle = args['notebook-title']; + + if (folderTitle) { + folder = await Folder.loadByField('title', folderTitle); + if (!folder) return cmdError(this, _('Folder does not exists: "%s"', folderTitle), end); + } else { + folderTitle = filename(filePath); + folderTitle = _('Imported - %s', folderTitle); + let inc = 0; + while (true) { + let t = folderTitle + (inc ? ' (' + inc + ')' : ''); + let f = await Folder.loadByField('title', t); + if (!f) { + folderTitle = t; + break; + } + inc++; + } + } + + let ok = await cmdPromptConfirm(this, _('File "%s" will be imported into notebook "%s". Continue?', basename(filePath), folderTitle)) + + if (!ok) { + end(); + return; + } + + let options = { + fuzzyMatching: args.options['fuzzy-matching'] === true, + } + + folder = !folder ? await Folder.save({ title: folderTitle }) : folder; + this.log(_('Importing notes...')); + await importEnex(folder.id, filePath, options); + this.log(_('The notes have been imported into "%s"', folderTitle)); + + end(); }, }); diff --git a/lib/base-model.js b/lib/base-model.js index 3ba15ba27f..8d2e91fe00 100644 --- a/lib/base-model.js +++ b/lib/base-model.js @@ -156,7 +156,7 @@ class BaseModel { }); } - static loadByField(fieldName, fieldValue) { + static loadByField(fieldName, fieldValue) { return this.modelSelectOne('SELECT * FROM `' + this.tableName() + '` WHERE `' + fieldName + '` = ?', [fieldValue]); } diff --git a/lib/database.js b/lib/database.js index 29f166ee41..6b6ae6d672 100644 --- a/lib/database.js +++ b/lib/database.js @@ -285,11 +285,8 @@ class Database { logQuery(sql, params = null) { if (!this.debugMode()) return; - if (params !== null) { - this.logger().debug('DB: ' + sql, JSON.stringify(params)); - } else { - this.logger().debug('DB: ' + sql); - } + this.logger().debug(sql); + if (params !== null) this.logger().debug(JSON.stringify(params)); } static insertQuery(tableName, data) { diff --git a/lib/path-utils.js b/lib/path-utils.js index 8582456588..1fdfea1ce3 100644 --- a/lib/path-utils.js +++ b/lib/path-utils.js @@ -13,7 +13,7 @@ function basename(path) { function filename(path) { if (!path) throw new Error('Path is empty'); - let output = dirname(path); + let output = basename(path); if (output.indexOf('.') < 0) return output; output = output.split('.'); @@ -27,4 +27,4 @@ function isHidden(path) { return b[0] === '.'; } -export { basename, dirname, isHidden }; \ No newline at end of file +export { basename, dirname, filename, isHidden }; \ No newline at end of file