Files
Art-gallery/scripts/audit-painting-images.js
T
Danila KhodjaefandCursor d8385d83d6 Add painting detail navigation, influence lamps, and catalog tooling.
Expand the gallery with prev/next browsing and fullscreen detail view, golden influence lamps and chronological wall layout in 3D halls, and scripts/docs for catalog expansion, influence edges, and multi-source image fetching.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-19 16:35:33 +03:00

71 lines
2.0 KiB
JavaScript

/**
* Find paintings whose thumbnail aspect ratio differs from the full image
* (likely wrong thumbnail from an external search result).
*/
const fs = require('fs');
const path = require('path');
const sharp = require('sharp');
const pool = require('../server/db');
const IMAGE_DIR = path.resolve(process.env.IMAGE_DIR || './data/images');
function localPath(rel) {
return path.join(IMAGE_DIR, rel);
}
async function aspectRatio(filePath) {
const meta = await sharp(filePath).metadata();
if (!meta.width || !meta.height) return null;
return meta.width / meta.height;
}
(async () => {
const rows = await pool.query(
`SELECT p.id, p.title, p.image_path, p.thumbnail_path, a.name AS artist_name
FROM paintings p
JOIN artists a ON a.id = p.artist_id
WHERE p.image_path IS NOT NULL AND p.thumbnail_path IS NOT NULL
ORDER BY a.name, p.title`
);
const mismatches = [];
for (const row of rows.rows) {
const fullPath = localPath(row.image_path);
const thumbPath = localPath(row.thumbnail_path);
if (!fs.existsSync(fullPath) || !fs.existsSync(thumbPath)) continue;
try {
const [fullAr, thumbAr] = await Promise.all([
aspectRatio(fullPath),
aspectRatio(thumbPath),
]);
if (!fullAr || !thumbAr) continue;
const delta = Math.abs(fullAr - thumbAr) / fullAr;
if (delta > 0.15) {
mismatches.push({
id: row.id,
artist: row.artist_name,
title: row.title,
fullAr: fullAr.toFixed(3),
thumbAr: thumbAr.toFixed(3),
delta: (delta * 100).toFixed(1) + '%',
});
}
} catch {
/* ignore unreadable files */
}
}
console.log('Checked:', rows.rows.length);
console.log('Aspect-ratio mismatches:', mismatches.length);
mismatches.forEach((m) =>
console.log(`#${m.id} ${m.artist}${m.title} (full ${m.fullAr}, thumb ${m.thumbAr}, Δ ${m.delta})`)
);
await pool.end();
})().catch((err) => {
console.error(err);
process.exit(1);
});