48 lines
2.2 KiB
TypeScript
48 lines
2.2 KiB
TypeScript
/**
|
|
* Import Ju's recommendations into movies.recs (the "Ju recommends" feed on /trackers/movies).
|
|
* Idempotent: upserts on (type, tmdb_id); title, for, reason and added_at are overwritten.
|
|
*
|
|
* scripts/movies-run.sh recs ~/imports/ju-recs.json # upsert
|
|
* scripts/movies-run.sh recs ~/imports/ju-recs.json --prune # also delete recs not in the file
|
|
* bun scripts/movies-recs-import.ts --dry-run ju-recs.json # validate only (no DB)
|
|
*
|
|
* JSON: an array of
|
|
* { "tmdb_id": 496243, "type": "movie", "title": "Parasite", "for": "both",
|
|
* "reason": "one line on why", "added_at": "2026-10-26T10:00:00+01:00" }
|
|
* type: movie | show ("tv" accepted); for: stan | juhee | both; reason and added_at optional
|
|
* (added_at defaults to now). Posters and year come from TMDB when TMDB_API_KEY is set.
|
|
*/
|
|
import { readFile } from 'node:fs/promises';
|
|
import postgres from 'postgres';
|
|
import { recsFile } from '../src/lib/server/movies/parse';
|
|
import { upsertRecs } from '../src/lib/server/movies/store';
|
|
import { Tmdb, runTmdb } from '../src/lib/server/movies/tmdb';
|
|
|
|
const args = process.argv.slice(2);
|
|
const files = args.filter((a) => !a.startsWith('--'));
|
|
if (files.length !== 1) {
|
|
console.error('usage: bun scripts/movies-recs-import.ts [--dry-run] [--prune] <file.json>');
|
|
process.exit(2);
|
|
}
|
|
const parsed = recsFile.safeParse(JSON.parse(await readFile(files[0], 'utf8')));
|
|
if (!parsed.success) {
|
|
for (const issue of parsed.error.issues.slice(0, 50))
|
|
console.error(`${issue.path.join('.')}: ${issue.message}`);
|
|
process.exit(1);
|
|
}
|
|
console.log(`Valid: ${parsed.data.length} recommendations`);
|
|
if (args.includes('--dry-run')) process.exit(0);
|
|
if (!process.env.DB_URL)
|
|
throw new Error('DB_URL is required (use scripts/movies-run.sh on stan-ovh)');
|
|
const sql = postgres(process.env.DB_URL, { max: 1, onnotice: () => {} });
|
|
try {
|
|
const r = await upsertRecs(sql, parsed.data, args.includes('--prune'));
|
|
console.log(`Upserted ${r.upserted} recommendations${r.pruned ? `, pruned ${r.pruned}` : ''}`);
|
|
if (process.env.TMDB_API_KEY) {
|
|
const m = await runTmdb(sql, new Tmdb(process.env.TMDB_API_KEY), { limit: 0 });
|
|
console.log(`TMDB: ${m.errors} errors`);
|
|
}
|
|
} finally {
|
|
await sql.end();
|
|
}
|