From 9e8a9089f6c21fea04a7f0132d315d699d67dba3 Mon Sep 17 00:00:00 2001 From: mehbark Date: Sun, 24 Mar 2024 20:34:58 -0400 Subject: [PATCH] serverside support for prngsentences --- html/derivative.tsx | 0 html/meltings.tsx | 1 + html/prngsentences.html | 58 ++++++++++++++++++++++++++++ serverside/prngnouns.ts | 85 +++++++++++++++++++---------------------- 4 files changed, 99 insertions(+), 45 deletions(-) create mode 100644 html/derivative.tsx create mode 100644 html/prngsentences.html diff --git a/html/derivative.tsx b/html/derivative.tsx new file mode 100644 index 0000000..e69de29 diff --git a/html/meltings.tsx b/html/meltings.tsx index aa1aff7..1fec72c 100644 --- a/html/meltings.tsx +++ b/html/meltings.tsx @@ -1,2 +1,3 @@ // like crumbling but more complex and maybe cooler (ha) looking // nah. too derivative +// that gives me an idea diff --git a/html/prngsentences.html b/html/prngsentences.html new file mode 100644 index 0000000..ced1f01 --- /dev/null +++ b/html/prngsentences.html @@ -0,0 +1,58 @@ + + + + + + PRNG sentences + + + + + + + + + + + + + + + + + + + + diff --git a/serverside/prngnouns.ts b/serverside/prngnouns.ts index 3ed4411..eacddd8 100644 --- a/serverside/prngnouns.ts +++ b/serverside/prngnouns.ts @@ -8,16 +8,17 @@ const font = await fetch("https://static.pyrope.net/courier-std-bold.otf") .then((r) => r.arrayBuffer()) .then((b) => new Uint8Array(b)); -// deciding now: pronouns (e.g. he/him) can be at most 32 chars - -let images: Map = new Map(); - -function make_image(s: string): Image { - console.log(`MAKING AN IMAGE FOR '${s}' (EXPENSIVE!)`); +function make_image( + { text, color = 0, outline_color = 0xff_ff_ff_ff }: { + text: string; + color?: number; + outline_color?: number; + }, +): Image { let image = Image.renderText( font, 64, - s, + text, 0, new TextLayout({ verticalAlign: "center", horizontalAlign: "middle" }), ); @@ -25,8 +26,8 @@ function make_image(s: string): Image { const outline = Image.renderText( font, 64, - s, - 0xff_ff_ff_ff, + text, + outline_color, new TextLayout({ verticalAlign: "center", horizontalAlign: "middle" }), ); @@ -35,52 +36,30 @@ function make_image(s: string): Image { image = image.composite(outline, hshift, vshift); } } - const text = Image.renderText( + const text_img = Image.renderText( font, 64, - s, - 0x00_00_00_ff, + text, + color, new TextLayout({ verticalAlign: "center", horizontalAlign: "middle" }), ); - const final = image.composite(text); + const final = image.composite(text_img); return final.crop(0, 0, final.width, final.height - 22); } -async function get_pronoun_image(prn: string): Promise { - if (images.has(prn)) { - const entry = images.get(prn)!; - entry.fetched++; - return entry.image; - } - const image = await make_image(prn).encode(); - images.set(prn, { image, fetched: 1 }); - return image; -} - // the whole cache thing def sketches me out, but people probably won't be *that* malicious const MAX_PRN_LENGTH = 128; -const MAX_PRN_CACHE = 64; // shouldn't really be a problem const MAX_PRN_CHOICES = 256; -function clean_up() { - if (images.size <= MAX_PRN_CACHE) { - console.log( - `not cleaning up, we only have ${images.size} cached which is less than ${MAX_PRN_CACHE}`, - ); - return; - } - - // reverse order! - const entries = [...images.entries()].toSorted(([_a, a], [_b, b]) => - b.fetched - a.fetched - ); - - console.log("before clean up:", images); - images = new Map(entries.slice(0, MAX_PRN_CACHE)); - console.log("after clean up:", images); -} +// let's stick to hex even though BigInt() can handle prefixes (prefices?) +const hex_string_to_color = (s: string): number | undefined => { + const parsed = parseInt(s, 16); + if (Number.isNaN(parsed)) return; + // JANK! SORRY + return Number((BigInt(parsed) << 8n) | 0xffn); +}; const image_response = (data: Uint8Array): Response => new Response(data, { @@ -88,7 +67,9 @@ const image_response = (data: Uint8Array): Response => }); Deno.serve({ port: 61265 }, async (req) => { - const prns = (new URL(req.url)).searchParams.getAll("p"); + const url = new URL(req.url); + const params = url.searchParams; + const prns = params.getAll("p"); if (prns.some((p) => p.length > MAX_PRN_LENGTH)) { return new Response(`MAX_PRN_LENGTH = ${MAX_PRN_LENGTH}`, { status: 413 }); @@ -103,7 +84,21 @@ Deno.serve({ port: 61265 }, async (req) => { const prn = prns[Math.floor(Math.random() * prns.length)] ?? "NONE, APPARENTLY"; - const resp = image_response(await get_pronoun_image(prn)); - clean_up(); + const fg_str = params.get("fg"); + const outline_str = params.get("outline"); + + const sentence_id = params.get("sentence_id"); + const sentence_index = params.get("sentence_index"); + + console.log( + `${sentence_id}#${sentence_index}: chose ${prn} from ${prns}. ${fg_str} on ${outline_str}`, + ); + + const fg = hex_string_to_color(fg_str ?? "0"); + const outline = hex_string_to_color(outline_str ?? "ffffff"); + + const resp = image_response( + await make_image({ text: prn, color: fg, outline_color: outline }).encode(), + ); return resp; });