cars: default to most-common-in-NL order; dex numbers oldest first with unknown years last (--renumber)
All checks were successful
Deploy production / deploy (push) Successful in 2m41s
All checks were successful
Deploy production / deploy (push) Successful in 2m41s
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
// bun scripts/cars-import.ts --dry-run fetch + build only, print a summary
|
// bun scripts/cars-import.ts --dry-run fetch + build only, print a summary
|
||||||
// bun scripts/cars-import.ts --cache /tmp/cars reuse raw downloads from that folder
|
// bun scripts/cars-import.ts --cache /tmp/cars reuse raw downloads from that folder
|
||||||
// bun scripts/cars-import.ts --dry-run --out x.json also dump the built catalogue
|
// bun scripts/cars-import.ts --dry-run --out x.json also dump the built catalogue
|
||||||
|
// bun scripts/cars-import.ts --renumber reassign Dex numbers from #1 (oldest first)
|
||||||
//
|
//
|
||||||
// Sources (no API keys):
|
// Sources (no API keys):
|
||||||
// - fueleconomy.gov vehicles.csv: every US EPA-tested car since 1984 (make, base model,
|
// - fueleconomy.gov vehicles.csv: every US EPA-tested car since 1984 (make, base model,
|
||||||
@@ -26,6 +27,8 @@ import { join } from 'node:path';
|
|||||||
|
|
||||||
const args = process.argv.slice(2);
|
const args = process.argv.slice(2);
|
||||||
const dryRun = args.includes('--dry-run');
|
const dryRun = args.includes('--dry-run');
|
||||||
|
// --renumber: hand out Dex numbers from #1 again instead of keeping existing ones.
|
||||||
|
const renumber = args.includes('--renumber');
|
||||||
const cacheDir = args.includes('--cache') ? args[args.indexOf('--cache') + 1] : null;
|
const cacheDir = args.includes('--cache') ? args[args.indexOf('--cache') + 1] : null;
|
||||||
const outFile = args.includes('--out') ? args[args.indexOf('--out') + 1] : null;
|
const outFile = args.includes('--out') ? args[args.indexOf('--out') + 1] : null;
|
||||||
|
|
||||||
@@ -927,12 +930,12 @@ async function write(brands: ReturnType<typeof build>) {
|
|||||||
const existing = await tx<{ id: number; dex: number; brand_id: number; slug: string }[]>`
|
const existing = await tx<{ id: number; dex: number; brand_id: number; slug: string }[]>`
|
||||||
select id, dex, brand_id, slug from cars.models`;
|
select id, dex, brand_id, slug from cars.models`;
|
||||||
const byKey = new Map(existing.map((e) => [`${e.brand_id}|${e.slug}`, e]));
|
const byKey = new Map(existing.map((e) => [`${e.brand_id}|${e.slug}`, e]));
|
||||||
let nextDex = Math.max(0, ...existing.map((e) => e.dex)) + 1;
|
let nextDex = renumber ? 1 : Math.max(0, ...existing.map((e) => e.dex)) + 1;
|
||||||
const all = brands
|
const all = brands
|
||||||
.flatMap((b) => b.models.map((m) => ({ b, m, brandId: brandIds.get(b.slug)! })))
|
.flatMap((b) => b.models.map((m) => ({ b, m, brandId: brandIds.get(b.slug)! })))
|
||||||
.sort(
|
.sort(
|
||||||
(x, y) =>
|
(x, y) =>
|
||||||
x.m.firstYear - y.m.firstYear ||
|
(x.m.firstYear ?? 9999) - (y.m.firstYear ?? 9999) ||
|
||||||
x.b.name.localeCompare(y.b.name) ||
|
x.b.name.localeCompare(y.b.name) ||
|
||||||
x.m.name.localeCompare(y.m.name)
|
x.m.name.localeCompare(y.m.name)
|
||||||
);
|
);
|
||||||
@@ -942,7 +945,7 @@ async function write(brands: ReturnType<typeof build>) {
|
|||||||
await tx`delete from cars.variants`;
|
await tx`delete from cars.variants`;
|
||||||
let variantCount = 0;
|
let variantCount = 0;
|
||||||
for (const { m, brandId } of all) {
|
for (const { m, brandId } of all) {
|
||||||
const prev = byKey.get(`${brandId}|${m.slug}`);
|
const prev = renumber ? undefined : byKey.get(`${brandId}|${m.slug}`);
|
||||||
const dex = prev?.dex ?? nextDex++;
|
const dex = prev?.dex ?? nextDex++;
|
||||||
const { variants, ...cols } = m;
|
const { variants, ...cols } = m;
|
||||||
const row = {
|
const row = {
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ export const BODIES = [
|
|||||||
] as const;
|
] as const;
|
||||||
export const DRIVES = ['fwd', 'rwd', 'awd', '4wd'] as const;
|
export const DRIVES = ['fwd', 'rwd', 'awd', '4wd'] as const;
|
||||||
export const SORTS = {
|
export const SORTS = {
|
||||||
dex: 'dex #',
|
|
||||||
popular: 'most common in NL',
|
popular: 'most common in NL',
|
||||||
|
dex: 'dex #',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
newest: 'newest',
|
newest: 'newest',
|
||||||
oldest: 'oldest',
|
oldest: 'oldest',
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export function parseFilters(params: URLSearchParams): CarFilters {
|
|||||||
market: pick(params.get('market'), ['nl', 'us'] as const),
|
market: pick(params.get('market'), ['nl', 'us'] as const),
|
||||||
from: year(params.get('from')),
|
from: year(params.get('from')),
|
||||||
to: year(params.get('to')),
|
to: year(params.get('to')),
|
||||||
sort: sort && sort in SORTS ? (sort as CarSort) : 'dex',
|
sort: sort && sort in SORTS ? (sort as CarSort) : 'popular',
|
||||||
page: Math.min(Math.max(1, Math.floor(Number(params.get('page')) || 1)), 1000)
|
page: Math.min(Math.max(1, Math.floor(Number(params.get('page')) || 1)), 1000)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const quick = [
|
const quick = [
|
||||||
{ label: '🔥 most common in NL', params: { sort: 'popular', market: 'nl' } },
|
{ label: '📖 dex order', params: { sort: 'dex' } },
|
||||||
{ label: '⚡ electric', params: { fuel: 'electric', sort: 'popular' } },
|
{ label: '⚡ electric', params: { fuel: 'electric', sort: 'popular' } },
|
||||||
{ label: '🍃 hybrids', params: { fuel: 'hybrid', sort: 'popular' } },
|
{ label: '🍃 hybrids', params: { fuel: 'hybrid', sort: 'popular' } },
|
||||||
{ label: '🏎️ coupés', params: { body: 'coupe', sort: 'popular' } },
|
{ label: '🏎️ coupés', params: { body: 'coupe', sort: 'popular' } },
|
||||||
|
|||||||
Reference in New Issue
Block a user