Files
Art-gallery/scripts/fetch-artist-images.js
T
Danila Khodjaef 02d238b043 Improve timeline UX and add catalog restore scripts for paintings and portraits.
Load the home-page catalog once with a lightweight artists API, batch pan/zoom updates per frame, use dynamic year labels, and speed up movement-flow zoom. Add sync-image-paths and fetch-artist-images plus docs for the post-seed pipeline.
2026-07-03 18:33:16 +03:00

81 lines
2.6 KiB
JavaScript

/**
* Download artist portrait images from Wikipedia (and fallbacks) into data/images/portraits/.
* Run: npm run fetch-artist-images
* Flags: --force (re-fetch even when portrait_path is set), --limit=N
*/
require('dotenv').config();
const fs = require('fs');
const path = require('path');
const pool = require('../server/db');
const { saveArtistPortrait, findLocalPortraitPath } = require('./image-fetcher');
const FORCE = process.argv.includes('--force');
const LIMIT = parseInt(process.argv.find((a) => a.startsWith('--limit='))?.split('=')[1] || '0', 10);
const IMAGE_DIR = path.resolve(process.env.IMAGE_DIR || path.join(__dirname, '../data/images'));
function portraitFileExists(portraitPath) {
return !!portraitPath && fs.existsSync(path.join(IMAGE_DIR, portraitPath));
}
function needsPortrait(artist, force) {
if (force) return true;
const local = findLocalPortraitPath(artist.name, IMAGE_DIR);
if (local) return artist.portrait_path !== local;
if (artist.portrait_path) return !portraitFileExists(artist.portrait_path);
return true;
}
async function main() {
const { rows: artists } = await pool.query(`
SELECT id, name, wikipedia_title, portrait_path
FROM artists
ORDER BY name
`);
let targets = artists.filter((a) => needsPortrait(a, FORCE));
if (LIMIT > 0) targets = targets.slice(0, LIMIT);
console.log(
`Artists total: ${artists.length}, to fetch: ${targets.length}${FORCE ? ' (force)' : ''}${LIMIT > 0 ? ` (limit ${LIMIT})` : ''}`
);
let updated = 0;
let linked = 0;
let failed = 0;
for (const artist of targets) {
try {
const local = findLocalPortraitPath(artist.name, IMAGE_DIR);
if (local) {
await pool.query('UPDATE artists SET portrait_path = $1 WHERE id = $2', [local, artist.id]);
console.log(`↺ ${artist.name}${local}`);
linked += 1;
continue;
}
const wikiTitle = artist.wikipedia_title || artist.name;
const saved = await saveArtistPortrait(artist.name, wikiTitle, IMAGE_DIR);
if (!saved.path) {
console.warn(`✗ ${artist.name} — no portrait found`);
failed += 1;
continue;
}
await pool.query('UPDATE artists SET portrait_path = $1 WHERE id = $2', [saved.path, artist.id]);
console.log(`✓ ${artist.name}${saved.path} (${saved.source || 'Wikipedia'})`);
updated += 1;
} catch (err) {
console.error(`✗ ${artist.name}${err.message}`);
failed += 1;
}
}
console.log(`\nDone: ${updated} downloaded, ${linked} linked from disk, ${failed} failed`);
await pool.end();
}
main().catch((err) => {
console.error(err);
process.exit(1);
});