129 lines
3.5 KiB
JavaScript
129 lines
3.5 KiB
JavaScript
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\>.*\<\/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:
|
||
"Automatically updating 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: " " })
|
||
);
|