mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
import images
This commit is contained in:
parent
d9429c4f4b
commit
4b1cf05c0e
0
bin/deps/mac-x64/image/cjpeg
Normal file → Executable file
0
bin/deps/mac-x64/image/cjpeg
Normal file → Executable file
0
bin/deps/win-x64/image/cjpeg.exe
Normal file → Executable file
0
bin/deps/win-x64/image/cjpeg.exe
Normal file → Executable file
@ -17,7 +17,7 @@ async function importToBranch(req) {
|
|||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
safeImport: req.body.safeImport !== 'false',
|
safeImport: req.body.safeImport !== 'false',
|
||||||
optimizedImages: req.body.optimizedImages !== 'false',
|
shrinkImages: req.body.shrinkImages !== 'false',
|
||||||
textImportedAsText: req.body.textImportedAsText !== 'false',
|
textImportedAsText: req.body.textImportedAsText !== 'false',
|
||||||
codeImportedAsCode: req.body.codeImportedAsCode !== 'false'
|
codeImportedAsCode: req.body.codeImportedAsCode !== 'false'
|
||||||
};
|
};
|
||||||
|
@ -35,6 +35,7 @@ async function saveImage(buffer, originalName, parentNoteId, shrinkImageSwitch)
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
fileName,
|
fileName,
|
||||||
|
note,
|
||||||
noteId: note.noteId,
|
noteId: note.noteId,
|
||||||
url: `api/images/${note.noteId}/${fileName}`
|
url: `api/images/${note.noteId}/${fileName}`
|
||||||
};
|
};
|
||||||
@ -47,7 +48,7 @@ async function shrinkImage(buffer) {
|
|||||||
try {
|
try {
|
||||||
finalImageBuffer = await optimize(resizedImage);
|
finalImageBuffer = await optimize(resizedImage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error(e);
|
log.error(e.message + e.stack);
|
||||||
finalImageBuffer = resizedImage;
|
finalImageBuffer = resizedImage;
|
||||||
}
|
}
|
||||||
return finalImageBuffer;
|
return finalImageBuffer;
|
||||||
@ -75,15 +76,7 @@ async function resize(buffer) {
|
|||||||
// when converting PNG to JPG we lose alpha channel, this is replaced by white to match Trilium white background
|
// when converting PNG to JPG we lose alpha channel, this is replaced by white to match Trilium white background
|
||||||
image.background(0xFFFFFFFF);
|
image.background(0xFFFFFFFF);
|
||||||
|
|
||||||
// getBuffer doesn't support promises so this workaround
|
return image.getBufferAsync(jimp.MIME_JPEG);
|
||||||
return await new Promise((resolve, reject) => image.getBuffer(jimp.MIME_JPEG, (err, data) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resolve(data);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function optimize(buffer) {
|
async function optimize(buffer) {
|
||||||
|
@ -6,6 +6,7 @@ const log = require("../log");
|
|||||||
const utils = require("../utils");
|
const utils = require("../utils");
|
||||||
const noteService = require("../notes");
|
const noteService = require("../notes");
|
||||||
const imageService = require("../image");
|
const imageService = require("../image");
|
||||||
|
const protectedSessionService = require('../protected_session');
|
||||||
|
|
||||||
// date format is e.g. 20181121T193703Z
|
// date format is e.g. 20181121T193703Z
|
||||||
function parseDate(text) {
|
function parseDate(text) {
|
||||||
@ -31,7 +32,8 @@ async function importEnex(importContext, file, parentNote) {
|
|||||||
// root note is new note into all ENEX/notebook's notes will be imported
|
// root note is new note into all ENEX/notebook's notes will be imported
|
||||||
const rootNote = (await noteService.createNote(parentNote.noteId, rootNoteTitle, "", {
|
const rootNote = (await noteService.createNote(parentNote.noteId, rootNoteTitle, "", {
|
||||||
type: 'text',
|
type: 'text',
|
||||||
mime: 'text/html'
|
mime: 'text/html',
|
||||||
|
isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(),
|
||||||
})).note;
|
})).note;
|
||||||
|
|
||||||
// we're persisting notes as we parse the document, but these are run asynchronously and may not be finished
|
// we're persisting notes as we parse the document, but these are run asynchronously and may not be finished
|
||||||
@ -215,7 +217,8 @@ async function importEnex(importContext, file, parentNote) {
|
|||||||
attributes,
|
attributes,
|
||||||
dateCreated,
|
dateCreated,
|
||||||
type: 'text',
|
type: 'text',
|
||||||
mime: 'text/html'
|
mime: 'text/html',
|
||||||
|
isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(),
|
||||||
})).note;
|
})).note;
|
||||||
|
|
||||||
importContext.increaseProgressCount();
|
importContext.increaseProgressCount();
|
||||||
@ -237,7 +240,8 @@ async function importEnex(importContext, file, parentNote) {
|
|||||||
const resourceNote = (await noteService.createNote(noteEntity.noteId, resource.title, resource.content, {
|
const resourceNote = (await noteService.createNote(noteEntity.noteId, resource.title, resource.content, {
|
||||||
attributes: resource.attributes,
|
attributes: resource.attributes,
|
||||||
type: 'file',
|
type: 'file',
|
||||||
mime: resource.mime
|
mime: resource.mime,
|
||||||
|
isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(),
|
||||||
})).note;
|
})).note;
|
||||||
|
|
||||||
importContext.increaseProgressCount();
|
importContext.increaseProgressCount();
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const noteService = require('../../services/notes');
|
const noteService = require('../../services/notes');
|
||||||
const parseString = require('xml2js').parseString;
|
const parseString = require('xml2js').parseString;
|
||||||
|
const protectedSessionService = require('../protected_session');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ImportContext} importContext
|
* @param {ImportContext} importContext
|
||||||
@ -43,7 +44,9 @@ async function importOpml(importContext, fileBuffer, parentNote) {
|
|||||||
throw new Error("Unrecognized OPML version " + opmlVersion);
|
throw new Error("Unrecognized OPML version " + opmlVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {note} = await noteService.createNote(parentNoteId, title, content);
|
const {note} = await noteService.createNote(parentNoteId, title, content, {
|
||||||
|
isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(),
|
||||||
|
});
|
||||||
|
|
||||||
importContext.increaseProgressCount();
|
importContext.increaseProgressCount();
|
||||||
|
|
||||||
|
@ -1,30 +1,124 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const noteService = require('../../services/notes');
|
const noteService = require('../../services/notes');
|
||||||
|
const imageService = require('../../services/image');
|
||||||
|
const protectedSessionService = require('../protected_session');
|
||||||
const commonmark = require('commonmark');
|
const commonmark = require('commonmark');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
|
const CODE_MIME_TYPES = {
|
||||||
|
'text/plain': true,
|
||||||
|
'text/x-csrc': true,
|
||||||
|
'text/x-c++src': true,
|
||||||
|
'text/x-csharp': true,
|
||||||
|
'text/x-clojure': true,
|
||||||
|
'text/css': true,
|
||||||
|
'text/x-dockerfile': true,
|
||||||
|
'text/x-erlang': true,
|
||||||
|
'text/x-feature': true,
|
||||||
|
'text/x-go': true,
|
||||||
|
'text/x-groovy': true,
|
||||||
|
'text/x-haskell': true,
|
||||||
|
'text/html': true,
|
||||||
|
'message/http': true,
|
||||||
|
'text/x-java': true,
|
||||||
|
'application/javascript': 'application/javascript;env=frontend',
|
||||||
|
'application/x-javascript': 'application/javascript;env=frontend',
|
||||||
|
'application/json': true,
|
||||||
|
'text/x-kotlin': true,
|
||||||
|
'text/x-stex': true,
|
||||||
|
'text/x-lua': true,
|
||||||
|
'text/x-markdown': true,
|
||||||
|
'text/x-objectivec': true,
|
||||||
|
'text/x-pascal': true,
|
||||||
|
'text/x-perl': true,
|
||||||
|
'text/x-php': true,
|
||||||
|
'text/x-python': true,
|
||||||
|
'text/x-ruby': true,
|
||||||
|
'text/x-rustsrc': true,
|
||||||
|
'text/x-scala': true,
|
||||||
|
'text/x-sh': true,
|
||||||
|
'text/x-sql': true,
|
||||||
|
'text/x-swift': true,
|
||||||
|
'text/xml': true,
|
||||||
|
'text/x-yaml': true
|
||||||
|
};
|
||||||
|
|
||||||
async function importSingleFile(importContext, file, parentNote) {
|
async function importSingleFile(importContext, file, parentNote) {
|
||||||
if (importContext.textImportedAsText) {
|
if (importContext.textImportedAsText) {
|
||||||
if (file.mimetype === 'text/html') {
|
if (file.mimetype === 'text/html') {
|
||||||
return importHtml(importContext, file, parentNote);
|
return await importHtml(importContext, file, parentNote);
|
||||||
} else if (file.mimetype === 'text/markdown') {
|
} else if (file.mimetype === 'text/markdown') {
|
||||||
return importMarkdown(importContext, file, parentNote);
|
return await importMarkdown(importContext, file, parentNote);
|
||||||
} else if (file.mimetype === 'text/plain') {
|
} else if (file.mimetype === 'text/plain') {
|
||||||
return importPlainText(importContext, file, parentNote);
|
return await importPlainText(importContext, file, parentNote);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (importContext.codeImportedAsCode && file.mimetype in CODE_MIME_TYPES) {
|
||||||
|
return await importCodeNote(importContext, file, parentNote);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (["image/jpeg", "image/gif", "image/png"].includes(file.mimetype)) {
|
||||||
|
return await importImage(file, parentNote, importContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await importFile(importContext, file, parentNote);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function importImage(file, parentNote, importContext) {
|
||||||
|
const {note} = await imageService.saveImage(file.buffer, getFileNameWithoutExtension(file.originalname), parentNote.noteId, importContext.shrinkImages);
|
||||||
|
|
||||||
|
importContext.increaseProgressCount();
|
||||||
|
|
||||||
|
return note;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function importFile(importContext, file, parentNote) {
|
||||||
|
const originalName = file.originalname;
|
||||||
|
const size = file.size;
|
||||||
|
|
||||||
|
const {note} = await noteService.createNote(parentNote.noteId, originalName, file.buffer, {
|
||||||
|
target: 'into',
|
||||||
|
isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(),
|
||||||
|
type: 'file',
|
||||||
|
mime: file.mimetype,
|
||||||
|
attributes: [
|
||||||
|
{ type: "label", name: "originalFileName", value: originalName },
|
||||||
|
{ type: "label", name: "fileSize", value: size }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
importContext.increaseProgressCount();
|
||||||
|
|
||||||
|
return note;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function importCodeNote(importContext, file, parentNote) {
|
||||||
|
const title = getFileNameWithoutExtension(file.originalname);
|
||||||
|
const content = file.buffer.toString("UTF-8");
|
||||||
|
const mime = CODE_MIME_TYPES[file.mimetype] === true ? file.mimetype : CODE_MIME_TYPES[file.mimetype];
|
||||||
|
|
||||||
|
const {note} = await noteService.createNote(parentNote.noteId, title, content, {
|
||||||
|
type: 'code',
|
||||||
|
mime: mime,
|
||||||
|
isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable()
|
||||||
|
});
|
||||||
|
|
||||||
|
importContext.increaseProgressCount();
|
||||||
|
|
||||||
|
return note;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function importPlainText(importContext, file, parentNote) {
|
async function importPlainText(importContext, file, parentNote) {
|
||||||
|
|
||||||
const title = getFileNameWithoutExtension(file.originalname);
|
const title = getFileNameWithoutExtension(file.originalname);
|
||||||
const plainTextContent = file.buffer.toString("UTF-8");
|
const plainTextContent = file.buffer.toString("UTF-8");
|
||||||
const htmlContent = convertTextToHtml(plainTextContent);
|
const htmlContent = convertTextToHtml(plainTextContent);
|
||||||
|
|
||||||
const {note} = await noteService.createNote(parentNote.noteId, title, htmlContent, {
|
const {note} = await noteService.createNote(parentNote.noteId, title, htmlContent, {
|
||||||
type: 'text',
|
type: 'text',
|
||||||
mime: 'text/html'
|
mime: 'text/html',
|
||||||
|
isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(),
|
||||||
});
|
});
|
||||||
|
|
||||||
importContext.increaseProgressCount();
|
importContext.increaseProgressCount();
|
||||||
@ -63,7 +157,8 @@ async function importMarkdown(importContext, file, parentNote) {
|
|||||||
|
|
||||||
const {note} = await noteService.createNote(parentNote.noteId, title, htmlContent, {
|
const {note} = await noteService.createNote(parentNote.noteId, title, htmlContent, {
|
||||||
type: 'text',
|
type: 'text',
|
||||||
mime: 'text/html'
|
mime: 'text/html',
|
||||||
|
isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(),
|
||||||
});
|
});
|
||||||
|
|
||||||
importContext.increaseProgressCount();
|
importContext.increaseProgressCount();
|
||||||
@ -77,7 +172,8 @@ async function importHtml(importContext, file, parentNote) {
|
|||||||
|
|
||||||
const {note} = await noteService.createNote(parentNote.noteId, title, content, {
|
const {note} = await noteService.createNote(parentNote.noteId, title, content, {
|
||||||
type: 'text',
|
type: 'text',
|
||||||
mime: 'text/html'
|
mime: 'text/html',
|
||||||
|
isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable(),
|
||||||
});
|
});
|
||||||
|
|
||||||
importContext.increaseProgressCount();
|
importContext.increaseProgressCount();
|
||||||
|
@ -14,6 +14,7 @@ const path = require('path');
|
|||||||
const commonmark = require('commonmark');
|
const commonmark = require('commonmark');
|
||||||
const mimeTypes = require('mime-types');
|
const mimeTypes = require('mime-types');
|
||||||
const ImportContext = require('../import_context');
|
const ImportContext = require('../import_context');
|
||||||
|
const protectedSessionService = require('../protected_session');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ImportContext} importContext
|
* @param {ImportContext} importContext
|
||||||
@ -193,7 +194,8 @@ async function importTar(importContext, fileBuffer, importRootNote) {
|
|||||||
type: noteMeta ? noteMeta.type : 'text',
|
type: noteMeta ? noteMeta.type : 'text',
|
||||||
mime: noteMeta ? noteMeta.mime : 'text/html',
|
mime: noteMeta ? noteMeta.mime : 'text/html',
|
||||||
prefix: noteMeta ? noteMeta.prefix : '',
|
prefix: noteMeta ? noteMeta.prefix : '',
|
||||||
isExpanded: noteMeta ? noteMeta.isExpanded : false
|
isExpanded: noteMeta ? noteMeta.isExpanded : false,
|
||||||
|
isProtected: importRootNote.isProtected && protectedSessionService.isProtectedSessionAvailable(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await saveAttributesAndLinks(note, noteMeta);
|
await saveAttributesAndLinks(note, noteMeta);
|
||||||
@ -271,7 +273,8 @@ async function importTar(importContext, fileBuffer, importRootNote) {
|
|||||||
mime,
|
mime,
|
||||||
prefix: noteMeta ? noteMeta.prefix : '',
|
prefix: noteMeta ? noteMeta.prefix : '',
|
||||||
isExpanded: noteMeta ? noteMeta.isExpanded : false,
|
isExpanded: noteMeta ? noteMeta.isExpanded : false,
|
||||||
notePosition: noteMeta ? noteMeta.notePosition : false
|
notePosition: noteMeta ? noteMeta.notePosition : false,
|
||||||
|
isProtected: importRootNote.isProtected && protectedSessionService.isProtectedSessionAvailable(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await saveAttributesAndLinks(note, noteMeta);
|
await saveAttributesAndLinks(note, noteMeta);
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label data-toggle="tooltip" title="Trilium <code>.tar</code> export files can contain executable scripts which may contain harmful behavior. Safe import will deactivate automatic execution of all imported scripts. Uncheck "Safe import" only if the imported tar archive is supposed to contain executable scripts and you completely trust the contents of the import file.">
|
<label data-toggle="tooltip" title="Trilium <code>.tar</code> export files can contain executable scripts which may contain harmful behavior. Safe import will deactivate automatic execution of all imported scripts. Uncheck "Safe import" only if the imported tar archive is supposed to contain executable scripts and you completely trust the contents of the import file.">
|
||||||
<input id="safe-import" value="1" type="checkbox" checked>
|
<input id="safe-import-checkbox" value="1" type="checkbox" checked>
|
||||||
Safe import
|
Safe import
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user