rss feed ?????

This commit is contained in:
MeowcaTheoRange 2024-08-31 00:54:10 -05:00
parent ab2c9d8529
commit 77ff2b43c1
8 changed files with 115 additions and 4 deletions

View file

@ -5,6 +5,7 @@ import SQLite from 'better-sqlite3';
import { Kysely, SqliteDialect } from 'kysely'; import { Kysely, SqliteDialect } from 'kysely';
import { nanoid } from "nanoid"; import { nanoid } from "nanoid";
import { JSDOM } from "jsdom"; import { JSDOM } from "jsdom";
import Parser from "rss-parser";
dotenvConfig(); dotenvConfig();
@ -18,6 +19,8 @@ const db = new Kysely({
}) })
}); });
const rssParser = new Parser();
rawDB.exec(`CREATE TABLE IF NOT EXISTS blurbs( 'id' TEXT, 'site' TEXT, 'blurb' TEXT, 'verified' INTEGER, 'time' INTEGER );`); rawDB.exec(`CREATE TABLE IF NOT EXISTS blurbs( 'id' TEXT, 'site' TEXT, 'blurb' TEXT, 'verified' INTEGER, 'time' INTEGER );`);
rawDB.exec(`CREATE TABLE IF NOT EXISTS blacklist( 'domain' TEXT );`); rawDB.exec(`CREATE TABLE IF NOT EXISTS blacklist( 'domain' TEXT );`);
@ -68,6 +71,18 @@ app.get('/about', async (req, res) => {
}); });
}); });
app.get('/updates', async (req, res) => {
const rssXML = await fetch("https://cdn.abtmtr.link/site_content/rss.xml")
.catch(() => res.status(500).send())
.then((res) => res.text());
const rssParsed = await rssParser.parseString(rssXML);
res.render('updates', {
rss: rssParsed
});
});
app.get('/sites', async (req, res) => { app.get('/sites', async (req, res) => {
const buttonsJson = await fetch("https://cdn.abtmtr.link/site_content/buttons.json") const buttonsJson = await fetch("https://cdn.abtmtr.link/site_content/buttons.json")
.catch(() => res.status(500).send()) .catch(() => res.status(500).send())
@ -211,6 +226,14 @@ app.get("/favicon.ico", (req, res) => {
res.redirect("https://cdn.abtmtr.link/site_content/favicon.ico") res.redirect("https://cdn.abtmtr.link/site_content/favicon.ico")
}) })
app.get(["/rss", "/rss.xml"], (req, res) => {
res.redirect("https://cdn.abtmtr.link/site_content/rss.xml")
})
app.all('*', (req, res) => {
res.status(404).render('404');
})
app.listen(process.env.PORT, () => { app.listen(process.env.PORT, () => {
const url = new URL("http://localhost/"); const url = new URL("http://localhost/");
url.port = process.env.PORT; url.port = process.env.PORT;

50
package-lock.json generated
View file

@ -16,7 +16,8 @@
"jsdom": "^25.0.0", "jsdom": "^25.0.0",
"kysely": "^0.27.4", "kysely": "^0.27.4",
"nanoid": "^5.0.7", "nanoid": "^5.0.7",
"pg": "^8.12.0" "pg": "^8.12.0",
"rss-parser": "^3.13.0"
}, },
"devDependencies": { "devDependencies": {
"nodemon": "^3.1.4" "nodemon": "^3.1.4"
@ -1805,6 +1806,25 @@
"integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/rss-parser": {
"version": "3.13.0",
"resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.13.0.tgz",
"integrity": "sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==",
"license": "MIT",
"dependencies": {
"entities": "^2.0.3",
"xml2js": "^0.5.0"
}
},
"node_modules/rss-parser/node_modules/entities": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
"license": "BSD-2-Clause",
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/safe-buffer": { "node_modules/safe-buffer": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@ -1831,6 +1851,12 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/sax": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
"license": "ISC"
},
"node_modules/saxes": { "node_modules/saxes": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
@ -2327,6 +2353,28 @@
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/xml2js": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
"integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
"license": "MIT",
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"license": "MIT",
"engines": {
"node": ">=4.0"
}
},
"node_modules/xmlchars": { "node_modules/xmlchars": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",

View file

@ -25,7 +25,8 @@
"jsdom": "^25.0.0", "jsdom": "^25.0.0",
"kysely": "^0.27.4", "kysely": "^0.27.4",
"nanoid": "^5.0.7", "nanoid": "^5.0.7",
"pg": "^8.12.0" "pg": "^8.12.0",
"rss-parser": "^3.13.0"
}, },
"devDependencies": { "devDependencies": {
"nodemon": "^3.1.4" "nodemon": "^3.1.4"

View file

@ -6,4 +6,6 @@
<link rel="stylesheet" href="/assets/style.css" /> <link rel="stylesheet" href="/assets/style.css" />
<link rel="me" href="https://abtmtr.link/about"> <link rel="me" href="https://abtmtr.link/about">
<link rel="me" href="https://abtmtr.link/blurbs/#Hx7CuB4_zIWMAsOZlyyqsUm2upXEEYEl"> <link rel="me" href="https://abtmtr.link/blurbs/#Hx7CuB4_zIWMAsOZlyyqsUm2upXEEYEl">
<link rel="alternate" type="application/rss+xml" href="http://abtmtr.link/rss.xml" title="RSS Feed">
<link rel="alternate" type="application/rss+xml" href="http://abtmtr.link/rss" title="RSS Feed">
</head> </head>

12
views/pages/404.ejs Normal file
View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<%- include("../components/page-head.ejs") %>
<body>
<main>
<h1>404 Not Found</h1>
<p>it seems the resource you're looking for doesn't exist.<br />try again later?</p>
<p>&lt;&lt; <a href="/">go back home</a></p>
</main>
<%- include("../components/footer.ejs") %>
</body>
</html>

View file

@ -11,6 +11,10 @@
<h3><a href="/blurbs/">blurbs</a></h3> <h3><a href="/blurbs/">blurbs</a></h3>
<p class="nomargin">what are other sites saying about abtmtr.link?</p> <p class="nomargin">what are other sites saying about abtmtr.link?</p>
</li> </li>
<li>
<h3><a href="/updates/">updates</a></h3>
<p class="nomargin">what's going on with abtmtr.link?</p>
</li>
<li> <li>
<h3><a href="/servers/">servers</a></h3> <h3><a href="/servers/">servers</a></h3>
<p class="nomargin">about the services on abtmtr.link and the machines that serve them.</p> <p class="nomargin">about the services on abtmtr.link and the machines that serve them.</p>

View file

@ -5,7 +5,7 @@
<main> <main>
<h1>sites</h1> <h1>sites</h1>
<p>a large collection of 88x31s.</p> <p>a large collection of 88x31s.</p>
<h2>friends (<%= b.length %>)</h2> <h2>friends of abtmtr.link (<%= b.length %>)</h2>
<div> <div>
<% b.forEach((button) => { %> <% b.forEach((button) => { %>
<% if (button.img != null) { %> <% if (button.img != null) { %>
@ -15,7 +15,7 @@
<% } %> <% } %>
<% }) %> <% }) %>
</div> </div>
<h2>following (<%= f.length %>)</h2> <h2>sites of interest (<%= f.length %>)</h2>
<div> <div>
<% f.forEach((button) => { %> <% f.forEach((button) => { %>
<% if (button.img != null) { %> <% if (button.img != null) { %>

21
views/pages/updates.ejs Normal file
View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<%- include("../components/page-head.ejs") %>
<body>
<main>
<h1>updates</h1>
<p><%= rss.description %><br />subscribe to the <a href="/rss">rss feed</a>!</p>
<h2>items</h2>
<ul>
<% rss.items.forEach((item) => { %>
<li>
<h3><a href="<%= item.link %>"><%= item.title %></a></h3>
<p class="nomargin" style="opacity: 0.5">by <%= item.author %> / <%= new Date(item.isoDate).toLocaleString(rss.language) %> Central Time</p>
<p style="white-space: pre-line;"><%= item.content.trim() %></p>
</li>
<% }) %>
</ul>
</main>
<%- include("../components/footer.ejs") %>
</body>
</html>