Files
zhdiary/web/backend/scripts/prepare.ts
T
2020-02-28 13:03:53 +07:00

108 lines
2.9 KiB
TypeScript

import fs from 'fs'
import crypto from 'crypto'
import matter from 'gray-matter'
import glob from 'fast-glob'
import DataStore from 'nedb-promises'
import dayjs from 'dayjs'
import MakeHtml from '../src/utils/make-html'
// eslint-disable-next-line camelcase
const excerpt_separator = '<!-- excerpt_separator -->'
const db = new DataStore('assets/data.nedb')
;(async () => {
await db.ensureIndex({ fieldName: 'h', unique: true })
const files = await glob('**/*.md', {
cwd: '../../data'
})
await Promise.all(files.map(async (f) => {
let type = ''
if (f.startsWith('slides/')) {
type = 'slides'
}
const s = fs.readFileSync(`../../data/${f}`, 'utf8')
const h = crypto.createHash('sha256').update(s).digest('base64')
const { data, content, excerpt } = matter(s, {
excerpt_separator
})
try {
if (type === 'slides') {
const slides = content.split(/\n===\n/g).map((ss) => {
return ss.split(/\n--\n/g).map((s) => {
const make = new MakeHtml()
return make.parse(s)
}).reduce((prev, c, i) => ({ ...prev, [i.toString()]: c }), {} as any)
}).reduce((prev, c, i) => ({ ...prev, [i.toString()]: c }), {} as any)
const computedExcerpt = slides['0']['0']
await db.insert({
...data,
date: formatDate(data.date),
filename: f,
type,
slug: f.replace(/^slides\//, '').replace(/\.md$/, ''),
h,
excerpt: computedExcerpt,
slides
})
} else {
const make = new MakeHtml()
let computedExcerpt = ''
let computedContent = ''
if (excerpt) {
computedExcerpt = make.parse(excerpt)
computedContent = make.parse(content.substr(excerpt.length + excerpt_separator.length))
} else {
computedContent = make.parse(content)
computedExcerpt = computedContent.substr(0, 500).replace(/<[^>]*$/, '')
computedContent = computedContent.substr(computedExcerpt.length)
}
await db.insert({
...data,
date: formatDate(data.date),
filename: f,
type: f.split('/')[0],
slug: f.startsWith('posts/blog/')
? f.replace(/^posts\/blog\//, '').replace(/\.md$/, '')
: f.startsWith('posts/')
? (() => {
const ff = f.split('/')
return ff[ff.length - 1].replace(/\.md$/, '')
})()
: f.replace(/^[^/]+?\//, '').replace(/\.md$/, ''),
h,
excerpt: computedExcerpt,
remaining: computedContent
})
}
} catch (e) {
console.error(e, f)
}
}))
})().catch(console.error)
const tzOffset = new Date().getTimezoneOffset()
function formatDate (d?: string | Date) {
if (d) {
if (typeof d === 'string') {
return dayjs(d).toDate()
} else {
return dayjs(d).add(tzOffset, 'minute').toDate()
}
}
return d
}