Allow collections to be created with movies or series

This commit is contained in:
Zoe Roux 2025-03-02 01:03:38 +01:00
parent dbfe836ce3
commit fc9afa5ede
No known key found for this signature in database
5 changed files with 54 additions and 6 deletions

View File

@ -0,0 +1,18 @@
import type { SeedCollection } from "~/models/collections";
import { insertShow } from "./shows";
export const insertCollection = async (collection?: SeedCollection) => {
if (!collection) return null;
const { translations: colTrans, ...col } = collection;
// TODO: need to compute start/end year & if missing tags & genres
const { updated, status, ...ret } = await insertShow(
{
kind: "collection",
status: "unknown",
nextRefresh,
...col,
},
colTrans,
);
return ret;
};

View File

@ -2,6 +2,7 @@ import { eq, sql } from "drizzle-orm";
import { db } from "~/db"; import { db } from "~/db";
import { showTranslations, shows } from "~/db/schema"; import { showTranslations, shows } from "~/db/schema";
import { conflictUpdateAllExcept } from "~/db/utils"; import { conflictUpdateAllExcept } from "~/db/utils";
import type { SeedCollection } from "~/models/collections";
import type { SeedMovie } from "~/models/movie"; import type { SeedMovie } from "~/models/movie";
import type { SeedSerie } from "~/models/serie"; import type { SeedSerie } from "~/models/serie";
import { getYear } from "~/utils"; import { getYear } from "~/utils";
@ -12,7 +13,10 @@ type ShowTrans = typeof showTranslations.$inferInsert;
export const insertShow = async ( export const insertShow = async (
show: Show, show: Show,
translations: SeedMovie["translations"] | SeedSerie["translations"], translations:
| SeedMovie["translations"]
| SeedSerie["translations"]
| SeedCollection["translations"],
) => { ) => {
return await db.transaction(async (tx) => { return await db.transaction(async (tx) => {
const ret = await insertBaseShow(tx, show); const ret = await insertBaseShow(tx, show);
@ -77,13 +81,14 @@ async function insertBaseShow(
// if at this point ret is still undefined, we could not reconciliate. // if at this point ret is still undefined, we could not reconciliate.
// simply bail and let the caller handle this. // simply bail and let the caller handle this.
const [{ id }] = await db const [{ pk, id }] = await db
.select({ id: shows.id }) .select({ pk: shows.pk, id: shows.id })
.from(shows) .from(shows)
.where(eq(shows.slug, show.slug)) .where(eq(shows.slug, show.slug))
.limit(1); .limit(1);
return { return {
status: 409 as const, status: 409 as const,
pk,
id, id,
slug: show.slug, slug: show.slug,
}; };

View File

@ -1,6 +1,7 @@
import { t } from "elysia"; import { t } from "elysia";
import type { SeedMovie } from "~/models/movie"; import type { SeedMovie } from "~/models/movie";
import { getYear } from "~/utils"; import { getYear } from "~/utils";
import { insertCollection } from "./insert/collection";
import { insertEntries } from "./insert/entries"; import { insertEntries } from "./insert/entries";
import { insertShow } from "./insert/shows"; import { insertShow } from "./insert/shows";
import { guessNextRefresh } from "./refresh"; import { guessNextRefresh } from "./refresh";
@ -11,6 +12,12 @@ export const SeedMovieResponse = t.Object({
videos: t.Array( videos: t.Array(
t.Object({ slug: t.String({ format: "slug", examples: ["bubble-v2"] }) }), t.Object({ slug: t.String({ format: "slug", examples: ["bubble-v2"] }) }),
), ),
collection: t.Nullable(
t.Object({
id: t.String({ format: "uuid" }),
slug: t.String({ format: "slug", examples: ["sawano-collection"] }),
}),
),
}); });
export type SeedMovieResponse = typeof SeedMovieResponse.static; export type SeedMovieResponse = typeof SeedMovieResponse.static;
@ -31,14 +38,17 @@ export const seedMovie = async (
seed.slug = `random-${getYear(seed.airDate)}`; seed.slug = `random-${getYear(seed.airDate)}`;
} }
const { translations, videos, ...bMovie } = seed; const { translations, videos, collection, ...bMovie } = seed;
const nextRefresh = guessNextRefresh(bMovie.airDate ?? new Date()); const nextRefresh = guessNextRefresh(bMovie.airDate ?? new Date());
const col = await insertCollection(collection);
const show = await insertShow( const show = await insertShow(
{ {
kind: "movie", kind: "movie",
startAir: bMovie.airDate, startAir: bMovie.airDate,
nextRefresh, nextRefresh,
collectionPk: col?.pk,
...bMovie, ...bMovie,
}, },
translations, translations,
@ -65,5 +75,6 @@ export const seedMovie = async (
id: show.id, id: show.id,
slug: show.slug, slug: show.slug,
videos: entry.videos, videos: entry.videos,
collection: col,
}; };
}; };

View File

@ -1,6 +1,7 @@
import { t } from "elysia"; import { t } from "elysia";
import type { SeedSerie } from "~/models/serie"; import type { SeedSerie } from "~/models/serie";
import { getYear } from "~/utils"; import { getYear } from "~/utils";
import { insertCollection } from "./insert/collection";
import { insertEntries } from "./insert/entries"; import { insertEntries } from "./insert/entries";
import { insertSeasons } from "./insert/seasons"; import { insertSeasons } from "./insert/seasons";
import { insertShow } from "./insert/shows"; import { insertShow } from "./insert/shows";
@ -35,6 +36,15 @@ export const SeedSerieResponse = t.Object({
slug: t.String({ format: "slug", examples: ["made-in-abyss-s1e1"] }), slug: t.String({ format: "slug", examples: ["made-in-abyss-s1e1"] }),
}), }),
), ),
collection: t.Nullable(
t.Object({
id: t.String({ format: "uuid" }),
slug: t.String({
format: "slug",
examples: ["made-in-abyss-collection"],
}),
}),
),
}); });
export type SeedSerieResponse = typeof SeedSerieResponse.static; export type SeedSerieResponse = typeof SeedSerieResponse.static;
@ -55,13 +65,16 @@ export const seedSerie = async (
seed.slug = `random-${getYear(seed.startAir)}`; seed.slug = `random-${getYear(seed.startAir)}`;
} }
const { translations, seasons, entries, extras, ...serie } = seed; const { translations, seasons, entries, extras, collection, ...serie } = seed;
const nextRefresh = guessNextRefresh(serie.startAir ?? new Date()); const nextRefresh = guessNextRefresh(serie.startAir ?? new Date());
const col = await insertCollection(collection);
const show = await insertShow( const show = await insertShow(
{ {
kind: "serie", kind: "serie",
nextRefresh, nextRefresh,
collectionPk: col?.pk,
...serie, ...serie,
}, },
translations, translations,
@ -82,5 +95,6 @@ export const seedSerie = async (
seasons: retSeasons, seasons: retSeasons,
entries: retEntries, entries: retEntries,
extras: retExtras, extras: retExtras,
collection: col,
}; };
}; };

View File

@ -52,7 +52,7 @@ export const Collection = t.Intersect([
export type Collection = Prettify<typeof Collection.static>; export type Collection = Prettify<typeof Collection.static>;
export const SeedCollection = t.Intersect([ export const SeedCollection = t.Intersect([
t.Omit(BaseCollection, ["createdAt", "nextRefresh"]), t.Omit(BaseCollection, ["startAir", "endAir", "createdAt", "nextRefresh"]),
t.Object({ t.Object({
slug: t.String({ format: "slug" }), slug: t.String({ format: "slug" }),
translations: TranslationRecord( translations: TranslationRecord(