1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-02-01 19:15:01 +02:00

Changed export format extension to JEX and made it a non-compressed tar file

This commit is contained in:
Laurent Cozic 2018-02-25 21:08:32 +00:00
parent 9f8a46b9d9
commit 39ddd934f6
6 changed files with 119 additions and 39 deletions

View File

@ -19,7 +19,7 @@ class Command extends BaseCommand {
options() {
return [
['--format <format>', 'jpz (compressed, default), raw (plain text files)'],
//['--format <format>', 'jex (default), raw'],
['--note <note>', _('Exports only the given note.')],
['--notebook <notebook>', _('Exports only the given notebook.')],
];
@ -29,7 +29,7 @@ class Command extends BaseCommand {
let exportOptions = {};
exportOptions.path = args.path;
exportOptions.format = args.options.format ? args.options.format : 'jpz';
exportOptions.format = args.options.format ? args.options.format : 'jex';
if (args.options.note) {

View File

@ -0,0 +1,39 @@
const { BaseCommand } = require('./base-command.js');
const InteropService = require('lib/services/InteropService.js');
const BaseModel = require('lib/BaseModel.js');
const Note = require('lib/models/Note.js');
const { reg } = require('lib/registry.js');
const { app } = require('./app.js');
const { _ } = require('lib/locale.js');
const fs = require('fs-extra');
class Command extends BaseCommand {
usage() {
return 'import <path>';
}
description() {
return _('Imports data into Joplin.');
}
options() {
return [
//['--format <format>', 'jex, markdown'],
];
}
async action(args) {
const importOptions = {};
importOptions.path = args.path;
importOptions.format = args.options.format ? args.options.format : 'jex';
const service = new InteropService();
const result = await service.import(importOptions);
result.warnings.map((w) => this.stdout(w));
}
}
module.exports = Command;

View File

@ -0,0 +1,24 @@
class FsDriverBase {
async isDirectory(path) {
const stat = await this.stat(path);
return !stat ? false : stat.isDirectory();
}
async readDirStatsHandleRecursion_(basePath, stat, output, options) {
if (options.recursive && stat.isDirectory()) {
const subPath = basePath + '/' + stat.path;
const subStats = await this.readDirStats(subPath, options);
for (let j = 0; j < subStats.length; j++) {
const subStat = subStats[j];
subStat.path = stat.path + '/' + subStat.path;
output.push(subStat);
}
}
return output;
}
}
module.exports = FsDriverBase;

View File

@ -1,7 +1,8 @@
const fs = require('fs-extra');
const { time } = require('lib/time-utils.js');
const FsDriverBase = require('lib/fs-driver-base');
class FsDriverNode {
class FsDriverNode extends FsDriverBase {
fsErrorToJsError_(error, path = null) {
let msg = error.toString();
@ -81,9 +82,14 @@ class FsDriverNode {
async stat(path) {
try {
const s = await fs.stat(path);
s.path = path;
return s;
const stat = await fs.stat(path);
return {
birthtime: stat.birthtime,
mtime: stat.mtime,
isDirectory: () => stat.isDirectory(),
path: path,
size: stat.size,
};
} catch (error) {
if (error.code == 'ENOENT') return null;
throw error;
@ -94,14 +100,20 @@ class FsDriverNode {
return fs.utimes(path, timestampDate, timestampDate);
}
async readDirStats(path) {
async readDirStats(path, options = null) {
if (!options) options = {};
if (!('recursive' in options)) options.recursive = false;
let items = await fs.readdir(path);
let output = [];
for (let i = 0; i < items.length; i++) {
let stat = await this.stat(path + '/' + items[i]);
const item = items[i];
let stat = await this.stat(path + '/' + item);
if (!stat) continue; // Has been deleted between the readdir() call and now
stat.path = stat.path.substr(path.length + 1);
output.push(stat);
output = await this.readDirStatsHandleRecursion_(path, stat, output, options);
}
return output;
}

View File

@ -1,6 +1,7 @@
const RNFS = require('react-native-fs');
const FsDriverBase = require('lib/fs-driver-base');
class FsDriverRN {
class FsDriverRN extends FsDriverBase {
appendFileSync(path, string) {
throw new Error('Not implemented');
@ -34,13 +35,18 @@ class FsDriverRN {
};
}
async readDirStats(path) {
async readDirStats(path, options = null) {
if (!options) options = {};
if (!('recursive' in options)) options.recursive = false;
let items = await RNFS.readDir(path);
let output = [];
for (let i = 0; i < items.length; i++) {
const item = items[i];
const relativePath = item.path.substr(path.length + 1);
output.push(this.rnfsStatToStd_(item, relativePath));
output = await this.readDirStatsHandleRecursion_(path, item, output, options);
}
return output;
}

View File

@ -9,6 +9,7 @@ const { basename } = require('lib/path-utils.js');
const fs = require('fs-extra');
const md5 = require('md5');
const { sprintf } = require('sprintf-js');
const { shim } = require('lib/shim');
class RawExporter {
@ -35,9 +36,11 @@ class RawExporter {
}
class JpzExporter {
class JexExporter {
async init(destPath) {
if (await shim.fsDriver().isDirectory(destPath)) throw new Error('Path is a directory: ' + destPath);
this.tempDir_ = require('os').tmpdir() + '/' + md5(Math.random() + Date.now());
this.destPath_ = destPath;
this.rawExporter_ = new RawExporter();
@ -53,27 +56,17 @@ class JpzExporter {
}
async close() {
const cwd = process.cwd();
process.chdir(this.tempDir_);
const stats = await shim.fsDriver().readDirStats(this.tempDir_, { recursive: true });
const filePaths = stats.map((a) => a.path);
const cleanUp = () => {
process.chdir(cwd);
}
await require('tar').create({
strict: true,
portable: true,
file: this.destPath_,
cwd: this.tempDir_,
}, filePaths);
try {
await require('tar').c({
strict: true,
gzip: true,
file: this.destPath_,
}, ['./']);
await fs.remove(this.tempDir_);
} catch (error) {
cleanUp();
throw error;
}
cleanUp();
await fs.remove(this.tempDir_);
}
}
@ -81,8 +74,18 @@ class JpzExporter {
function newExporter(format) {
if (format === 'raw') {
return new RawExporter();
} else if (format === 'jpz') {
return new JpzExporter();
} else if (format === 'jex') {
return new JexExporter();
} else {
throw new Error('Unknown format: ' + format);
}
}
function newImporter(format) {
if (format === 'raw') {
return new RawImporter();
} else if (format === 'jex') {
return new JexImporter();
} else {
throw new Error('Unknown format: ' + format);
}
@ -91,19 +94,15 @@ function newExporter(format) {
class InteropService {
async import(options) {
// format
// file/dir path
const importer = newImporter(options.format);
await importer.init(options.path);
}
async export(options) {
const exportPath = options.path ? options.path : null;
const sourceFolderIds = options.sourceFolderIds ? options.sourceFolderIds : [];
const sourceNoteIds = options.sourceNoteIds ? options.sourceNoteIds : [];
const result = {
warnings: [],
}
const result = { warnings: [] }
const itemsToExport = [];
const queueExportItem = (itemType, itemOrId) => {