og/server.js
2023-08-03 04:40:18 -05:00

167 lines
4 KiB
JavaScript

import 'dotenv/config'
import express from 'express'
import { Eta } from 'eta'
import render, { renderHtml } from './lib/render.js'
import languageColors from './lib/languagecolors.js'
import fetch from 'node-fetch'
// satori is using the native fetch api, causing a warning, so make node-fetch the default
globalThis.fetch = fetch
const forgejoBaseUrl = process.env.FORGEJO_BASE_URL
if (!forgejoBaseUrl) throw new Error('FORGEJO_BASE_URL unspecified')
const debug = process.env.DEBUG ? true : false
const eta = new Eta({
views: 'views',
cache: !debug
})
const app = express()
app.get('/', function (req, res) {
res.redirect('https://git.gay/gitgay/og.git')
})
function getLanguagePercentages(languages) {
let sum = 0
const values = Object.values(languages)
for (const value of values) {
sum += value
}
return Object.fromEntries(
Object.keys(languages).map(language => {
return [language, (languages[language] / sum) * 100]
})
)
}
app.get('/:owner/:repo', async function (req, res) {
const repoResp = await fetch(
`${forgejoBaseUrl}/api/v1/repos/${encodeURIComponent(
req.params.owner
)}/${encodeURIComponent(req.params.repo)}`
)
if (!repoResp.ok) {
res.status(repoResp.status)
res.end()
return
}
const repo = await repoResp.json()
let languages = {}
if (!repo.empty && repo.languages_url) {
const languagesResp = await fetch(
`${forgejoBaseUrl}/api/v1/repos/${encodeURIComponent(
req.params.owner
)}/${encodeURIComponent(req.params.repo)}/languages`
)
if (languagesResp.ok) {
languages = getLanguagePercentages(await languagesResp.json())
}
}
const html = await eta.renderAsync('repo', {
repo,
languages,
languageColors,
debug
})
if (debug) {
res.send(await renderHtml(html))
return
}
res.type('png')
res.set('Content-Disposition', 'inline')
res.send(await render(html))
})
app.get('/:owner/:repo/commit/:hash', async function (req, res) {
const commitResp = await fetch(
`${forgejoBaseUrl}/api/v1/repos/${encodeURIComponent(
req.params.owner
)}/${encodeURIComponent(req.params.repo)}/git/commits/${encodeURIComponent(
req.params.hash
)}`
)
if (!commitResp.ok) {
res.status(commitResp.status)
res.end()
return
}
const commit = await commitResp.json()
let languages = {}
const languagesResp = await fetch(
`${forgejoBaseUrl}/api/v1/repos/${encodeURIComponent(
req.params.owner
)}/${encodeURIComponent(req.params.repo)}/languages`
)
if (languagesResp.ok) {
languages = getLanguagePercentages(await languagesResp.json())
}
const html = await eta.renderAsync('commit', {
commit: {
...commit.commit,
sha: commit.sha,
repository: {
full_name: `${req.params.owner}/${req.params.repo}`
},
committer: commit.committer,
stats: commit.stats,
created_at: commit.created
},
languages,
languageColors,
debug
})
if (debug) {
res.send(await renderHtml(html))
return
}
res.type('png')
res.set('Content-Disposition', 'inline')
res.send(await render(html))
})
app.get('/:owner/:repo/issue/:num', async function (req, res) {
const issueResp = await fetch(
`${forgejoBaseUrl}/api/v1/repos/${encodeURIComponent(
req.params.owner
)}/${encodeURIComponent(req.params.repo)}/issues/${encodeURIComponent(
req.params.num
)}`
)
if (!issueResp.ok) {
res.status(issueResp.status)
res.end()
return
}
const issue = await issueResp.json()
let languages = {}
const languagesResp = await fetch(
`${forgejoBaseUrl}/api/v1/repos/${encodeURIComponent(
req.params.owner
)}/${encodeURIComponent(req.params.repo)}/languages`
)
if (languagesResp.ok) {
languages = getLanguagePercentages(await languagesResp.json())
}
const html = await eta.renderAsync('issue', {
issue,
languages,
languageColors,
debug
})
if (debug) {
res.send(await renderHtml(html))
return
}
res.type('png')
res.set('Content-Disposition', 'inline')
res.send(await render(html))
})
const [port, host] = [process.env.PORT ?? 9054, process.env.HOST ?? '127.0.0.1']
app.listen(port, host, () => {
console.log(`Listening on http://${host}:${port}`)
})