mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	reverted incomplete work on export per-directory metadata
This commit is contained in:
		| @@ -16,7 +16,6 @@ const archiver = require('archiver'); | ||||
| const log = require("../log"); | ||||
| const TaskContext = require("../task_context"); | ||||
| const ValidationError = require("../../errors/validation_error"); | ||||
| const MetaFile = require("../meta/meta_file"); | ||||
| const NoteMeta = require("../meta/note_meta"); | ||||
| const AttachmentMeta = require("../meta/attachment_meta"); | ||||
| const AttributeMeta = require("../meta/attribute_meta"); | ||||
| @@ -40,24 +39,6 @@ async function exportToZip(taskContext, branch, format, res, setHeaders = true) | ||||
|     /** @type {Object.<string, NoteMeta>} */ | ||||
|     const noteIdToMeta = {}; | ||||
|  | ||||
|     /** @type {Object.<string, NoteMeta>} */ | ||||
|     const childNoteIdToParentMeta = {}; | ||||
|  | ||||
|     /** @type {Object.<string, NoteMeta[]>} */ | ||||
|     const parentNoteIdToChildrenMeta = {}; | ||||
|  | ||||
|     function getNotePath(noteId) { | ||||
|         const notePath = [noteId]; | ||||
|  | ||||
|         let cur = noteIdToMeta[noteId]; | ||||
|         while (cur = childNoteIdToParentMeta[cur.noteId]) { | ||||
|             notePath.push(cur.noteId); | ||||
|         } | ||||
|  | ||||
|         notePath.reverse(); | ||||
|         return notePath; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param {Object.<string, int>} existingFileNames | ||||
|      * @param {string} fileName | ||||
| @@ -135,49 +116,13 @@ async function exportToZip(taskContext, branch, format, res, setHeaders = true) | ||||
|         return getUniqueFilename(existingFileNames, fileName); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param {BBranch[]} branches | ||||
|      * @param {Object.<string, int>} existingFileNames | ||||
|      * @returns {MetaFile} | ||||
|      */ | ||||
|     function createMetaFileForDirectory(branches, existingFileNames = {}) { | ||||
|         // namespace is shared by children in the same note | ||||
|         const metas = []; | ||||
|  | ||||
|         for (const branch of branches) { | ||||
|             const noteMeta = createNoteMeta(branch, existingFileNames); | ||||
|  | ||||
|             // can be undefined if export is disabled for this note | ||||
|             if (noteMeta) { | ||||
|                 metas.push(noteMeta); | ||||
|  | ||||
|                 const parentMeta = noteIdToMeta[branch.parentNoteId]; | ||||
|  | ||||
|                 if (parentMeta) { | ||||
|                     childNoteIdToParentMeta[noteMeta.noteId] = parentMeta; | ||||
|                     parentNoteIdToChildrenMeta[parentMeta.noteId] = parentNoteIdToChildrenMeta[parentMeta.noteId] || []; | ||||
|                     parentNoteIdToChildrenMeta[parentMeta.noteId].push(noteMeta); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!metas.length) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         const metaFile = new MetaFile(); | ||||
|         metaFile.formatVersion = 3; | ||||
|         metaFile.appVersion = packageInfo.version; | ||||
|         metaFile.files = metas; | ||||
|         return metaFile; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param {BBranch} branch | ||||
|      * @param {NoteMeta} parentMeta | ||||
|      * @param {Object.<string, int>} existingFileNames | ||||
|      * @returns {NoteMeta|null} | ||||
|      */ | ||||
|     function createNoteMeta(branch, existingFileNames) { | ||||
|     function createNoteMeta(branch, parentMeta, existingFileNames) { | ||||
|         const note = branch.getNote(); | ||||
|  | ||||
|         if (note.hasOwnedLabel('excludeFromExport')) { | ||||
| @@ -192,13 +137,15 @@ async function exportToZip(taskContext, branch, format, res, setHeaders = true) | ||||
|             baseFileName = baseFileName.substr(0, 200); | ||||
|         } | ||||
|  | ||||
|         const notePath = parentMeta.notePath.concat([note.noteId]); | ||||
|  | ||||
|         if (note.noteId in noteIdToMeta) { | ||||
|             const fileName = getUniqueFilename(existingFileNames, | ||||
|                 `${baseFileName}.clone.${format === 'html' ? 'html' : 'md'}`); | ||||
|             const fileName = getUniqueFilename(existingFileNames, `${baseFileName}.clone.${format === 'html' ? 'html' : 'md'}`); | ||||
|  | ||||
|             const meta = new NoteMeta(); | ||||
|             meta.isClone = true; | ||||
|             meta.noteId = note.noteId; | ||||
|             meta.notePath = notePath; | ||||
|             meta.title = note.getTitleOrProtected(); | ||||
|             meta.prefix = branch.prefix; | ||||
|             meta.dataFileName = fileName; | ||||
| @@ -210,6 +157,7 @@ async function exportToZip(taskContext, branch, format, res, setHeaders = true) | ||||
|         const meta = new NoteMeta(); | ||||
|         meta.isClone = false; | ||||
|         meta.noteId = note.noteId; | ||||
|         meta.notePath = notePath; | ||||
|         meta.title = note.getTitleOrProtected(); | ||||
|         meta.notePosition = branch.notePosition; | ||||
|         meta.prefix = branch.prefix; | ||||
| @@ -260,10 +208,23 @@ async function exportToZip(taskContext, branch, format, res, setHeaders = true) | ||||
|                     existingFileNames | ||||
|                 ); | ||||
|                 return attMeta; | ||||
|         }); | ||||
|             }); | ||||
|  | ||||
|         if (childBranches.length > 0) { | ||||
|             meta.dirFileName = getUniqueFilename(existingFileNames, baseFileName); | ||||
|             meta.children = []; | ||||
|  | ||||
|             // namespace is shared by children in the same note | ||||
|             const childExistingNames = {}; | ||||
|  | ||||
|             for (const childBranch of childBranches) { | ||||
|                 const note = createNoteMeta(childBranch, meta, childExistingNames); | ||||
|  | ||||
|                 // can be undefined if export is disabled for this note | ||||
|                 if (note) { | ||||
|                     meta.children.push(note); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return meta; | ||||
| @@ -281,8 +242,8 @@ async function exportToZip(taskContext, branch, format, res, setHeaders = true) | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         const targetPath = getNotePath(targetMeta.noteId); | ||||
|         const sourcePath = getNotePath(sourceMeta.noteId); | ||||
|         const targetPath = targetMeta.notePath.slice(); | ||||
|         const sourcePath = sourceMeta.notePath.slice(); | ||||
|  | ||||
|         // > 1 for the edge case that targetPath and sourcePath are exact same (a link to itself) | ||||
|         while (targetPath.length > 1 && sourcePath.length > 1 && targetPath[0] === sourcePath[0]) { | ||||
| @@ -367,7 +328,7 @@ async function exportToZip(taskContext, branch, format, res, setHeaders = true) | ||||
|  | ||||
|         if (noteMeta.format === 'html') { | ||||
|             if (!content.substr(0, 100).toLowerCase().includes("<html")) { | ||||
|                 const cssUrl = `${"../".repeat(getNotePath(noteMeta.noteId).length - 1)}style.css`; | ||||
|                 const cssUrl = `${"../".repeat(noteMeta.notePath.length - 1)}style.css`; | ||||
|                 const htmlTitle = utils.escapeHtml(title); | ||||
|  | ||||
|                 // <base> element will make sure external links are openable - https://github.com/zadam/trilium/issues/1289#issuecomment-704066809 | ||||
| @@ -448,17 +409,14 @@ ${markdownContent}`; | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         const metaFile = createMetaFileForDirectory(note.getChildBranches()); | ||||
|         if (metaFile) { | ||||
|             const childFilePathPrefix = `${filePathPrefix}${noteMeta.dirFileName}/`; | ||||
|         if (noteMeta.children?.length > 0) { | ||||
|             const directoryPath = filePathPrefix + noteMeta.dirFileName; | ||||
|  | ||||
|             // create directory | ||||
|             archive.append('', { name: childFilePathPrefix, date: dateUtils.parseDateTime(note.utcDateModified) }); | ||||
|             archive.append('', { name: `${directoryPath}/`, date: dateUtils.parseDateTime(note.utcDateModified) }); | ||||
|  | ||||
|             metaFile.save(archive, childFilePathPrefix); | ||||
|  | ||||
|             for (const childMeta of metaFile.files) { | ||||
|                 saveNote(childMeta, childFilePathPrefix); | ||||
|             for (const childMeta of noteMeta.children) { | ||||
|                 saveNote(childMeta, `${directoryPath}/`); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -482,13 +440,11 @@ ${markdownContent}`; | ||||
|                 html += escapedTitle; | ||||
|             } | ||||
|  | ||||
|             const childrenMeta = parentNoteIdToChildrenMeta[meta.noteId]; | ||||
|  | ||||
|             if (childrenMeta?.length > 0) { | ||||
|             if (meta.children && meta.children.length > 0) { | ||||
|                 html += '<ul>'; | ||||
|  | ||||
|                 for (const childMeta of childrenMeta) { | ||||
|                     html += saveNavigationInner(childMeta); | ||||
|                 for (const child of meta.children) { | ||||
|                     html += saveNavigationInner(child); | ||||
|                 } | ||||
|  | ||||
|                 html += '</ul>' | ||||
| @@ -526,10 +482,8 @@ ${markdownContent}`; | ||||
|                 firstNonEmptyNote = getNoteTargetUrl(curMeta.noteId, rootMeta); | ||||
|             } | ||||
|  | ||||
|             const childrenMeta = parentNoteIdToChildrenMeta[curMeta.noteId]; | ||||
|  | ||||
|             if (childrenMeta?.length > 0) { | ||||
|                 curMeta = childrenMeta[0]; | ||||
|             if (curMeta.children && curMeta.children.length > 0) { | ||||
|                 curMeta = curMeta.children[0]; | ||||
|             } | ||||
|             else { | ||||
|                 break; | ||||
| @@ -561,13 +515,14 @@ ${markdownContent}`; | ||||
|         archive.append(cssContent, { name: cssMeta.dataFileName }); | ||||
|     } | ||||
|  | ||||
|     const existingFileNames = format === 'html' ? { 'navigation': 1, 'index': 1 } : {}; | ||||
|     const metaFile = createMetaFileForDirectory([branch], existingFileNames); | ||||
|     const existingFileNames = format === 'html' ? ['navigation', 'index'] : []; | ||||
|     const rootMeta = createNoteMeta(branch, { notePath: [] }, existingFileNames); | ||||
|  | ||||
|     if (!metaFile) { // corner case of disabled export for exported note | ||||
|         res.sendStatus(400); | ||||
|         return; | ||||
|     } | ||||
|     const metaFile = { | ||||
|         formatVersion: 2, | ||||
|         appVersion: packageInfo.version, | ||||
|         files: [ rootMeta ] | ||||
|     }; | ||||
|  | ||||
|     let navigationMeta, indexMeta, cssMeta; | ||||
|  | ||||
| @@ -610,9 +565,15 @@ ${markdownContent}`; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     metaFile.save(archive); | ||||
|     if (!rootMeta) { // corner case of disabled export for exported note | ||||
|         res.sendStatus(400); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const metaFileJson = JSON.stringify(metaFile, null, '\t'); | ||||
|  | ||||
|     archive.append(metaFileJson, { name: "!!!meta.json" }); | ||||
|  | ||||
|     const rootMeta = metaFile.files[0]; | ||||
|     saveNote(rootMeta, ''); | ||||
|  | ||||
|     if (format === 'html') { | ||||
|   | ||||
| @@ -1,16 +0,0 @@ | ||||
| class MetaFile { | ||||
|     /** @type {int} */ | ||||
|     formatVersion; | ||||
|     /** @type {string} */ | ||||
|     appVersion; | ||||
|     /** @type {NoteMeta[]} */ | ||||
|     files; | ||||
|  | ||||
|     save(archive, filePathPrefix = '') { | ||||
|         const metaFileJson = JSON.stringify(this, null, '\t'); | ||||
|  | ||||
|         archive.append(metaFileJson, { name: filePathPrefix + "!!!meta.json" }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = MetaFile; | ||||
| @@ -1,10 +1,7 @@ | ||||
| class NoteMeta { | ||||
|     /** @type {string} */ | ||||
|     noteId; | ||||
|     /** | ||||
|      * @type {string[]} | ||||
|      * @deprecated unused as of v3 | ||||
|      */ | ||||
|     /** @type {string} */ | ||||
|     notePath; | ||||
|     /** @type {boolean} */ | ||||
|     isClone; | ||||
| @@ -32,10 +29,7 @@ class NoteMeta { | ||||
|     attributes; | ||||
|     /** @type {AttachmentMeta[]} */ | ||||
|     attachments; | ||||
|     /** | ||||
|      * @type {NoteMeta[]|undefined} | ||||
|      * @deprecated unused as of v3, there's meta file for each directory, avoiding the need to use this | ||||
|      */ | ||||
|     /** @type {NoteMeta[]|undefined} */ | ||||
|     children; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user