Add first /poster route

This commit is contained in:
Zoe Roux 2025-03-19 10:00:38 +01:00
parent 47554590a9
commit 9905587c83
No known key found for this signature in database

View File

@ -1,11 +1,18 @@
import { stat } from "node:fs/promises";
import type { BunFile } from "bun";
import { and, eq, sql } from "drizzle-orm";
import Elysia, { t } from "elysia";
import { db } from "~/db";
import { showTranslations, shows } from "~/db/schema";
import { sqlarr } from "~/db/utils";
import { KError } from "~/models/error";
import { bubble } from "~/models/examples";
import { AcceptLanguage, isUuid, processLanguages } from "~/models/utils";
import { imageDir } from "./seed/images";
export const imagesH = new Elysia({ prefix: "/images", tags: ["images"] }).get(
":id",
export const imagesH = new Elysia({ tags: ["images"] })
.get(
"/images/:id",
async ({ params: { id }, query: { quality }, headers: reqHeaders }) => {
const path = `${imageDir}/${id}.${quality}.jpg`;
const file = Bun.file(path);
@ -47,7 +54,86 @@ export const imagesH = new Elysia({ prefix: "/images", tags: ["images"] }).get(
404: { ...KError, description: "No image found with this id." },
},
},
);
)
.get(
"/movies/:id/poster",
async ({
params: { id },
headers: { "accept-language": languages },
query: { quality },
set,
error,
redirect,
}) => {
const lang = processLanguages(languages);
const [movie] = await db
.select({
poster: showTranslations.poster,
language: showTranslations.language,
})
.from(shows)
.leftJoin(showTranslations, eq(shows.pk, showTranslations.pk))
.where(
and(
eq(shows.kind, "movie"),
isUuid(id) ? eq(shows.id, id) : eq(shows.slug, id),
!lang.includes("*")
? eq(showTranslations.language, sql`any(${sqlarr(lang)})`)
: undefined,
),
)
.orderBy(
sql`array_position(${sqlarr(lang)}, ${showTranslations.language})`,
)
.limit(1);
if (!movie) {
return error(404, {
status: 404,
message: `No movie found with id or slug: '${id}'.`,
});
}
if (!movie.language) {
return error(422, {
status: 422,
message: "Accept-Language header could not be satisfied.",
});
}
set.headers["content-language"] = movie.language;
return redirect(`/images/${movie.poster!.id}?quality=${quality}`);
},
{
detail: { description: "Get the poster of a movie" },
params: t.Object({
id: t.String({
description: "The id or slug of the movie to retrieve.",
example: bubble.slug,
}),
}),
query: t.Object({
quality: t.Optional(
t.UnionEnum(["high", "medium", "low"], {
default: "high",
description: "The quality you want your image to be in.",
}),
),
}),
headers: t.Object({
"accept-language": AcceptLanguage(),
}),
response: {
302: t.Void({
description:
"Redirected to the [/movies/{id}](#tag/movies/GET/movies/{id}) route.",
}),
404: {
...KError,
description: "No movie found with the given id or slug.",
},
422: KError,
},
},
);
// stolen from https://github.com/elysiajs/elysia-static/blob/main/src/cache.ts