import { DOMParser, } from "https://deno.land/x/deno_dom@v0.1.38/deno-dom-wasm.ts"; // maybe a bit high, maybe a bit low const MAX_AGE_MS = 10 * 60 * 1000; // > "light-dark(oklab(000, 000, 000), oklab(255, 255, 255))".length // 54 const MAX_COLOR_LEN = 64; const colors: Record< string, { color: string | undefined; last_checked: Date } > = {}; const dom_parser = new DOMParser(); async function get_name_color(name: string): Promise { console.log(`fetching ${name}...`); const resp = await fetch(`https://cohost.org/${name}`); if (!resp.ok) { console.log(`fetching https://cohost.org/${name} failed!`); return; } const body = await resp.text(); const dom = dom_parser.parseFromString(body, "text/html"); if (!dom) { console.log(`parsing https://cohost.org/${name} to the dom failed!`); return; } for (const p of dom.querySelectorAll("p")) { const text = p.textContent; if (text.startsWith("name-color: ")) { return text.split("name-color: ")[1].slice(0, MAX_COLOR_LEN); } } } async function update_name_color(name: string) { const now = new Date(); if ( colors[name] && now.getTime() - colors[name].last_checked.getTime() <= MAX_AGE_MS ) { return; } const color = await get_name_color(name); colors[name] = { color, last_checked: now }; } // TODO: ONE BIG REQUEST/RESPONSE DUHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHh Deno.serve({ port: 61266 }, async (req) => { const url = new URL(req.url); const names = url.searchParams.getAll("name").filter((name) => !name.match(/\/\?/) ); await Promise.all(names.map(update_name_color)); return Response.json(colors); });