celery/handlers/directory.js

86 lines
2.2 KiB
JavaScript

const fs = require("fs");
const path = require("path");
const mustache = require("mustache");
const { version } = require("../modules/03-cache.js");
const generate = require("../static.js");
const template = fs.readFileSync("assets/directory.html", "utf8");
const indexes = new Map();
const comments = fs.readFileSync(path.join(__dirname, "../assets/comments"), "utf8")
.split("\n")
.filter(i => i)
.map(i => i.split("\t"))
.reduce((map, a) => (map.set(a[0], a[1]), map), new Map());
exports.hash = (where) => {
if(indexes.has(where)) {
try {
return fs.statSync(path.join(where, indexes.get(where))).mtime;
} catch {
indexes.delete(where);
}
}
let hash = 5381;
const str = fs.readdirSync(where).join(",");
for(let i = 0; i < str.length; i++) {
hash = ((hash << 5) + hash + str.charCodeAt(i))
hash = hash & hash;
}
return hash;
}
exports.render = (where, name) => {
const files = [];
const names = fs.readdirSync(where);
let git = false;
const index = names.find(i => ["index.gmi", "index.md", "index.html"].includes(i));
if(index) {
indexes.set(where, index);
return generate(path.join(where, index).slice(path.join(__dirname, "..", "overlay").length));
}
for(let file of names) {
try {
const stat = fs.statSync(path.join(where, file));
if(stat.isDirectory()) file = file + "/";
files.push({
name: file,
link: file,
date: stat.mtime.toISOString().slice(0, -5).replace("T", " "),
size: stat.isDirectory() ? "dir" : fmtSize(stat.size),
});
} catch {
continue;
}
}
const sorted = files.sort((a, b) =>
a.size === "dir" && b.size !== "dir" ? -1 :
a.size !== "dir" && b.size === "dir" ? 1 :
a.name > b.name);
return mustache.render(template, {
dir: name,
files: sorted,
comment: comments.get(name),
git: git,
cache: {
style: version("/assets/style.css"),
dir: version("/assets/directory.css"),
upload: version("/assets/upload.js"),
},
});
}
function fmtSize(size) {
const units = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "ZiB", "YiB"];
let max = 1024;
for(let unit of units) {
if(size < max) return Math.floor(size / (max / 10240)) / 10 + " " + unit;
max *= 1024;
}
return "quite a lot";
}