-
Notifications
You must be signed in to change notification settings - Fork 552
/
Copy pathgetBlogIndex.ts
99 lines (87 loc) · 2.72 KB
/
getBlogIndex.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
import { Sema } from 'async-sema'
import rpc, { values } from './rpc'
import createTable from './createTable'
import getTableData from './getTableData'
import { getPostPreview } from './getPostPreview'
import { readFile, writeFile } from '../fs-helpers'
import { BLOG_INDEX_ID, BLOG_INDEX_CACHE } from './server-constants'
export default async function getBlogIndex(
previews = true,
include_future_posts = false
) {
let postsTable: any = null
const useCache = process.env.USE_CACHE === 'true'
const cacheFile = `${BLOG_INDEX_CACHE}${previews ? '_previews' : ''}`
if (useCache) {
try {
postsTable = JSON.parse(await readFile(cacheFile, 'utf8'))
} catch (_) {
/* not fatal */
}
}
if (!postsTable) {
try {
const data = await rpc('loadPageChunk', {
pageId: BLOG_INDEX_ID,
limit: 999, // TODO: figure out Notion's way of handling pagination
cursor: { stack: [] },
chunkNumber: 0,
verticalColumns: false,
})
// Parse table with posts
const tableBlock = values(data.recordMap.block).find(
(block: any) => block.value.type === 'collection_view'
)
postsTable = await getTableData(tableBlock, true)
} catch (err) {
console.warn(
`Failed to load Notion posts, attempting to auto create table`
)
try {
await createTable()
console.log(`Successfully created table in Notion`)
} catch (err) {
console.error(
`Auto creating table failed, make sure you created a blank page and site the id with BLOG_INDEX_ID in your environment`,
err
)
}
return {}
}
// only get 10 most recent post's previews
const postsKeys = Object.keys(postsTable).splice(0, 10)
const sema = new Sema(3, { capacity: postsKeys.length })
if (previews) {
await Promise.all(
postsKeys
.sort((a, b) => {
const postA = postsTable[a]
const postB = postsTable[b]
const timeA = postA.Date
const timeB = postB.Date
return Math.sign(timeB - timeA)
})
.map(async postKey => {
await sema.acquire()
const post = postsTable[postKey]
post.preview = post.id
? await getPostPreview(postsTable[postKey].id)
: []
sema.release()
})
)
}
if (!include_future_posts) {
const nowDate = Date.now()
Object.keys(postsTable).forEach(slug => {
if (postsTable[slug].Date > nowDate) {
delete postsTable[slug]
}
})
}
if (useCache) {
writeFile(cacheFile, JSON.stringify(postsTable), 'utf8').catch(() => {})
}
}
return postsTable
}