the home site for me: also iteration 3 or 4 of my site
1import puppeteer from "puppeteer";
2import { readdir, mkdir } from "node:fs/promises";
3
4const template = await Bun.file("tools/og.html").text();
5
6const browser = await puppeteer.launch();
7
8async function og(
9 postname: string,
10 type: string,
11 by: string | undefined,
12 outputPath: string,
13 width = 1200,
14 height = 630,
15) {
16 const page = await browser.newPage();
17
18 await page.setViewport({ width, height });
19
20 await page.setContent(
21 template
22 .toString()
23 .replace("{{postname}}", postname)
24 .replace("{{type}}", type)
25 .replace("{{by}}", by || ""),
26 );
27
28 await page.screenshot({ path: outputPath });
29}
30
31async function fileExists(path: string): Promise<boolean> {
32 try {
33 await Bun.file(path);
34 return true;
35 } catch (e) {
36 return false;
37 }
38}
39
40try {
41 // check if the public/blog folder exists
42 // if not exit
43 // if it does, get all the folders and then get the title tag from the index.html
44
45 if (!(await fileExists("public/"))) {
46 console.error("public/ does not exist");
47 process.exit(1);
48 }
49
50 // read all the files in the current directory filtering for index.htmls
51 const files = (await readdir("public/", { recursive: true })).filter((file) =>
52 file.endsWith("index.html"),
53 );
54
55 const directories = new Set(
56 files.map((file) => file.replace("index.html", "")),
57 );
58
59 const existing = (await readdir("static/")).filter((file) =>
60 directories.has(file),
61 );
62
63 // create not existing
64 for (const dir of directories) {
65 if (!existing.includes(dir)) {
66 await mkdir(`static/${dir.split("/").slice(0, -1).join("/")}`, {
67 recursive: true,
68 });
69 }
70 }
71
72 console.log("Generating OG images for", files.length, "files");
73
74 // for each file, get the title tag from the index.html
75 for (const file of files) {
76 const index = await Bun.file(`public/${file}`).text();
77 const title = index.match(/<title>(.*?)<\/title>/)[1];
78 let type = "Page";
79 let by: string | undefined;
80 switch (file.split("/")[0]) {
81 case "blog":
82 type = "Blog";
83 if (file.split("/")[1] !== "index.html") {
84 by = "<p>A post ... yeah thats about it</p>";
85 } else {
86 by = "<p>All authored by me ... or are they???</p>";
87 }
88 break;
89 case "verify":
90 type = "Slash Page";
91 by = "<p>So you can stalk me 💀</p>";
92 break;
93 case "pfp":
94 type = "Slash Page";
95 by = "<p>Want to stare at my pretty face?</p>";
96 break;
97 case "tags":
98 if (file.split("/")[1] === "index.html") {
99 type = "Tags";
100 by = "<p>A total archive!</p>";
101 } else {
102 type = "Tag";
103 by = "<p>Find more posts like this!</p>";
104 }
105 break;
106 case "index.html":
107 type = "Root";
108 by = "<p>Where it all begins</p>";
109 break;
110 }
111
112 console.log("Generating OG for", file, "title:", title, "with type:", type);
113 await og(title, type, by, `static/${file.replace("index.html", "og.png")}`);
114 }
115} catch (e) {
116 console.error(e);
117} finally {
118 await browser.close();
119}