From cdca271e08424a8c807aebf44eddab8e76475596 Mon Sep 17 00:00:00 2001 From: Danila Khodjaef Date: Wed, 8 Jul 2026 18:15:52 +0300 Subject: [PATCH] Release: weekly deploy --- ...daio_The_Last_Supper_Ghirlandaio_thumb.jpg | Bin 0 -> 28567 bytes scripts/regenerate-thumbnails.js | 41 ++++++++++++++---- 2 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 data/images/paintings/thumbs/Domenico_Ghirlandaio_The_Last_Supper_Ghirlandaio_thumb.jpg diff --git a/data/images/paintings/thumbs/Domenico_Ghirlandaio_The_Last_Supper_Ghirlandaio_thumb.jpg b/data/images/paintings/thumbs/Domenico_Ghirlandaio_The_Last_Supper_Ghirlandaio_thumb.jpg new file mode 100644 index 0000000000000000000000000000000000000000..af2f693fcd8f273fa407836e1f2e55b169badf7d GIT binary patch literal 28567 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

NC`89JYqJEzQ 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 literal 0 HcmV?d00001 diff --git a/scripts/regenerate-thumbnails.js b/scripts/regenerate-thumbnails.js index 9a6a083..3c78e48 100644 --- a/scripts/regenerate-thumbnails.js +++ b/scripts/regenerate-thumbnails.js @@ -19,6 +19,37 @@ function localPath(rel) { return path.join(IMAGE_DIR, rel); } +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +function isPaintingThumbRel(rel) { + if (!rel) return false; + return rel.replace(/\\/g, '/').startsWith('paintings/thumbs/'); +} + +async function unlinkWithRetry(absPath, attempts = 5) { + if (!absPath || !fs.existsSync(absPath)) return; + + for (let attempt = 1; attempt <= attempts; attempt++) { + try { + fs.unlinkSync(absPath); + return; + } catch (err) { + if (err.code === 'EBUSY' && attempt < attempts) { + await sleep(200 * attempt); + continue; + } + throw err; + } + } +} + +async function unlinkOldThumbRel(thumbRel, imageRel) { + if (!thumbRel || thumbRel === imageRel || !isPaintingThumbRel(thumbRel)) return; + await unlinkWithRetry(localPath(thumbRel)); +} + async function aspectRatio(filePath) { const meta = await sharp(filePath).metadata(); if (!meta.width || !meta.height) return null; @@ -65,14 +96,8 @@ async function aspectRatio(filePath) { } try { - if (fs.existsSync(thumbPath)) fs.unlinkSync(thumbPath); - if ( - row.thumbnail_path && - row.thumbnail_path !== thumbRel && - fs.existsSync(localPath(row.thumbnail_path)) - ) { - fs.unlinkSync(localPath(row.thumbnail_path)); - } + await unlinkWithRetry(thumbPath); + await unlinkOldThumbRel(row.thumbnail_path, row.image_path); await generateThumbnailFromFull(fullPath, thumbPath); await pool.query(`UPDATE paintings SET thumbnail_path = $1 WHERE id = $2`, [thumbRel, row.id]);