diff --git a/server/db/migrations/20221223131625_preserve_original_format_of_images.js b/server/db/migrations/20221223131625_preserve_original_format_of_images.js index 6d53eb25..de2ec07c 100644 --- a/server/db/migrations/20221223131625_preserve_original_format_of_images.js +++ b/server/db/migrations/20221223131625_preserve_original_format_of_images.js @@ -42,6 +42,49 @@ const rollbackImage = async (knex, tableName, fieldName, prevFieldName) => { }); }; +const processAttachmentImage = async (attachment, attachmentsPath) => { + const rootPath = path.join(attachmentsPath, attachment.dirname); + const thumbnailsPath = path.join(rootPath, 'thumbnails'); + + const image = sharp(path.join(rootPath, attachment.filename), { + animated: true, + }); + + let metadata; + try { + metadata = await image.metadata(); + } catch (error) { + return null; + } + + const { width, pageHeight: height = metadata.height } = metadata; + const thumbnailsExtension = metadata.format === 'jpeg' ? 'jpg' : metadata.format; + + try { + await image + .resize(256, height > width ? 320 : undefined, { + kernel: sharp.kernel.nearest, + }) + .toFile(path.join(thumbnailsPath, `cover-256.${thumbnailsExtension}`)); + } catch (error) { + return null; + } + + if (thumbnailsExtension !== 'jpg') { + try { + rimraf.sync(path.join(thumbnailsPath, 'cover-256.jpg')); + } catch (error) { + console.warn(error.stack); // eslint-disable-line no-console + } + } + + return { + width, + height, + thumbnailsExtension, + }; +}; + module.exports.up = async (knex) => { await migrateImage(knex, 'user_account', 'avatar', 'avatar_dirname'); await migrateImage(knex, 'project', 'background_image', 'background_image_dirname'); @@ -51,49 +94,13 @@ module.exports.up = async (knex) => { // eslint-disable-next-line no-restricted-syntax for (attachment of attachments) { - const rootPath = path.join(config.custom.attachmentsPath, attachment.dirname); - const thumbnailsPath = path.join(rootPath, 'thumbnails'); - - const image = sharp(path.join(rootPath, attachment.filename), { - animated: true, - }); - - let metadata; - try { - metadata = await image.metadata(); // eslint-disable-line no-await-in-loop - } catch (error) { - continue; // eslint-disable-line no-continue - } - - const extension = metadata.format === 'jpeg' ? 'jpg' : metadata.format; - - try { - // eslint-disable-next-line no-await-in-loop - await image - .resize(256, metadata.height > metadata.width ? 320 : undefined, { - kernel: sharp.kernel.nearest, - }) - .toFile(path.join(thumbnailsPath, `cover-256.${extension}`)); - } catch (error) { - continue; // eslint-disable-line no-continue - } - - if (extension !== 'jpg') { - try { - rimraf.sync(path.join(thumbnailsPath, 'cover-256.jpg')); - } catch (error) { - console.warn(error.stack); // eslint-disable-line no-console - } - } + // eslint-disable-next-line no-await-in-loop + const image = await processAttachmentImage(attachment, config.custom.attachmentsPath); // eslint-disable-next-line no-await-in-loop await knex('attachment') .update({ - image: { - width: metadata.width, - height: metadata.pageHeight || metadata.height, - thumbnailsExtension: extension, - }, + image: image || knex.raw('?? || \'{"thumbnailsExtension":"jpg"}\'', ['image']), }) .where('id', attachment.id); }