This commit is contained in:
zadam 2023-01-26 09:42:11 +01:00
parent c68a67d148
commit 63c62df787
4 changed files with 104 additions and 80 deletions

View File

@ -90,6 +90,7 @@ class BNoteAttachment extends AbstractBeccaEntity {
} }
setContent(content) { setContent(content) {
sql.transactional(() => {
this.contentCheckSum = this.calculateCheckSum(content); this.contentCheckSum = this.calculateCheckSum(content);
this.save(); // also explicitly save note_attachment to update contentCheckSum this.save(); // also explicitly save note_attachment to update contentCheckSum
@ -102,8 +103,7 @@ class BNoteAttachment extends AbstractBeccaEntity {
if (this.isProtected) { if (this.isProtected) {
if (protectedSessionService.isProtectedSessionAvailable()) { if (protectedSessionService.isProtectedSessionAvailable()) {
pojo.content = protectedSessionService.encrypt(pojo.content); pojo.content = protectedSessionService.encrypt(pojo.content);
} } else {
else {
throw new Error(`Cannot update content of noteAttachmentId=${this.noteAttachmentId} since we're out of protected session.`); throw new Error(`Cannot update content of noteAttachmentId=${this.noteAttachmentId} since we're out of protected session.`);
} }
} }
@ -118,6 +118,7 @@ class BNoteAttachment extends AbstractBeccaEntity {
utcDateChanged: pojo.utcDateModified, utcDateChanged: pojo.utcDateModified,
isSynced: true isSynced: true
}); });
});
} }
calculateCheckSum(content) { calculateCheckSum(content) {

View File

@ -65,6 +65,24 @@ function getImageMimeFromExtension(ext) {
return `image/${ext === 'svg' ? 'svg+xml' : ext}`; return `image/${ext === 'svg' ? 'svg+xml' : ext}`;
} }
function runOcr(note, buffer) {
if (!optionService.getOptionBool('ocrImages')) {
return;
}
const start = Date.now();
const img = new Canvas.Image();
img.src = buffer;
const canvas = new Canvas.createCanvas(img.width, img.height);
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
const plainText = OCRAD(canvas);
log.info(`OCR of ${buffer.byteLength} image bytes into ${plainText.length} chars of text took ${Date.now() - start}ms`);
note.saveNoteAttachment('plainText', 'text/plain', plainText);
}
function updateImage(noteId, uploadBuffer, originalName) { function updateImage(noteId, uploadBuffer, originalName) {
log.info(`Updating image ${noteId}: ${originalName}`); log.info(`Updating image ${noteId}: ${originalName}`);
@ -85,17 +103,7 @@ function updateImage(noteId, uploadBuffer, originalName) {
note.setContent(buffer); note.setContent(buffer);
}); });
const start = Date.now(); runOcr(note, buffer);
const img = new Canvas.Image();
img.src = buffer;
const canvas = new Canvas.createCanvas(img.width, img.height);
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
const text = OCRAD(canvas);
console.log(text);
log.info(`OCR of ${buffer.byteLength} bytes took ${Date.now() - start}ms`);
}); });
} }
@ -136,7 +144,9 @@ function saveImage(parentNoteId, uploadBuffer, originalName, shrinkImageSwitch,
note.save(); note.save();
note.setContent(buffer); note.setContent(buffer);
}) });
runOcr(note, buffer);
}); });
return { return {

View File

@ -90,6 +90,7 @@ const defaultOptions = [
{ name: 'checkForUpdates', value: 'true', isSynced: true }, { name: 'checkForUpdates', value: 'true', isSynced: true },
{ name: 'disableTray', value: 'false', isSynced: false }, { name: 'disableTray', value: 'false', isSynced: false },
{ name: 'userGuideSha256Hash', value: '', isSynced: true }, { name: 'userGuideSha256Hash', value: '', isSynced: true },
{ name: 'ocrImages', value: 'true', isSynced: true },
]; ];
function initStartupOptions() { function initStartupOptions() {

View File

@ -40,25 +40,40 @@ class NoteContentFulltextExp extends Expression {
const resultNoteSet = new NoteSet(); const resultNoteSet = new NoteSet();
const sql = require('../../sql'); const sql = require('../../sql');
for (let {noteId, type, mime, content, isProtected} of sql.iterateRows(` for (const row of sql.iterateRows(`
SELECT noteId, type, mime, content, isProtected SELECT noteId, type, mime, content, isProtected
FROM notes JOIN note_contents USING (noteId) FROM notes JOIN note_contents USING (noteId)
WHERE type IN ('text', 'code', 'mermaid') AND isDeleted = 0`)) { WHERE type IN ('text', 'code', 'mermaid') AND isDeleted = 0`)) {
this.findInText(row, inputNoteSet, resultNoteSet);
}
for (const row of sql.iterateRows(`
SELECT noteId, 'plainText' as type, mime, content, isProtected
FROM note_attachments JOIN note_attachment_contents USING (noteAttachmentId)
WHERE name IN ('plainText') AND isDeleted = 0`)) {
this.findInText(row, inputNoteSet, resultNoteSet);
}
return resultNoteSet;
}
findInText({noteId, isProtected, content, type, mime}, inputNoteSet, resultNoteSet) {
if (!inputNoteSet.hasNoteId(noteId) || !(noteId in becca.notes)) { if (!inputNoteSet.hasNoteId(noteId) || !(noteId in becca.notes)) {
continue; return;
} }
if (isProtected) { if (isProtected) {
if (!protectedSessionService.isProtectedSessionAvailable()) { if (!protectedSessionService.isProtectedSessionAvailable()) {
continue; return;
} }
try { try {
content = protectedSessionService.decryptString(content); content = protectedSessionService.decryptString(content);
} catch (e) { } catch (e) {
log.info(`Cannot decrypt content of note ${noteId}`); log.info(`Cannot decrypt content of note ${noteId}`);
continue; return;
} }
} }
@ -76,8 +91,7 @@ class NoteContentFulltextExp extends Expression {
resultNoteSet.add(becca.notes[noteId]); resultNoteSet.add(becca.notes[noteId]);
} }
} } else {
else {
const nonMatchingToken = this.tokens.find(token => const nonMatchingToken = this.tokens.find(token =>
!content.includes(token) && !content.includes(token) &&
( (
@ -92,9 +106,7 @@ class NoteContentFulltextExp extends Expression {
resultNoteSet.add(becca.notes[noteId]); resultNoteSet.add(becca.notes[noteId]);
} }
} }
} return content;
return resultNoteSet;
} }
preprocessContent(content, type, mime) { preprocessContent(content, type, mime) {