108 lines
2.9 KiB
TypeScript
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
|
|
}
|