more changes for scripts - separate API etc.

This commit is contained in:
azivner 2018-01-27 17:18:19 -05:00
parent 005480059a
commit 3f1e73d06b
7 changed files with 202 additions and 71 deletions

View File

@ -84,12 +84,12 @@ karma: ${comment.score}, created at ${dateTimeStr}</p><p></p>`
let parentNoteId = await getDateNoteIdForReddit(dateTimeStr, rootNoteId); let parentNoteId = await getDateNoteIdForReddit(dateTimeStr, rootNoteId);
commentNoteId = await createNote(parentNoteId, comment.link_title, noteText);
log.info("Reddit: Imported comment to note " + commentNoteId);
importedComments++;
await sql.doInTransaction(async () => { await sql.doInTransaction(async () => {
commentNoteId = await createNote(parentNoteId, comment.link_title, noteText);
log.info("Reddit: Imported comment to note " + commentNoteId);
importedComments++;
await attributes.createAttribute(commentNoteId, "reddit_kind", child.kind); await attributes.createAttribute(commentNoteId, "reddit_kind", child.kind);
await attributes.createAttribute(commentNoteId, "reddit_id", redditId(child.kind, comment.id)); await attributes.createAttribute(commentNoteId, "reddit_id", redditId(child.kind, comment.id));
await attributes.createAttribute(commentNoteId, "reddit_created_utc", comment.created_utc); await attributes.createAttribute(commentNoteId, "reddit_created_utc", comment.created_utc);

View File

@ -29,12 +29,12 @@ const server = (function() {
return await call('DELETE', url); return await call('DELETE', url);
} }
async function exec(script, params = []) { async function exec(params, script) {
if (typeof script === "function") { if (typeof script === "function") {
script = script.toString(); script = script.toString();
} }
return await post('script/exec', { script: script, params: params }); return await post('script/exec/noteId', { script: script, params: params });
} }
let i = 1; let i = 1;

View File

@ -8,7 +8,6 @@ const notes = require('../../services/notes');
const log = require('../../services/log'); const log = require('../../services/log');
const utils = require('../../services/utils'); const utils = require('../../services/utils');
const protected_session = require('../../services/protected_session'); const protected_session = require('../../services/protected_session');
const data_encryption = require('../../services/data_encryption');
const tree = require('../../services/tree'); const tree = require('../../services/tree');
const sync_table = require('../../services/sync_table'); const sync_table = require('../../services/sync_table');
const wrap = require('express-promise-wrap').wrap; const wrap = require('express-promise-wrap').wrap;
@ -36,11 +35,13 @@ router.post('/:parentNoteId/children', auth.checkApiAuth, wrap(async (req, res,
const parentNoteId = req.params.parentNoteId; const parentNoteId = req.params.parentNoteId;
const note = req.body; const note = req.body;
const { noteId, noteTreeId } = await notes.createNewNote(parentNoteId, note, sourceId); await sql.doInTransaction(async () => {
const { noteId, noteTreeId } = await notes.createNewNote(parentNoteId, note, req, sourceId);
res.send({ res.send({
'note_id': noteId, 'note_id': noteId,
'note_tree_id': noteTreeId 'note_tree_id': noteTreeId
});
}); });
})); }));

View File

@ -10,8 +10,10 @@ const protected_session = require('../../services/protected_session');
const attributes = require('../../services/attributes'); const attributes = require('../../services/attributes');
const script = require('../../services/script'); const script = require('../../services/script');
router.post('/exec', auth.checkApiAuth, wrap(async (req, res, next) => { router.post('/exec/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => {
const ret = await script.executeScript(req, req.body.script, req.body.params); const noteId = req.params.noteId;
const ret = await script.executeScript(noteId, req, req.body.script, req.body.params);
res.send(ret); res.send(ret);
})); }));

View File

@ -1,7 +1,6 @@
const sql = require('./sql'); const sql = require('./sql');
const options = require('./options'); const options = require('./options');
const utils = require('./utils'); const utils = require('./utils');
const notes = require('./notes');
const sync_table = require('./sync_table'); const sync_table = require('./sync_table');
const attributes = require('./attributes'); const attributes = require('./attributes');
const protected_session = require('./protected_session'); const protected_session = require('./protected_session');
@ -14,73 +13,110 @@ async function getNoteById(noteId, dataKey) {
return note; return note;
} }
async function createNewNote(parentNoteId, note, sourceId) { async function getJsonNoteById(noteId, dataKey) {
const note = await getNoteById(noteId, dataKey);
note.data = JSON.parse(note.note_text);
return note;
}
async function updateJsonNote(noteId, data) {
const ret = await createNewNote(noteId, {
note_title: name,
note_text: JSON.stringify(data),
target: 'into',
is_protected: false,
type: 'code',
mime: 'application/json'
});
return ret.noteId;
}
async function createNewJsonNote(parentNoteId, name, payload) {
const ret = await createNewNote(parentNoteId, {
note_title: name,
note_text: JSON.stringify(payload),
target: 'into',
is_protected: false,
type: 'code',
mime: 'application/json'
});
return ret.noteId;
}
async function createNewNote(parentNoteId, noteOpts, dataKey, sourceId) {
const noteId = utils.newNoteId(); const noteId = utils.newNoteId();
const noteTreeId = utils.newNoteTreeId(); const noteTreeId = utils.newNoteTreeId();
let newNotePos = 0; let newNotePos = 0;
await sql.doInTransaction(async () => { if (noteOpts.target === 'into') {
if (note.target === 'into') { const maxNotePos = await sql.getFirstValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]);
const maxNotePos = await sql.getFirstValue('SELECT MAX(note_position) FROM notes_tree WHERE parent_note_id = ? AND is_deleted = 0', [parentNoteId]);
newNotePos = maxNotePos === null ? 0 : maxNotePos + 1; newNotePos = maxNotePos === null ? 0 : maxNotePos + 1;
} }
else if (note.target === 'after') { else if (noteOpts.target === 'after') {
const afterNote = await sql.getFirst('SELECT note_position FROM notes_tree WHERE note_tree_id = ?', [note.target_note_tree_id]); const afterNote = await sql.getFirst('SELECT note_position FROM notes_tree WHERE note_tree_id = ?', [noteOpts.target_note_tree_id]);
newNotePos = afterNote.note_position + 1; newNotePos = afterNote.note_position + 1;
// not updating date_modified to avoig having to sync whole rows // not updating date_modified to avoig having to sync whole rows
await sql.execute('UPDATE notes_tree SET note_position = note_position + 1 WHERE parent_note_id = ? AND note_position > ? AND is_deleted = 0', await sql.execute('UPDATE notes_tree SET note_position = note_position + 1 WHERE parent_note_id = ? AND note_position > ? AND is_deleted = 0',
[parentNoteId, afterNote.note_position]); [parentNoteId, afterNote.note_position]);
await sync_table.addNoteReorderingSync(parentNoteId, sourceId); await sync_table.addNoteReorderingSync(parentNoteId, sourceId);
} }
else { else {
throw new Error('Unknown target: ' + note.target); throw new Error('Unknown target: ' + noteOpts.target);
}
if (parentNoteId !== 'root') {
const parent = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [parentNoteId]);
if (!noteOpts.type) {
noteOpts.type = parent.type;
} }
if (parentNoteId !== 'root') { if (!noteOpts.mime) {
const parent = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [parentNoteId]); noteOpts.mime = parent.mime;
if (!note.type) {
note.type = parent.type;
}
if (!note.mime) {
note.mime = parent.mime;
}
} }
}
const now = utils.nowDate(); const now = utils.nowDate();
await sql.insert("notes", { const note = {
note_id: noteId, note_id: noteId,
note_title: note.note_title, note_title: noteOpts.note_title,
note_text: note.note_text ? note.note_text : '', note_text: noteOpts.note_text ? noteOpts.note_text : '',
is_protected: note.is_protected, is_protected: noteOpts.is_protected,
type: note.type ? note.type : 'text', type: noteOpts.type ? noteOpts.type : 'text',
mime: note.mime ? note.mime : 'text/html', mime: noteOpts.mime ? noteOpts.mime : 'text/html',
date_created: now, date_created: now,
date_modified: now date_modified: now
}); };
await sync_table.addNoteSync(noteId, sourceId); if (note.is_protected) {
protected_session.encryptNote(dataKey, note);
}
await sql.insert("notes_tree", { await sql.insert("notes", note);
note_tree_id: noteTreeId,
note_id: noteId,
parent_note_id: parentNoteId,
note_position: newNotePos,
is_expanded: 0,
date_modified: now,
is_deleted: 0
});
await sync_table.addNoteTreeSync(noteTreeId, sourceId); await sync_table.addNoteSync(noteId, sourceId);
await sql.insert("notes_tree", {
note_tree_id: noteTreeId,
note_id: noteId,
parent_note_id: parentNoteId,
note_position: newNotePos,
is_expanded: 0,
date_modified: now,
is_deleted: 0
}); });
await sync_table.addNoteTreeSync(noteTreeId, sourceId);
return { return {
noteId, noteId,
noteTreeId noteTreeId

View File

@ -1,18 +1,19 @@
const log = require('./log'); const log = require('./log');
const protected_session = require('./protected_session'); const sql = require('./sql');
const ScriptContext = require('./script_context');
async function executeScript(dataKey, script, params) { async function executeScript(noteId, dataKey, script, params) {
log.info('Executing script: ' + script); log.info('Executing script: ' + script);
const ctx = { const ctx = new ScriptContext(noteId, dataKey);
dataKey: protected_session.getDataKey(dataKey)
};
params.unshift(ctx);
const paramsStr = getParams(params); const paramsStr = getParams(params);
const ret = await eval(`(${script})(${paramsStr})`); let ret;
await sql.doInTransaction(async () => {
ret = await (function() { return eval(`(${script})(${paramsStr})`); }.call(ctx));
});
log.info('Execution result: ' + ret); log.info('Execution result: ' + ret);

View File

@ -0,0 +1,91 @@
const log = require('./log');
const protected_session = require('./protected_session');
const notes = require('./notes');
const attributes = require('./attributes');
const date_notes = require('./date_notes');
const sql = require('./sql');
const sync_table = require('./sync_table');
function ScriptContext(noteId, dataKey) {
this.scriptNoteId = noteId;
this.dataKey = protected_session.getDataKey(dataKey);
function deserializePayload(note) {
if (note.type === "code" && note.mime === "application/json") {
note.payload = JSON.parse(note.note_text);
}
}
this.getNoteById = async function(noteId) {
const note = await notes.getNoteById(noteId, this.dataKey);
deserializePayload(note);
return note;
};
this.getNoteWithAttribute = async function (attrName, attrValue) {
const note = await attributes.getNoteWithAttribute(this.dataKey, attrName, attrValue);
deserializePayload(note);
return note;
};
this.createNote = async function (parentNoteId, name, payload, extraOptions = {}) {
const note = {
note_title: name,
note_text: extraOptions.json ? JSON.stringify(payload) : payload,
target: 'into',
is_protected: extraOptions.isProtected !== undefined ? extraOptions.isProtected : false,
type: extraOptions.type,
mime: extraOptions.mime
};
if (extraOptions.json) {
note.type = "code";
note.mime = "application/json";
}
if (!note.type) {
note.type = "text";
note.mime = "";
}
const noteId = (await notes.createNewNote(parentNoteId, note)).noteId;
if (extraOptions.attributes) {
for (const attrName in extraOptions.attributes) {
await attributes.createAttribute(noteId, attrName, extraOptions.attributes[attrName]);
}
}
return noteId;
};
this.updateNote = async function (note) {
if (note.type === 'code' && note.mime === 'application/json') {
note.note_text = JSON.stringify(note.payload);
}
log.info("new note text: ", note.note_text);
delete note.payload;
if (note.is_protected) {
protected_session.encryptNote(this.dataKey, note);
}
await sql.replace("notes", note);
await sync_table.addNoteSync(note.note_id);
};
this.log = function(message) {
log.info(`Script ${this.scriptNoteId}: ${message}`);
};
this.getDateNoteId = date_notes.getDateNoteId;
}
module.exports = ScriptContext;