UNPKG

@opengis/fastify-table

Version:

core-plugins

144 lines (143 loc) 5.52 kB
/* eslint-disable no-console */ import { imageSize } from "image-size"; import { pgClients, eventStream, logger, isFileExists, downloadFile, uploadFile, } from "../../../../utils.js"; import grpc from "../../../plugins/grpc/grpc.js"; import { images } from "../../../plugins/file/utils/allowedExtensions.js"; const { resizeImage } = grpc(); async function resizeOne({ relpath: relpath1, resizeQuality = 80, maxWidth = 2048, errors = [], success = [], notfound = [], equalwidth = [], send = () => { }, }) { const exists = await isFileExists(relpath1); const existsOriginal = await isFileExists(relpath1.replace("files/", "files/original/")); const relpath = existsOriginal ? relpath1.replace("files/", "files/original/") : relpath1; const buffer = exists || existsOriginal ? await downloadFile(relpath, { buffer: true }) : null; if (!buffer?.length) { notfound.push(relpath1); send(`file not found: ${relpath1}`); return null; } if (!existsOriginal) { await uploadFile(relpath1.replace("files/", "files/original/"), buffer); send(`original image moved to: ${relpath1.replace("files/", "files/original/")}`); } else { send(`original image already saved to: ${relpath}`); } const dimensions = {}; try { const { width, height } = imageSize(buffer) || {}; Object.assign(dimensions, { width, height }); } catch (err) { // handle broken image (callback w/ buffer input not supported) errors.push(relpath1); send(`${err.toString()}: ${relpath1} (${buffer?.length} - ${exists.ContentType})`); return null; } const { width = maxWidth, height = 240 } = dimensions; const ratio = width / height; const resizeWidth = Math.min(width, maxWidth); const resizeHeight = resizeWidth / ratio; send(`original ${relpath} width/height/ratio: ${width} / ${height} / ${ratio}`); send(`resize ${relpath} width/height/ratio/quality: ${resizeWidth} / ${resizeHeight} / ${resizeWidth / resizeHeight} / ${resizeQuality}`); const unittest = process.env.NODE_ENV === "test" || process.env.VITEST; // skip for resize with small unit test image if (resizeWidth === width && !unittest) { send(`resize ${relpath} skip: resize width equals to original`); equalwidth.push(relpath1); return null; } const { result } = await resizeImage({ base64: buffer.toString("base64"), width: resizeWidth, height: resizeHeight, quality: resizeQuality, }); await uploadFile(relpath1, Buffer.from(result, "base64")); send(`resize ${relpath1} success`); success.push(relpath1); return null; } export default async function resizeAll(req, reply) { const { pg = pgClients.client, query = {} } = req; const { nocache, filepath, quality = 80, limit, sql, w = 2048 } = query; if (nocache) { const clearQ = `update crm.files set resized=null where ext=any($1) and ${filepath ? "file_path=$2" : "1=1"} and resized is not null`; if (sql) return clearQ; const { rowCount = 0 } = await pg.query(clearQ, [images, filepath].filter(Boolean)); return reply.status(200).send({ msg: "clear cache success", rowCount }); } const resizeQuality = Math.min(quality, 100); const q = `select file_id as id, file_path as relpath from crm.files where ext=any($1) and ${filepath ? "file_path=$2" : "1=1"} and resized is null ${limit ? `limit ${limit}` : ""}`; if (sql) return q; const { rows = [], rowCount = 0 } = await pg.query(q, [images, filepath].filter(Boolean)); if (rowCount === 0) { return reply.status(200).send("nothing to resize"); } const success = []; const errors = []; const notfound = []; const equalwidth = []; const send = process.env.NODE_ENV === "test" || process.env.VITEST ? console.log : eventStream(reply); try { send(`file max resize width: ${w}`); send(`file max resize quality: ${resizeQuality}`); send(`rows found: ${rowCount}`); await rows .filter((el, idx, array) => array.findIndex((item) => item.relpath === el.relpath) === idx) .reduce((promise, { relpath, id }) => promise.then(() => resizeOne({ relpath, id, resizeQuality, maxWidth: w, errors, success, notfound, equalwidth, send, })), Promise.resolve()); if (success.length) { await pg.query("update crm.files set resized=true where file_path=any($1::text[])", [success]); } const skip = errors.concat(notfound).concat(equalwidth); if (skip.length) { await pg.query("update crm.files set resized=false where file_path=any($1::text[])", [skip]); } logger.file("file/resize", { success, errors, notfound, equalwidth, }); send("resize all success"); } catch (err) { send(err.toString()); logger.file("file/resize", { error: err.toString(), stack: err.stack }); } finally { send("event stream finish", 1); } return { success, errors, notfound, equalwidth, options: { maxWidth: w, quality: resizeQuality, }, }; }