mirror of
https://github.com/zoriya/Kyoo.git
synced 2026-06-05 05:45:16 -04:00
Make movie get work
This commit is contained in:
@@ -1,57 +1,45 @@
|
||||
import { and, eq, sql } from "drizzle-orm";
|
||||
import { Elysia, t } from "elysia";
|
||||
import { Movie, MovieTranslation } from "../models/movie";
|
||||
import { KError } from "~/models/error";
|
||||
import { isUuid, processLanguages } from "~/models/utils";
|
||||
import { comment } from "~/utils";
|
||||
import { db } from "../db";
|
||||
import { shows, showTranslations } from "../db/schema/shows";
|
||||
import { eq, and, sql, or } from "drizzle-orm";
|
||||
import { getColumns } from "../db/schema/utils";
|
||||
import { bubble } from "../models/examples";
|
||||
import { comment } from "~/utils";
|
||||
import { processLanguages } from "~/models/utils";
|
||||
import { Movie, MovieTranslation } from "../models/movie";
|
||||
|
||||
const translations = db
|
||||
.selectDistinctOn([showTranslations.pk])
|
||||
.from(showTranslations)
|
||||
// .where(
|
||||
// or(
|
||||
// eq(showTranslations.language, sql`any(${sql.placeholder("langs")})`),
|
||||
// eq(showTranslations.language, shows.originalLanguage),
|
||||
// ),
|
||||
// )
|
||||
.orderBy(
|
||||
showTranslations.pk,
|
||||
sql`array_position(${sql.placeholder("langs")}, ${showTranslations.language})`,
|
||||
)
|
||||
.as("t");
|
||||
// drizzle is bugged and doesn't allow js arrays to be used in raw sql.
|
||||
export function sqlarr(array: unknown[]) {
|
||||
return `{${array.map((item) => `"${item}"`).join(",")}}`;
|
||||
}
|
||||
|
||||
const getTranslationQuery = (languages: string[]) => {
|
||||
const fallback = languages.includes("*");
|
||||
const query = db
|
||||
.selectDistinctOn([showTranslations.pk])
|
||||
.from(showTranslations)
|
||||
.where(
|
||||
fallback
|
||||
? undefined
|
||||
: eq(showTranslations.language, sql`any(${sqlarr(languages)})`),
|
||||
)
|
||||
.orderBy(
|
||||
showTranslations.pk,
|
||||
sql`array_position(${sqlarr(languages)}, ${showTranslations.language})`,
|
||||
)
|
||||
.as("t");
|
||||
|
||||
const { pk, ...col } = getColumns(query);
|
||||
return [query, col] as const;
|
||||
};
|
||||
|
||||
const { pk: _, kind, startAir, endAir, ...moviesCol } = getColumns(shows);
|
||||
const { pk, language, ...translationsCol } = getColumns(translations);
|
||||
|
||||
const findMovie = db
|
||||
.select({
|
||||
...moviesCol,
|
||||
...translationsCol,
|
||||
airDate: startAir,
|
||||
})
|
||||
.from(shows)
|
||||
.innerJoin(translations, eq(shows.pk, translations.pk))
|
||||
.where(
|
||||
and(
|
||||
eq(shows.kind, "movie"),
|
||||
// or(
|
||||
// eq(shows.id, sql.placeholder("id")),
|
||||
eq(shows.slug, sql.placeholder("id")),
|
||||
// ),
|
||||
),
|
||||
)
|
||||
// .orderBy()
|
||||
.limit(1)
|
||||
.prepare("findMovie");
|
||||
|
||||
export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
|
||||
.model({
|
||||
movie: Movie,
|
||||
"movie-translation": MovieTranslation,
|
||||
error: t.Object({}),
|
||||
})
|
||||
.guard({
|
||||
params: t.Object({
|
||||
@@ -61,7 +49,7 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
|
||||
}),
|
||||
}),
|
||||
headers: t.Object({
|
||||
"Accept-Language": t.String({
|
||||
"accept-language": t.String({
|
||||
default: "*",
|
||||
examples: "en-us, ja;q=0.5",
|
||||
description: comment`
|
||||
@@ -71,26 +59,66 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
|
||||
`,
|
||||
}),
|
||||
}),
|
||||
response: { 200: "movie", 404: "error" },
|
||||
response: {
|
||||
200: "movie",
|
||||
404: {
|
||||
...KError,
|
||||
description: "No movie found with the given id or slug.",
|
||||
},
|
||||
422: {
|
||||
...KError,
|
||||
description: comment`
|
||||
The Accept-Language header can't be satisfied (all languages listed are
|
||||
unavailable). Try with another languages or add * to the list of languages
|
||||
to fallback to any language.
|
||||
`,
|
||||
},
|
||||
},
|
||||
})
|
||||
.get(
|
||||
"/:id",
|
||||
async ({
|
||||
params: { id },
|
||||
headers: { "Accept-Language": languages },
|
||||
headers: { "accept-language": languages },
|
||||
error,
|
||||
set,
|
||||
}) => {
|
||||
const langs = processLanguages(languages);
|
||||
console.log(langs);
|
||||
console.log(findMovie.getQuery());
|
||||
const ret = await findMovie.execute({ id, langs });
|
||||
console.log(ret);
|
||||
if (ret.length !== 1) return error(404, {});
|
||||
return ret[0];
|
||||
const [transQ, transCol] = getTranslationQuery(langs);
|
||||
|
||||
const idFilter = isUuid(id) ? eq(shows.id, id) : eq(shows.slug, id);
|
||||
|
||||
const [ret] = await db
|
||||
.select({
|
||||
...moviesCol,
|
||||
...transCol,
|
||||
airDate: startAir,
|
||||
})
|
||||
.from(shows)
|
||||
.leftJoin(transQ, eq(shows.pk, transQ.pk))
|
||||
.where(and(eq(shows.kind, "movie"), idFilter))
|
||||
.limit(1);
|
||||
|
||||
if (!ret) {
|
||||
return error(404, {
|
||||
status: 404,
|
||||
message: "Movie not found",
|
||||
details: undefined,
|
||||
});
|
||||
}
|
||||
if (!ret.language) {
|
||||
return error(422, {
|
||||
status: 422,
|
||||
message: "Accept-Language header could not be satisfied.",
|
||||
details: undefined,
|
||||
});
|
||||
}
|
||||
set.headers["content-language"] = ret.language;
|
||||
return ret;
|
||||
},
|
||||
{
|
||||
detail: {
|
||||
description: "Get a movie by id or slug",
|
||||
},
|
||||
},
|
||||
)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user