/** * Copyright (c) 2025 miwa * SPDX-License-Identifier: AGPL-3.0-or-later */ #!/usr/bin/env -S deno run --allow-net --allow-write /** * Copyright (c) 2025 miwa * SPDX-License-Identifier: AGPL-3.0-or-later */ import { getPosts, type Report } from "../utils/atproto.ts"; function escapeXml(unsafe: string): string { return unsafe .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } function stripHtml(html: string): string { return html .replace(/<[^>]+>/g, " ") .replace(/\s+/g, " ") .trim(); } function generateRSSItem(report: Report): string { const link = `https://acpi.at/reports/${report.rkey}`; const description = report.excerpt || stripHtml(report.content).substring(0, 200); return [ ` `, ` ${escapeXml(report.title)}`, ` ${link}`, ` ${link}`, ` ${report.date.toUTCString()}`, ` ${escapeXml(description)}`, ` `, ].join("\n"); } async function generateRSS() { const reports = await getPosts(); const items = reports.map(generateRSSItem); const xml = [ ``, ``, ` `, ` $reports - acpi.at`, ` https://acpi.at/reports`, ` thoughts, ramblings, and occasional coherence`, items.join("\n"), ` `, ``, ].join("\n"); await Deno.writeTextFile("./static/rss.xml", xml); console.log("done"); } if (import.meta.main) { await generateRSS(); }