-
Notifications
You must be signed in to change notification settings - Fork 552
/
Copy pathbuild-rss.ts
105 lines (88 loc) · 2.84 KB
/
build-rss.ts
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
import { resolve } from 'path'
import { writeFile } from './fs-helpers'
import { renderToStaticMarkup } from 'react-dom/server'
import { textBlock } from './notion/renderers'
import getBlogIndex from './notion/getBlogIndex'
import getNotionUsers from './notion/getNotionUsers'
import { postIsPublished, getBlogLink } from './blog-helpers'
// must use weird syntax to bypass auto replacing of NODE_ENV
process.env['NODE' + '_ENV'] = 'production'
process.env.USE_CACHE = 'true'
// constants
const NOW = new Date().toJSON()
function mapToAuthor(author) {
return `<author><name>${author.full_name}</name></author>`
}
function decode(string) {
return string
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
}
function mapToEntry(post) {
return `
<entry>
<id>${post.link}</id>
<title>${decode(post.title)}</title>
<link href="${post.link}"/>
<updated>${new Date(post.date).toJSON()}</updated>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
${renderToStaticMarkup(
post.preview
? (post.preview || []).map((block, idx) =>
textBlock(block, false, post.title + idx)
)
: post.content
)}
<p class="more">
<a href="${post.link}">Read more</a>
</p>
</div>
</content>
${(post.authors || []).map(mapToAuthor).join('\n ')}
</entry>`
}
function concat(total, item) {
return total + item
}
function createRSS(blogPosts = []) {
const postsString = blogPosts.map(mapToEntry).reduce(concat, '')
return `<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>My Blog</title>
<subtitle>Blog</subtitle>
<link href="/atom" rel="self" type="application/rss+xml"/>
<link href="/" />
<updated>${NOW}</updated>
<id>My Notion Blog</id>${postsString}
</feed>`
}
async function main() {
const postsTable = await getBlogIndex(true, false)
const neededAuthors = new Set<string>()
const blogPosts = Object.keys(postsTable)
.map(slug => {
const post = postsTable[slug]
if (!postIsPublished(post)) return
post.authors = post.Authors || []
for (const author of post.authors) {
neededAuthors.add(author)
}
return post
})
.filter(Boolean)
const { users } = await getNotionUsers([...neededAuthors])
blogPosts.forEach(post => {
post.authors = post.authors.map(id => users[id])
post.link = getBlogLink(post.Slug)
post.title = post.Page
post.date = post.Date
})
const outputPath = './public/atom'
await writeFile(resolve(outputPath), createRSS(blogPosts))
console.log(`Atom feed file generated at \`${outputPath}\``)
}
main().catch(error => console.error(error))