From d79b6e094af5648d8584deaab554c9636943ebe6 Mon Sep 17 00:00:00 2001 From: ehhc Date: Sun, 9 Sep 2018 17:41:51 +0200 Subject: [PATCH] export folder should also export the attachments -> fixes #2374 --- browser/components/MarkdownPreview.js | 39 ++---------------------- browser/main/SideNav/StorageItem.js | 14 +++++++++ browser/main/lib/dataApi/exportFolder.js | 8 ++--- browser/main/lib/dataApi/exportNote.js | 26 +++++++++++++--- package.json | 2 +- yarn.lock | 6 ++-- 6 files changed, 46 insertions(+), 49 deletions(-) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index 5376a773..ebf32ccd 100755 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -251,26 +251,7 @@ export default class MarkdownPreview extends React.Component { } handleSaveAsMd () { - this.exportAsDocument('md', (noteContent, exportTasks) => { - let result = noteContent - if (this.props && this.props.storagePath && this.props.noteKey) { - const attachmentsAbsolutePaths = attachmentManagement.getAbsolutePathsOfAttachmentsInContent( - noteContent, - this.props.storagePath - ) - attachmentsAbsolutePaths.forEach(attachment => { - exportTasks.push({ - src: attachment, - dst: attachmentManagement.DESTINATION_FOLDER - }) - }) - result = attachmentManagement.removeStorageAndNoteReferences( - noteContent, - this.props.noteKey - ) - } - return result - }) + this.exportAsDocument('md') } handleSaveAsHtml () { @@ -301,11 +282,6 @@ export default class MarkdownPreview extends React.Component { escapeHtmlCharacters(noteContent, { detectCodeBlock: true }) ) const files = [this.GetCodeThemeLink(codeBlockTheme), ...CSS_FILES] - const attachmentsAbsolutePaths = attachmentManagement.getAbsolutePathsOfAttachmentsInContent( - noteContent, - this.props.storagePath - ) - files.forEach(file => { if (global.process.platform === 'win32') { file = file.replace('file:///', '') @@ -317,16 +293,6 @@ export default class MarkdownPreview extends React.Component { dst: 'css' }) }) - attachmentsAbsolutePaths.forEach(attachment => { - exportTasks.push({ - src: attachment, - dst: attachmentManagement.DESTINATION_FOLDER - }) - }) - body = attachmentManagement.removeStorageAndNoteReferences( - body, - this.props.noteKey - ) let styles = '' files.forEach(file => { @@ -359,8 +325,9 @@ export default class MarkdownPreview extends React.Component { if (filename) { const content = this.props.value const storage = this.props.storagePath + const nodeKey = this.props.noteKey - exportNote(storage, content, filename, contentFormatter) + exportNote(nodeKey, storage, content, filename, contentFormatter) .then(res => { dialog.showMessageBox(remote.getCurrentWindow(), { type: 'info', diff --git a/browser/main/SideNav/StorageItem.js b/browser/main/SideNav/StorageItem.js index d72f0a8f..242bf328 100644 --- a/browser/main/SideNav/StorageItem.js +++ b/browser/main/SideNav/StorageItem.js @@ -164,6 +164,20 @@ class StorageItem extends React.Component { folderKey: data.folderKey, fileType: data.fileType }) + return data + }) + .then(data => { + dialog.showMessageBox(remote.getCurrentWindow(), { + type: 'info', + message: 'Exported to "' + data.exportDir + '"' + }) + }) + .catch(err => { + dialog.showErrorBox( + 'Export error', + err ? err.message || err : 'Unexpected error during export' + ) + throw err }) } }) diff --git a/browser/main/lib/dataApi/exportFolder.js b/browser/main/lib/dataApi/exportFolder.js index 3e998f15..771f77dc 100644 --- a/browser/main/lib/dataApi/exportFolder.js +++ b/browser/main/lib/dataApi/exportFolder.js @@ -1,9 +1,9 @@ import { findStorage } from 'browser/lib/findStorage' import resolveStorageData from './resolveStorageData' import resolveStorageNotes from './resolveStorageNotes' +import exportNote from './exportNote' import filenamify from 'filenamify' import * as path from 'path' -import * as fs from 'fs' /** * @param {String} storageKey @@ -45,9 +45,9 @@ function exportFolder (storageKey, folderKey, fileType, exportDir) { notes .filter(note => note.folder === folderKey && note.isTrashed === false && note.type === 'MARKDOWN_NOTE') - .forEach(snippet => { - const notePath = path.join(exportDir, `${filenamify(snippet.title, {replacement: '_'})}.${fileType}`) - fs.writeFileSync(notePath, snippet.content) + .forEach(note => { + const notePath = path.join(exportDir, `${filenamify(note.title, {replacement: '_'})}.${fileType}`) + exportNote(note.key, storage.path, note.content, notePath, null) }) return { diff --git a/browser/main/lib/dataApi/exportNote.js b/browser/main/lib/dataApi/exportNote.js index e4fec5f4..b358e548 100755 --- a/browser/main/lib/dataApi/exportNote.js +++ b/browser/main/lib/dataApi/exportNote.js @@ -4,27 +4,43 @@ import { findStorage } from 'browser/lib/findStorage' const fs = require('fs') const path = require('path') +const attachmentManagement = require('./attachmentManagement') + /** - * Export note together with images + * Export note together with attachments * - * If images is stored in the storage, creates 'images' subfolder in target directory - * and copies images to it. Changes links to images in the content of the note + * If attachments are stored in the storage, creates 'attachments' subfolder in target directory + * and copies attachments to it. Changes links to images in the content of the note * + * @param {String} nodeKey key of the node that should be exported * @param {String} storageKey or storage path * @param {String} noteContent Content to export * @param {String} targetPath Path to exported file * @param {function} outputFormatter * @return {Promise.<*[]>} */ -function exportNote (storageKey, noteContent, targetPath, outputFormatter) { +function exportNote (nodeKey, storageKey, noteContent, targetPath, outputFormatter) { const storagePath = path.isAbsolute(storageKey) ? storageKey : findStorage(storageKey).path const exportTasks = [] if (!storagePath) { throw new Error('Storage path is not found') } + const attachmentsAbsolutePaths = attachmentManagement.getAbsolutePathsOfAttachmentsInContent( + noteContent, + storagePath + ) + attachmentsAbsolutePaths.forEach(attachment => { + exportTasks.push({ + src: attachment, + dst: attachmentManagement.DESTINATION_FOLDER + }) + }) - let exportedData = noteContent + let exportedData = attachmentManagement.removeStorageAndNoteReferences( + noteContent, + nodeKey + ) if (outputFormatter) { exportedData = outputFormatter(exportedData, exportTasks) diff --git a/package.json b/package.json index c9e22164..dd793f9e 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "electron-gh-releases": "^2.0.2", "escape-string-regexp": "^1.0.5", "file-url": "^2.0.2", - "filenamify": "^2.0.0", + "filenamify": "^2.1.0", "flowchart.js": "^1.6.5", "font-awesome": "^4.3.0", "fs-extra": "^5.0.0", diff --git a/yarn.lock b/yarn.lock index 4ecfa51b..0d919cf3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3514,9 +3514,9 @@ filename-reserved-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" -filenamify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.0.0.tgz#bd162262c0b6e94bfbcdcf19a3bbb3764f785695" +filenamify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.1.0.tgz#88faf495fb1b47abfd612300002a16228c677ee9" dependencies: filename-reserved-regex "^2.0.0" strip-outer "^1.0.0"