feat: add series
This commit is contained in:
108
lib/resource/series.ts
Normal file
108
lib/resource/series.ts
Normal file
@ -0,0 +1,108 @@
|
||||
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";
|
||||
|
||||
export type Series = {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
type: "series";
|
||||
tags: string[];
|
||||
meta: {
|
||||
date: Date;
|
||||
image: string;
|
||||
author: string;
|
||||
rating: number;
|
||||
status: "not-seen" | "watch-again" | "finished";
|
||||
};
|
||||
};
|
||||
|
||||
function renderSeries(movie: Series) {
|
||||
const meta = movie.meta;
|
||||
if ("date" in meta) {
|
||||
meta.date = formatDate(meta.date);
|
||||
}
|
||||
|
||||
return fixRenderedMarkdown(`${
|
||||
meta
|
||||
? `---
|
||||
${stringify(meta)}
|
||||
---`
|
||||
: `---
|
||||
---`
|
||||
}
|
||||
# ${movie.name}
|
||||
${movie.meta.image ? `` : ""}
|
||||
${movie.tags.map((t) => `#${t}`).join(" ")}
|
||||
${movie.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<Series>({
|
||||
prefix: "Media/series/",
|
||||
parse: parseSeries,
|
||||
});
|
||||
|
||||
export const getSeries = crud.read;
|
||||
export const getAllSeries = crud.readAll;
|
||||
export const createSeries = (series: Series) => {
|
||||
const content = renderSeries(series);
|
||||
return crud.create(series.id, content);
|
||||
};
|
@ -23,4 +23,10 @@ export const resources = {
|
||||
link: "/articles",
|
||||
prefix: "Media/articles/",
|
||||
},
|
||||
"series": {
|
||||
emoji: "🎥",
|
||||
name: "Series",
|
||||
link: "/series",
|
||||
prefix: "Media/series/",
|
||||
},
|
||||
} as const;
|
||||
|
@ -6,6 +6,10 @@ export function searchMovie(query: string) {
|
||||
return moviedb.searchMovie({ query });
|
||||
}
|
||||
|
||||
export function searchTVShow(query: string) {
|
||||
return moviedb.searchTv({ query });
|
||||
}
|
||||
|
||||
export function getMovie(id: number) {
|
||||
return moviedb.movieInfo({ id });
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import { getAllRecipes } from "@lib/resource/recipes.ts";
|
||||
import { getAllArticles } from "@lib/resource/articles.ts";
|
||||
import { createLogger } from "@lib/log.ts";
|
||||
import { debounce } from "https://deno.land/std@0.193.0/async/mod.ts";
|
||||
import { getAllSeries } from "@lib/resource/series.ts";
|
||||
|
||||
const log = createLogger("typesense");
|
||||
|
||||
@ -100,6 +101,7 @@ async function synchronizeWithTypesense() {
|
||||
getAllMovies(),
|
||||
getAllArticles(),
|
||||
getAllRecipes(),
|
||||
getAllSeries(),
|
||||
])).flat(); // Replace with your function to get all resources from the database
|
||||
|
||||
const client = await getTypeSenseClient();
|
||||
|
Reference in New Issue
Block a user