import { HandlerContext } from "$fresh/server.ts"; import { createDocument, getDocument, transformDocument, } from "@lib/documents.ts"; import { fileExtension } from "https://deno.land/x/file_extension@v2.1.0/mod.ts"; import { type Movie, parseMovie } from "@lib/movies.ts"; import * as tmdb from "@lib/tmdb.ts"; import { parse, stringify } from "https://deno.land/std@0.194.0/yaml/mod.ts"; import { formatDate } from "@lib/string.ts"; function safeFileName(inputString: string): string { // Convert the string to lowercase let fileName = inputString.toLowerCase(); // Replace spaces with underscores fileName = fileName.replace(/ /g, "_"); // Remove characters that are not safe for file names fileName = fileName.replace(/[^\w.-]/g, ""); return fileName; } export async function getMovie(name: string) { const document = await getDocument(`Media/movies/${name}.md`); const movie = parseMovie(document, name); return movie; } async function updateMovieMetadata( name: string, metadata: Partial, ) { const docId = `Media/movies/${name}.md`; const currentDoc = await getDocument(docId); if (!currentDoc) return; const newDoc = transformDocument(currentDoc, (root) => { const frontmatterNode = root.children.find((c) => c.type === "yaml"); const frontmatter = frontmatterNode?.value as string; if (frontmatter) { const value = parse(frontmatter) as Movie["meta"]; if (metadata.author && !value.author) { value.author = metadata.author; } if (metadata.image && !value.image) { value.image = metadata.image; } if (metadata.date && !value.date) { value.date = formatDate(metadata.date); } frontmatterNode.value = stringify(value); } return root; }); const response = await createDocument(docId, newDoc); return response; } export const handler = async ( _req: Request, _ctx: HandlerContext, ): Promise => { const headers = new Headers(); headers.append("Content-Type", "application/json"); const movie = await getMovie(_ctx.params.name); if (_req.method === "GET") { return new Response(JSON.stringify(movie)); } if (_req.method === "POST") { const body = await _req.json(); const name = _ctx.params.name; const { tmdbId } = body; if (!name || !tmdbId) { return new Response("Bad Request", { status: 400, }); } const movieDetails = await tmdb.getMovie(tmdbId); const movieCredits = !movie.meta.author && await tmdb.getMovieCredits(tmdbId); const releaseDate = movieDetails.release_date; const posterPath = movieDetails.poster_path; const director = movieCredits?.crew?.filter?.((person) => person.job === "Director" )[0]; let finalPath = ""; if (posterPath && !movie.meta.image) { const poster = await tmdb.getMoviePoster(posterPath); const extension = fileExtension(posterPath); finalPath = `Media/movies/images/${ safeFileName(name) }_cover.${extension}`; await createDocument(finalPath, poster); } const metadata = {} as Movie["meta"]; if (releaseDate) { metadata.date = new Date(releaseDate); } if (finalPath) { metadata.image = finalPath; } if (director) { metadata.author = director.name; } await updateMovieMetadata(name, metadata); return new Response(JSON.stringify(movieCredits), { headers, }); } return new Response(); };