converted export/import notes

This commit is contained in:
azivner 2018-03-30 15:34:07 -04:00
parent 88c07a9e48
commit e36a81e189
7 changed files with 99 additions and 84 deletions

View File

@ -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="

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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 = {