You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

91 lines
2.1 KiB

// @ts-check
import { readdir, readFile, writeFile, mkdir } from "node:fs/promises";
import { renderPreviewImg } from "imagen";
const toplevel = (await readdir("public/blog")).filter(x => x !== "assets");
const removeExtn = path => {
const parts = path.split(".");
parts.splice(parts.length - 1);
return parts.join(".");
};
const parseMetadata = (slug, contents) => {
return Object.fromEntries(
contents
.split("---")[1]
.trim()
.split("\n")
.map(line => {
const [name, value] = line.split(/:(.*)/).map(x => x.trim());
return [name, value];
})
.concat([["slug", slug]]),
);
};
/**
* @type {import("./blog.types").Data}
*/
const data = Object.fromEntries(
await Promise.all(
toplevel.map(year =>
readdir("public/blog/" + year).then(slugs =>
Promise.all(
slugs.map(async slug => {
const path = `public/blog/${year}/${slug}`;
const contents = await readFile(path, "utf-8");
return parseMetadata(removeExtn(slug), contents);
}),
)
.then(list =>
list
.sort(
(a, b) =>
new Date(a["featured-img"]).valueOf() -
new Date(b["featured-img"]).valueOf(),
)
.map(x => [x.slug, x]),
)
.then(list => Object.fromEntries(list))
.then(cont => [year, cont]),
),
),
),
);
function rewriteExtn(filename, extn) {
const split = filename.split(".");
split[split.length - 1] = extn;
return split.join(".");
}
/**
*
* @param {import("./blog.types").Data} data
*/
export async function generateFeaturedImages(data) {
for (const year in data) {
const yearData = data[year];
for (const slug in yearData) {
const article = yearData[slug];
await renderPreviewImg(
[1920, 1080],
"public/blog/assets/" + article["featured-img"],
article.title,
["MKRhere", article.category, article.published].join(" · "),
"public/blog/assets/featured/" +
rewriteExtn(article["featured-img"], "jpg"),
);
}
}
}
writeFile("src/blog.json", JSON.stringify(data, null, "\t"), "utf-8").then(() =>
console.log("Done"),
);
mkdir("public/blog/assets/featured", { recursive: true }).then(() =>
generateFeaturedImages(data),
);