From 0eb18d206d83b2a51fe57641d6ee9a3c865a07d8 Mon Sep 17 00:00:00 2001 From: Ben Fisher Date: Sun, 11 Nov 2018 12:17:43 -0800 Subject: [PATCH] Patch to implement feature, exporting notes to JSON (#912, issues/912). (#927) * Patch to implement feature, exporting notes to JSON (#912, issues/912). * Revising based on feedback * Directly calling JSON.stringify on the item --- CliClient/tests/services_InteropService.js | 21 +++++++++++++ ReactNativeClient/lib/models/BaseItem.js | 11 +++++-- .../lib/services/InteropService.js | 4 +++ .../services/InteropService_Exporter_Json.js | 30 +++++++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 ReactNativeClient/lib/services/InteropService_Exporter_Json.js diff --git a/CliClient/tests/services_InteropService.js b/CliClient/tests/services_InteropService.js index 40b9f0959..d53f8f628 100644 --- a/CliClient/tests/services_InteropService.js +++ b/CliClient/tests/services_InteropService.js @@ -310,4 +310,25 @@ describe('services_InteropService', function() { expect(note2_2.body.indexOf(note1_2.id) >= 0).toBe(true); })); + it('should export into json format', asyncTest(async () => { + const service = new InteropService(); + let folder1 = await Folder.save({ title: 'folder1' }); + let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id }); + note1 = await Note.load(note1.id); + const filePath = exportDir(); + + await service.export({ path: filePath, format: 'json' }); + + // verify that the json files exist and can be parsed + const items = [folder1, note1]; + for (let i = 0; i < items.length; i++) { + const jsonFile = filePath + '/' + items[i].id + '.json'; + let json = await fs.readFile(jsonFile, 'utf-8'); + let obj = JSON.parse(json); + expect(obj.id).toBe(items[i].id); + expect(obj.type_).toBe(items[i].type_); + expect(obj.title).toBe(items[i].title); + expect(obj.body).toBe(items[i].body); + } + })); }); \ No newline at end of file diff --git a/ReactNativeClient/lib/models/BaseItem.js b/ReactNativeClient/lib/models/BaseItem.js index 36773d510..7930a1820 100644 --- a/ReactNativeClient/lib/models/BaseItem.js +++ b/ReactNativeClient/lib/models/BaseItem.js @@ -75,9 +75,14 @@ class BaseItem extends BaseModel { return r.total; } - static systemPath(itemOrId) { - if (typeof itemOrId === 'string') return itemOrId + '.md'; - return itemOrId.id + '.md'; + static systemPath(itemOrId, extension = null) { + if (extension === null) + extension = 'md'; + + if (typeof itemOrId === 'string') + return itemOrId + '.' + extension; + else + return itemOrId.id + '.' + extension; } static isSystemPath(path) { diff --git a/ReactNativeClient/lib/services/InteropService.js b/ReactNativeClient/lib/services/InteropService.js index f7a14db37..c67f0b947 100644 --- a/ReactNativeClient/lib/services/InteropService.js +++ b/ReactNativeClient/lib/services/InteropService.js @@ -58,6 +58,10 @@ class InteropService { format: 'raw', target: 'directory', description: _('Joplin Export Directory'), + }, { + format: 'json', + target: 'directory', + description: _('Json Export Directory'), }, { format: 'md', target: 'directory', diff --git a/ReactNativeClient/lib/services/InteropService_Exporter_Json.js b/ReactNativeClient/lib/services/InteropService_Exporter_Json.js new file mode 100644 index 000000000..8bcb634af --- /dev/null +++ b/ReactNativeClient/lib/services/InteropService_Exporter_Json.js @@ -0,0 +1,30 @@ +const InteropService_Exporter_Base = require('lib/services/InteropService_Exporter_Base'); +const { basename, filename } = require('lib/path-utils.js'); +const { shim } = require('lib/shim'); + +class InteropService_Exporter_Json extends InteropService_Exporter_Base { + + async init(destDir) { + this.destDir_ = destDir; + this.resourceDir_ = destDir ? destDir + '/resources' : null; + + await shim.fsDriver().mkdir(this.destDir_); + await shim.fsDriver().mkdir(this.resourceDir_); + } + + async processItem(ItemClass, item) { + const fileName = ItemClass.systemPath(item, "json"); + const filePath = this.destDir_ + '/' + fileName; + const serialized = JSON.stringify(item); + await shim.fsDriver().writeFile(filePath, serialized, 'utf-8'); + } + + async processResource(resource, filePath) { + const destResourcePath = this.resourceDir_ + '/' + basename(filePath); + await shim.fsDriver().copy(filePath, destResourcePath); + } + + async close() {} +} + +module.exports = InteropService_Exporter_Json; \ No newline at end of file