import fs from "fs"; import xml from "xml"; import crypto from "crypto"; class Shooting { date; location; state; victims_dead; victims_injured; victims_total; description; source_urls; /** * @param {string} input */ constructor(input) { const lines = input.trim().split("\n"); this.date = lines[0].replace(/(^\|+)|(\{\{[\w\s]*\|)|(\}\})|((-|–)[0-9]+)/g, ""); this.location = lines[1].replace(/(^\|+)|(\[\[(.*\|)?)|(\]\].*)/g, ""); this.state = lines[2].replace(/(^\|+)|(\[\[(.*\|)?)|(\]\])/g, ""); this.victims_dead = Number(lines[3].replace(/^\|+/, "")) || 0; this.victims_injured = Number(lines[4].replace(/^\|+/, "")) || 0; this.victims_total = Number(lines[5].replace(/(^\|+)|(''')/g, "")) || 0; this.description = lines[6] .replace(/^\|+/, "") .replace(/(\[\[(.*\|)?)|(\]\])/g, "") .replace(/\.*\<\/ref\>/g, "") .replace(/\{\{.*\}\}/g, "") .replace(/\}\}.*/g, "") .trim(); this.source_urls = /\|url=^[\s|]*/g .exec(lines[6]) ?.map((match) => match.replace("|url=", "")); } } const input = fs.readFileSync("/tmp/feed_input.txt").toString("utf8"); const text = input .substring( input.indexOf("== List =="), input.indexOf("== Monthly statistics ==") - 1 ) .trim(); const segments = text .split(/\n\|-.*\n/) .slice(2) .filter((segment) => segment.length); const shootings = []; for (const segment of segments) { const shooting = new Shooting(segment); shootings.push(shooting); } // fs.writeFileSync("./shootings.json", JSON.stringify(shootings, null, 4)); const feed = { rss: [ { _attr: { version: "2.0", "xmlns:atom": "http://www.w3.org/2005/Atom", }, }, { channel: [ { "atom:link": { _attr: { href: "https://futacockinside.me/files/mass_shootings.rss", rel: "self", type: "application/rss+xml", }, }, }, { title: "Mass shootings in America (2023)", }, { link: "https://en.m.wikipedia.org/w/index.php?title=List_of_mass_shootings_in_the_United_States_in_2023", }, { description: "Feed of mass shootings in America, updated automatically from Wikipedia", }, { language: "en-US" }, ...shootings.map((shooting) => { const guid = crypto .createHash("sha256") .update( `${shooting.date} ${shooting.location} ${shooting.state} ${shooting.victims_dead}/${shooting.victims_injured}/${shooting.victims_total}` ) .digest("hex"); return { item: [ { title: `${shooting.date} - ${shooting.location}, ${shooting.state}`, }, { pubDate: new Date(`${shooting.date} 2023`).toUTCString() }, { guid: guid }, { link: "https://en.m.wikipedia.org/w/index.php?title=List_of_mass_shootings_in_the_United_States_in_2023" }, { description: `${shooting.victims_dead} dead, ${ shooting.victims_injured } injured.\n\n${shooting.description}\n${ shooting.source_urls?.join(" ") || "" }`.trim(), }, ], }; }), ], }, ], }; fs.writeFileSync( "/tmp/feed_output.rss", xml(feed, { indent: " " }) );