server-ts: Port services/image

This commit is contained in:
Elian Doran 2024-02-20 23:29:03 +02:00
parent 29d37c40c1
commit fa0ed35752
11 changed files with 39 additions and 31 deletions

View File

@ -95,7 +95,7 @@ class Becca {
return this.notes[noteId];
}
getNoteOrThrow(noteId: string): BNote | null {
getNoteOrThrow(noteId: string): BNote {
const note = this.notes[noteId];
if (!note) {
throw new NotFoundError(`Note '${noteId}' doesn't exist.`);

View File

@ -1,7 +1,7 @@
const becca = require('../../becca/becca');
const blobService = require('../../services/blob');
const ValidationError = require('../../errors/validation_error');
const imageService = require("../../services/image.js");
const imageService = require("../../services/image");
function getAttachmentBlob(req) {
const preview = req.query.preview === 'true';

View File

@ -5,7 +5,7 @@ const cloneService = require('../../services/cloning');
const noteService = require('../../services/notes');
const dateNoteService = require('../../services/date_notes');
const dateUtils = require('../../services/date_utils');
const imageService = require('../../services/image.js');
const imageService = require('../../services/image');
const appInfo = require('../../services/app_info');
const ws = require('../../services/ws');
const log = require('../../services/log');

View File

@ -1,6 +1,6 @@
"use strict";
const imageService = require('../../services/image.js');
const imageService = require('../../services/image');
const becca = require('../../becca/becca');
const RESOURCE_DIR = require('../../services/resource_dir').RESOURCE_DIR;
const fs = require('fs');

View File

@ -1,7 +1,7 @@
"use strict";
const imageType = require('image-type');
const imageService = require('../../services/image.js');
const imageService = require('../../services/image');
const noteService = require('../../services/notes');
const {sanitizeAttributeName} = require('../../services/sanitize_attribute_name');
const specialNotesService = require('../../services/special_notes.js');

View File

@ -41,7 +41,7 @@ const importRoute = require('./api/import.js');
const setupApiRoute = require('./api/setup.js');
const sqlRoute = require('./api/sql');
const databaseRoute = require('./api/database.js');
const imageRoute = require('./api/image.js');
const imageRoute = require('./api/image');
const attributesRoute = require('./api/attributes');
const scriptRoute = require('./api/script.js');
const senderRoute = require('./api/sender.js');

View File

@ -1,19 +1,19 @@
"use strict";
const becca = require('../becca/becca');
const log = require('./log');
const protectedSessionService = require('./protected_session');
const noteService = require('./notes');
const optionService = require('./options');
const sql = require('./sql');
const jimp = require('jimp');
const imageType = require('image-type');
const sanitizeFilename = require('sanitize-filename');
const isSvg = require('is-svg');
const isAnimated = require('is-animated');
const htmlSanitizer = require('./html_sanitizer');
import becca = require('../becca/becca');
import log = require('./log');
import protectedSessionService = require('./protected_session');
import noteService = require('./notes');
import optionService = require('./options');
import sql = require('./sql');
import jimp = require('jimp');
import imageType = require('image-type');
import sanitizeFilename = require('sanitize-filename');
import isSvg = require('is-svg');
import isAnimated = require('is-animated');
import htmlSanitizer = require('./html_sanitizer');
async function processImage(uploadBuffer, originalName, shrinkImageSwitch) {
async function processImage(uploadBuffer: Buffer, originalName: string, shrinkImageSwitch: boolean) {
const compressImages = optionService.getOptionBool("compressImages");
const origImageFormat = getImageType(uploadBuffer);
@ -44,7 +44,7 @@ async function processImage(uploadBuffer, originalName, shrinkImageSwitch) {
};
}
function getImageType(buffer) {
function getImageType(buffer: Buffer) {
if (isSvg(buffer)) {
return {
ext: 'svg'
@ -57,18 +57,19 @@ function getImageType(buffer) {
}
}
function getImageMimeFromExtension(ext) {
function getImageMimeFromExtension(ext: string) {
ext = ext.toLowerCase();
return `image/${ext === 'svg' ? 'svg+xml' : ext}`;
}
function updateImage(noteId, uploadBuffer, originalName) {
function updateImage(noteId: string, uploadBuffer: Buffer, originalName: string) {
log.info(`Updating image ${noteId}: ${originalName}`);
originalName = htmlSanitizer.sanitize(originalName);
const note = becca.getNote(noteId);
if (!note) { throw new Error("Unable to find note."); }
note.saveRevision();
@ -85,7 +86,7 @@ function updateImage(noteId, uploadBuffer, originalName) {
});
}
function saveImage(parentNoteId, uploadBuffer, originalName, shrinkImageSwitch, trimFilename = false) {
function saveImage(parentNoteId: string, uploadBuffer: Buffer, originalName: string, shrinkImageSwitch: boolean, trimFilename = false) {
log.info(`Saving image ${originalName} into parent ${parentNoteId}`);
if (trimFilename && originalName.length > 40) {
@ -95,6 +96,7 @@ function saveImage(parentNoteId, uploadBuffer, originalName, shrinkImageSwitch,
const fileName = sanitizeFilename(originalName);
const parentNote = becca.getNote(parentNoteId);
if (!parentNote) { throw new Error("Unable to find parent note."); }
const {note} = noteService.createNewNote({
parentNoteId,
@ -131,7 +133,7 @@ function saveImage(parentNoteId, uploadBuffer, originalName, shrinkImageSwitch,
};
}
function saveImageToAttachment(noteId, uploadBuffer, originalName, shrinkImageSwitch, trimFilename = false) {
function saveImageToAttachment(noteId: string, uploadBuffer: Buffer, originalName: string, shrinkImageSwitch: boolean, trimFilename = false) {
log.info(`Saving image '${originalName}' as attachment into note '${noteId}'`);
if (trimFilename && originalName.length > 40) {
@ -163,6 +165,7 @@ function saveImageToAttachment(noteId, uploadBuffer, originalName, shrinkImageSw
processImage(uploadBuffer, originalName, shrinkImageSwitch).then(({buffer, imageFormat}) => {
sql.transactional(() => {
// re-read, might be changed in the meantime
if (!attachment.attachmentId) { throw new Error("Missing attachment ID."); }
attachment = becca.getAttachmentOrThrow(attachment.attachmentId);
attachment.mime = getImageMimeFromExtension(imageFormat.ext);
@ -179,7 +182,7 @@ function saveImageToAttachment(noteId, uploadBuffer, originalName, shrinkImageSw
return attachment;
}
async function shrinkImage(buffer, originalName) {
async function shrinkImage(buffer: Buffer, originalName: string) {
let jpegQuality = optionService.getOptionInt('imageJpegQuality', 0);
if (jpegQuality < 10 || jpegQuality > 100) {
@ -190,7 +193,7 @@ async function shrinkImage(buffer, originalName) {
try {
finalImageBuffer = await resize(buffer, jpegQuality);
}
catch (e) {
catch (e: any) {
log.error(`Failed to resize image '${originalName}', stack: ${e.stack}`);
finalImageBuffer = buffer;
@ -205,7 +208,7 @@ async function shrinkImage(buffer, originalName) {
return finalImageBuffer;
}
async function resize(buffer, quality) {
async function resize(buffer: Buffer, quality: number) {
const imageMaxWidthHeight = optionService.getOptionInt('imageMaxWidthHeight');
const start = Date.now();

View File

@ -5,7 +5,7 @@ const log = require('../log');
const utils = require('../utils');
const sql = require('../sql');
const noteService = require('../notes');
const imageService = require('../image.js');
const imageService = require('../image');
const protectedSessionService = require('../protected_session');
const htmlSanitizer = require('../html_sanitizer');
const {sanitizeAttributeName} = require('../sanitize_attribute_name');

View File

@ -1,7 +1,7 @@
"use strict";
const noteService = require('../../services/notes');
const imageService = require('../../services/image.js');
const imageService = require('../../services/image');
const protectedSessionService = require('../protected_session');
const markdownService = require('./markdown.js');
const mimeService = require('./mime.js');

View File

@ -506,7 +506,7 @@ async function downloadImage(noteId: string, imageUrl: string) {
const parsedUrl = url.parse(unescapedUrl);
const title = path.basename(parsedUrl.pathname || "");
const imageService = require('../services/image.js');
const imageService = require('../services/image');
const attachment = imageService.saveImageToAttachment(noteId, imageBuffer, title, true, true);
imageUrlToAttachmentIdMapping[imageUrl] = attachment.attachmentId;
@ -539,7 +539,7 @@ function downloadImages(noteId: string, content: string) {
const imageBase64 = url.substr(inlineImageMatch[0].length);
const imageBuffer = Buffer.from(imageBase64, 'base64');
const imageService = require('../services/image.js');
const imageService = require('../services/image');
const attachment = imageService.saveImageToAttachment(noteId, imageBuffer, "inline image", true, true);
const encodedTitle = encodeURIComponent(attachment.title);

5
src/types.d.ts vendored
View File

@ -24,4 +24,9 @@ declare module 'joplin-turndown-plugin-gfm' {
function gfm(service: TurndownService): void;
}
export = gfm;
}
declare module 'is-animated' {
function isAnimated(buffer: Buffer): boolean;
export = isAnimated;
}