blinky/libs/server.js

125 lines
3.9 KiB
JavaScript
Raw Normal View History

2021-04-06 16:41:49 +02:00
// requirements
const path = require('path');
const config = require('../config');
const packageJSON = require('../package.json');
const logger = require('./logger');
const blinkstick = require('./blinkstick');
// third party requirements
const express = require('express');
const favicon = require('serve-favicon')
const parser = require('body-parser');
// setup express, blinkstick and other stuff
const app = express();
app.use(favicon(path.join(path.dirname(__dirname), "public", "favicon.ico")));
app.use(parser.json());
app.use(parser.urlencoded({ extended: true }));
// get the html content for get requests
// TODO: replace with template engine (vue.js)
function getHTML() {
let welcomeMessage =
"<html>" +
"<head>" +
"<title>" + packageJSON.name + " " + packageJSON.version + "</title>" +
"<style>" +
"body { background: #2a2a2a; color: #f1f1f1; margin: 1.25% }" +
"th, td { border: 1px solid #919191; padding: 6px; text-align: left }" +
"</style>" +
"</head>" +
"<body>" +
"<div>" +
"<h1>" + packageJSON.name + " " + packageJSON.version + "</h1>" +
"</div>" +
"<hr>";
welcomeMessage +=
"<div>" +
"<h2>get:</h2>" +
"<p>" + config.api.get.description + "</p>" +
"</div>";
welcomeMessage +=
"<div>" +
"<h2>post:</h2>" +
"<table style=\"width:100%\">" +
"<th>argument</th>" +
"<th>available values</th>" +
"<th>default</th>" +
"<th>description</th>";
Object.keys(config.api.post).forEach(function (argument) {
welcomeMessage +=
"<tr>" +
"<td>" + argument + "</td>" +
"<td>" + config.api.post[argument].available + "</td>" +
"<td>" + config.api.post[argument].default + "</td>" +
"<td>" + config.api.post[argument].description + "</td>" +
"</tr>";
});
welcomeMessage +=
"</table>" +
"</div>" +
"</body>" +
"</html>"
return welcomeMessage;
}
// run the express http server and handle gets/posts
function start() {
return new Promise(function (resolve, reject) {
app.listen(config.server.port, config.server.listen)
.on("listening", function () {
return resolve("server listening on " + config.server.listen + ":" + config.server.port + "...")
})
.on("error", function (err) {
return reject("error starting server (" + err + ")");
});
});
}
function handleRequests() {
// GET methods
app.get('*', function (request, response) {
logger.logRequest(request);
response.send(getHTML());
response.end();
});
// POST methods
app.post('*', function (request, response) {
logger.logRequest(request);
if (!blinkstick.isAnimationInProgress() || blinkstick.isInfiniteAnimationInProgress()) {
response.end();
blinkstick.parseColor(parseRequest(request.body))
.then(blinkstick.illuminate)
.then(logger.info)
.catch(logger.error);
return;
}
response.sendStatus(503);
});
}
// parse the request and return an object with sane defaults
function parseRequest(data) {
const blinkstickConfig = {
"id": Math.random(),
"mode": data["mode"] || config.api.post.mode.default,
"color": data["color"] || config.api.post.color.default,
"options": {
"duration": data["duration"] || config.api.post.duration.default,
"pulse": {
"max": data["pulses"] || 0,
"done": 0
}
}
};
blinkstickConfig.options.steps = blinkstickConfig.options.duration / 10;
if (blinkstickConfig.options.duration < 100) {
blinkstickConfig.options.duration = 100;
}
return blinkstickConfig;
}
// exports
module.exports = {
start,
handleRequests
};