spotters: most-active-in sort with country/region selector, collection tracking (seen marks, progress, filters), refresh scripts score activity and report new NL entries
Some checks failed
Deploy production / deploy (push) Has been cancelled
Some checks failed
Deploy production / deploy (push) Has been cancelled
This commit is contained in:
56
scripts/spotters-report-nl.ts
Normal file
56
scripts/spotters-report-nl.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
// Adds Netherlands relevance to a refresh report (stdin JSON -> stdout JSON), so a "new
|
||||
// entries" ping can be limited to things that actually show up in NL.
|
||||
//
|
||||
// bun scripts/cars-import.ts --report-new | bun scripts/spotters-report-nl.ts cars
|
||||
//
|
||||
// Every new item (newModels / newTypes / newSpecies, matched by the /trackers/... url) gets
|
||||
// `nl` (its activity score in NL from <schema>.activity, 0 when none) and the report gets
|
||||
// `newInNl`: the same items with nl > 0, most active first. Needs DB_URL. Run after
|
||||
// scripts/spotters-activity.ts so new entries already have scores.
|
||||
import postgres from 'postgres';
|
||||
|
||||
const tracker = process.argv[2];
|
||||
const CFG = {
|
||||
cars: {
|
||||
key: 'newModels',
|
||||
sql: "select a.score from cars.activity a join cars.models m on m.id = a.model_id join cars.brands b on b.id = m.brand_id where a.area = 'nl' and b.slug = $1 and m.slug = $2"
|
||||
},
|
||||
planes: {
|
||||
key: 'newTypes',
|
||||
sql: "select a.score from planes.activity a join planes.types t on t.id = a.type_id join planes.makers m on m.id = t.maker_id where a.area = 'nl' and m.slug = $1 and t.slug = $2"
|
||||
},
|
||||
trains: {
|
||||
key: 'newTypes',
|
||||
sql: "select a.score from trains.activity a join trains.types t on t.id = a.type_id join trains.makers m on m.id = t.maker_id where a.area = 'nl' and m.slug = $1 and t.slug = $2"
|
||||
},
|
||||
wildlife: {
|
||||
key: 'newSpecies',
|
||||
sql: "select a.score from wildlife.activity a join wildlife.species s on s.id = a.species_id join wildlife.groups g on g.id = s.group_id where a.area = 'nl' and g.slug = $1 and s.slug = $2"
|
||||
}
|
||||
} as const;
|
||||
if (!(tracker in CFG)) {
|
||||
console.error(
|
||||
'usage: bun scripts/spotters-report-nl.ts <cars|planes|trains|wildlife> < report.json'
|
||||
);
|
||||
process.exit(2);
|
||||
}
|
||||
const cfg = CFG[tracker as keyof typeof CFG];
|
||||
const input = await new Response(Bun.stdin.stream()).text();
|
||||
if (!input.trim()) process.exit(0);
|
||||
const report = JSON.parse(input) as Record<string, unknown>;
|
||||
const items = (report[cfg.key] ?? []) as { url?: string; nl?: number }[];
|
||||
const sql = postgres(process.env.DB_URL!, { max: 1 });
|
||||
try {
|
||||
for (const item of items) {
|
||||
const path = item.url ? new URL(item.url, 'https://x').pathname : '';
|
||||
const [a, b] = path.replace(/^\/trackers\/[a-z]+\//, '').split('/');
|
||||
const [row] = a && b ? await sql.unsafe<{ score: number }[]>(cfg.sql, [a, b]) : [];
|
||||
item.nl = row ? Math.round(row.score * 10) / 10 : 0;
|
||||
}
|
||||
report.newInNl = items
|
||||
.filter((x) => (x.nl ?? 0) > 0)
|
||||
.toSorted((x, y) => (y.nl ?? 0) - (x.nl ?? 0));
|
||||
} finally {
|
||||
await sql.end();
|
||||
}
|
||||
console.log(JSON.stringify(report, null, 1));
|
||||
Reference in New Issue
Block a user