Skip to content

Commit

Permalink
set up rss
Browse files Browse the repository at this point in the history
  • Loading branch information
EndangeredMassa committed Jan 16, 2024
1 parent 927abcd commit bd23596
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 35 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

## To Do

- add RSS (so that https://massalabs.com/feed.xml still works)
- 404 protection: https://remysharp.com/2023/09/26/no-more-404
- add search: https://pagefind.app/
- add "callout" component
40 changes: 28 additions & 12 deletions app/styles/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,26 +56,51 @@ h1, h2, h3 {
margin-bottom: 0;
}

h1 {
font-size: 2.6rem;
color: var(--accent);
}

h2 {
font-size: 2.1rem;
color: var(--accent-sub2);
}

h3 {
font-size: 1.6rem;
color: var(--accent-sub3);
}

h1:has(+ h2), h2:has(+ h3) {
margin-bottom: 0;
}

h1, h1 a, h1 a:visited {
h1 a, h1 a:visited {
color: var(--accent);
/* text-decoration: wavy underline; */
/* text-decoration-color: #939191; */
}

h2, h2 a, h2 a:visited {
h2 a, h2 a:visited {
color: var(--accent-sub2);
/* text-decoration: wavy underline; */
/* text-decoration-color: #939191; */
}

h3, h3 a, h3 a:visited {
h3 a, h3 a:visited {
color: var(--accent-sub3);
/* text-decoration: wavy underline; */
/* text-decoration-color: #939191; */
}

a, a:visited {
color:var(--accent);
}

a:hover {
text-decoration: underline dotted;
}

header>nav {
padding:0;
}
Expand Down Expand Up @@ -133,10 +158,6 @@ footer p a[href^="https://"]:after,
padding-right: 1em; /* sizing */
}

.blog-item h2 a {
font-size: 1.6rem;
}

.blog-item h1, .blog-item h2, .blog-item h3 {
margin-bottom: 0;
margin-top: 0.7em;
Expand All @@ -160,11 +181,6 @@ footer p a[href^="https://"]:after,
display: inline-block;
}

.post-link {
font-size: 1.6rem;
font-weight: bold;
}

.meta {
color: var(--text-light);
font-size: 1rem;
Expand Down
88 changes: 88 additions & 0 deletions lib/generate-rss.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
let fs = require('node:fs/promises');
let path = require('node:path');
let getArticles = require('./get-articles');

let siteData = {
title: "Massa Labs",
description: "Sean Massa's personal site where they discuss tech, organizations, ethics, and games.",
url: 'https://massalabs.com'
};

// Source: https://stackoverflow.com/a/27979933
function escapeXml(unsafe) {
return unsafe.replace(/[<>&'"]/g, function (c) {
switch (c) {
case '<': return '&lt;';
case '>': return '&gt;';
case '&': return '&amp;';
case '\'': return '&apos;';
case '"': return '&quot;';
}
});
}

function toUtcDate(str) {
return new Date(Date.parse(str)).toUTCString();;
}

function generateTags(article) {
// TODO: implement tags
// <category>{{ tag | xml_escape }}</category>
return '';
}

function generateRssItem(article) {
let fullUrl = `https://massalabs.com/blog/${article.slug}`;
let tags = generateTags(article);

return `
<item>
<title>${escapeXml(article.title)}</title>
<description>${escapeXml(article.description)}</description>
<pubDate>${toUtcDate(article.date)}</pubDate>
<link>${fullUrl}</link>
<guid isPermaLink="true">${fullUrl}</guid>
${tags}
</item>
`.trim();
}

function generateRss(articles) {
let mostRecentPublishedArticle = articles.find((a) => a.published);
let mostRecentPublishedDate = toUtcDate(mostRecentPublishedArticle.date);
let generationDate = (new Date()).toUTCString();
let posts = articles.map(a => generateRssItem(a)).join('\n');

return `
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>${siteData.title}</title>
<description>${siteData.description}</description>
<link>${siteData.url}</link>
<atom:link href="${siteData.url}/feed.xml" rel="self" type="application/rss+xml" />
<pubDate>${generationDate}</pubDate>
<lastBuildDate>${mostRecentPublishedDate}</lastBuildDate>
${posts}
</channel>
</rss>
`.trim();
}

async function writeRss() {
let articles = getArticles();
let rssString = generateRss(articles);

let pathToRss = path.join(__dirname, '../dist/feed.xml');
await fs.writeFile(pathToRss, rssString);
}

writeRss().then(() => {
console.log('Generated rss!')
}).catch((error) => {
console.error('Failed to generate rss!');
console.error(error);
});



24 changes: 24 additions & 0 deletions lib/get-articles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
let fs = require('fs');
let { join } = require('path');

function tryParseJSON(jsonText, originalFilePath) {
try {
return JSON.parse(jsonText);
} catch (error) {
console.log(`JSON Parse Error of "${originalFilePath}": ${error.message}\nText:\n${jsonText}`);
}
}

module.exports = function getArticles() {
/*
We have to convert the module format into json because no other mechanism for
share this data worked between ember build (node, commonjs) and the
project code (browser, module).
*/
let articlePath = join(__dirname, '/../app/article-data.js');
let articleData = fs.readFileSync(articlePath).toString();
let trimmedArticleData = articleData
.replace('let articles =', '')
.replace('export default articles;', '');
return tryParseJSON(trimmedArticleData, articlePath);
}
23 changes: 2 additions & 21 deletions lib/scan-dir.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,7 @@
let fs = require('fs');
let { join } = require('path');

function tryParseJSON(jsonText, originalFilePath) {
try {
return JSON.parse(jsonText);
} catch (error) {
console.log(`JSON Parse Error of "${originalFilePath}": ${error.message}\nText:\n${jsonText}`);
}
}
let getArticles = require('./get-articles');

module.exports = async function ({ distDir, visit }) {
/*
We haev to convert the module format into json because no other mechanism for
share this data worked between ember build (node, commonjs) and the
project code (browser, module).
*/
let articlePath = join(__dirname, '/../app/article-data.js');
let articleData = fs.readFileSync(articlePath).toString();
let trimmedArticleData = articleData
.replace('let articles =', '')
.replace('export default articles;', '');
let articles = tryParseJSON(trimmedArticleData, articlePath);
let articles = getArticles();
let articleUrls = articles.map((a) => {
return '/blog/' + a.slug.replace(/\./g, '/');
});
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"test": "tests"
},
"scripts": {
"build": "ember build --environment=production",
"gen-rss": "node lib/generate-rss.js",
"build": "ember build --environment=production && npm run gen-rss",
"start": "ember serve",
"test": "ember test"
},
Expand Down

0 comments on commit bd23596

Please sign in to comment.