cars: Wikimedia Commons photos (cars.photos, card heroes, model gallery + lightbox, brand hero/logo), cars:photos + cars:refresh with --report-new, fold duplicate names (Golf VI, Peugot, Mustang Mach 1, Model 3/Y, i10/i30, Ceed, Lynk & Co)
All checks were successful
Deploy production / deploy (push) Successful in 3m0s
All checks were successful
Deploy production / deploy (push) Successful in 3m0s
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// Car pokedex queries (/trackers/cars). Public, read-only; data is written only by
|
||||
// scripts/cars-import.ts.
|
||||
import { db } from '#lib/server/db/index.js';
|
||||
import { carBrands, carModels, carVariants } from '#lib/server/db/schema/index.js';
|
||||
import { carBrands, carModels, carPhotos, carVariants } from '#lib/server/db/schema/index.js';
|
||||
import { and, arrayContains, asc, desc, eq, gt, gte, ilike, lte, sql, type SQL } from 'drizzle-orm';
|
||||
import { BODIES, DRIVES, FUELS, SORTS, type CarCard, type CarSort } from '#lib/cars/shared.js';
|
||||
|
||||
@@ -55,7 +55,8 @@ const cardColumns = {
|
||||
bodies: carModels.bodies,
|
||||
nlCount: carModels.nlCount,
|
||||
nlPriceLatest: carModels.nlPriceLatest,
|
||||
powerKwMax: carModels.powerKwMax
|
||||
powerKwMax: carModels.powerKwMax,
|
||||
photo: carModels.photo
|
||||
};
|
||||
|
||||
const escapeLike = (s: string) => s.replace(/[\\%_]/g, (c) => `\\${c}`);
|
||||
@@ -145,7 +146,21 @@ export async function getBrand(slug: string) {
|
||||
.innerJoin(carBrands, eq(carBrands.id, carModels.brandId))
|
||||
.where(eq(carModels.brandId, brand.id))
|
||||
.orderBy(desc(carModels.nlCount), desc(carModels.variantCount), asc(carModels.name));
|
||||
return { brand, models };
|
||||
const [hero] = brand.photo
|
||||
? await db
|
||||
.select({
|
||||
file: carPhotos.file,
|
||||
author: carPhotos.author,
|
||||
license: carPhotos.license,
|
||||
licenseUrl: carPhotos.licenseUrl,
|
||||
model: carModels.name
|
||||
})
|
||||
.from(carPhotos)
|
||||
.innerJoin(carModels, eq(carModels.id, carPhotos.modelId))
|
||||
.where(and(eq(carModels.brandId, brand.id), eq(carPhotos.thumb, brand.photo)))
|
||||
.limit(1)
|
||||
: [];
|
||||
return { brand, models, hero: hero ?? null };
|
||||
}
|
||||
|
||||
export async function getModel(brandSlug: string, modelSlug: string) {
|
||||
@@ -156,7 +171,7 @@ export async function getModel(brandSlug: string, modelSlug: string) {
|
||||
.where(and(eq(carBrands.slug, brandSlug), eq(carModels.slug, modelSlug)))
|
||||
.limit(1);
|
||||
if (!row) return null;
|
||||
const [variants, neighbours] = await Promise.all([
|
||||
const [variants, neighbours, photos] = await Promise.all([
|
||||
db
|
||||
.select()
|
||||
.from(carVariants)
|
||||
@@ -175,11 +190,27 @@ export async function getModel(brandSlug: string, modelSlug: string) {
|
||||
sql`${carModels.dex} in (
|
||||
(select max(dex) from cars.models where dex < ${row.model.dex}),
|
||||
(select min(dex) from cars.models where dex > ${row.model.dex}))`
|
||||
)
|
||||
),
|
||||
db
|
||||
.select({
|
||||
file: carPhotos.file,
|
||||
kind: carPhotos.kind,
|
||||
caption: carPhotos.caption,
|
||||
thumb: carPhotos.thumb,
|
||||
width: carPhotos.width,
|
||||
height: carPhotos.height,
|
||||
author: carPhotos.author,
|
||||
license: carPhotos.license,
|
||||
licenseUrl: carPhotos.licenseUrl
|
||||
})
|
||||
.from(carPhotos)
|
||||
.where(eq(carPhotos.modelId, row.model.id))
|
||||
.orderBy(asc(carPhotos.position))
|
||||
]);
|
||||
return {
|
||||
...row,
|
||||
variants,
|
||||
photos,
|
||||
prev: neighbours.find((n) => n.dex < row.model.dex) ?? null,
|
||||
next: neighbours.find((n) => n.dex > row.model.dex) ?? null
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user