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 0000000..af2f693 Binary files /dev/null and b/data/images/paintings/thumbs/Domenico_Ghirlandaio_The_Last_Supper_Ghirlandaio_thumb.jpg differ 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]);