forked from rwalshe/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
createRSSFeeds.mjs
147 lines (127 loc) · 5.48 KB
/
createRSSFeeds.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import fs from "fs-extra";
import xml from "xml";
import { JSDOM } from 'jsdom';
import MarkdownIt from 'markdown-it'
const md = new MarkdownIt();
// Get all the markdown files for release notes
let astro = await fs.readFile('./astro/release-notes.md', 'utf8');
let astroRuntime = await fs.readFile('./astro/runtime-release-notes.md', 'utf8');
let astroCLI = await fs.readFile('./astro/cli/release-notes.md', 'utf8');
let software = await fs.readFile('./software/release-notes.md', 'utf8');
let softwareRuntime = await fs.readFile('./astro/runtime-release-notes.md', 'utf8');
let currentDate = new Date();
// function to get all elements between two elements
function nextUntil(elem, selector, filter) {
let siblings = [];
elem = elem.nextElementSibling;
while (elem) {
if (elem.matches(selector)) break;
if (filter && !elem.matches(filter)) {
elem = elem.nextElementSibling;
continue;
}
siblings.push(elem.outerHTML);
elem = elem.nextElementSibling;
}
return siblings.join('').toString();
};
// this function takes a markdown file imported above, renders to markdown,
// then parses that markdown for the "posts" for our release notes
function getPosts(content) {
// take md file and use JSDOM to get an HTML fragment we can work with
const contentRender = JSDOM.fragment(md.render(content));
// get all of the h2s which are also our post titles
const H2s = [...contentRender.querySelectorAll("h2")].slice(1);
// empty array to stick our posts in
let posts = [];
// for each h2 create post with title, slug,
// and get all the content between this h2 until the next h2
H2s.map((h2) => {
const postContent = nextUntil(h2, 'h2');
const postDate = postContent.match(/(?<=Release date: ).*?(?=<.)/sg) || h2.textContent;
const post = {
"title": h2.textContent,
"slug": h2.textContent.toLowerCase().replace(/ /g, '-').replace(',', ''),
"content": postContent,
"pubDate": postDate
};
posts.push(post);
})
return posts;
}
async function createRssFeed(feedTitle, feedDescription, feedPageURL, content) {
function buildFeed(posts, pageURL) {
const feedItems = [];
posts.map((post) => {
const pubDate = new Date(post.pubDate);
const item = {
item: [
{ title: post.title },
{
link: `${pageURL}#${post.slug.replace(/\./g, '')}`
},
{
pubDate: pubDate.toUTCString()
},
{
guid: `${pageURL}#${post.slug.replace(/\./g, '')}`
},
{
description: {
_cdata: post.content,
},
},
]
};
feedItems.push(item);
})
return feedItems;
}
const posts = getPosts(content);
const websiteURL = "https://docs.astronomer.io/";
const feedSlug = feedTitle.replace(/ /g, "-",).toLowerCase();
const feedRSSLink = websiteURL + feedSlug + '.xml';
console.log(`📡 Creating ${feedTitle} RSS feed`);
const feedObject = {
rss: [
{
_attr: {
version: "2.0",
"xmlns:atom": "http://www.w3.org/2005/Atom",
},
},
{
channel: [
{
"atom:link": {
_attr: {
href: feedRSSLink,
rel: "self",
type: "application/rss+xml",
},
},
},
{
title: feedTitle,
},
{
link: feedPageURL,
},
{
pubDate: currentDate.toUTCString()
},
{ description: feedDescription },
{ language: "en-US" },
...buildFeed(posts, feedPageURL),
],
},
],
};
const feed = '<?xml version="1.0" encoding="UTF-8"?>' + xml(feedObject);
await fs.writeFile(`./static/${feedTitle.toLowerCase().replace(/ /g, '-').replace(',', '')}.xml`, feed, "utf8");
};
createRssFeed("Astro Release Notes", "Astronomer is committed to continuous delivery of both features and bug fixes to Astro. To keep your team up to date on what's new, this document will provide a regular summary of all changes released to Astro.", "https://docs.astronomer.io/astro/release-notes", astro);
createRssFeed("Astro Runtime Release Notes", "Astronomer is committed to continuous delivery of both features and bug fixes to Astro. To keep your team up to date on what's new, this document will provide a regular summary of all changes released to Astro Runtime.", "https://docs.astronomer.io/astro/runtime-release-notes", astroRuntime);
createRssFeed("Astro CLI Release Notes", "Astronomer is committed to continuous delivery of both features and bug fixes to Astro. To keep your team up to date on what's new, this document will provide a regular summary of all changes released to Astro CLI.", "https://docs.astronomer.io/astro/cli/release-notes", astroCLI);
createRssFeed("Astro Software Release Notes", "Astronomer is committed to continuous delivery of both features and bug fixes to Astro. To keep your team up to date on what's new, this document will provide a regular summary of all changes released to Astro Software.", "https://docs.astronomer.io/software/release-notes", software);
createRssFeed("Astro Software Runtime Release Notes", "Astronomer is committed to continuous delivery of both features and bug fixes to Astro. To keep your team up to date on what's new, this document will provide a regular summary of all changes released to Astro Software.", "https://docs.astronomer.io/software/runtime-release-notes", softwareRuntime);