93 lines
2.6 KiB
TypeScript
93 lines
2.6 KiB
TypeScript
import { FreshContext, Handlers } from "$fresh/server.ts";
|
|
import { fileExtension } from "https://deno.land/x/file_extension@v2.1.0/mod.ts";
|
|
import * as tmdb from "@lib/tmdb.ts";
|
|
import { formatDate, isString, safeFileName } from "@lib/string.ts";
|
|
import { json } from "@lib/helpers.ts";
|
|
import {
|
|
AccessDeniedError,
|
|
BadRequestError,
|
|
NotFoundError,
|
|
} from "@lib/errors.ts";
|
|
import { createRecommendationResource } from "@lib/recommendation.ts";
|
|
import { createResource, fetchResource } from "@lib/marka/index.ts";
|
|
import { ReviewResource } from "@lib/marka/schema.ts";
|
|
|
|
const POST = async (
|
|
req: Request,
|
|
ctx: FreshContext,
|
|
): Promise<Response> => {
|
|
const session = ctx.state.session;
|
|
if (!session) {
|
|
throw new AccessDeniedError();
|
|
}
|
|
|
|
const movie = await fetchResource<ReviewResource>(
|
|
`movies/${ctx.params.name}`,
|
|
);
|
|
if (!movie) {
|
|
throw new NotFoundError();
|
|
}
|
|
|
|
const body = await req.json();
|
|
const name = ctx.params.name;
|
|
const { tmdbId } = body;
|
|
if (!name || !tmdbId) {
|
|
throw new BadRequestError();
|
|
}
|
|
|
|
const movieDetails = await tmdb.getMovie(tmdbId);
|
|
const movieCredits = !movie.content?.author &&
|
|
await tmdb.getMovieCredits(tmdbId);
|
|
|
|
const releaseDate = movieDetails.release_date;
|
|
if (releaseDate && !movie.content?.datePublished) {
|
|
movie.content = movie.content || {};
|
|
movie.content.datePublished = formatDate(new Date(releaseDate));
|
|
}
|
|
const director = movieCredits &&
|
|
movieCredits?.crew?.filter?.((person) => person.job === "Director")[0];
|
|
if (director && !movie.content?.author) {
|
|
movie.content = movie.content || {};
|
|
movie.content.author = {
|
|
_type: "Person",
|
|
name: director.name,
|
|
};
|
|
}
|
|
|
|
if (movieDetails.genres) {
|
|
movie.content.keywords = [
|
|
...new Set([
|
|
...(movie.content.keywords?.map((g) => g.toLowerCase()) || []),
|
|
...movieDetails.genres.map((g) =>
|
|
g.name?.toLowerCase().replaceAll(" ", "-")
|
|
),
|
|
].filter(isString)),
|
|
];
|
|
}
|
|
|
|
if (!movie.name) {
|
|
movie.name = tmdbId;
|
|
}
|
|
|
|
let finalPath = "";
|
|
const posterPath = movieDetails.poster_path;
|
|
if (posterPath && !movie.content?.image) {
|
|
const poster = await tmdb.getMoviePoster(posterPath);
|
|
const extension = fileExtension(posterPath);
|
|
finalPath = `movies/images/${safeFileName(name)}_cover.${extension}`;
|
|
await createResource(finalPath, poster);
|
|
movie.content = movie.content || {};
|
|
movie.content.image = finalPath;
|
|
}
|
|
|
|
await createResource(`movies/${safeFileName(movie.name)}.md`, movie);
|
|
|
|
createRecommendationResource(movie, movieDetails.overview);
|
|
|
|
return json(movie);
|
|
};
|
|
|
|
export const handler: Handlers = {
|
|
POST,
|
|
};
|