diff --git a/fresh.gen.ts b/fresh.gen.ts index 09f4fec..5067d08 100644 --- a/fresh.gen.ts +++ b/fresh.gen.ts @@ -5,21 +5,22 @@ import * as $0 from "./routes/_404.tsx"; import * as $1 from "./routes/_app.tsx"; import * as $2 from "./routes/_middleware.ts"; -import * as $3 from "./routes/api/images/index.ts"; -import * as $4 from "./routes/api/index.ts"; -import * as $5 from "./routes/api/movies/[name].ts"; -import * as $6 from "./routes/api/movies/enhance/[name].ts"; -import * as $7 from "./routes/api/movies/index.ts"; -import * as $8 from "./routes/api/recipes/[name].ts"; -import * as $9 from "./routes/api/recipes/index.ts"; -import * as $10 from "./routes/api/tmdb/[id].ts"; -import * as $11 from "./routes/api/tmdb/credits/[id].ts"; -import * as $12 from "./routes/api/tmdb/query.ts"; -import * as $13 from "./routes/index.tsx"; -import * as $14 from "./routes/movies/[name].tsx"; -import * as $15 from "./routes/movies/index.tsx"; -import * as $16 from "./routes/recipes/[name].tsx"; -import * as $17 from "./routes/recipes/index.tsx"; +import * as $3 from "./routes/api/cache/index.ts"; +import * as $4 from "./routes/api/images/index.ts"; +import * as $5 from "./routes/api/index.ts"; +import * as $6 from "./routes/api/movies/[name].ts"; +import * as $7 from "./routes/api/movies/enhance/[name].ts"; +import * as $8 from "./routes/api/movies/index.ts"; +import * as $9 from "./routes/api/recipes/[name].ts"; +import * as $10 from "./routes/api/recipes/index.ts"; +import * as $11 from "./routes/api/tmdb/[id].ts"; +import * as $12 from "./routes/api/tmdb/credits/[id].ts"; +import * as $13 from "./routes/api/tmdb/query.ts"; +import * as $14 from "./routes/index.tsx"; +import * as $15 from "./routes/movies/[name].tsx"; +import * as $16 from "./routes/movies/index.tsx"; +import * as $17 from "./routes/recipes/[name].tsx"; +import * as $18 from "./routes/recipes/index.tsx"; import * as $$0 from "./islands/Counter.tsx"; import * as $$1 from "./islands/IngredientsList.tsx"; import * as $$2 from "./islands/KMenu.tsx"; @@ -31,21 +32,22 @@ const manifest = { "./routes/_404.tsx": $0, "./routes/_app.tsx": $1, "./routes/_middleware.ts": $2, - "./routes/api/images/index.ts": $3, - "./routes/api/index.ts": $4, - "./routes/api/movies/[name].ts": $5, - "./routes/api/movies/enhance/[name].ts": $6, - "./routes/api/movies/index.ts": $7, - "./routes/api/recipes/[name].ts": $8, - "./routes/api/recipes/index.ts": $9, - "./routes/api/tmdb/[id].ts": $10, - "./routes/api/tmdb/credits/[id].ts": $11, - "./routes/api/tmdb/query.ts": $12, - "./routes/index.tsx": $13, - "./routes/movies/[name].tsx": $14, - "./routes/movies/index.tsx": $15, - "./routes/recipes/[name].tsx": $16, - "./routes/recipes/index.tsx": $17, + "./routes/api/cache/index.ts": $3, + "./routes/api/images/index.ts": $4, + "./routes/api/index.ts": $5, + "./routes/api/movies/[name].ts": $6, + "./routes/api/movies/enhance/[name].ts": $7, + "./routes/api/movies/index.ts": $8, + "./routes/api/recipes/[name].ts": $9, + "./routes/api/recipes/index.ts": $10, + "./routes/api/tmdb/[id].ts": $11, + "./routes/api/tmdb/credits/[id].ts": $12, + "./routes/api/tmdb/query.ts": $13, + "./routes/index.tsx": $14, + "./routes/movies/[name].tsx": $15, + "./routes/movies/index.tsx": $16, + "./routes/recipes/[name].tsx": $17, + "./routes/recipes/index.tsx": $18, }, islands: { "./islands/Counter.tsx": $$0, diff --git a/islands/KMenu/commands.ts b/islands/KMenu/commands.ts index 54c6c08..45fda8d 100644 --- a/islands/KMenu/commands.ts +++ b/islands/KMenu/commands.ts @@ -14,6 +14,17 @@ export const menus: Record = { }, visible: () => false, }, + { + title: "Clear Cache", + cb: async (state) => { + state.activeState.value = "loading"; + await fetch("/api/cache", { + method: "DELETE", + }); + state.activeState.value = "normal"; + state.visible.value = false; + }, + }, { title: "Add Movie infos", meta: "", @@ -23,10 +34,6 @@ export const menus: Record = { const query = movie.name; - // if (movie.meta.author) { - // query += movie.meta.author; - // } - const response = await fetch( `/api/tmdb/query?q=${encodeURIComponent(query)}`, ); @@ -41,7 +48,7 @@ export const menus: Record = { title: `${m.title} released ${m.release_date}`, cb: async () => { state.activeState.value = "loading"; - await fetch(`/api/movies/${movie.name}/`, { + await fetch(`/api/movies/enhance/${movie.name}/`, { method: "POST", body: JSON.stringify({ tmdbId: m.id }), }); diff --git a/lib/cache/cache.ts b/lib/cache/cache.ts index bbf3f29..c7454ee 100644 --- a/lib/cache/cache.ts +++ b/lib/cache/cache.ts @@ -19,7 +19,7 @@ async function createCache(): Promise | Redis> { conf.password = REDIS_PASS; } const client = await connect(conf); - console.log("Connected to redis"); + console.log("[redis] connected"); return client; } @@ -33,15 +33,26 @@ export async function get(id: string, binary = false) { const cacheHit = await cache.sendCommand("GET", [id], { returnUint8Arrays: true, }) as T; - if (cacheHit) console.log("[cache] HIT ", { id }); - else console.log("[cache] MISS", { id }); return cacheHit; } const cacheHit = await cache.get(id) as T; - if (cacheHit) console.log("[cache] HIT ", { id }); - else console.log("[cache] MISS", { id }); return cacheHit; } +export function clearAll() { + if ("flushall" in cache) { + return cache.flushall(); + } else { + for (const k of cache.keys()) { + cache.delete(k); + } + } +} + +export function expire(id: string, seconds: number) { + if ("expire" in cache) { + return cache.expire(id, seconds); + } +} export async function set(id: string, content: T) { console.log("[cache] storing ", { id }); diff --git a/lib/cache/image.ts b/lib/cache/image.ts index abbb4d1..a695bf1 100644 --- a/lib/cache/image.ts +++ b/lib/cache/image.ts @@ -49,6 +49,8 @@ export async function setImage( const pointerId = await hash(cacheKey); await cache.set(pointerId, clone); + cache.expire(pointerId, 60 * 10); + cache.expire(cacheKey, 60 * 10); await cache.set( cacheKey, diff --git a/lib/documents.ts b/lib/documents.ts index a859dcf..7132b28 100644 --- a/lib/documents.ts +++ b/lib/documents.ts @@ -1,5 +1,5 @@ -import { unified } from "https://esm.sh/unified"; -import remarkParse from "https://esm.sh/remark-parse"; +import { unified } from "https://esm.sh/unified@10.1.2"; +import remarkParse from "https://esm.sh/remark-parse@10.0.2"; import remarkStringify from "https://esm.sh/remark-stringify@10.0.3"; import remarkFrontmatter, { Root, diff --git a/routes/api/cache/index.ts b/routes/api/cache/index.ts new file mode 100644 index 0000000..b12f350 --- /dev/null +++ b/routes/api/cache/index.ts @@ -0,0 +1,9 @@ +import { Handlers } from "$fresh/server.ts"; +import * as cache from "@lib/cache/cache.ts"; + +export const handler: Handlers = { + async DELETE() { + await cache.clearAll(); + return new Response("OK"); + }, +}; diff --git a/routes/api/images/index.ts b/routes/api/images/index.ts index b6e85d4..3a7b3ea 100644 --- a/routes/api/images/index.ts +++ b/routes/api/images/index.ts @@ -126,14 +126,20 @@ const GET = async ( console.log("[api/image] resized image", { imageUrl }); - cache.setImage(modifiedImage, { + await cache.setImage(modifiedImage, { url: imageUrl, width: params.width, height: params.height, mediaType: remoteImage.mediaType, }); - return new Response(modifiedImage, { + const cachedImage = await cache.getImage({ + url: imageUrl, + width: params.width, + height: params.height, + }); + + return new Response(cachedImage.data || modifiedImage, { headers: { "Content-Type": remoteImage.mediaType, }, diff --git a/routes/api/movies/enhance/[name].ts b/routes/api/movies/enhance/[name].ts index 51225e3..49157fb 100644 --- a/routes/api/movies/enhance/[name].ts +++ b/routes/api/movies/enhance/[name].ts @@ -18,40 +18,37 @@ async function updateMovieMetadata( ) { const docId = `Media/movies/${name}.md`; - const currentDoc = await getDocument(docId); + let currentDoc = await getDocument(docId); if (!currentDoc) return; + if (!currentDoc.startsWith("---\n---\n")) { + currentDoc = `---\n---\n\n${currentDoc}`; + } + 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"]; + const value = parse(frontmatter) as Movie["meta"]; - if (metadata.author && !value.author) { - value.author = metadata.author; - } + const newValue = { + ...metadata, + date: formatDate(metadata.date), + ...value, + }; - if (metadata.image && !value.image) { - value.image = metadata.image; - } - - if (metadata.date && !value.date) { - value.date = formatDate(metadata.date); - } - frontmatterNode.value = stringify(value); - } + frontmatterNode.value = stringify(newValue); return root; }); - const response = await createDocument(docId, newDoc); + console.log({ newDoc }); - return response; + return createDocument(docId, newDoc); } -const GET = async ( +const POST = async ( _req: Request, _ctx: HandlerContext, ): Promise => { @@ -99,5 +96,5 @@ const GET = async ( }; export const handler: Handlers = { - GET, + POST, }; diff --git a/routes/api/readable/index.ts b/routes/api/readable/index.ts new file mode 100644 index 0000000..e69de29