mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-08-07 09:01:29 -04:00
Add with=show
to /videos/:id
This commit is contained in:
parent
899697e1aa
commit
34efb2b534
@ -227,7 +227,6 @@ export const staffH = new Elysia({ tags: ["staff"] })
|
|||||||
.from(watchlist)
|
.from(watchlist)
|
||||||
.leftJoin(profiles, eq(watchlist.profilePk, profiles.pk))
|
.leftJoin(profiles, eq(watchlist.profilePk, profiles.pk))
|
||||||
.where(and(eq(profiles.id, sub), eq(watchlist.showPk, shows.pk)))
|
.where(and(eq(profiles.id, sub), eq(watchlist.showPk, shows.pk)))
|
||||||
.limit(1)
|
|
||||||
.as("watchstatus");
|
.as("watchstatus");
|
||||||
|
|
||||||
const items = await db
|
const items = await db
|
||||||
|
@ -15,7 +15,15 @@ import { alias } from "drizzle-orm/pg-core";
|
|||||||
import { Elysia, t } from "elysia";
|
import { Elysia, t } from "elysia";
|
||||||
import { auth } from "~/auth";
|
import { auth } from "~/auth";
|
||||||
import { db, type Transaction } from "~/db";
|
import { db, type Transaction } from "~/db";
|
||||||
import { entries, entryVideoJoin, shows, videos } from "~/db/schema";
|
import {
|
||||||
|
entries,
|
||||||
|
entryVideoJoin,
|
||||||
|
profiles,
|
||||||
|
shows,
|
||||||
|
showTranslations,
|
||||||
|
videos,
|
||||||
|
} from "~/db/schema";
|
||||||
|
import { watchlist } from "~/db/schema/watchlist";
|
||||||
import {
|
import {
|
||||||
coalesce,
|
coalesce,
|
||||||
conflictUpdateAllExcept,
|
conflictUpdateAllExcept,
|
||||||
@ -30,10 +38,13 @@ import {
|
|||||||
import { Entry } from "~/models/entry";
|
import { Entry } from "~/models/entry";
|
||||||
import { KError } from "~/models/error";
|
import { KError } from "~/models/error";
|
||||||
import { bubbleVideo } from "~/models/examples";
|
import { bubbleVideo } from "~/models/examples";
|
||||||
|
import { Movie, type MovieStatus } from "~/models/movie";
|
||||||
|
import { Serie, type Serie } from "~/models/serie";
|
||||||
import {
|
import {
|
||||||
AcceptLanguage,
|
AcceptLanguage,
|
||||||
buildRelations,
|
buildRelations,
|
||||||
createPage,
|
createPage,
|
||||||
|
type Image,
|
||||||
isUuid,
|
isUuid,
|
||||||
keysetPaginate,
|
keysetPaginate,
|
||||||
Page,
|
Page,
|
||||||
@ -44,6 +55,7 @@ import {
|
|||||||
} from "~/models/utils";
|
} from "~/models/utils";
|
||||||
import { desc as description } from "~/models/utils/descriptions";
|
import { desc as description } from "~/models/utils/descriptions";
|
||||||
import { Guess, Guesses, SeedVideo, Video } from "~/models/video";
|
import { Guess, Guesses, SeedVideo, Video } from "~/models/video";
|
||||||
|
import type { MovieWatchStatus, SerieWatchStatus } from "~/models/watchlist";
|
||||||
import { comment } from "~/utils";
|
import { comment } from "~/utils";
|
||||||
import {
|
import {
|
||||||
entryProgressQ,
|
entryProgressQ,
|
||||||
@ -56,6 +68,7 @@ import {
|
|||||||
updateAvailableCount,
|
updateAvailableCount,
|
||||||
updateAvailableSince,
|
updateAvailableSince,
|
||||||
} from "./seed/insert/shows";
|
} from "./seed/insert/shows";
|
||||||
|
import { watchStatusQ } from "./shows/logic";
|
||||||
|
|
||||||
async function linkVideos(
|
async function linkVideos(
|
||||||
tx: Transaction,
|
tx: Transaction,
|
||||||
@ -206,9 +219,10 @@ const videoRelations = {
|
|||||||
slugs: () => {
|
slugs: () => {
|
||||||
return db
|
return db
|
||||||
.select({
|
.select({
|
||||||
slugs: coalesce(jsonbAgg(entryVideoJoin.slug), sql`'[]'::jsonb`).as(
|
slugs: coalesce<string[]>(
|
||||||
"slugs",
|
jsonbAgg(entryVideoJoin.slug),
|
||||||
),
|
sql`'[]'::jsonb`,
|
||||||
|
).as("slugs"),
|
||||||
})
|
})
|
||||||
.from(entryVideoJoin)
|
.from(entryVideoJoin)
|
||||||
.where(eq(entryVideoJoin.videoPk, videos.pk))
|
.where(eq(entryVideoJoin.videoPk, videos.pk))
|
||||||
@ -242,6 +256,72 @@ const videoRelations = {
|
|||||||
.where(eq(entryVideoJoin.videoPk, videos.pk))
|
.where(eq(entryVideoJoin.videoPk, videos.pk))
|
||||||
.as("entries");
|
.as("entries");
|
||||||
},
|
},
|
||||||
|
show: ({
|
||||||
|
languages,
|
||||||
|
preferOriginal,
|
||||||
|
}: {
|
||||||
|
languages: string[];
|
||||||
|
preferOriginal: boolean;
|
||||||
|
}) => {
|
||||||
|
const transQ = db
|
||||||
|
.selectDistinctOn([showTranslations.pk])
|
||||||
|
.from(showTranslations)
|
||||||
|
.orderBy(
|
||||||
|
showTranslations.pk,
|
||||||
|
sql`array_position(${sqlarr(languages)}, ${showTranslations.language})`,
|
||||||
|
)
|
||||||
|
.as("t");
|
||||||
|
|
||||||
|
const watchStatusQ = db
|
||||||
|
.select({
|
||||||
|
watchStatus: jsonbBuildObject<MovieWatchStatus & SerieWatchStatus>({
|
||||||
|
...getColumns(watchlist),
|
||||||
|
percent: watchlist.seenCount,
|
||||||
|
}).as("watchStatus"),
|
||||||
|
})
|
||||||
|
.from(watchlist)
|
||||||
|
.leftJoin(profiles, eq(watchlist.profilePk, profiles.pk))
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
eq(profiles.id, sql.placeholder("userId")),
|
||||||
|
eq(watchlist.showPk, shows.pk),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return db
|
||||||
|
.select({
|
||||||
|
json: jsonbBuildObject<Serie | Movie>({
|
||||||
|
...getColumns(shows),
|
||||||
|
...getColumns(transQ),
|
||||||
|
// movie columns (status is only a typescript hint)
|
||||||
|
status: sql<MovieStatus>`${shows.status}`,
|
||||||
|
airDate: shows.startAir,
|
||||||
|
kind: sql<any>`${shows.kind}`,
|
||||||
|
isAvailable: sql<boolean>`${shows.availableCount} != 0`,
|
||||||
|
|
||||||
|
...(preferOriginal && {
|
||||||
|
poster: sql<Image>`coalesce(nullif(${shows.original}->'poster', 'null'::jsonb), ${transQ.poster})`,
|
||||||
|
thumbnail: sql<Image>`coalesce(nullif(${shows.original}->'thumbnail', 'null'::jsonb), ${transQ.thumbnail})`,
|
||||||
|
banner: sql<Image>`coalesce(nullif(${shows.original}->'banner', 'null'::jsonb), ${transQ.banner})`,
|
||||||
|
logo: sql<Image>`coalesce(nullif(${shows.original}->'logo', 'null'::jsonb), ${transQ.logo})`,
|
||||||
|
}),
|
||||||
|
watchStatus: sql`${watchStatusQ}`,
|
||||||
|
}).as("json"),
|
||||||
|
})
|
||||||
|
.from(shows)
|
||||||
|
.innerJoin(transQ, eq(shows.pk, transQ.pk))
|
||||||
|
.where(
|
||||||
|
eq(
|
||||||
|
shows.pk,
|
||||||
|
db
|
||||||
|
.select({ pk: entries.showPk })
|
||||||
|
.from(entries)
|
||||||
|
.innerJoin(entryVideoJoin, eq(entryVideoJoin.entryPk, entries.pk))
|
||||||
|
.where(eq(videos.pk, entryVideoJoin.videoPk)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.as("show");
|
||||||
|
},
|
||||||
previous: ({ languages }: { languages: string[] }) => {
|
previous: ({ languages }: { languages: string[] }) => {
|
||||||
return getNextVideoEntry({ languages, prev: true });
|
return getNextVideoEntry({ languages, prev: true });
|
||||||
},
|
},
|
||||||
@ -263,7 +343,7 @@ function getNextVideoEntry({
|
|||||||
const evj = alias(entryVideoJoin, `evj_${prev ? "prev" : "next"}`);
|
const evj = alias(entryVideoJoin, `evj_${prev ? "prev" : "next"}`);
|
||||||
return db
|
return db
|
||||||
.select({
|
.select({
|
||||||
json: jsonbBuildObject<Entry>({
|
json: jsonbBuildObject<{ video: string; entry: Entry }>({
|
||||||
video: entryVideoJoin.slug,
|
video: entryVideoJoin.slug,
|
||||||
entry: {
|
entry: {
|
||||||
...getColumns(entries),
|
...getColumns(entries),
|
||||||
@ -274,7 +354,7 @@ function getNextVideoEntry({
|
|||||||
createdAt: sql`to_char(${entries.createdAt}, 'YYYY-MM-DD"T"HH24:MI:SS"Z"')`,
|
createdAt: sql`to_char(${entries.createdAt}, 'YYYY-MM-DD"T"HH24:MI:SS"Z"')`,
|
||||||
updatedAt: sql`to_char(${entries.updatedAt}, 'YYYY-MM-DD"T"HH24:MI:SS"Z"')`,
|
updatedAt: sql`to_char(${entries.updatedAt}, 'YYYY-MM-DD"T"HH24:MI:SS"Z"')`,
|
||||||
},
|
},
|
||||||
}),
|
}).as("json"),
|
||||||
})
|
})
|
||||||
.from(entries)
|
.from(entries)
|
||||||
.innerJoin(transQ, eq(entries.pk, transQ.pk))
|
.innerJoin(transQ, eq(entries.pk, transQ.pk))
|
||||||
@ -337,9 +417,9 @@ export const videosH = new Elysia({ prefix: "/videos", tags: ["videos"] })
|
|||||||
":id",
|
":id",
|
||||||
async ({
|
async ({
|
||||||
params: { id },
|
params: { id },
|
||||||
query: { with: relations },
|
query: { with: relations, preferOriginal },
|
||||||
headers: { "accept-language": langs },
|
headers: { "accept-language": langs },
|
||||||
jwt: { sub },
|
jwt: { sub, settings },
|
||||||
status,
|
status,
|
||||||
}) => {
|
}) => {
|
||||||
const languages = processLanguages(langs);
|
const languages = processLanguages(langs);
|
||||||
@ -355,6 +435,7 @@ export const videosH = new Elysia({ prefix: "/videos", tags: ["videos"] })
|
|||||||
videoRelations,
|
videoRelations,
|
||||||
{
|
{
|
||||||
languages,
|
languages,
|
||||||
|
preferOriginal: preferOriginal ?? settings.preferOriginal,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
@ -382,10 +463,15 @@ export const videosH = new Elysia({ prefix: "/videos", tags: ["videos"] })
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
query: t.Object({
|
query: t.Object({
|
||||||
with: t.Array(t.UnionEnum(["previous", "next"]), {
|
with: t.Array(t.UnionEnum(["previous", "next", "show"]), {
|
||||||
default: [],
|
default: [],
|
||||||
description: "Include related entries in the response.",
|
description: "Include related entries in the response.",
|
||||||
}),
|
}),
|
||||||
|
preferOriginal: t.Optional(
|
||||||
|
t.Boolean({
|
||||||
|
description: description.preferOriginal,
|
||||||
|
}),
|
||||||
|
),
|
||||||
}),
|
}),
|
||||||
headers: t.Object(
|
headers: t.Object(
|
||||||
{
|
{
|
||||||
@ -423,6 +509,7 @@ export const videosH = new Elysia({ prefix: "/videos", tags: ["videos"] })
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
show: t.Optional(t.Union([Movie, Serie])),
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
404: {
|
404: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user