lua-serve/index.js
2021-06-05 22:22:49 -04:00

123 lines
No EOL
3.1 KiB
JavaScript

const express = require('express');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const port = 8080;
var app = express();
const cache = {
};
app.use("/files", express.static("projects"));
function get_indexes(project_id) {
if (cache[project_id]) {
let indexes = "";
for (let path in cache[project_id]) {
indexes += `${path} ${cache[project_id][path]}\n`;
}
return indexes.trim();
}
else if (fs.existsSync(path.join(__dirname, "projects", project_id))) {
let files = fs.readdirSync(path.join(__dirname, "projects", project_id));
let indexes = "";
cache[project_id] = {};
for (let file of files) {
let fileContents = fs.readFileSync(path.join(__dirname, "projects", project_id, file));
let hash = crypto.createHash("md5");
hash.update(fileContents);
cache[project_id][file] = hash.digest('hex');
indexes += `${file} ${cache[project_id][file]}\n`;
}
return indexes.trim();
}
else {
return undefined;
}
}
app.get("/indexes/:project(\\w+)", (req, res) => {
let project_id = req.params['project'];
let indexes = get_indexes(project_id);
if (indexes != undefined) {
res.send(indexes);
}
else {
res.sendStatus(404);
}
});
app.use("/updates", express.text());
function diff(current, checked) {
let lines_current = current.split('\n').map(l => l.trim());
let lines_checked = checked.split('\n').map(l => l.trim());
let filenames_checked = lines_checked.map(l => l.split(" ")[0]);
console.log(lines_current, lines_checked);
let result = "";
for (let line of lines_current) {
if (line.length != 0) {
let split = line.split(" ");
console.log(`split: ${split}`);
let index = filenames_checked.indexOf(split[0]);
console.log(`index: ${index}`);
if (index == -1) {
result += `${split[0]} download\n`;
continue;
}
let filename = filenames_checked[index];
let hash = lines_checked[index].split(" ")[1].trim();
console.log(`expected: ${split[0]} hash ${split[1]} found: ${filename} hash ${hash}`);
if (split[0] != filename || split[1] != hash) {
result += `${split[0]} download\n`;
}
console.log(`popping line ${index}, current: ${lines_checked}`);
lines_checked.splice(index, 1);
console.log(`result: ${lines_checked}`);
}
}
// now take care of the rest.
if (Array.isArray(lines_checked)) {
for (let line of lines_checked) {
console.log(`delete line ${line}`);
result += `${line.split(" ")[0]} delete\n`;
}
}
else {
// only 1 file left!
result += `${lines_checked.split(" ")[0]} delete\n`;
}
return result;
}
app.post("/updates/:project(\\w+)", (req, res) => {
let project_id = req.params['project'];
const body = req.body.replace(/\r/, "");
let indexes = get_indexes(project_id);
let difference = diff(indexes, body);
if (difference.length > 0) {
res.send(difference);
}
else {
res.sendStatus(204);
}
});
app.all("/", (req, res) => {
res.send("OK.");
});
app.listen(port, () => {
console.log(`listening on ${port}`);
});