mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Create movie seed route handler
This commit is contained in:
parent
1309749e46
commit
30d5d65755
19
api/src/controllers/seed/images.ts
Normal file
19
api/src/controllers/seed/images.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import type { Image } from "~/models/utils";
|
||||
|
||||
export const processImage = async (url: string): Promise<Image> => {
|
||||
const hasher = new Bun.CryptoHasher("sha256");
|
||||
hasher.update(url);
|
||||
|
||||
// TODO: download source, save it in multiples qualities & process blurhash
|
||||
|
||||
return {
|
||||
id: hasher.digest().toString(),
|
||||
source: url,
|
||||
blurhash: "",
|
||||
};
|
||||
};
|
||||
|
||||
export const processOptImage = (url: string | null): Promise<Image | null> => {
|
||||
if (!url) return Promise.resolve(null);
|
||||
return processImage(url);
|
||||
};
|
79
api/src/controllers/seed/index.ts
Normal file
79
api/src/controllers/seed/index.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import Elysia, { t } from "elysia";
|
||||
import { Movie, SeedMovie } from "~/models/movie";
|
||||
import { db } from "~/db";
|
||||
import {
|
||||
shows,
|
||||
showTranslations,
|
||||
entries,
|
||||
entryTranslations,
|
||||
} from "~/db/schema";
|
||||
import { guessNextRefresh } from "./refresh";
|
||||
import { processOptImage } from "./images";
|
||||
|
||||
type Show = typeof shows.$inferInsert;
|
||||
type ShowTrans = typeof showTranslations.$inferInsert;
|
||||
type Entry = typeof entries.$inferInsert;
|
||||
|
||||
export const seed = new Elysia()
|
||||
.model({
|
||||
movie: Movie,
|
||||
"seed-movie": SeedMovie,
|
||||
error: t.String(),
|
||||
})
|
||||
.post(
|
||||
"/movies",
|
||||
async ({ body }) => {
|
||||
const { translations, videos, ...bMovie } = body;
|
||||
|
||||
const ret = await db.transaction(async (tx) => {
|
||||
const movie: Show = {
|
||||
kind: "movie",
|
||||
startAir: bMovie.airDate,
|
||||
nextRefresh: guessNextRefresh(bMovie.airDate ?? new Date()),
|
||||
...bMovie,
|
||||
};
|
||||
const [ret] = await tx
|
||||
.insert(shows)
|
||||
.values(movie)
|
||||
.returning({ pk: shows.pk, id: shows.id });
|
||||
|
||||
// even if never shown to the user, a movie still has an entry.
|
||||
const movieEntry: Entry = { type: "movie", ...bMovie };
|
||||
const [entry] = await tx
|
||||
.insert(entries)
|
||||
.values(movieEntry)
|
||||
.returning({ pk: entries.pk });
|
||||
|
||||
const trans: ShowTrans[] = await Promise.all(
|
||||
Object.entries(translations).map(async ([lang, tr]) => ({
|
||||
pk: ret.pk,
|
||||
// TODO: normalize lang or error if invalid
|
||||
language: lang,
|
||||
...tr,
|
||||
poster: await processOptImage(tr.poster),
|
||||
thumbnail: await processOptImage(tr.thumbnail),
|
||||
logo: await processOptImage(tr.logo),
|
||||
banner: await processOptImage(tr.banner),
|
||||
})),
|
||||
);
|
||||
await tx.insert(showTranslations).values(trans);
|
||||
|
||||
const entryTrans = trans.map((x) => ({ ...x, pk: entry.pk }));
|
||||
await tx.insert(entryTranslations).values(entryTrans);
|
||||
|
||||
return { ...ret, entry: entry.pk };
|
||||
});
|
||||
|
||||
// TODO: insert entry-video links
|
||||
// await db.transaction(async tx => {
|
||||
// await tx.insert(videos).values(videos);
|
||||
// });
|
||||
|
||||
return ret.id;
|
||||
},
|
||||
{
|
||||
body: "seed-movie",
|
||||
response: { 200: "movie", 400: "error" },
|
||||
tags: ["movies"],
|
||||
},
|
||||
);
|
12
api/src/controllers/seed/refresh.ts
Normal file
12
api/src/controllers/seed/refresh.ts
Normal file
@ -0,0 +1,12 @@
|
||||
// oh i hate js dates so much.
|
||||
export const guessNextRefresh = (airDate: Date | string) => {
|
||||
if (typeof airDate === "string") airDate = new Date(airDate);
|
||||
const diff = new Date().getTime() - airDate.getTime();
|
||||
const days = diff / (24 * 60 * 60 * 1000);
|
||||
|
||||
const ret = new Date();
|
||||
if (days <= 4) ret.setDate(ret.getDate() + 4);
|
||||
else if (days <= 21) ret.setDate(ret.getDate() + 14);
|
||||
else ret.setMonth(ret.getMonth() + 2);
|
||||
return ret.toISOString().substring(0, 10);
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
import { t } from "elysia";
|
||||
|
||||
export const Image = t.Object({
|
||||
id: t.String({ format: "uuid" }),
|
||||
id: t.String(),
|
||||
source: t.String({ format: "uri" }),
|
||||
blurhash: t.String(),
|
||||
});
|
||||
|
@ -3,11 +3,19 @@
|
||||
"target": "ES2021",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "node",
|
||||
"types": ["bun-types"],
|
||||
"types": [
|
||||
"bun-types"
|
||||
],
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noErrorTruncation": true
|
||||
"noErrorTruncation": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": [
|
||||
"./src/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user