mirror of
https://github.com/zadam/trilium.git
synced 2025-10-31 18:36:30 +01:00
OPML export support (issue #78), import missing for now
This commit is contained in:
@@ -5,12 +5,85 @@ const html = require('html');
|
||||
const tar = require('tar-stream');
|
||||
const sanitize = require("sanitize-filename");
|
||||
const repository = require("../../services/repository");
|
||||
const utils = require('../../services/utils');
|
||||
|
||||
async function exportNote(req, res) {
|
||||
const noteId = req.params.noteId;
|
||||
const format = req.params.format;
|
||||
|
||||
const branchId = await sql.getValue('SELECT branchId FROM branches WHERE noteId = ?', [noteId]);
|
||||
|
||||
if (format === 'tar') {
|
||||
await exportToTar(branchId, res);
|
||||
}
|
||||
else if (format === 'opml') {
|
||||
await exportToOpml(branchId, res);
|
||||
}
|
||||
else {
|
||||
return [404, "Unrecognized export format " + format];
|
||||
}
|
||||
}
|
||||
|
||||
function escapeXmlAttribute(text) {
|
||||
return text.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
function prepareText(text) {
|
||||
const newLines = text.replace(/(<p[^>]*>|<br\s*\/?>)/g, '\n')
|
||||
.replace(/ /g, ' '); // nbsp isn't in XML standard (only HTML)
|
||||
|
||||
const stripped = utils.stripTags(newLines);
|
||||
|
||||
const escaped = escapeXmlAttribute(stripped);
|
||||
|
||||
return escaped.replace(/\n/g, ' ');
|
||||
}
|
||||
|
||||
async function exportToOpml(branchId, res) {
|
||||
const branch = await repository.getBranch(branchId);
|
||||
const note = await branch.getNote();
|
||||
const title = (branch.prefix ? (branch.prefix + ' - ') : '') + note.title;
|
||||
const sanitizedTitle = sanitize(title);
|
||||
|
||||
async function exportNoteInner(branchId) {
|
||||
const branch = await repository.getBranch(branchId);
|
||||
const note = await branch.getNote();
|
||||
const title = (branch.prefix ? (branch.prefix + ' - ') : '') + note.title;
|
||||
|
||||
const preparedTitle = prepareText(title);
|
||||
const preparedContent = prepareText(note.content);
|
||||
|
||||
res.write(`<outline title="${preparedTitle}" text="${preparedContent}">\n`);
|
||||
|
||||
for (const child of await note.getChildBranches()) {
|
||||
await exportNoteInner(child.branchId);
|
||||
}
|
||||
|
||||
res.write('</outline>');
|
||||
}
|
||||
|
||||
res.setHeader('Content-Disposition', 'file; filename="' + sanitizedTitle + '.opml"');
|
||||
res.setHeader('Content-Type', 'text/x-opml');
|
||||
|
||||
res.write(`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<opml version="1.0">
|
||||
<head>
|
||||
<title>Trilium export</title>
|
||||
</head>
|
||||
<body>`);
|
||||
|
||||
await exportNoteInner(branchId);
|
||||
|
||||
res.write(`</body>
|
||||
</opml>`);
|
||||
res.end();
|
||||
}
|
||||
|
||||
async function exportToTar(branchId, res) {
|
||||
const pack = tar.pack();
|
||||
|
||||
const exportedNoteIds = [];
|
||||
|
||||
Reference in New Issue
Block a user