// Restore image_url from seed JSON files for any station where it is currently NULL. // Match priority: explicit uuid → uuidFromSlug(slug) → exact name. import 'dotenv/config'; import Database from 'better-sqlite3'; import { readFileSync, readdirSync } from 'node:fs'; import { resolve, dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { createHash } from 'node:crypto'; const __dirname = dirname(fileURLToPath(import.meta.url)); const SEED_DIR = resolve(__dirname, '../../data/seed'); function uuidFromSlug(slug) { const h = createHash('sha1').update('oradio:' + slug).digest('hex'); return [h.slice(0, 8), h.slice(8, 12), '5' + h.slice(13, 16), '8' + h.slice(17, 20), h.slice(20, 32)].join('-'); } const db = new Database(process.env.DB_PATH || './data/db/oradio.sqlite'); const apply = process.argv.includes('--apply'); const entries = []; for (const f of readdirSync(SEED_DIR).filter((x) => x.startsWith('stations') && x.endsWith('.json'))) { try { const data = JSON.parse(readFileSync(join(SEED_DIR, f), 'utf8')); if (Array.isArray(data)) entries.push(...data); } catch { } } const byUuid = new Map(); const byName = new Map(); for (const e of entries) { if (!e.image_url) continue; const u = e.uuid || (e.slug ? uuidFromSlug(e.slug) : null); if (u) byUuid.set(u, e.image_url); if (e.name) byName.set(e.name.toLowerCase(), e.image_url); } const rows = db.prepare(`SELECT id, uuid, name FROM stations WHERE image_url IS NULL OR image_url = ''`).all(); const upd = db.prepare('UPDATE stations SET image_url = ? WHERE id = ?'); let restored = 0; for (const r of rows) { const url = (r.uuid && byUuid.get(r.uuid)) || byName.get(r.name?.toLowerCase()); if (!url) continue; console.log(`restore ${r.name} -> ${url}`); if (apply) upd.run(url, r.id); restored++; } console.log(`Done. restored=${restored}${apply ? '' : ' (dry run; pass --apply to write)'}`);