stacker.news/lib/rss.js

75 lines
2.5 KiB
JavaScript
Raw Normal View History

2023-05-04 18:17:02 +00:00
import getSSRApolloClient from '../api/ssrApollo'
2021-07-23 15:45:09 +00:00
const SITE_URL = 'https://stacker.news'
const SITE_TITLE = 'stacker news'
const SITE_SUBTITLE = 'It\'s like Hacker News, but we pay you Bitcoin.'
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;'
}
})
}
2021-07-23 15:45:09 +00:00
const generateRssItem = (item) => {
2021-08-19 21:19:35 +00:00
const guid = `${SITE_URL}/items/${item.id}`
const link = item.url || guid
let title = item.title
if (item.isJob) {
title = item.title + ' \\ ' + item.company + ' \\ ' + `${item.location || ''}${item.location && item.remote ? ' or ' : ''}${item.remote ? 'Remote' : ''}`
}
const category = item.subName ? `<category domain="${SITE_URL}/~${item.subName}">${item.subName}</category>` : '<category></category>'
2021-07-23 15:45:09 +00:00
return `
<item>
2023-05-04 18:28:50 +00:00
<guid>${guid}</guid>
<title>${escapeXml(title)}</title>
2021-08-24 19:44:00 +00:00
<link>${escapeXml(link)}</link>
2021-08-19 21:19:35 +00:00
<comments>${guid}</comments>
<description><![CDATA[<a href="${guid}">Comments</a>]]></description>
2021-07-23 15:45:09 +00:00
<pubDate>${new Date(item.createdAt).toUTCString()}</pubDate>
${category}
<atom:author><atom:name>${item.user.name}</atom:name></atom:author>
2021-07-23 15:45:09 +00:00
</item>
`
}
function generateRssFeed (items, sub = null) {
2021-07-23 15:45:09 +00:00
const itemsList = items.map(generateRssItem)
2022-01-07 21:29:38 +00:00
return `<?xml version="1.0" encoding="UTF-8" ?>
2021-08-24 19:44:00 +00:00
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
2021-07-23 15:45:09 +00:00
<channel>
<title>${SITE_TITLE}${sub ? ` ~${sub}` : ''}</title>
<link>${SITE_URL}${sub ? `/~${sub}` : ''}</link>
2021-07-23 15:45:09 +00:00
<description>${SITE_SUBTITLE}</description>
<language>en</language>
<lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
2021-08-24 19:44:00 +00:00
<atom:link href="${SITE_URL}/rss" rel="self" type="application/rss+xml" />
2021-07-23 15:45:09 +00:00
${itemsList.join('')}
</channel>
</rss>
`
}
2023-05-04 18:17:02 +00:00
2023-05-04 20:05:07 +00:00
export default function getGetRssServerSideProps (query, variables = null) {
return async function ({ req, res, query: params }) {
2023-05-04 18:17:02 +00:00
const emptyProps = { props: {} } // to avoid server side warnings
const client = await getSSRApolloClient({ req, res })
2023-05-04 18:17:02 +00:00
const { error, data: { items: { items } } } = await client.query({
2023-05-04 20:05:07 +00:00
query, variables: { ...params, ...variables }
2023-05-04 18:17:02 +00:00
})
if (!items || error) return emptyProps
res.setHeader('Content-Type', 'text/xml; charset=utf-8')
res.write(generateRssFeed(items, params?.sub))
2023-05-04 18:17:02 +00:00
res.end()
return emptyProps
}
}