mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
converted export/import notes
This commit is contained in:
parent
88c07a9e48
commit
e36a81e189
@ -1,6 +1,7 @@
|
|||||||
import treeService from './tree.js';
|
import treeService from './tree.js';
|
||||||
import protectedSessionHolder from './protected_session_holder.js';
|
import protectedSessionHolder from './protected_session_holder.js';
|
||||||
import utils from './utils.js';
|
import utils from './utils.js';
|
||||||
|
import server from './server.js';
|
||||||
|
|
||||||
function exportSubTree(noteId) {
|
function exportSubTree(noteId) {
|
||||||
const url = utils.getHost() + "/api/export/" + noteId + "?protectedSessionId="
|
const url = utils.getHost() + "/api/export/" + noteId + "?protectedSessionId="
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const app_info = require('../../services/app_info');
|
const app_info = require('../../services/app_info');
|
||||||
const auth = require('../../services/auth');
|
|
||||||
const wrap = require('express-promise-wrap').wrap;
|
|
||||||
|
|
||||||
router.get('', auth.checkApiAuth, wrap(async (req, res, next) => {
|
async function getAppInfo() {
|
||||||
res.send(app_info);
|
return app_info;
|
||||||
}));
|
}
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = {
|
||||||
|
getAppInfo
|
||||||
|
};
|
@ -1,18 +1,12 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const sql = require('../../services/sql');
|
const sql = require('../../services/sql');
|
||||||
const auth = require('../../services/auth');
|
|
||||||
const wrap = require('express-promise-wrap').wrap;
|
|
||||||
|
|
||||||
router.get('', auth.checkApiAuth, wrap(async (req, res, next) => {
|
async function getEventLog() {
|
||||||
await deleteOld();
|
await deleteOld();
|
||||||
|
|
||||||
const result = await sql.getRows("SELECT * FROM event_log ORDER BY dateAdded DESC");
|
return await sql.getRows("SELECT * FROM event_log ORDER BY dateAdded DESC");
|
||||||
|
}
|
||||||
res.send(result);
|
|
||||||
}));
|
|
||||||
|
|
||||||
async function deleteOld() {
|
async function deleteOld() {
|
||||||
const cutoffId = await sql.getValue("SELECT id FROM event_log ORDER BY id DESC LIMIT 1000, 1");
|
const cutoffId = await sql.getValue("SELECT id FROM event_log ORDER BY id DESC LIMIT 1000, 1");
|
||||||
@ -24,4 +18,6 @@ async function deleteOld() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = {
|
||||||
|
getEventLog
|
||||||
|
};
|
@ -1,16 +1,12 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const sql = require('../../services/sql');
|
const sql = require('../../services/sql');
|
||||||
const html = require('html');
|
const html = require('html');
|
||||||
const auth = require('../../services/auth');
|
|
||||||
const wrap = require('express-promise-wrap').wrap;
|
|
||||||
const tar = require('tar-stream');
|
const tar = require('tar-stream');
|
||||||
const sanitize = require("sanitize-filename");
|
const sanitize = require("sanitize-filename");
|
||||||
const Repository = require("../../services/repository");
|
const Repository = require("../../services/repository");
|
||||||
|
|
||||||
router.get('/:noteId/', auth.checkApiAuthOrElectron, wrap(async (req, res, next) => {
|
async function exportNote(req, res) {
|
||||||
const noteId = req.params.noteId;
|
const noteId = req.params.noteId;
|
||||||
const repo = new Repository(req);
|
const repo = new Repository(req);
|
||||||
|
|
||||||
@ -18,7 +14,7 @@ router.get('/:noteId/', auth.checkApiAuthOrElectron, wrap(async (req, res, next)
|
|||||||
|
|
||||||
const pack = tar.pack();
|
const pack = tar.pack();
|
||||||
|
|
||||||
const name = await exportNote(branchId, '', pack, repo);
|
const name = await exportNoteInner(branchId, '', pack, repo);
|
||||||
|
|
||||||
pack.finalize();
|
pack.finalize();
|
||||||
|
|
||||||
@ -26,9 +22,9 @@ router.get('/:noteId/', auth.checkApiAuthOrElectron, wrap(async (req, res, next)
|
|||||||
res.setHeader('Content-Type', 'application/tar');
|
res.setHeader('Content-Type', 'application/tar');
|
||||||
|
|
||||||
pack.pipe(res);
|
pack.pipe(res);
|
||||||
}));
|
}
|
||||||
|
|
||||||
async function exportNote(branchId, directory, pack, repo) {
|
async function exportNoteInner(branchId, directory, pack, repo) {
|
||||||
const branch = await sql.getRow("SELECT * FROM branches WHERE branchId = ?", [branchId]);
|
const branch = await sql.getRow("SELECT * FROM branches WHERE branchId = ?", [branchId]);
|
||||||
const note = await repo.getEntity("SELECT notes.* FROM notes WHERE noteId = ?", [branch.noteId]);
|
const note = await repo.getEntity("SELECT notes.* FROM notes WHERE noteId = ?", [branch.noteId]);
|
||||||
|
|
||||||
@ -55,7 +51,7 @@ async function exportNote(branchId, directory, pack, repo) {
|
|||||||
|
|
||||||
if (children.length > 0) {
|
if (children.length > 0) {
|
||||||
for (const child of children) {
|
for (const child of children) {
|
||||||
await exportNote(child.branchId, childFileName + "/", pack, repo);
|
await exportNoteInner(child.branchId, childFileName + "/", pack, repo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,4 +73,6 @@ async function getMetadata(note) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = {
|
||||||
|
exportNote
|
||||||
|
};
|
@ -90,7 +90,7 @@ async function parseImportFile(file) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
router.post('/:parentNoteId', auth.checkApiAuthOrElectron, multer.single('upload'), wrap(async (req, res, next) => {
|
async function importTar(req, res) {
|
||||||
const sourceId = req.headers.source_id;
|
const sourceId = req.headers.source_id;
|
||||||
const parentNoteId = req.params.parentNoteId;
|
const parentNoteId = req.params.parentNoteId;
|
||||||
const file = req.file;
|
const file = req.file;
|
||||||
@ -103,12 +103,10 @@ router.post('/:parentNoteId', auth.checkApiAuthOrElectron, multer.single('upload
|
|||||||
|
|
||||||
const files = await parseImportFile(file);
|
const files = await parseImportFile(file);
|
||||||
|
|
||||||
await sql.doInTransaction(async () => {
|
await importNotes(files, parentNoteId, sourceId);
|
||||||
await importNotes(files, parentNoteId, sourceId);
|
|
||||||
});
|
|
||||||
|
|
||||||
res.send({});
|
res.send({});
|
||||||
}));
|
}
|
||||||
|
|
||||||
async function importNotes(files, parentNoteId, sourceId) {
|
async function importNotes(files, parentNoteId, sourceId) {
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
@ -136,4 +134,6 @@ async function importNotes(files, parentNoteId, sourceId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = {
|
||||||
|
importTar
|
||||||
|
};
|
@ -1,38 +1,9 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const express = require('express');
|
|
||||||
const router = express.Router();
|
|
||||||
const sql = require('../../services/sql');
|
const sql = require('../../services/sql');
|
||||||
const auth = require('../../services/auth');
|
|
||||||
const utils = require('../../services/utils');
|
const utils = require('../../services/utils');
|
||||||
const sync_table = require('../../services/sync_table');
|
const sync_table = require('../../services/sync_table');
|
||||||
const options = require('../../services/options');
|
const options = require('../../services/options');
|
||||||
const wrap = require('express-promise-wrap').wrap;
|
|
||||||
|
|
||||||
router.get('', auth.checkApiAuth, wrap(async (req, res, next) => {
|
|
||||||
res.send(await getRecentNotes());
|
|
||||||
}));
|
|
||||||
|
|
||||||
router.put('/:branchId/:notePath', auth.checkApiAuth, wrap(async (req, res, next) => {
|
|
||||||
const branchId = req.params.branchId;
|
|
||||||
const notePath = req.params.notePath;
|
|
||||||
const sourceId = req.headers.source_id;
|
|
||||||
|
|
||||||
await sql.doInTransaction(async () => {
|
|
||||||
await sql.replace('recent_notes', {
|
|
||||||
branchId: branchId,
|
|
||||||
notePath: notePath,
|
|
||||||
dateAccessed: utils.nowDate(),
|
|
||||||
isDeleted: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
await sync_table.addRecentNoteSync(branchId, sourceId);
|
|
||||||
|
|
||||||
await options.setOption('start_note_path', notePath, sourceId);
|
|
||||||
});
|
|
||||||
|
|
||||||
res.send(await getRecentNotes());
|
|
||||||
}));
|
|
||||||
|
|
||||||
async function getRecentNotes() {
|
async function getRecentNotes() {
|
||||||
return await sql.getRows(`
|
return await sql.getRows(`
|
||||||
@ -49,4 +20,27 @@ async function getRecentNotes() {
|
|||||||
LIMIT 200`);
|
LIMIT 200`);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = router;
|
|
||||||
|
async function addRecentNote(req) {
|
||||||
|
const branchId = req.params.branchId;
|
||||||
|
const notePath = req.params.notePath;
|
||||||
|
const sourceId = req.headers.source_id;
|
||||||
|
|
||||||
|
await sql.replace('recent_notes', {
|
||||||
|
branchId: branchId,
|
||||||
|
notePath: notePath,
|
||||||
|
dateAccessed: utils.nowDate(),
|
||||||
|
isDeleted: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
await sync_table.addRecentNoteSync(branchId, sourceId);
|
||||||
|
|
||||||
|
await options.setOption('start_note_path', notePath, sourceId);
|
||||||
|
|
||||||
|
return await getRecentNotes();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getRecentNotes,
|
||||||
|
addRecentNote
|
||||||
|
};
|
@ -3,6 +3,7 @@ const loginRoute = require('./login');
|
|||||||
const logoutRoute = require('./logout');
|
const logoutRoute = require('./logout');
|
||||||
const migrationRoute = require('./migration');
|
const migrationRoute = require('./migration');
|
||||||
const setupRoute = require('./setup');
|
const setupRoute = require('./setup');
|
||||||
|
const multer = require('multer')();
|
||||||
|
|
||||||
// API routes
|
// API routes
|
||||||
const treeApiRoute = require('./api/tree');
|
const treeApiRoute = require('./api/tree');
|
||||||
@ -39,17 +40,13 @@ const auth = require('../services/auth');
|
|||||||
const cls = require('../services/cls');
|
const cls = require('../services/cls');
|
||||||
const sql = require('../services/sql');
|
const sql = require('../services/sql');
|
||||||
|
|
||||||
function apiRoute(method, path, handler) {
|
function apiRoute(method, path, routeHandler) {
|
||||||
router[method](path, auth.checkApiAuth, async (req, res, next) => {
|
route({
|
||||||
try {
|
method,
|
||||||
const result = await cls.init(async () => {
|
path,
|
||||||
cls.namespace.set('sourceId', req.headers.source_id);
|
middleware: [auth.checkApiAuth],
|
||||||
|
routeHandler,
|
||||||
return await sql.doInTransaction(async () => {
|
resultHandler: (res, result) => {
|
||||||
return await handler(req, res, next);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// if it's an array and first element is integer then we consider this to be [statusCode, response] format
|
// if it's an array and first element is integer then we consider this to be [statusCode, response] format
|
||||||
if (Array.isArray(result) && result.length > 0 && Number.isInteger(result[0])) {
|
if (Array.isArray(result) && result.length > 0 && Number.isInteger(result[0])) {
|
||||||
const [statusCode, response] = result;
|
const [statusCode, response] = result;
|
||||||
@ -67,12 +64,38 @@ function apiRoute(method, path, handler) {
|
|||||||
res.status(200).send(result);
|
res.status(200).send(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// API routes requiring HTTP protocol. This means we ignore route return value and make an electron auth exception
|
||||||
|
function httpApiRoute(method, path, routeHandler) {
|
||||||
|
route({
|
||||||
|
method,
|
||||||
|
path,
|
||||||
|
middleware: [auth.checkApiAuth, multer.single('upload')],
|
||||||
|
routeHandler
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function route({ method, path, middleware, routeHandler, resultHandler }) {
|
||||||
|
router[method](path, ...middleware, async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const result = await cls.init(async () => {
|
||||||
|
cls.namespace.set('sourceId', req.headers.source_id);
|
||||||
|
|
||||||
|
return await sql.doInTransaction(async () => {
|
||||||
|
return await routeHandler(req, res, next);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (resultHandler) {
|
||||||
|
resultHandler(res, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
log.info(`${method} ${path} threw exception: ` + e.stack);
|
log.info(`${method} ${path} threw exception: ` + e.stack);
|
||||||
|
|
||||||
res.send(500);
|
res.sendStatus(500);
|
||||||
|
|
||||||
next(e);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -146,12 +169,16 @@ function register(app) {
|
|||||||
apiRoute(PUT, '/api/sync/labels', syncApiRoute.updateLabel);
|
apiRoute(PUT, '/api/sync/labels', syncApiRoute.updateLabel);
|
||||||
apiRoute(PUT, '/api/sync/api_tokens', syncApiRoute.updateApiToken);
|
apiRoute(PUT, '/api/sync/api_tokens', syncApiRoute.updateApiToken);
|
||||||
|
|
||||||
app.use('/api/login', loginApiRoute);
|
apiRoute(GET, '/api/event-log', eventLogRoute.getEventLog);
|
||||||
app.use('/api/event-log', eventLogRoute);
|
|
||||||
app.use('/api/recent-notes', recentNotesRoute);
|
apiRoute(GET, '/api/recent-notes', recentNotesRoute.getRecentNotes);
|
||||||
app.use('/api/app-info', appInfoRoute);
|
apiRoute(PUT, '/api/recent-notes/:branchId/:notePath', recentNotesRoute.addRecentNote);
|
||||||
app.use('/api/export', exportRoute);
|
apiRoute(GET, '/api/app-info', appInfoRoute.getAppInfo);
|
||||||
app.use('/api/import', importRoute);
|
|
||||||
|
httpApiRoute(GET, '/api/export/:noteId', exportRoute.exportNote);
|
||||||
|
|
||||||
|
httpApiRoute(POST, '/api/import/:parentNoteId', importRoute.importTar);
|
||||||
|
|
||||||
app.use('/api/setup', setupApiRoute);
|
app.use('/api/setup', setupApiRoute);
|
||||||
app.use('/api/sql', sqlRoute);
|
app.use('/api/sql', sqlRoute);
|
||||||
app.use('/api/anonymization', anonymizationRoute);
|
app.use('/api/anonymization', anonymizationRoute);
|
||||||
@ -166,6 +193,7 @@ function register(app) {
|
|||||||
|
|
||||||
|
|
||||||
app.use('/api/migration', migrationApiRoute);
|
app.use('/api/migration', migrationApiRoute);
|
||||||
|
app.use('/api/login', loginApiRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user