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