mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	more changes for scripts - separate API etc.
This commit is contained in:
		| @@ -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); | ||||||
|  |  | ||||||
|  |         await sql.doInTransaction(async () => { | ||||||
|             commentNoteId = await createNote(parentNoteId, comment.link_title, noteText); |             commentNoteId = await createNote(parentNoteId, comment.link_title, noteText); | ||||||
|  |  | ||||||
|             log.info("Reddit: Imported comment to note " + commentNoteId); |             log.info("Reddit: Imported comment to note " + commentNoteId); | ||||||
|             importedComments++; |             importedComments++; | ||||||
|  |  | ||||||
|         await sql.doInTransaction(async () => { |  | ||||||
|             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); | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -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,12 +35,14 @@ 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 | ||||||
|         }); |         }); | ||||||
|  |     }); | ||||||
| })); | })); | ||||||
|  |  | ||||||
| router.put('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => { | router.put('/:noteId', auth.checkApiAuth, wrap(async (req, res, next) => { | ||||||
|   | |||||||
| @@ -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); | ||||||
| })); | })); | ||||||
|   | |||||||
| @@ -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,20 +13,52 @@ 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; | ||||||
|  |  | ||||||
| @@ -38,33 +69,39 @@ async function createNewNote(parentNoteId, note, sourceId) { | |||||||
|         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') { |     if (parentNoteId !== 'root') { | ||||||
|         const parent = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [parentNoteId]); |         const parent = await sql.getFirst("SELECT * FROM notes WHERE note_id = ?", [parentNoteId]); | ||||||
|  |  | ||||||
|             if (!note.type) { |         if (!noteOpts.type) { | ||||||
|                 note.type = parent.type; |             noteOpts.type = parent.type; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|             if (!note.mime) { |         if (!noteOpts.mime) { | ||||||
|                 note.mime = parent.mime; |             noteOpts.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 | ||||||
|         }); |     }; | ||||||
|  |  | ||||||
|  |     if (note.is_protected) { | ||||||
|  |         protected_session.encryptNote(dataKey, note); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     await sql.insert("notes", note); | ||||||
|  |  | ||||||
|     await sync_table.addNoteSync(noteId, sourceId); |     await sync_table.addNoteSync(noteId, sourceId); | ||||||
|  |  | ||||||
| @@ -79,7 +116,6 @@ async function createNewNote(parentNoteId, note, sourceId) { | |||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     await sync_table.addNoteTreeSync(noteTreeId, sourceId); |     await sync_table.addNoteTreeSync(noteTreeId, sourceId); | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
|         noteId, |         noteId, | ||||||
|   | |||||||
| @@ -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); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										91
									
								
								services/script_context.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								services/script_context.js
									
									
									
									
									
										Normal 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; | ||||||
		Reference in New Issue
	
	Block a user