You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-07-16 00:14:34 +02:00
Done MD importer
This commit is contained in:
@ -19,14 +19,18 @@ class Command extends BaseCommand {
|
|||||||
|
|
||||||
options() {
|
options() {
|
||||||
return [
|
return [
|
||||||
//['--format <format>', 'jex, markdown'],
|
['--format <format>', 'auto, jex, md'],
|
||||||
|
['--notebook <notebook>', 'Notebook to import the notes to.'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
async action(args) {
|
async action(args) {
|
||||||
|
const folder = await app().loadItem(BaseModel.TYPE_FOLDER, args.options.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 : 'jex';
|
||||||
|
importOptions.destinationFolderId = folder ? folder.id : null;
|
||||||
|
|
||||||
const service = new InteropService();
|
const service = new InteropService();
|
||||||
const result = await service.import(importOptions);
|
const result = await service.import(importOptions);
|
||||||
|
@ -104,7 +104,13 @@ class FsDriverNode extends FsDriverBase {
|
|||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
if (!('recursive' in options)) options.recursive = false;
|
if (!('recursive' in options)) options.recursive = false;
|
||||||
|
|
||||||
let items = await fs.readdir(path);
|
let items = [];
|
||||||
|
try {
|
||||||
|
items = await fs.readdir(path);
|
||||||
|
} catch (error) {
|
||||||
|
throw this.fsErrorToJsError_(error);
|
||||||
|
}
|
||||||
|
|
||||||
let output = [];
|
let output = [];
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
const item = items[i];
|
const item = items[i];
|
||||||
|
@ -5,7 +5,7 @@ const Folder = require('lib/models/Folder.js');
|
|||||||
const NoteTag = require('lib/models/NoteTag.js');
|
const NoteTag = require('lib/models/NoteTag.js');
|
||||||
const Note = require('lib/models/Note.js');
|
const Note = require('lib/models/Note.js');
|
||||||
const Tag = require('lib/models/Tag.js');
|
const Tag = require('lib/models/Tag.js');
|
||||||
const { basename } = require('lib/path-utils.js');
|
const { basename, filename } = require('lib/path-utils.js');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const md5 = require('md5');
|
const md5 = require('md5');
|
||||||
const { sprintf } = require('sprintf-js');
|
const { sprintf } = require('sprintf-js');
|
||||||
@ -81,18 +81,19 @@ class JexExporter {
|
|||||||
|
|
||||||
class RawImporter {
|
class RawImporter {
|
||||||
|
|
||||||
async init(sourceDir) {
|
async init(sourceDir, options) {
|
||||||
this.sourceDir_ = sourceDir;
|
this.sourceDir_ = sourceDir;
|
||||||
|
this.options_ = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
async exec(result, options) {
|
async exec(result) {
|
||||||
const noteIdMap = {};
|
const noteIdMap = {};
|
||||||
const folderIdMap = {};
|
const folderIdMap = {};
|
||||||
const resourceIdMap = {};
|
const resourceIdMap = {};
|
||||||
const tagIdMap = {};
|
const tagIdMap = {};
|
||||||
const createdResources = {};
|
const createdResources = {};
|
||||||
const noteTagsToCreate = [];
|
const noteTagsToCreate = [];
|
||||||
const destinationFolderId = options.destinationFolderId;
|
const destinationFolderId = this.options_.destinationFolderId;
|
||||||
|
|
||||||
const replaceResourceNoteIds = (noteBody) => {
|
const replaceResourceNoteIds = (noteBody) => {
|
||||||
let output = noteBody;
|
let output = noteBody;
|
||||||
@ -202,9 +203,10 @@ class JexImporter {
|
|||||||
|
|
||||||
async init(sourcePath, options) {
|
async init(sourcePath, options) {
|
||||||
this.sourcePath_ = sourcePath;
|
this.sourcePath_ = sourcePath;
|
||||||
|
this.options_ = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
async exec(result, options) {
|
async exec(result) {
|
||||||
const tempDir = await temporaryDirectory(true);
|
const tempDir = await temporaryDirectory(true);
|
||||||
|
|
||||||
await require('tar').extract({
|
await require('tar').extract({
|
||||||
@ -215,8 +217,8 @@ class JexImporter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const importer = newImporter('raw');
|
const importer = newImporter('raw');
|
||||||
await importer.init(tempDir);
|
await importer.init(tempDir, this.options_);
|
||||||
result = await importer.exec(result, options);
|
result = await importer.exec(result);
|
||||||
|
|
||||||
await fs.remove(tempDir);
|
await fs.remove(tempDir);
|
||||||
|
|
||||||
@ -225,6 +227,54 @@ class JexImporter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MdImporter {
|
||||||
|
|
||||||
|
async init(sourcePath, options) {
|
||||||
|
this.sourcePath_ = sourcePath;
|
||||||
|
this.options_ = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec(result) {
|
||||||
|
if (!this.options_.destinationFolder) throw new Error('Destination folder must be specified');
|
||||||
|
|
||||||
|
const parentFolderId = this.options_.destinationFolder.id;
|
||||||
|
|
||||||
|
const filePaths = [];
|
||||||
|
if (await shim.fsDriver().isDirectory(this.sourcePath_)) {
|
||||||
|
const stats = await shim.fsDriver().readDirStats(this.sourcePath_);
|
||||||
|
for (let i = 0; i < stats.length; i++) {
|
||||||
|
const stat = stats[i];
|
||||||
|
if (fileExtension(stat.path).toLowerCase() === 'md') {
|
||||||
|
filePaths.push(this.sourcePath_ + '/' + stat.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filePaths.push(this.sourcePath_);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < filePaths.length; i++) {
|
||||||
|
const path = filePaths[i];
|
||||||
|
const stat = await shim.fsDriver().stat(path);
|
||||||
|
if (!stat) throw new Error('Cannot read ' + path);
|
||||||
|
const title = filename(path);
|
||||||
|
const body = await shim.fsDriver().readFile(path);
|
||||||
|
const note = {
|
||||||
|
parent_id: parentFolderId,
|
||||||
|
title: title,
|
||||||
|
body: body,
|
||||||
|
updated_time: stat.mtime.getTime(),
|
||||||
|
created_time: stat.birthtime.getTime(),
|
||||||
|
user_updated_time: stat.mtime.getTime(),
|
||||||
|
user_created_time: stat.birthtime.getTime(),
|
||||||
|
};
|
||||||
|
await Note.save(note, { autoTimestamp: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function newExporter(format) {
|
function newExporter(format) {
|
||||||
if (format === 'raw') {
|
if (format === 'raw') {
|
||||||
return new RawExporter();
|
return new RawExporter();
|
||||||
@ -240,6 +290,8 @@ function newImporter(format) {
|
|||||||
return new RawImporter();
|
return new RawImporter();
|
||||||
} else if (format === 'jex') {
|
} else if (format === 'jex') {
|
||||||
return new JexImporter();
|
return new JexImporter();
|
||||||
|
} else if (format === 'md') {
|
||||||
|
return new MdImporter();
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unknown format: ' + format);
|
throw new Error('Unknown format: ' + format);
|
||||||
}
|
}
|
||||||
@ -251,6 +303,7 @@ class InteropService {
|
|||||||
options = Object.assign({}, {
|
options = Object.assign({}, {
|
||||||
format: 'auto',
|
format: 'auto',
|
||||||
destinationFolderId: null,
|
destinationFolderId: null,
|
||||||
|
destinationFolder: null,
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
if (options.format === 'auto') {
|
if (options.format === 'auto') {
|
||||||
@ -265,13 +318,14 @@ class InteropService {
|
|||||||
if (options.destinationFolderId) {
|
if (options.destinationFolderId) {
|
||||||
const folder = await Folder.load(options.destinationFolderId);
|
const folder = await Folder.load(options.destinationFolderId);
|
||||||
if (!folder) throw new Error('Notebook not found: ' + options.destinationFolderId);
|
if (!folder) throw new Error('Notebook not found: ' + options.destinationFolderId);
|
||||||
|
options.destinationFolder = folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = { warnings: [] }
|
let result = { warnings: [] }
|
||||||
|
|
||||||
const importer = newImporter(options.format);
|
const importer = newImporter(options.format);
|
||||||
await importer.init(options.path);
|
await importer.init(options.path, options);
|
||||||
result = await importer.exec(result, options);
|
result = await importer.exec(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user