openCountdown/index.js

375 lines
10 KiB
JavaScript
Raw Normal View History

2022-02-23 21:55:13 +01:00
const express = require("express");
const fs = require("fs");
const bodyParser = require("body-parser");
2022-03-10 18:56:51 +01:00
const ws = require('ws');
2022-03-06 00:44:28 +01:00
const helper = require("./helpers.js");
2022-03-30 16:16:59 +02:00
const loggy = require("./logging")
2022-04-06 22:17:55 +02:00
const Eta = require("eta");
2022-03-30 16:16:59 +02:00
loggy.init(true)
2022-02-23 21:55:13 +01:00
2022-03-30 16:16:59 +02:00
loggy.log("Preparing server", "info", "Server");
2022-02-23 21:55:13 +01:00
const app = express();
2022-03-30 16:16:59 +02:00
loggy.log("Preparing static routes", "info", "Server");
2022-02-23 21:55:13 +01:00
app.use(express.static("static"));
2022-03-30 16:16:59 +02:00
loggy.log("Preparing middlewares", "info", "Server");
2022-02-23 21:55:13 +01:00
app.use(bodyParser.json());
app.use(
bodyParser.urlencoded({
// to support URL-encoded bodies
extended: true,
})
);
let loadedData = {}
2022-03-30 16:16:59 +02:00
loggy.log("Loading config", "info", "Config");
2022-03-06 00:44:28 +01:00
if (fs.existsSync("data-persistence.json")) {
const loadedDataRaw = fs.readFileSync("data-persistence.json", "utf8");
loadedData = JSON.parse(loadedDataRaw);
2022-03-06 00:44:28 +01:00
} else {
console.warn("Unable to load persistent data");
}
2022-02-23 21:55:13 +01:00
currentState = {
mode: "clock",
2022-02-24 19:11:13 +01:00
countdownGoal: new Date().getTime(),
showMilliSeconds: true,
2022-02-24 20:17:24 +01:00
defaultFullScreen: true,
timeAmountInital: 0,
timerRunState: false,
2022-02-24 21:08:31 +01:00
pauseMoment: 0,
showTimeOnCountdown: true,
message: "",
showMessage: false,
2022-02-24 22:18:21 +01:00
messageAppearTime: 0,
showProgressbar: true,
colorSegments: { 40000: "yellow", 20000: "#FFAE00", 5000: "#ff0000", "START": "green" },
2022-02-25 17:22:59 +01:00
textColors: {},
srvTime: 0,
enableColoredText: true,
2022-03-10 20:55:23 +01:00
debug: false,
sessionToken: Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15),
2022-02-23 21:55:13 +01:00
};
const dataToBeWritten = {};
currentState = Object.assign({}, currentState, loadedData);
2022-02-25 17:22:59 +01:00
currentState.textColors = currentState.colorSegments
2022-04-06 22:17:55 +02:00
loggy.log("Reading language file", "info", "Language")
const languageProfile = JSON.parse(fs.readFileSync("lang/en_uk.json", "utf8"));
2022-03-30 16:16:59 +02:00
loggy.log("Preparing websocket", "info", "Websocket");
2022-03-10 18:56:51 +01:00
const wsServer = new ws.Server({ noServer: true });
wsServer.on('connection', socket => {
socket.on('message', function incoming(data) {
if (data.toString() == "new client") {
2022-03-10 18:56:51 +01:00
updatedData()
}
});
});
wsServer.broadcast = function broadcast(data) {
wsServer.clients.forEach(function each(client) {
// The data is coming in correctly
// console.log(data);
client.send(data);
});
};
let updatey = undefined;
function updatedData() {
currentState.srvTime = new Date().getTime()
wsServer.broadcast(JSON.stringify(currentState));
clearTimeout(updatey);
setTimeout(updatedData, 5000);
2022-03-10 18:56:51 +01:00
}
2022-03-30 16:16:59 +02:00
loggy.log("Preparing routes", "info", "Server");
2022-02-23 21:55:13 +01:00
app.get("/", function (req, res) {
2022-02-25 22:24:45 +01:00
const data = fs.readFileSync("templates/newAdminPanel.html", "utf8");
2022-05-10 21:49:08 +02:00
try {
res.send(
Eta.render(data, {
lang: languageProfile
}));
} catch (e) {
const data = fs.readFileSync("templates/brokenTranslation.html", "utf8");
res.send(data);
}
2022-02-25 22:24:45 +01:00
});
2022-02-23 21:55:13 +01:00
app.get("/timer", function (req, res) {
const data = fs.readFileSync("templates/timerPage.html", "utf8");
res.send(data);
});
app.get("/api/v1/data", function (req, res) {
2022-02-25 17:22:59 +01:00
currentState.srvTime = new Date().getTime()
2022-02-23 21:55:13 +01:00
res.json(currentState);
});
2022-03-10 20:55:23 +01:00
app.get("/api/v1/system", function (req, res) {
const tempPkgFile = fs.readFileSync("package.json", "utf8");
const tempPkgObj = JSON.parse(tempPkgFile);
2022-03-10 20:55:23 +01:00
const systemData = {
uptime: process.uptime(),
memoryUsage: process.memoryUsage(),
cpuUsage: process.cpuUsage(),
platform: process.platform,
arch: process.arch,
nodeVersion: process.version,
nodePath: process.execPath,
nodeArgv: process.argv,
nodeExecArgv: process.execArgv,
nodeCwd: process.cwd(),
nodeEnv: process.env,
nodeConfig: process.config,
nodeTitle: process.title,
systemVersion: tempPkgObj.version
2022-03-10 20:55:23 +01:00
}
res.json(systemData);
});
2022-02-23 21:55:13 +01:00
app.get("/api/v1/set/mode", function (req, res) {
currentState.mode = req.query.mode;
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-23 21:55:13 +01:00
res.json({ status: "ok" });
});
2022-02-25 17:22:59 +01:00
app.get("/api/v1/set/layout/showMillis", function (req, res) {
2022-03-06 00:44:28 +01:00
const resy = helper.wrapBooleanConverter(req.query.show, res)
if (resy != undefined) {
2022-03-06 00:44:28 +01:00
currentState.showMilliSeconds = resy;
if (req.query.persist === 'true') {
dataToBeWritten.showMilliSeconds = currentState.showMilliSeconds
}
res.json({ status: "ok" });
}
2022-03-10 18:56:51 +01:00
updatedData()
2022-03-06 00:44:28 +01:00
2022-02-24 19:11:13 +01:00
});
2022-02-23 22:17:12 +01:00
app.get("/api/v1/set/timerGoal", function (req, res) {
2022-02-25 17:22:59 +01:00
currentState.countdownGoal = new Date(parseInt(req.query.time)).getTime(); // ToDO error handling
2022-02-23 21:55:13 +01:00
res.json({ status: "ok" });
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-23 21:55:13 +01:00
});
2022-02-24 19:11:13 +01:00
app.get("/api/v1/set/addMillisToTimer", function (req, res) {
2022-02-24 20:17:24 +01:00
currentState.timeAmountInital = req.query.time;
2022-02-24 19:11:13 +01:00
currentState.countdownGoal = new Date().getTime() + parseInt(req.query.time)
currentState.pauseMoment = new Date().getTime();
2022-02-24 19:11:13 +01:00
res.json({ status: "ok" });
2022-03-10 18:56:51 +01:00
updatedData()
2022-03-06 00:44:28 +01:00
});
2022-02-23 21:55:13 +01:00
2022-02-24 20:17:24 +01:00
app.get("/api/v1/ctrl/timer/pause", function (req, res) {
currentState.timerRunState = false;
currentState.pauseMoment = new Date().getTime();
res.json({ status: "ok" });
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-24 20:17:24 +01:00
});
app.get("/api/v1/ctrl/timer/play", function (req, res) {
2022-03-06 00:44:28 +01:00
if (currentState.timerRunState == false) {
2022-02-26 23:22:53 +01:00
currentState.timerRunState = true
currentState.countdownGoal += new Date().getTime() - currentState.pauseMoment;
}
2022-02-24 20:17:24 +01:00
res.json({ status: "ok" });
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-24 20:17:24 +01:00
});
app.get("/api/v1/ctrl/timer/restart", function (req, res) {
currentState.countdownGoal = new Date().getTime() + parseInt(currentState.timeAmountInital)
res.json({ status: "ok" });
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-24 20:17:24 +01:00
});
2022-02-25 17:22:59 +01:00
app.get("/api/v1/set/layout/showTime", function (req, res) {
2022-03-06 00:44:28 +01:00
const resy = helper.wrapBooleanConverter(req.query.show, res)
if (resy != undefined) {
2022-03-06 00:44:28 +01:00
currentState.showTimeOnCountdown = resy;
if (req.query.persist === 'true') {
dataToBeWritten.showTimeOnCountdown = currentState.showTimeOnCountdown
}
res.json({ status: "ok" });
}
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-24 21:08:31 +01:00
});
2022-02-25 17:22:59 +01:00
app.get("/api/v1/set/progressbar/show", function (req, res) {
2022-02-24 22:18:21 +01:00
currentState.showProgressbar = (req.query.show === 'true');
2022-03-06 00:44:28 +01:00
if (req.query.persist === 'true') {
dataToBeWritten.showProgressbar = currentState.showProgressbar
}
2022-02-24 22:18:21 +01:00
res.json({ status: "ok" });
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-24 22:18:21 +01:00
});
2022-02-25 17:22:59 +01:00
app.get("/api/v1/set/progressbar/colors", function (req, res) {
try {
2022-03-06 18:07:51 +01:00
let data = req.query.colors
if (req.query.isBase64 === "true") {
2022-03-06 18:07:51 +01:00
data = atob(data)
}
currentState.colorSegments = JSON.parse(data);
2022-03-06 00:44:28 +01:00
if (req.query.persist === 'true') {
dataToBeWritten.colorSegments = currentState.colorSegments
}
2022-02-25 17:22:59 +01:00
res.json({ status: "ok" });
} catch (error) {
res.json({ status: "error", message: error });
2022-03-06 18:07:51 +01:00
console.error(error)
2022-02-25 17:22:59 +01:00
}
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-25 17:22:59 +01:00
});
app.get("/api/v1/set/text/colors", function (req, res) {
try {
if (req.query.copy === "true") {
currentState.textColors = currentState.colorSegments
res.json({ status: "ok" });
} else {
let data = req.query.colors
if (req.query.isBase64 === "true") {
data = atob(data)
}
console.debug(data)
currentState.textColors = JSON.parse(data);
if (req.query.persist === 'true') {
dataToBeWritten.textColors = currentState.textColors
}
}
2022-02-25 17:22:59 +01:00
res.json({ status: "ok" });
} catch (error) {
res.json({ status: "error", message: error });
2022-03-08 16:13:39 +01:00
console.error(error)
2022-02-25 17:22:59 +01:00
}
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-25 17:22:59 +01:00
});
app.get("/api/v1/set/text/enableColoring", function (req, res) {
currentState.enableColoredText = (req.query.enable === 'true');
2022-03-06 00:44:28 +01:00
if (req.query.persist === 'true') {
dataToBeWritten.enableColoredText = currentState.enableColoredText
}
res.json({ status: "ok" });
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-25 17:22:59 +01:00
});
2022-02-24 22:18:21 +01:00
2022-02-24 21:08:31 +01:00
app.get("/api/v1/ctrl/message/show", function (req, res) {
currentState.message = req.query.msg
currentState.showMessage = true
currentState.messageAppearTime = new Date().getTime()
res.json({ status: "ok" });
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-24 21:08:31 +01:00
});
2022-02-25 17:22:59 +01:00
app.get("/api/v1/debug", function (req, res) {
currentState.debug = (req.query.enable === 'true');
res.json({ status: "ok" });
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-25 17:22:59 +01:00
});
2022-02-24 21:08:31 +01:00
app.get("/api/v1/ctrl/message/hide", function (req, res) {
currentState.showMessage = false
res.json({ status: "ok" });
2022-03-10 18:56:51 +01:00
updatedData()
2022-02-24 21:08:31 +01:00
});
app.get("/api/v1/storage/commit", function (req, res) {
const tempString = JSON.stringify(dataToBeWritten);
2022-03-06 00:44:28 +01:00
try {
fs.writeFileSync("data-persistence.json", tempString);
res.json({ status: "ok" });
} catch (error) {
res.json({ status: "error", reason: error });
}
2022-03-10 18:56:51 +01:00
updatedData()
2022-03-06 00:44:28 +01:00
});
app.get("/api/v1/storage/delete", function (req, res) {
if (req.query.delete === "true") {
if (fs.existsSync("data-persistence.json")) {
fs.unlinkSync("data-persistence.json");
res.json({ status: "ok" });
} else {
res.json({ status: "error", reason: "No persistence data was found" });
}
} else {
} res.json({ status: "error", reason: "Missing delete argument" });
2022-03-10 18:56:51 +01:00
updatedData()
});
2022-05-10 21:49:08 +02:00
app.use(function (req, res, next) {
res.status(404);
2022-03-30 16:16:59 +02:00
loggy.log("Server responded with 404 error", "warn", "Server", true);
// respond with html page
if (req.accepts('html')) {
const data = fs.readFileSync("templates/errorPages/404.html", "utf8");
res.status(404)
res.send(data);
return;
}
// respond with json
if (req.accepts('json')) {
res.json({ error: 'Not found' });
return;
}
// default to plain-text. send()
res.type('txt').send('Not found');
});
2022-05-10 21:49:08 +02:00
/*app.use(function(err, req, res, next) {
2022-04-06 22:17:55 +02:00
console.error(err.stack);
if(String(err.stack).includes("TypeError: Cannot read properties of undefined")) {
const data = fs.readFileSync("templates/brokenTranslation.html", "utf8");
res.send(data);
}else{
res.status(500).send('Something broke!');
}
2022-05-10 21:49:08 +02:00
});*/
2022-04-06 22:17:55 +02:00
2022-03-30 16:16:59 +02:00
loggy.log("Starting server", "info", "Server");
2022-05-10 21:49:08 +02:00
const port = 3005;
2022-03-30 16:16:59 +02:00
process.on('SIGINT', function () {
loggy.log("Caught interrupt signal and shutting down gracefully", "info", "Shutdown");
server.close(); // Make the express server stop
2022-05-10 21:49:08 +02:00
loggy.log("Goodbye! 👋", "magic", "Shutdown", true)
loggy.close(); // Close and write log
process.exit(); // Quit the application
2022-03-30 16:16:59 +02:00
});
2022-03-10 18:56:51 +01:00
const server = app.listen(port);
server.on('upgrade', (request, socket, head) => {
wsServer.handleUpgrade(request, socket, head, socket => {
wsServer.emit('connection', socket, request);
});
});
2022-03-30 16:16:59 +02:00
loggy.log("=======================", "info", "", true);
loggy.log("Server running on port " + port, "magic", "", true);
loggy.log("Visit http://localhost:" + port + "/timer for the timer view", "magic", "", true);
loggy.log("Visit http://localhost:" + port + " for the admin view", "magic", "", true);
loggy.log("=======================", "info", "", true);