import { parseDocument } from "@lib/documents.ts"; import { parse, stringify } from "yaml"; import { createCrud } from "@lib/crud.ts"; import { extractHashTags, formatDate } from "@lib/string.ts"; import { fixRenderedMarkdown } from "@lib/helpers.ts"; import { getThumbhash } from "@lib/cache/image.ts"; export type Series = { id: string; name: string; description: string; type: "series"; tags: string[]; meta: { date: Date; image: string; author: string; tmdbId?: number; rating: number; average?: string; thumbnail?: string; done?: boolean; }; }; function renderSeries(series: Series) { const meta = series.meta; if ("date" in meta) { meta.date = formatDate(meta.date); } delete meta.thumbnail; delete meta.average; const movieImage = `![](${series.meta.image})`; return fixRenderedMarkdown(`${ meta ? `--- ${stringify(meta)} ---` : `--- ---` } # ${series.name} ${ // So we do not add a new image to the description everytime we render (series.meta.image && !series.description.includes(movieImage)) ? movieImage : ""} ${series.tags.map((t) => `#${t}`).join(" ")} ${series.description} `); } export function parseSeries(original: string, id: string): Series { const doc = parseDocument(original); let meta = {} as Series["meta"]; let name = ""; const range = [Infinity, -Infinity]; for (const child of doc.children) { if (child.type === "yaml") { try { meta = (parse(child.value) || {}) as Series["meta"]; } catch (_) { // ignore here } if (meta["rating"] && typeof meta["rating"] === "string") { meta.rating = [...meta.rating?.matchAll("⭐")].length; } continue; } if ( child.type === "heading" && child.depth === 1 && !name && child.children.length === 1 && child.children[0].type === "text" ) { name = child.children[0].value; continue; } if (name) { const start = child.position?.start.offset || Infinity; const end = child.position?.end.offset || -Infinity; if (start < range[0]) range[0] = start; if (end > range[1]) range[1] = end; } } let description = original.slice(range[0], range[1]); const tags = extractHashTags(description); for (const tag of tags) { description = description.replace("#" + tag, ""); } return { type: "series", id, name, tags, description, meta, }; } const crud = createCrud({ prefix: "Media/series/", parse: parseSeries, render: renderSeries, hasThumbnails: true, }); export const getSeries = crud.read; export const getAllSeries = crud.readAll; export const createSeries = crud.create;