2023-11-28 03:05:02 +01:00
|
|
|
import { join } from "https://deno.land/std@0.208.0/path/mod.ts";
|
|
|
|
import { emptyDir } from "https://deno.land/std@0.196.0/fs/empty_dir.ts";
|
|
|
|
import { parse, stringify } from "npm:yaml";
|
2024-01-25 20:45:28 +01:00
|
|
|
import { exists } from "https://deno.land/std@0.213.0/fs/exists.ts";
|
2024-02-02 05:23:07 +01:00
|
|
|
import { copy } from "https://deno.land/std@0.214.0/fs/copy.ts";
|
2023-11-28 03:05:02 +01:00
|
|
|
|
2024-01-25 20:45:28 +01:00
|
|
|
const SRC_DIR = "./src";
|
2023-11-28 03:05:02 +01:00
|
|
|
const DEST_DIR = "./dist";
|
|
|
|
const SCHEMA_DIR = "./schema";
|
|
|
|
|
|
|
|
export class Engine {
|
|
|
|
constructor() {
|
|
|
|
this.index = {};
|
|
|
|
this.db = {};
|
|
|
|
this.schemas = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
async init() {
|
|
|
|
// load schemas
|
|
|
|
for await (const dirEntry of Deno.readDir(SCHEMA_DIR)) {
|
2024-02-02 05:23:07 +01:00
|
|
|
const [fn, _] = dirEntry.name.split(".");
|
|
|
|
this.schemas[fn] = await readYamlFile(join(SCHEMA_DIR, dirEntry.name));
|
2023-11-28 03:05:02 +01:00
|
|
|
}
|
2024-01-25 20:45:28 +01:00
|
|
|
// load
|
2023-11-28 03:05:02 +01:00
|
|
|
this.index = await readYamlFile(join(SRC_DIR, "index.yaml"));
|
2024-01-25 20:45:28 +01:00
|
|
|
this.rendered = await this.render(this.index);
|
|
|
|
}
|
|
|
|
|
2024-02-02 06:12:21 +01:00
|
|
|
async loadDir(src, opts = {}, full = {}) {
|
2024-02-02 05:23:07 +01:00
|
|
|
const out = {};
|
|
|
|
const dir = join(SRC_DIR, src);
|
|
|
|
console.log(`reading dir=${dir}`);
|
|
|
|
|
2024-01-25 20:45:28 +01:00
|
|
|
if (await exists(join(dir, "index.yaml"))) {
|
2024-02-02 06:12:21 +01:00
|
|
|
const out = await readYamlFile(join(dir, "index.yaml"));
|
|
|
|
if (opts.loader === "events") {
|
2024-03-07 13:28:46 +01:00
|
|
|
// check speaker connection & load event images
|
2024-02-02 06:12:21 +01:00
|
|
|
for (const ev of out) {
|
|
|
|
if (ev.speakers) {
|
|
|
|
for (const spId of ev.speakers) {
|
|
|
|
if (!full.people.find((p) => p.id === spId)) {
|
|
|
|
throw new Error(`Speaker not exists: ${spId} (event ${ev.id})`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-03-07 13:28:46 +01:00
|
|
|
// load events images
|
|
|
|
const year = ev.date.match(/^(\d{4})/)[1];
|
|
|
|
const yearDir = join(dir, '_images', year);
|
|
|
|
if (!await exists(yearDir)) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
const images = {}
|
|
|
|
for await (const ie of Deno.readDir(yearDir)) {
|
|
|
|
const [id, ext] = ie.name.split(".");
|
|
|
|
if (id.match(new RegExp(`^${ev.id}-`))) {
|
|
|
|
const imgName = id.split('-').slice(1).join('-')
|
|
|
|
images[imgName] = `https://data.web3privacy.info/img/events/${year}/${id}.${ext}`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ev.images = images
|
2024-03-07 17:47:20 +01:00
|
|
|
|
|
|
|
ev.thumbs = {}
|
|
|
|
// scan for thumbnails
|
|
|
|
for await (const ti of Deno.readDir(join(yearDir, "thumbs"))) {
|
|
|
|
const [name, ext] = ti.name.split('.')
|
2024-03-07 18:00:53 +01:00
|
|
|
|
|
|
|
//console.log(name, `^${ev.id}-(.+)-(\\d+)px$`)
|
|
|
|
const match = name.match(new RegExp(`^${ev.id}-([\\w\\d-]+)-(\\d+)px`));
|
|
|
|
if (!match) {
|
|
|
|
continue
|
2024-03-07 17:47:20 +01:00
|
|
|
}
|
2024-03-07 18:04:21 +01:00
|
|
|
const thumbKey = match[2]
|
|
|
|
const imageKey = match[1]
|
2024-03-07 18:00:53 +01:00
|
|
|
|
2024-03-07 18:06:52 +01:00
|
|
|
ev.thumbs[[ imageKey, thumbKey.replace('px', '')].join(':')] = `https://data.web3privacy.info/img/events/${year}/thumbs/${ev.id}-${imageKey}-${thumbKey}px.${ext}`
|
2024-03-07 17:47:20 +01:00
|
|
|
}
|
2024-02-02 06:12:21 +01:00
|
|
|
}
|
|
|
|
}
|
2024-02-02 05:23:07 +01:00
|
|
|
return out;
|
2024-01-25 20:45:28 +01:00
|
|
|
}
|
|
|
|
|
2024-02-02 05:23:07 +01:00
|
|
|
let images = [];
|
|
|
|
if (await exists(join(dir, "_images"))) {
|
|
|
|
for await (const ie of Deno.readDir(join(dir, "_images"))) {
|
|
|
|
const [id, ext] = ie.name.split(".");
|
|
|
|
images.push({ id, ext });
|
|
|
|
}
|
|
|
|
}
|
2024-03-07 13:28:46 +01:00
|
|
|
|
2024-01-25 21:38:08 +01:00
|
|
|
const arr = [];
|
2024-01-25 20:45:28 +01:00
|
|
|
for await (const dirEntry of Deno.readDir(dir)) {
|
2023-11-28 03:05:02 +01:00
|
|
|
const [fn, ext] = dirEntry.name.split(".");
|
2024-01-25 20:45:28 +01:00
|
|
|
|
2024-02-02 05:23:07 +01:00
|
|
|
if (!ext && !fn.startsWith("_")) {
|
|
|
|
const obj = Object.assign(
|
|
|
|
{ id: fn },
|
2024-02-02 06:12:21 +01:00
|
|
|
await this.loadDir(join(src, fn), opts, full),
|
2024-02-02 05:23:07 +01:00
|
|
|
);
|
|
|
|
arr.push(obj);
|
|
|
|
}
|
|
|
|
if (ext === "yaml" && fn !== "index") {
|
2024-02-02 05:28:04 +01:00
|
|
|
const item = Object.assign(
|
|
|
|
{ id: fn },
|
|
|
|
await readYamlFile(join(dir, dirEntry.name)),
|
|
|
|
);
|
2024-02-02 05:23:07 +01:00
|
|
|
if (opts.loader === "person") {
|
|
|
|
// load image
|
|
|
|
const img = images.find((i) => i.id === fn);
|
|
|
|
if (img) {
|
|
|
|
item.imageUrl =
|
|
|
|
`https://data.web3privacy.info/img/people/${img.id}.${img.ext}`;
|
2024-03-07 17:47:20 +01:00
|
|
|
|
|
|
|
item.thumbs = {}
|
|
|
|
|
|
|
|
// scan for thumbnails
|
|
|
|
for await (const ti of Deno.readDir(join(dir, "_images", "thumbs"))) {
|
|
|
|
const [name, ext] = ti.name.split('.')
|
|
|
|
const split = name.split('-')
|
|
|
|
const thumbKey = split[split.length-1]
|
|
|
|
const sid = split.slice(0, split.length-1).join('-')
|
|
|
|
|
|
|
|
if (item.id === sid) {
|
|
|
|
item.thumbs[thumbKey.replace('px', '')] = `https://data.web3privacy.info/img/people/thumbs/${img.id}-${thumbKey}.${ext}`
|
|
|
|
}
|
|
|
|
}
|
2024-02-02 05:23:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
arr.push(item);
|
2024-01-25 20:45:28 +01:00
|
|
|
}
|
2023-11-28 03:05:02 +01:00
|
|
|
}
|
2024-02-02 05:23:07 +01:00
|
|
|
return arr;
|
2024-01-25 20:45:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
async render(src) {
|
2024-02-02 05:23:07 +01:00
|
|
|
const out = {};
|
2024-01-25 20:45:28 +01:00
|
|
|
for (const key of Object.keys(src)) {
|
|
|
|
const val = src[key];
|
|
|
|
if (typeof val === "object" && val.$load) {
|
2024-02-02 06:12:21 +01:00
|
|
|
out[key] = await this.loadDir(val.$load, val.$opts, out);
|
2024-01-25 20:45:28 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-02-02 05:23:07 +01:00
|
|
|
out[key] = val;
|
2024-01-25 20:45:28 +01:00
|
|
|
}
|
2024-02-02 05:23:07 +01:00
|
|
|
return out;
|
2023-11-28 03:05:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
async build() {
|
|
|
|
await emptyDir(DEST_DIR);
|
2024-01-25 20:45:28 +01:00
|
|
|
//await writeJSONFile(join(DEST_DIR, "index.json"), this.index);
|
2024-02-02 05:23:07 +01:00
|
|
|
// copy images
|
|
|
|
await emptyDir(join(DEST_DIR, "img"));
|
|
|
|
await copy(
|
|
|
|
join(SRC_DIR, "people", "_images"),
|
|
|
|
join(DEST_DIR, "img", "people"),
|
|
|
|
);
|
|
|
|
|
2024-03-07 13:28:46 +01:00
|
|
|
// copy event images
|
|
|
|
await copy(
|
|
|
|
join(SRC_DIR, "events", "_images"),
|
|
|
|
join(DEST_DIR, "img", "events"),
|
|
|
|
);
|
|
|
|
|
2023-11-28 03:05:02 +01:00
|
|
|
await writeJSONFile(
|
2024-01-25 20:45:28 +01:00
|
|
|
join(DEST_DIR, "index.json"),
|
|
|
|
Object.assign({}, this.rendered),
|
2023-11-28 03:05:02 +01:00
|
|
|
);
|
2024-01-25 20:45:28 +01:00
|
|
|
/*for (const col of Object.keys(this.db)) {
|
2023-11-28 03:05:02 +01:00
|
|
|
await writeJSONFile(join(DEST_DIR, `${col}.json`), this.db[col]);
|
2024-01-25 20:45:28 +01:00
|
|
|
}*/
|
2023-11-28 03:05:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function readYamlFile(fn) {
|
|
|
|
return parse(await Deno.readTextFile(fn));
|
|
|
|
}
|
|
|
|
|
|
|
|
async function writeJSONFile(fn, data) {
|
|
|
|
console.log(`File written: ${fn}`);
|
|
|
|
return Deno.writeTextFile(fn, JSON.stringify(data, null, 2));
|
|
|
|
}
|