/** * Download artist portrait images from Wikipedia (and fallbacks) into data/images/portraits/. * Run: npm run dev: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); });