memorium/lib/resource/movies.ts

77 lines
1.8 KiB
TypeScript

import { parseDocument, renderMarkdown } from "@lib/documents.ts";
import { parse } from "yaml";
import { createCrud } from "@lib/crud.ts";
export type Movie = {
id: string;
name: string;
description: string;
hashtags: string[];
meta: {
date: Date;
image: string;
author: string;
rating: number;
status: "not-seen" | "watch-again" | "finished";
};
};
export function parseMovie(original: string, id: string): Movie {
const doc = parseDocument(original);
let meta = {} as Movie["meta"];
let name = "";
const range = [Infinity, -Infinity];
for (const child of doc.children) {
if (child.type === "yaml") {
meta = parse(child.value) as Movie["meta"];
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 hashtags = [];
for (const [hashtag] of original.matchAll(/\B(\#[a-zA-Z]+\b)(?!;)/g)) {
hashtags.push(hashtag.replace(/\#/g, ""));
description = description.replace(hashtag, "");
}
return {
id,
name,
hashtags,
description: renderMarkdown(description),
meta,
};
}
const crud = createCrud<Movie>({
prefix: "Media/movies/",
parse: parseMovie,
});
export const getMovie = crud.read;
export const getAllMovies = crud.readAll;