-
Notifications
You must be signed in to change notification settings - Fork 0
/
generateCoursePreview.mjs
112 lines (97 loc) · 4.81 KB
/
generateCoursePreview.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
import axios from "axios";
import fs from "fs";
import { JSDOM } from "jsdom";
let now = new Date()
let sitemapUrls = []
let dom = await JSDOM.fromFile('./dist/200.html')
let document = dom.window.document
function setMeta(name, content) {
let meta
meta = document.querySelector(`meta[name="${name}"]`)
if (!meta) {
meta = document.createElement('meta')
meta.setAttribute('name', name)
document.head.appendChild(meta)
}
meta.setAttribute('content', content)
}
function updateTags({ title, description, image, url }) {
setMeta('og:title', title)
setMeta('og:description', description)
setMeta('og:url', url)
setMeta('og:image', image)
setMeta('description', description)
setMeta('twitter:title', title)
setMeta('twitter:description', description)
setMeta('twitter:image', image)
setMeta('twitter:card', 'summary_large_image')
document.querySelector('title').textContent = title
}
console.log('Generate course preview')
let yearSems = await axios.get('https://gnehs.github.io/ntut-course-crawler-node/main.json').then((res) => res.data);
let withdrawal = await axios.get(`https://gnehs.github.io/ntut-course-crawler-node/analytics/withdrawal.json`).then((res) => res.data);
console.log(`Data fetched`)
let tasks = []
tasks.push(...Object.entries(yearSems)
.map((([year, sems]) => sems.map(sem => ({ year, sem }))))
.flat()
.map(async ({ year, sem }) => {
let courses = await axios.get(`https://gnehs.github.io/ntut-course-crawler-node/${year}/${sem}/main.json`).then(x => x.data)
let departments = await axios.get(`https://gnehs.github.io/ntut-course-crawler-node/${year}/${sem}/department.json`).then(x => x.data)
fs.mkdirSync(`./dist/course/${year}/${sem}/`, { recursive: true })
fs.mkdirSync(`./dist/class/${year}/${sem}/`, { recursive: true })
courses.map(course => {
let courseNumber = [`𝟬`, `𝟭`, `𝟮`, `𝟯`, `𝟰`, `𝟱`, `𝟲`, `𝟳`, `𝟴`, `𝟵`]
let parsedCourseId = course.id.split('').map((c) => courseNumber[c]).join('')
let title = `${parsedCourseId} ${course.name.zh}`
let description = `${course.description.zh}`
let image = `https://ntut-course-og.gnehs.net/api?year=${year}&sem=${sem}&id=${course.id}`
let url = `https://ntut-course.gnehs.net/course/${year}/${sem}/${course.id}`
updateTags({ title, description, image, url })
fs.writeFileSync(`./dist/course/${year}/${sem}/${course.id}.html`, dom.serialize().replace(/&/g, '&'))
sitemapUrls.push(url)
})
console.log(`Generate routes: ${year}/${sem} for ${courses.length} courses`)
departments.map(department => {
department.class.map(x => {
let courseData = courses.filter(y => y.class.some(z => z.name == x.name))
let title = x.name
let description = `在北科好朋友上查看課程「${x.name}」的資訊`
if (courseData.length) {
description += `,包含${[...new Set(courseData.map(x => x.name.zh))].slice(0, 3).join('、')}課程與博雅、必選修等相關資訊`
} else {
description += `,如必選修課程、博雅等相關課程資訊`
}
let image = `https://ntut-course-og.gnehs.net/api/class?year=${year}&sem=${sem}&id=${x.id}`
let url = `https://ntut-course.gnehs.net/class/${year}/${sem}/${encodeURIComponent(x.name)}`
updateTags({ title, description, image, url })
fs.writeFileSync(`./dist/class/${year}/${sem}/${x.name}.html`, dom.serialize().replace(/&/g, '&'))
sitemapUrls.push(url)
})
})
console.log(`Generate routes: ${year}/${sem} for ${departments.map(x => x.class).flat().length} classes`)
})
)
fs.mkdirSync(`./dist/teacher/`, { recursive: true })
tasks.push(...withdrawal.data.map(x => {
let title = x.name
let description = `在北科好朋友上查看教師「${x.name}」的資訊,包含${[...new Set(x.course.map(x => x.name.zh))].slice(0, 3).join('、')}等課程與選課人數等相關資訊`
let image = `https://ntut-course-og.gnehs.net/api/teacher?name=${encodeURIComponent(x.name)}`
let url = `https://ntut-course.gnehs.net/teacher/${encodeURIComponent(x.name)}`
updateTags({ title, description, image, url })
fs.writeFileSync(`./dist/teacher/${x.name}.html`, dom.serialize().replace(/&/g, '&'))
sitemapUrls.push(url)
}))
await Promise.all(tasks)
console.log(`Generate time: ${((new Date() - now) / 1000).toFixed(2)}s`)
//https://stackoverflow.com/questions/8495687/split-array-into-chunks
Object.defineProperty(Array.prototype, 'chunk', {
value: function (n) {
let ceil = Math.ceil;
return Array.from(Array(ceil(this.length / n)), (_, i) => this.slice(i * n, i * n + n));
}
});
sitemapUrls.chunk(50000).forEach((chunk, index) => {
fs.writeFileSync(`./dist/sitemap-${index + 1}.txt`, chunk.join('\n'), { encoding: 'utf8' })
})
console.log(`${sitemapUrls.length} urls in sitemap`)