82 lines
2.4 KiB
TypeScript
82 lines
2.4 KiB
TypeScript
import { Handlers } from "$fresh/server.ts";
|
|
import { json } from "@lib/helpers.ts";
|
|
import * as tmdb from "@lib/tmdb.ts";
|
|
import { fileExtension } from "https://deno.land/x/file_extension@v2.1.0/mod.ts";
|
|
import { formatDate, isString, safeFileName } from "@lib/string.ts";
|
|
import { AccessDeniedError, BadRequestError } from "@lib/errors.ts";
|
|
import { createResource, fetchResource } from "@lib/marka/index.ts";
|
|
import { ReviewResource } from "@lib/marka/schema.ts";
|
|
import { toUrlSafeString } from "@lib/string.ts";
|
|
|
|
function pickDirector(
|
|
credits: Awaited<ReturnType<typeof tmdb.getSeriesCredits>>,
|
|
createdBy?: { name?: string }[],
|
|
): string | undefined {
|
|
const crewDirector = credits?.crew?.find?.((p) => p.job === "Director");
|
|
return crewDirector?.name ?? createdBy?.[0]?.name;
|
|
}
|
|
|
|
export const handler: Handlers = {
|
|
async GET(_, ctx) {
|
|
const series = await fetchResource(`series/${ctx.params.name}`);
|
|
return json(series);
|
|
},
|
|
async POST(_, ctx) {
|
|
const session = ctx.state.session;
|
|
if (!session) {
|
|
throw new AccessDeniedError();
|
|
}
|
|
|
|
const tmdbId = parseInt(ctx.params.name);
|
|
if (Number.isNaN(tmdbId)) throw new BadRequestError();
|
|
|
|
const [seriesDetails, seriesCredits] = await Promise.all([
|
|
tmdb.getSeries(tmdbId),
|
|
tmdb.getSeriesCredits(tmdbId),
|
|
]);
|
|
|
|
const name = seriesDetails.name ||
|
|
seriesDetails.original_name ||
|
|
ctx.params.name;
|
|
|
|
let finalPath = "";
|
|
const posterPath = seriesDetails.poster_path;
|
|
if (posterPath) {
|
|
const poster = await tmdb.getMoviePoster(posterPath);
|
|
const extension = fileExtension(posterPath);
|
|
const imagePath = `series/images/${
|
|
safeFileName(name)
|
|
}_cover.${extension}`;
|
|
await createResource(imagePath, poster);
|
|
finalPath = imagePath;
|
|
}
|
|
|
|
const keywords = seriesDetails.genres
|
|
?.map((g) => g.name?.toLowerCase())
|
|
.filter(isString) ??
|
|
[];
|
|
|
|
const series: ReviewResource["content"] = {
|
|
_type: "Review",
|
|
image: `resources/${finalPath}`,
|
|
datePublished: formatDate(seriesDetails.first_air_date),
|
|
tmdbId,
|
|
author: {
|
|
_type: "Person",
|
|
name: pickDirector(seriesCredits, seriesDetails?.created_by),
|
|
},
|
|
itemReviewed: {
|
|
name: name,
|
|
},
|
|
reviewBody: "",
|
|
keywords: keywords,
|
|
};
|
|
|
|
const fileName = toUrlSafeString(name);
|
|
|
|
await createResource(`series/${fileName}.md`, series);
|
|
|
|
return json({ name: fileName });
|
|
},
|
|
};
|