2025-01-04 18:25:49 -05:00
|
|
|
const path = require('path')
|
|
|
|
const fs = require('fs/promises')
|
|
|
|
|
|
|
|
const gitRef = process.env.WWW_GIT_REF ?? 'master'
|
2023-10-30 00:18:38 -04:00
|
|
|
|
|
|
|
async function readFirstLines(filePath, lineCount = 1) {
|
2025-01-04 18:25:49 -05:00
|
|
|
const gitFileFetch = await fetch(`https://git.paulw.xyz/api/v1/repos/lambdapaul/www/raw/${filePath}?ref=${gitRef}`)
|
|
|
|
if (!gitFileFetch.ok) return null
|
|
|
|
const file = await gitFileFetch.text()
|
|
|
|
const lines = file.split('\n')
|
|
|
|
const out = []
|
|
|
|
for (let i = 0; i < lineCount && i < lines.length; i++) {
|
|
|
|
out.push(lines[i])
|
|
|
|
}
|
|
|
|
return out
|
2023-10-30 00:18:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
async function getTitle(filePath) {
|
2025-01-04 18:25:49 -05:00
|
|
|
const firstLines = await readFirstLines(filePath)
|
|
|
|
if (firstLines === null || firstLines === undefined || firstLines.length === 0) return null
|
|
|
|
let title = firstLines[0]
|
|
|
|
|
|
|
|
if (title.substring(0, 2) !== '# ') return null
|
2023-10-30 00:18:38 -04:00
|
|
|
title = title
|
|
|
|
.substring(1, firstLines[0].length)
|
2025-01-04 18:25:49 -05:00
|
|
|
.trim()
|
2023-10-30 00:18:38 -04:00
|
|
|
if (title.length < 3)
|
2025-01-04 18:25:49 -05:00
|
|
|
return null
|
|
|
|
return title
|
2023-10-30 00:18:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
async function getMarkdownMetadata(dir) {
|
2025-01-04 18:25:49 -05:00
|
|
|
const dirGitInfoFetch = await fetch(`https://git.paulw.xyz/api/v1/repos/lambdapaul/www/contents/${dir}/?ref=${gitRef}`)
|
|
|
|
if (!dirGitInfoFetch.ok) return {}
|
|
|
|
|
|
|
|
const commits = {}
|
|
|
|
const out = {}
|
|
|
|
|
|
|
|
const dirGitInfo = await dirGitInfoFetch.json()
|
|
|
|
for (const file of dirGitInfo) {
|
|
|
|
if (file.name.startsWith('.') || !file.name.endsWith('.md')) continue
|
|
|
|
const title = await getTitle(file.path)
|
|
|
|
if (title === null) continue
|
|
|
|
|
|
|
|
const slug = file.name.replace(/\.md$/, '')
|
|
|
|
let mtime = new Date(); // better to have an incorrect recent date than the more incorrect unix time 0 (assuming the host doesn't have messed up clock)
|
|
|
|
|
|
|
|
|
|
|
|
if (!(file.last_commit_sha in commits)) {
|
|
|
|
const lastCommitSha = await fetch(`https://git.paulw.xyz/api/v1/repos/lambdapaul/www/git/commits/${file.last_commit_sha}`)
|
|
|
|
if (lastCommitSha.ok) {
|
|
|
|
const commitJson = await lastCommitSha.json()
|
|
|
|
commits[commitJson.sha] = (new Date(commitJson.created))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mtime = commits[file.last_commit_sha]
|
|
|
|
|
2023-10-30 00:18:38 -04:00
|
|
|
out[slug] = {
|
|
|
|
title: title,
|
2025-01-04 18:25:49 -05:00
|
|
|
mtime: mtime.toISOString(),
|
|
|
|
}
|
2023-10-30 00:18:38 -04:00
|
|
|
}
|
2025-01-04 18:25:49 -05:00
|
|
|
return out
|
2023-10-30 00:18:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
async function readFilesMetadata(dir) {
|
2025-01-04 18:25:49 -05:00
|
|
|
const filePath = jsonFilePath(dir)
|
2023-10-30 00:18:38 -04:00
|
|
|
try {
|
2025-01-04 18:25:49 -05:00
|
|
|
const fileContent = await fs.readFile(filePath, 'utf-8')
|
|
|
|
const metadata = JSON.parse(fileContent)
|
|
|
|
return metadata
|
2023-10-30 00:18:38 -04:00
|
|
|
} catch {
|
2025-01-04 18:25:49 -05:00
|
|
|
return []
|
2023-10-30 00:18:38 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function writeFilesMetadata(filePath, metadata) {
|
|
|
|
try {
|
2025-01-04 18:25:49 -05:00
|
|
|
await fs.writeFile(filePath, JSON.stringify(metadata, null, 4), 'utf-8')
|
2023-10-30 00:18:38 -04:00
|
|
|
} catch (error) {
|
2025-01-04 18:25:49 -05:00
|
|
|
console.error(error)
|
2023-10-30 00:18:38 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function jsonFilePath(dir) {
|
2025-01-04 18:25:49 -05:00
|
|
|
return path.join(process.cwd(), 'public', `${dir}.json`); // ehh
|
2023-10-30 00:18:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
async function generateNotesMetadata() {
|
2025-01-04 18:25:49 -05:00
|
|
|
const dir = 'notes'
|
|
|
|
await writeFilesMetadata(jsonFilePath(dir), await getMarkdownMetadata(dir))
|
2023-10-30 00:18:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
async function generatePostsMetadata() {
|
2025-01-04 18:25:49 -05:00
|
|
|
const dir = 'posts'
|
|
|
|
const currMetadata = await readFilesMetadata(dir)
|
|
|
|
const generatedMetadata = await getMarkdownMetadata(dir)
|
|
|
|
const newMetadata = {}
|
2023-10-30 00:18:38 -04:00
|
|
|
|
|
|
|
for (const [name, data] of Object.entries(generatedMetadata)) {
|
2025-01-04 18:25:49 -05:00
|
|
|
let otime = new Date()
|
|
|
|
if (currMetadata[name]?.otime !== undefined && currMetadata[name]?.otime !== null)
|
|
|
|
otime = currMetadata[name].otime ?? otime
|
2023-10-30 00:18:38 -04:00
|
|
|
else
|
2025-01-04 18:25:49 -05:00
|
|
|
otime = data.mtime ?? otime
|
2023-10-30 00:18:38 -04:00
|
|
|
|
|
|
|
newMetadata[name] = { ...data, otime }
|
|
|
|
}
|
2025-01-04 18:25:49 -05:00
|
|
|
await writeFilesMetadata(jsonFilePath(dir), newMetadata)
|
2023-10-30 00:18:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
async function generateSiteMap() {
|
2025-01-04 18:25:49 -05:00
|
|
|
await generateNotesMetadata()
|
|
|
|
await generatePostsMetadata()
|
2023-10-30 00:18:38 -04:00
|
|
|
|
|
|
|
const sitemap = {
|
|
|
|
title: 'PaulW.XYZ',
|
2024-12-28 12:23:50 -05:00
|
|
|
pages: await readFilesMetadata('home')
|
2025-01-04 18:25:49 -05:00
|
|
|
}
|
2023-10-30 00:18:38 -04:00
|
|
|
|
2025-01-04 18:25:49 -05:00
|
|
|
const pages = ['posts', 'notes']
|
2023-10-30 00:18:38 -04:00
|
|
|
for (const page of pages) {
|
2025-01-04 18:25:49 -05:00
|
|
|
sitemap.pages[page].pages = await readFilesMetadata(page)
|
2023-10-30 00:18:38 -04:00
|
|
|
}
|
|
|
|
|
2025-01-04 18:25:49 -05:00
|
|
|
await writeFilesMetadata(jsonFilePath('sitemap'), sitemap)
|
2023-10-30 00:18:38 -04:00
|
|
|
}
|
|
|
|
|
2025-01-04 18:25:49 -05:00
|
|
|
generateSiteMap()
|