the home site for me: also iteration 3 or 4 of my site

bug: migrate to node

Changed files
+143 -141
.github
workflows
tools
+4 -4
.github/workflows/genOG.yaml
···
uses: actions/cache@v3
id: node-modules-cache
with:
-
path: tools/node_modules
-
key: node-modules-${{ runner.os }}-${{ hashFiles('tools/bun.lockb') }}
+
path: node_modules
+
key: node-modules-${{ runner.os }}-${{ hashFiles('bun.lockb', 'package.json') }}
restore-keys: |
node-modules-${{ runner.os }}-
- name: Install dependencies (tools)
+
if: steps.node-modules-cache.outputs.cache-hit != 'true'
env:
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: "true"
run: bun install --cwd tools
···
env:
CI: "true"
with:
-
args: bun run tools/genOG.ts
+
args: npm run gen
- name: Check for changes
id: git-check
···
git add public/og/*
git commit -m "chore: generated og images"
git push origin HEAD:main
-
+18
package.json
···
+
{
+
"name": "zera",
+
"module": "index.ts",
+
"type": "module",
+
"scripts": {
+
"gen": "node tools/genOG.js"
+
},
+
"devDependencies": {
+
"@types/bun": "latest",
+
"puppeteer": "^23.6.0"
+
},
+
"peerDependencies": {
+
"typescript": "^5.0.0"
+
},
+
"dependencies": {
+
"dotenv": "^16.4.7"
+
}
+
}
+5
tools/bun.lock bun.lock
···
"workspaces": {
"": {
"name": "zera",
+
"dependencies": {
+
"dotenv": "^16.4.7",
+
},
"devDependencies": {
"@types/bun": "latest",
"puppeteer": "^23.6.0",
···
"degenerator": ["degenerator@5.0.1", "", { "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", "esprima": "^4.0.1" } }, "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ=="],
"devtools-protocol": ["devtools-protocol@0.0.1367902", "", {}, "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg=="],
+
+
"dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
+116
tools/genOG.js
···
+
import "dotenv/config";
+
import puppeteer from "puppeteer";
+
import { readdir, mkdir, readFile, access } from "node:fs/promises";
+
+
const template = await readFile("tools/og.html", "utf-8");
+
+
const browser = await puppeteer.launch({
+
args: ["--no-sandbox"],
+
executablePath: process.env.PUPPETEER_EXEC_PATH,
+
});
+
+
async function og(postname, type, by, outputPath, width = 1200, height = 630) {
+
const page = await browser.newPage();
+
+
await page.setViewport({ width, height });
+
+
await page.setContent(
+
template
+
.toString()
+
.replace("{{postname}}", postname)
+
.replace("{{type}}", type)
+
.replace("{{by}}", by || ""),
+
);
+
+
await page.screenshot({ path: outputPath });
+
}
+
+
async function fileExists(path) {
+
try {
+
await access(path);
+
return true;
+
} catch (e) {
+
return false;
+
}
+
}
+
+
try {
+
// check if the public/blog folder exists
+
// if not exit
+
// if it does, get all the folders and then get the title tag from the index.html
+
+
if (!(await fileExists("public/"))) {
+
console.error("public/ does not exist");
+
process.exit(1);
+
}
+
+
// read all the files in the current directory filtering for index.htmls
+
const files = (await readdir("public/", { recursive: true })).filter((file) =>
+
file.endsWith("index.html"),
+
);
+
+
const directories = new Set(
+
files.map((file) => file.replace("index.html", "")),
+
);
+
+
const existing = (await readdir("static/")).filter((file) =>
+
directories.has(file),
+
);
+
+
// create not existing
+
for (const dir of directories) {
+
if (!existing.includes(dir)) {
+
await mkdir(`static/${dir.split("/").slice(0, -1).join("/")}`, {
+
recursive: true,
+
});
+
}
+
}
+
+
console.log("Generating OG images for", files.length, "files");
+
+
// for each file, get the title tag from the index.html
+
for (const file of files) {
+
const index = await readFile(`public/${file}`, "utf-8");
+
const title = index.match(/<title>(.*?)<\/title>/)?.[1] ?? "Untitled";
+
let type = "Page";
+
let by;
+
switch (file.split("/")[0]) {
+
case "blog":
+
type = "Blog";
+
if (file.split("/")[1] !== "index.html") {
+
by = "<p>A post ... yeah thats about it</p>";
+
} else {
+
by = "<p>All authored by me ... or are they???</p>";
+
}
+
break;
+
case "verify":
+
type = "Slash Page";
+
by = "<p>So you can stalk me 💀</p>";
+
break;
+
case "pfp":
+
type = "Slash Page";
+
by = "<p>Want to stare at my pretty face?</p>";
+
break;
+
case "tags":
+
if (file.split("/")[1] === "index.html") {
+
type = "Tags";
+
by = "<p>A total archive!</p>";
+
} else {
+
type = "Tag";
+
by = "<p>Find more posts like this!</p>";
+
}
+
break;
+
case "index.html":
+
type = "Root";
+
by = "<p>Where it all begins</p>";
+
break;
+
}
+
+
console.log("Generating OG for", file, "title:", title, "with type:", type);
+
await og(title, type, by, `static/${file.replace("index.html", "og.png")}`);
+
}
+
} catch (e) {
+
console.error(e);
+
} finally {
+
await browser.close();
+
}
-122
tools/genOG.ts
···
-
import puppeteer from "puppeteer";
-
import { readdir, mkdir } from "node:fs/promises";
-
-
const template = await Bun.file("tools/og.html").text();
-
-
const browser = await puppeteer.launch({
-
args: ["--no-sandbox"],
-
executablePath: process.env.PUPPETEER_EXEC_PATH, // set by docker container
-
});
-
-
async function og(
-
postname: string,
-
type: string,
-
by: string | undefined,
-
outputPath: string,
-
width = 1200,
-
height = 630,
-
) {
-
const page = await browser.newPage();
-
-
await page.setViewport({ width, height });
-
-
await page.setContent(
-
template
-
.toString()
-
.replace("{{postname}}", postname)
-
.replace("{{type}}", type)
-
.replace("{{by}}", by || ""),
-
);
-
-
await page.screenshot({ path: outputPath });
-
}
-
-
async function fileExists(path: string): Promise<boolean> {
-
try {
-
await Bun.file(path);
-
return true;
-
} catch (e) {
-
return false;
-
}
-
}
-
-
try {
-
// check if the public/blog folder exists
-
// if not exit
-
// if it does, get all the folders and then get the title tag from the index.html
-
-
if (!(await fileExists("public/"))) {
-
console.error("public/ does not exist");
-
process.exit(1);
-
}
-
-
// read all the files in the current directory filtering for index.htmls
-
const files = (await readdir("public/", { recursive: true })).filter((file) =>
-
file.endsWith("index.html"),
-
);
-
-
const directories = new Set(
-
files.map((file) => file.replace("index.html", "")),
-
);
-
-
const existing = (await readdir("static/")).filter((file) =>
-
directories.has(file),
-
);
-
-
// create not existing
-
for (const dir of directories) {
-
if (!existing.includes(dir)) {
-
await mkdir(`static/${dir.split("/").slice(0, -1).join("/")}`, {
-
recursive: true,
-
});
-
}
-
}
-
-
console.log("Generating OG images for", files.length, "files");
-
-
// for each file, get the title tag from the index.html
-
for (const file of files) {
-
const index = await Bun.file(`public/${file}`).text();
-
const title = index.match(/<title>(.*?)<\/title>/)[1];
-
let type = "Page";
-
let by: string | undefined;
-
switch (file.split("/")[0]) {
-
case "blog":
-
type = "Blog";
-
if (file.split("/")[1] !== "index.html") {
-
by = "<p>A post ... yeah thats about it</p>";
-
} else {
-
by = "<p>All authored by me ... or are they???</p>";
-
}
-
break;
-
case "verify":
-
type = "Slash Page";
-
by = "<p>So you can stalk me 💀</p>";
-
break;
-
case "pfp":
-
type = "Slash Page";
-
by = "<p>Want to stare at my pretty face?</p>";
-
break;
-
case "tags":
-
if (file.split("/")[1] === "index.html") {
-
type = "Tags";
-
by = "<p>A total archive!</p>";
-
} else {
-
type = "Tag";
-
by = "<p>Find more posts like this!</p>";
-
}
-
break;
-
case "index.html":
-
type = "Root";
-
by = "<p>Where it all begins</p>";
-
break;
-
}
-
-
console.log("Generating OG for", file, "title:", title, "with type:", type);
-
await og(title, type, by, `static/${file.replace("index.html", "og.png")}`);
-
}
-
} catch (e) {
-
console.error(e);
-
} finally {
-
await browser.close();
-
}
-15
tools/package.json
···
-
{
-
"name": "zera",
-
"module": "index.ts",
-
"type": "module",
-
"scripts": {
-
"gen": "bun run tools/genOG.ts"
-
},
-
"devDependencies": {
-
"@types/bun": "latest",
-
"puppeteer": "^23.6.0"
-
},
-
"peerDependencies": {
-
"typescript": "^5.0.0"
-
}
-
}