Files
2023-08-01 13:49:46 +02:00

79 lines
2.9 KiB
JavaScript

const fs = require('fs')
const path = require('path')
const Feed = require('feed')
const zopfli = require('node-zopfli')
const brotli = require('iltorb')
const chalk = require('chalk')
const log = console.log;
const types = {
rss: 'feed.xml',
atom: 'feed.atom',
json: 'feed.json',
}
/* Generate base feed instance */
const generate_base_feed = config => {
const feed = new Feed(config.rss)
config.rss.categories.forEach(cat => feed.addCategory(cat))
return feed
}
/* Generate feed items from ghost blog posts */
const generate_feed_items = (config, contents, feed) => {
contents.content.ghost.posts.forEach(post => {
if (post.visibility === 'public') {
feed.addItem({
title: post.title,
description: post.meta_description,
content: post.html,
link: path.join(config.rss.id, '/articles/', post.slug + '.html'),
id: post.uuid,
date: new Date(post.published_at),
author: [config.rss.author]
})
}
})
return feed
}
// Write plain feed file to dist
const write_feed_file = (config, type, feed) => new Promise((resolve, reject) => fs.writeFile(path.join(config.basepath, config.dist_path, types[type]), feed, err => err ? reject(err) : resolve(feed)))
// Create brotli & zopfli compressed versions and write them to dist
const compress_feed_file = (config, type, feed) => {
return new Promise(async (resolve, reject) => {
const destination = path.join(config.basepath, config.dist_path, types[type])
let write_promises = []
try {
// write zopfli compressed file
write_promises.push(new Promise((res, rej) => zopfli.gzip(new Buffer(feed), (err, output) => fs.writeFile(destination + '.gz', output, err => err ? rej(err) : res()))))
// write brotli compressed file
write_promises.push(new Promise((res, rej) => brotli.compress(new Buffer(feed), (err, output) => fs.writeFile(destination + '.br', output, err => err ? rej(err) : res()))))
await Promise.all(write_promises)
resolve()
} catch(err) {
reject(err)
}
})
}
module.exports = (config, results) => {
return new Promise(async (resolve, reject) => {
try {
log(' ', chalk.green('>>'), 'Building RSS/Atom/JSON feed')
let feed = generate_base_feed(config)
feed = generate_feed_items(config, results, feed)
log(' ', chalk.green('>>'), 'Writing feed files')
const rss = await write_feed_file(config, 'rss', feed.rss2())
const atom = await write_feed_file(config, 'atom', feed.atom1())
const json = await write_feed_file(config, 'json', feed.json1())
log(' ', chalk.green('>>'), 'Compressing feed files')
await compress_feed_file(config, 'rss', rss)
await compress_feed_file(config, 'atom', atom)
await compress_feed_file(config, 'json', json)
resolve({rss, atom, json})
} catch (err) {
reject(err)
}
})
}