mirror of
https://github.com/laurent22/joplin.git
synced 2025-03-20 20:55:18 +02:00
Moved Enex import to InteropService
This commit is contained in:
parent
3cee671f25
commit
d7fd8944f7
@ -1,68 +0,0 @@
|
|||||||
const { BaseCommand } = require('./base-command.js');
|
|
||||||
const { app } = require('./app.js');
|
|
||||||
const { _ } = require('lib/locale.js');
|
|
||||||
const Folder = require('lib/models/Folder.js');
|
|
||||||
const { importEnex } = require('lib/import-enex');
|
|
||||||
const { filename, basename } = require('lib/path-utils.js');
|
|
||||||
const { cliUtils } = require('./cli-utils.js');
|
|
||||||
|
|
||||||
class Command extends BaseCommand {
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
return 'import-enex <file> [notebook]';
|
|
||||||
}
|
|
||||||
|
|
||||||
description() {
|
|
||||||
return _('Imports an Evernote notebook file (.enex file).');
|
|
||||||
}
|
|
||||||
|
|
||||||
options() {
|
|
||||||
return [
|
|
||||||
['-f, --force', _('Do not ask for confirmation.')],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
async action(args) {
|
|
||||||
let filePath = args.file;
|
|
||||||
let folder = null;
|
|
||||||
let folderTitle = args['notebook'];
|
|
||||||
let force = args.options.force === true;
|
|
||||||
|
|
||||||
if (!folderTitle) folderTitle = filename(filePath);
|
|
||||||
folder = await Folder.loadByField('title', folderTitle);
|
|
||||||
const msg = folder ? _('File "%s" will be imported into existing notebook "%s". Continue?', basename(filePath), folderTitle) : _('New notebook "%s" will be created and file "%s" will be imported into it. Continue?', folderTitle, basename(filePath));
|
|
||||||
const ok = force ? true : await this.prompt(msg);
|
|
||||||
if (!ok) return;
|
|
||||||
|
|
||||||
let lastProgress = '';
|
|
||||||
|
|
||||||
let options = {
|
|
||||||
onProgress: (progressState) => {
|
|
||||||
let line = [];
|
|
||||||
line.push(_('Found: %d.', progressState.loaded));
|
|
||||||
line.push(_('Created: %d.', progressState.created));
|
|
||||||
if (progressState.updated) line.push(_('Updated: %d.', progressState.updated));
|
|
||||||
if (progressState.skipped) line.push(_('Skipped: %d.', progressState.skipped));
|
|
||||||
if (progressState.resourcesCreated) line.push(_('Resources: %d.', progressState.resourcesCreated));
|
|
||||||
if (progressState.notesTagged) line.push(_('Tagged: %d.', progressState.notesTagged));
|
|
||||||
lastProgress = line.join(' ');
|
|
||||||
cliUtils.redraw(lastProgress);
|
|
||||||
},
|
|
||||||
onError: (error) => {
|
|
||||||
let s = error.trace ? error.trace : error.toString();
|
|
||||||
this.stdout(s);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
folder = !folder ? await Folder.save({ title: folderTitle }) : folder;
|
|
||||||
|
|
||||||
app().gui().showConsole();
|
|
||||||
this.stdout(_('Importing notes...'));
|
|
||||||
await importEnex(folder.id, filePath, options);
|
|
||||||
cliUtils.redrawDone();
|
|
||||||
this.stdout(_('The notes have been imported: %s', lastProgress));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Command;
|
|
@ -2,6 +2,9 @@ const { BaseCommand } = require('./base-command.js');
|
|||||||
const InteropService = require('lib/services/InteropService.js');
|
const InteropService = require('lib/services/InteropService.js');
|
||||||
const BaseModel = require('lib/BaseModel.js');
|
const BaseModel = require('lib/BaseModel.js');
|
||||||
const Note = require('lib/models/Note.js');
|
const Note = require('lib/models/Note.js');
|
||||||
|
const { filename, basename, fileExtension } = require('lib/path-utils.js');
|
||||||
|
const { importEnex } = require('lib/import-enex');
|
||||||
|
const { cliUtils } = require('./cli-utils.js');
|
||||||
const { reg } = require('lib/registry.js');
|
const { reg } = require('lib/registry.js');
|
||||||
const { app } = require('./app.js');
|
const { app } = require('./app.js');
|
||||||
const { _ } = require('lib/locale.js');
|
const { _ } = require('lib/locale.js');
|
||||||
@ -10,7 +13,7 @@ const fs = require('fs-extra');
|
|||||||
class Command extends BaseCommand {
|
class Command extends BaseCommand {
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
return 'import <path>';
|
return 'import <path> [notebook]';
|
||||||
}
|
}
|
||||||
|
|
||||||
description() {
|
description() {
|
||||||
@ -19,23 +22,49 @@ class Command extends BaseCommand {
|
|||||||
|
|
||||||
options() {
|
options() {
|
||||||
return [
|
return [
|
||||||
['--format <format>', 'auto, jex, md'],
|
['-f, --force', _('Do not ask for confirmation.')],
|
||||||
['--notebook <notebook>', 'Notebook to import the notes to.'],
|
['--format <format>', 'auto, jex, enex, md'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
async action(args) {
|
async action(args) {
|
||||||
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, args.options.notebook);
|
let folder = await app().loadItem(BaseModel.TYPE_FOLDER, args.notebook);
|
||||||
|
|
||||||
|
if (args.notebook && !folder) throw new Error(_('Cannot find "%s".', args.notebook));
|
||||||
|
|
||||||
const importOptions = {};
|
const importOptions = {};
|
||||||
importOptions.path = args.path;
|
importOptions.path = args.path;
|
||||||
importOptions.format = args.options.format ? args.options.format : 'jex';
|
importOptions.format = args.options.format ? args.options.format : 'auto';
|
||||||
importOptions.destinationFolderId = folder ? folder.id : null;
|
importOptions.destinationFolderId = folder ? folder.id : null;
|
||||||
|
|
||||||
|
let lastProgress = '';
|
||||||
|
|
||||||
|
// onProgress/onError supported by Enex import only
|
||||||
|
|
||||||
|
importOptions.onProgress = (progressState) => {
|
||||||
|
let line = [];
|
||||||
|
line.push(_('Found: %d.', progressState.loaded));
|
||||||
|
line.push(_('Created: %d.', progressState.created));
|
||||||
|
if (progressState.updated) line.push(_('Updated: %d.', progressState.updated));
|
||||||
|
if (progressState.skipped) line.push(_('Skipped: %d.', progressState.skipped));
|
||||||
|
if (progressState.resourcesCreated) line.push(_('Resources: %d.', progressState.resourcesCreated));
|
||||||
|
if (progressState.notesTagged) line.push(_('Tagged: %d.', progressState.notesTagged));
|
||||||
|
lastProgress = line.join(' ');
|
||||||
|
cliUtils.redraw(lastProgress);
|
||||||
|
};
|
||||||
|
|
||||||
|
importOptions.onError = (error) => {
|
||||||
|
let s = error.trace ? error.trace : error.toString();
|
||||||
|
this.stdout(s);
|
||||||
|
};
|
||||||
|
|
||||||
|
app().gui().showConsole();
|
||||||
|
this.stdout(_('Importing notes...'));
|
||||||
const service = new InteropService();
|
const service = new InteropService();
|
||||||
const result = await service.import(importOptions);
|
const result = await service.import(importOptions);
|
||||||
|
|
||||||
result.warnings.map((w) => this.stdout(w));
|
result.warnings.map((w) => this.stdout(w));
|
||||||
|
cliUtils.redrawDone();
|
||||||
|
if (lastProgress) this.stdout(_('The notes have been imported: %s', lastProgress));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,10 @@ const fs = require('fs-extra');
|
|||||||
const md5 = require('md5');
|
const md5 = require('md5');
|
||||||
const { sprintf } = require('sprintf-js');
|
const { sprintf } = require('sprintf-js');
|
||||||
const { shim } = require('lib/shim');
|
const { shim } = require('lib/shim');
|
||||||
|
const { _ } = require('lib/locale');
|
||||||
const { fileExtension } = require('lib/path-utils');
|
const { fileExtension } = require('lib/path-utils');
|
||||||
const { uuid } = require('lib/uuid.js');
|
const { uuid } = require('lib/uuid.js');
|
||||||
|
const { importEnex } = require('lib/import-enex');
|
||||||
|
|
||||||
async function temporaryDirectory(createIt) {
|
async function temporaryDirectory(createIt) {
|
||||||
const tempDir = require('os').tmpdir() + '/' + md5(Math.random() + Date.now());
|
const tempDir = require('os').tmpdir() + '/' + md5(Math.random() + Date.now());
|
||||||
@ -209,12 +211,19 @@ class JexImporter {
|
|||||||
async exec(result) {
|
async exec(result) {
|
||||||
const tempDir = await temporaryDirectory(true);
|
const tempDir = await temporaryDirectory(true);
|
||||||
|
|
||||||
|
try {
|
||||||
await require('tar').extract({
|
await require('tar').extract({
|
||||||
strict: true,
|
strict: true,
|
||||||
portable: true,
|
portable: true,
|
||||||
file: this.sourcePath_,
|
file: this.sourcePath_,
|
||||||
cwd: tempDir,
|
cwd: tempDir,
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
let msg = ['Cannot untar file ' + this.sourcePath_, error.message];
|
||||||
|
if (error.data) msg.push(JSON.stringify(error.data));
|
||||||
|
let e = new Error(msg.join(': '));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
const importer = newImporter('raw');
|
const importer = newImporter('raw');
|
||||||
await importer.init(tempDir, this.options_);
|
await importer.init(tempDir, this.options_);
|
||||||
@ -275,6 +284,28 @@ class MdImporter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EnexImporter {
|
||||||
|
|
||||||
|
async init(sourcePath, options) {
|
||||||
|
this.sourcePath_ = sourcePath;
|
||||||
|
this.options_ = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(result) {
|
||||||
|
let folder = this.options_.destinationFolder;
|
||||||
|
|
||||||
|
if (!folder) {
|
||||||
|
const folderTitle = await Folder.findUniqueFolderTitle(filename(this.sourcePath_));
|
||||||
|
folder = await Folder.save({ title: folderTitle });
|
||||||
|
}
|
||||||
|
|
||||||
|
await importEnex(folder.id, this.sourcePath_, this.options_);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function newExporter(format) {
|
function newExporter(format) {
|
||||||
if (format === 'raw') {
|
if (format === 'raw') {
|
||||||
return new RawExporter();
|
return new RawExporter();
|
||||||
@ -292,6 +323,8 @@ function newImporter(format) {
|
|||||||
return new JexImporter();
|
return new JexImporter();
|
||||||
} else if (format === 'md') {
|
} else if (format === 'md') {
|
||||||
return new MdImporter();
|
return new MdImporter();
|
||||||
|
} else if (format === 'enex') {
|
||||||
|
return new EnexImporter();
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unknown format: ' + format);
|
throw new Error('Unknown format: ' + format);
|
||||||
}
|
}
|
||||||
@ -300,6 +333,8 @@ function newImporter(format) {
|
|||||||
class InteropService {
|
class InteropService {
|
||||||
|
|
||||||
async import(options) {
|
async import(options) {
|
||||||
|
if (!await shim.fsDriver().exists(options.path)) throw new Error(_('Cannot find "%s".', options.path));
|
||||||
|
|
||||||
options = Object.assign({}, {
|
options = Object.assign({}, {
|
||||||
format: 'auto',
|
format: 'auto',
|
||||||
destinationFolderId: null,
|
destinationFolderId: null,
|
||||||
@ -307,9 +342,11 @@ class InteropService {
|
|||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
if (options.format === 'auto') {
|
if (options.format === 'auto') {
|
||||||
const ext = fileExtension(options.path);
|
const ext = fileExtension(options.path).toLowerCase();
|
||||||
if (ext.toLowerCase() === 'jex') {
|
if (ext === 'jex') {
|
||||||
options.format = 'jex';
|
options.format = 'jex';
|
||||||
|
} else if (ext === 'enex') {
|
||||||
|
options.format = 'enex';
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Cannot automatically detect source format from path: ' + options.path);
|
throw new Error('Cannot automatically detect source format from path: ' + options.path);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user