og/server.js

135 lines
2.7 KiB
JavaScript
Raw Normal View History

2023-08-02 18:09:44 -04:00
import html2png from '@besties/html2png'
import express from 'express'
import fs from 'node:fs'
2023-08-02 18:17:21 -04:00
const app = express()
2023-08-02 18:09:44 -04:00
const figtreeRegular = fs.readFileSync('./assets/Figtree-Regular.woff')
const figtreeMedium = fs.readFileSync('./assets/Figtree-Medium.woff')
const figtreeExtraBold = fs.readFileSync('./assets/Figtree-ExtraBold.woff')
const ATTR_REGEX = /["&]/g
const CONTENT_REGEX = /[&<]/g
function escape(value, is_attr = false) {
const str = String(value)
const pattern = is_attr ? ATTR_REGEX : CONTENT_REGEX
pattern.lastIndex = 0
let escaped = ''
let last = 0
while (pattern.test(str)) {
const i = pattern.lastIndex - 1
const ch = str[i]
escaped +=
// eslint-disable-next-line unicorn/prefer-string-slice
str.substring(last, i) +
(ch === '&' ? '&amp;' : ch === '"' ? '&quot;' : '&lt;')
last = i + 1
}
return escaped + str.slice(Math.max(0, last))
}
2023-08-02 18:17:21 -04:00
app.get('/', function (req, res) {
res.redirect('https://git.gay/gitgay/og.git')
})
2023-08-02 18:09:44 -04:00
2023-08-02 18:17:21 -04:00
app.get('/:owner/:repo', async function (req, res) {
let repo = await (
await fetch(
`https://git.gay/api/v1/repos/${req.params.owner}/${req.params.repo}`
)
).json()
let infoHtml = `
<p style="font-size: 36px; color: #9A8FA7;">${escape(
repo.owner.full_name
)} ${escape(`@${repo.owner.login}`)}</p>
<p style="font-weight: 800; font-size: 4.5rem; line-height: 1.2em;">${escape(
repo.name
)}</p>
`
if (repo.description)
infoHtml = `${infoHtml}<p style="font-size: 42px; font-weight: 500; color: #9A8FA7;">${escape(
repo.description
)}</p>`
let img = await html2png(
2023-08-02 18:09:44 -04:00
`<div class="main">
<div class="contents">
<div class="info">
${infoHtml}
</div>
<div class="graphics">
<img width="120" height="120" src="${escape(
repo.avatar_url || repo.owner.avatar_url,
true
)}"></img>
</div>
</div>
</div>`,
`p {
margin: 0;
}
.main {
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
background-color: #1B171F;
width: 1200px;
height: 600px;
}
.contents {
display: flex;
}
.info {
display: flex;
flex-direction: column;
justify-content: center;
width: 800px;
gap: 10px;
}
.graphics {
display: flex;
justify-content: flex-end;
align-items: flex-start;
width: 240px;
}
.graphics > img {
border-radius: 100%;
width: 120px;
height: 120px;
}`,
{
fonts: [
{
name: 'Figtree',
data: figtreeRegular,
weight: 400,
style: 'normal'
},
{
name: 'Figtree',
data: figtreeMedium,
weight: 500,
style: 'normal'
},
{
name: 'Figtree',
data: figtreeExtraBold,
weight: 800,
style: 'normal'
}
]
}
2023-08-02 18:17:21 -04:00
)
2023-08-02 18:09:44 -04:00
2023-08-02 18:17:21 -04:00
res.send(img)
2023-08-02 18:09:44 -04:00
})
2023-08-02 18:17:21 -04:00
app.listen(8085)