mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	Merge pull request #4075 from manto89/feature/add-clippings-existing
Feature/add clippings existing url
This commit is contained in:
		| @@ -1,6 +1,7 @@ | |||||||
| "use strict"; | "use strict"; | ||||||
|  |  | ||||||
| const attributeService = require("../../services/attributes"); | const attributeService = require("../../services/attributes"); | ||||||
|  | const cloneService = require("../../services/cloning"); | ||||||
| const noteService = require('../../services/notes'); | const noteService = require('../../services/notes'); | ||||||
| const dateNoteService = require('../../services/date_notes'); | const dateNoteService = require('../../services/date_notes'); | ||||||
| const dateUtils = require('../../services/date_utils'); | const dateUtils = require('../../services/date_utils'); | ||||||
| @@ -13,8 +14,12 @@ const path = require('path'); | |||||||
| const BAttribute = require('../../becca/entities/battribute'); | const BAttribute = require('../../becca/entities/battribute'); | ||||||
| const htmlSanitizer = require('../../services/html_sanitizer'); | const htmlSanitizer = require('../../services/html_sanitizer'); | ||||||
| const {formatAttrForSearch} = require("../../services/attribute_formatter"); | const {formatAttrForSearch} = require("../../services/attribute_formatter"); | ||||||
|  | const jsdom = require("jsdom"); | ||||||
|  | const { JSDOM } = jsdom; | ||||||
|  |  | ||||||
| function findClippingNote(clipperInboxNote, pageUrl) { | function findClippingNote(clipperInboxNote, pageUrl, clipType) { | ||||||
|  |     //Avoid searching for empty of browser pages like about:blank | ||||||
|  |     if (pageUrl.trim().length > 1 && pageUrl.trim().indexOf('about:') != 0 ){ | ||||||
|         const notes = clipperInboxNote.searchNotesInSubtree( |         const notes = clipperInboxNote.searchNotesInSubtree( | ||||||
|             formatAttrForSearch({ |             formatAttrForSearch({ | ||||||
|                 type: 'label', |                 type: 'label', | ||||||
| @@ -24,10 +29,16 @@ function findClippingNote(clipperInboxNote, pageUrl) { | |||||||
|         ); |         ); | ||||||
|  |  | ||||||
|         for (const note of notes) { |         for (const note of notes) { | ||||||
|         if (note.getOwnedLabelValue('clipType') === 'clippings') { |             if (clipType){ | ||||||
|  |                 if (note.getOwnedLabelValue('clipType') === clipType) { | ||||||
|                     return note; |                     return note; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |             else{ | ||||||
|  |                 return note; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     return null; |     return null; | ||||||
| } | } | ||||||
| @@ -36,23 +47,29 @@ function getClipperInboxNote() { | |||||||
|     let clipperInbox = attributeService.getNoteWithLabel('clipperInbox'); |     let clipperInbox = attributeService.getNoteWithLabel('clipperInbox'); | ||||||
|  |  | ||||||
|     if (!clipperInbox) { |     if (!clipperInbox) { | ||||||
|         clipperInbox = dateNoteService.getDayNote(dateUtils.localNowDate()); |         clipperInbox = dateNoteService.getRootCalendarNote(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return clipperInbox; |     return clipperInbox; | ||||||
| } | } | ||||||
|  |  | ||||||
| function addClipping(req) { | function addClipping(req) { | ||||||
|  |     //if a note under the clipperInbox as the same 'pageUrl' attribute, add the content to that note | ||||||
|  |     //and clone it under today's inbox | ||||||
|  |     //otherwise just create a new note under today's inbox | ||||||
|     let {title, content, pageUrl, images} = req.body; |     let {title, content, pageUrl, images} = req.body; | ||||||
|  |     const clipType = 'clippings'; | ||||||
|  |  | ||||||
|  |     //this is only for reference | ||||||
|     const clipperInbox = getClipperInboxNote(); |     const clipperInbox = getClipperInboxNote(); | ||||||
|  |     const dailyNote = dateNoteService.getDayNote(dateUtils.localNowDate()); | ||||||
|  |  | ||||||
|     pageUrl = htmlSanitizer.sanitizeUrl(pageUrl); |     pageUrl = htmlSanitizer.sanitizeUrl(pageUrl); | ||||||
|     let clippingNote = findClippingNote(clipperInbox, pageUrl); |     let clippingNote = findClippingNote(clipperInbox, pageUrl, clipType); | ||||||
|      |      | ||||||
|     if (!clippingNote) { |     if (!clippingNote) { | ||||||
|         clippingNote = noteService.createNewNote({ |         clippingNote = noteService.createNewNote({ | ||||||
|             parentNoteId: clipperInbox.noteId, |             parentNoteId: dailyNote.noteId, | ||||||
|             title: title, |             title: title, | ||||||
|             content: '', |             content: '', | ||||||
|             type: 'text' |             type: 'text' | ||||||
| @@ -63,12 +80,16 @@ function addClipping(req) { | |||||||
|         clippingNote.setLabel('iconClass', 'bx bx-globe'); |         clippingNote.setLabel('iconClass', 'bx bx-globe'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     const rewrittenContent = processContent(images, clippingNote, content); |     const rewrittenContent = processContent(images, clippingNote, content); | ||||||
|  |  | ||||||
|     const existingContent = clippingNote.getContent(); |     const existingContent = clippingNote.getContent(); | ||||||
|  |  | ||||||
|     clippingNote.setContent(`${existingContent}${existingContent.trim() ? "<br/>" : ""}${rewrittenContent}`); |     clippingNote.setContent(`${existingContent}${existingContent.trim() ? "<br>" : ""}${rewrittenContent}`); | ||||||
|      |      | ||||||
|  |     if (clippingNote.parentNoteId != dailyNote.noteId){ | ||||||
|  |         cloneService.cloneNoteToParentNote(clippingNote.noteId, dailyNote.noteId); | ||||||
|  |     } | ||||||
|     return { |     return { | ||||||
|         noteId: clippingNote.noteId |         noteId: clippingNote.noteId | ||||||
|     }; |     }; | ||||||
| @@ -81,19 +102,23 @@ function createNote(req) { | |||||||
|         title = `Clipped note from ${pageUrl}`; |         title = `Clipped note from ${pageUrl}`; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const clipperInbox = getClipperInboxNote(); |  | ||||||
|  |  | ||||||
|     const {note} = noteService.createNewNote({ |  | ||||||
|         parentNoteId: clipperInbox.noteId, |  | ||||||
|         title, |  | ||||||
|         content, |  | ||||||
|         type: 'text' |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     clipType = htmlSanitizer.sanitize(clipType); |     clipType = htmlSanitizer.sanitize(clipType); | ||||||
|  |  | ||||||
|     note.setLabel('clipType', clipType); |     const clipperInbox = getClipperInboxNote(); | ||||||
|  |     const dailyNote = dateNoteService.getDayNote(dateUtils.localNowDate()); | ||||||
|  |     pageUrl = htmlSanitizer.sanitizeUrl(pageUrl); | ||||||
|  |     let note = findClippingNote(clipperInbox, pageUrl, clipType); | ||||||
|  |  | ||||||
|  |     if (!note){ | ||||||
|  |         note = noteService.createNewNote({ | ||||||
|  |             parentNoteId: dailyNote.noteId, | ||||||
|  |             title, | ||||||
|  |             content: '', | ||||||
|  |             type: 'text' | ||||||
|  |         }).note; | ||||||
|  |  | ||||||
|  |         note.setLabel('clipType', clipType); | ||||||
|         if (pageUrl) { |         if (pageUrl) { | ||||||
|             pageUrl = htmlSanitizer.sanitizeUrl(pageUrl); |             pageUrl = htmlSanitizer.sanitizeUrl(pageUrl); | ||||||
|  |  | ||||||
| @@ -101,6 +126,11 @@ function createNote(req) { | |||||||
|             note.setLabel('iconClass', 'bx bx-globe'); |             note.setLabel('iconClass', 'bx bx-globe'); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |      | ||||||
|     if (labels) { |     if (labels) { | ||||||
|         for (const labelName in labels) { |         for (const labelName in labels) { | ||||||
|             const labelValue = htmlSanitizer.sanitize(labels[labelName]); |             const labelValue = htmlSanitizer.sanitize(labels[labelName]); | ||||||
| @@ -108,9 +138,11 @@ function createNote(req) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     const existingContent = note.getContent(); | ||||||
|     const rewrittenContent = processContent(images, note, content); |     const rewrittenContent = processContent(images, note, content); | ||||||
|  |     note.setContent(`${existingContent}${existingContent.trim() ? "<br/>" : ""}${rewrittenContent}`); | ||||||
|  |  | ||||||
|     note.setContent(rewrittenContent); |     // note.setContent(rewrittenContent); | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
|         noteId: note.noteId |         noteId: note.noteId | ||||||
| @@ -158,6 +190,15 @@ function processContent(images, note, content) { | |||||||
|  |  | ||||||
|     // fallback if parsing/downloading images fails for some reason on the extension side ( |     // fallback if parsing/downloading images fails for some reason on the extension side ( | ||||||
|     rewrittenContent = noteService.downloadImages(note.noteId, rewrittenContent); |     rewrittenContent = noteService.downloadImages(note.noteId, rewrittenContent); | ||||||
|  |     // Check if rewrittenContent contains at least one HTML tag | ||||||
|  |     if (!/<.+?>/.test(rewrittenContent)) { | ||||||
|  |         rewrittenContent = '<p>'+rewrittenContent + '</p>'; | ||||||
|  |     } | ||||||
|  |     // Create a JSDOM object from the existing HTML content | ||||||
|  |     let dom = new JSDOM(rewrittenContent); | ||||||
|  |  | ||||||
|  |     // Get the content inside the body tag and serialize it | ||||||
|  |     rewrittenContent = dom.window.document.body.innerHTML; | ||||||
|  |  | ||||||
|     return rewrittenContent; |     return rewrittenContent; | ||||||
| } | } | ||||||
| @@ -187,9 +228,20 @@ function handshake() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function findNotesByUrl(req){ | ||||||
|  |     let pageUrl = req.params.noteUrl; | ||||||
|  |     const clipperInbox = getClipperInboxNote(); | ||||||
|  |     let foundPage = findClippingNote(clipperInbox, pageUrl, null); | ||||||
|  |     return { | ||||||
|  |         noteId: foundPage ? foundPage.noteId : null | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     createNote, |     createNote, | ||||||
|     addClipping, |     addClipping, | ||||||
|     openNote, |     openNote, | ||||||
|     handshake |     handshake, | ||||||
|  |     findNotesByUrl | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -286,6 +286,7 @@ function register(app) { | |||||||
|     route(POST, '/api/clipper/clippings', clipperMiddleware, clipperRoute.addClipping, apiResultHandler); |     route(POST, '/api/clipper/clippings', clipperMiddleware, clipperRoute.addClipping, apiResultHandler); | ||||||
|     route(POST, '/api/clipper/notes', clipperMiddleware, clipperRoute.createNote, apiResultHandler); |     route(POST, '/api/clipper/notes', clipperMiddleware, clipperRoute.createNote, apiResultHandler); | ||||||
|     route(POST, '/api/clipper/open/:noteId', clipperMiddleware, clipperRoute.openNote, apiResultHandler); |     route(POST, '/api/clipper/open/:noteId', clipperMiddleware, clipperRoute.openNote, apiResultHandler); | ||||||
|  |     route(GET, '/api/clipper/notes-by-url/:noteUrl', clipperMiddleware, clipperRoute.findNotesByUrl, apiResultHandler); | ||||||
|  |  | ||||||
|     apiRoute(GET, '/api/similar-notes/:noteId', similarNotesRoute.getSimilarNotes); |     apiRoute(GET, '/api/similar-notes/:noteId', similarNotesRoute.getSimilarNotes); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user