galerie/srv/src/sync.ts

81 lines
1.7 KiB
TypeScript

import { createHash } from "crypto";
import { Request, Response } from "express";
import { readdirSync, existsSync, mkdirSync, statSync, readFileSync } from "fs";
import path from "path";
class Sync {
constructor() {
this.root = path.join(process.cwd(), "public");
if (!existsSync(this.root)) {
mkdirSync(this.root);
}
this.update();
}
async update() {
return new Promise<void>((res, rej) => {
this.files = readdirSync(this.root).filter(async (v) => {
let f = path.join(this.root, v);
if (existsSync(f)) {
let s = statSync(f);
return s.isFile() && s.size > 1;
} else {
await this.update();
res();
}
})
let c = createHash("sha1");
this.files.forEach(async (v) => {
let f = path.join(this.root, v);
if (existsSync(f))
c.update(readFileSync(f))
else {
await this.update();
res();
}
});
this.checksum = c.digest("hex");
res();
});
}
root: string;
files: string[];
checksum: string;
}
const state: Sync = new Sync();
let sync = async (req: Request, res: Response) => {
switch (req.method) {
case "GET": { // "Update me"
await state.update();
res.write(JSON.stringify({
checksum: state.checksum,
files: state.files
}));
break;
}
case "POST": { // "Am I up to date?"
await state.update();
let checksum = req.body;
if (checksum == state.checksum)
res.write('{"valid": true}');
else
res.write('{"valid": false}');
break;
}
}
res.end();
}
export default sync;