mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 03:55:38 -04:00
Add actor/cast information with person pages and search support
Integrate TMDB credits data into the app: cast carousels on title detail pages, person detail pages with biography and filmography, and person search results in the command palette. Includes new persons/titleCast DB tables, profile image caching, and a nightly credits refresh cron job. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,18 +2,31 @@ import { mkdir, rename } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "@/lib/db/client";
|
||||
import { availabilityOffers, episodes, seasons, titles } from "@/lib/db/schema";
|
||||
import {
|
||||
availabilityOffers,
|
||||
episodes,
|
||||
persons,
|
||||
seasons,
|
||||
titleCast,
|
||||
titles,
|
||||
} from "@/lib/db/schema";
|
||||
import { createLogger } from "@/lib/logger";
|
||||
|
||||
const log = createLogger("image-cache");
|
||||
|
||||
export type ImageCategory = "posters" | "backdrops" | "stills" | "logos";
|
||||
export type ImageCategory =
|
||||
| "posters"
|
||||
| "backdrops"
|
||||
| "stills"
|
||||
| "logos"
|
||||
| "profiles";
|
||||
|
||||
const CATEGORY_SIZES: Record<ImageCategory, string> = {
|
||||
posters: "w500",
|
||||
backdrops: "w1280",
|
||||
stills: "w1280",
|
||||
logos: "w92",
|
||||
profiles: "w185",
|
||||
};
|
||||
|
||||
const IMAGE_BASE_URL =
|
||||
@@ -218,3 +231,28 @@ export async function cacheProviderLogos(titleId: string) {
|
||||
}
|
||||
await Promise.allSettled(tasks);
|
||||
}
|
||||
|
||||
export async function cacheProfilePhotos(titleId: string) {
|
||||
const castRows = db
|
||||
.select({ profilePath: persons.profilePath })
|
||||
.from(titleCast)
|
||||
.innerJoin(persons, eq(titleCast.personId, persons.id))
|
||||
.where(eq(titleCast.titleId, titleId))
|
||||
.all();
|
||||
|
||||
const tasks: Promise<unknown>[] = [];
|
||||
const seen = new Set<string>();
|
||||
for (const row of castRows) {
|
||||
if (row.profilePath) {
|
||||
const basename = path.basename(row.profilePath);
|
||||
if (!seen.has(basename) && !(await isImageCached("profiles", basename))) {
|
||||
seen.add(basename);
|
||||
tasks.push(downloadAndCacheImage(row.profilePath, "profiles"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tasks.length > 0) {
|
||||
log.debug(`Caching ${tasks.length} profile photos for title ${titleId}`);
|
||||
}
|
||||
await Promise.allSettled(tasks);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user