blinky/libs/parser.js

159 lines
No EOL
4.3 KiB
JavaScript

const constants = require('./constants.js');
const hexcolor = require('hex-color-regex');
// parse a http post and return an object with sane defaults
function parseRequest(requestBody, mode) {
if (mode === undefined) {
mode = constants.MODE_SET;
}
let config = {
'id': Math.random(),
'mode': mode,
'options': {
'index': parseIndex(requestBody.index),
}
};
if (config.mode === constants.MODE_POWEROFF) {
config.color = '#000000';
return config;
} else {
config.color = parseColor(requestBody.color);
}
switch (config.mode) {
case constants.MODE_MORPH:
config.options.duration = parseDuration(requestBody.duration, config.options.index);
config.options.steps = parseSteps(requestBody.steps, config.options.duration);
break;
case constants.MODE_BLINK:
config.options.repeats = 1;
config.repetitions = parseRepetitions(requestBody.repeats, config.options.index);
config.options.delay = parseDelay(requestBody.delay);
break;
case constants.MODE_PULSE:
config.options.repeats = 1;
config.repetitions = parseRepetitions(requestBody.repeats, config.options.index);
config.options.duration = parseDuration(requestBody.duration, config.options.index, constants.MODE_PULSE);
config.options.steps = parseSteps(requestBody.steps, config.options.duration);
break;
}
return config;
}
// parse the index
function parseIndex(index) {
if (index === undefined) {
return constants.ALL;
}
index = parseInt(index);
if (index !== index) {
return constants.ALL;
}
if (index < 0) {
index = 0;
} else if (index > 7) {
index = 7;
}
return index;
}
// parse the duration
function parseDuration(duration, index, mode) {
if (duration === undefined) {
duration = constants.DURATION_DEFAULT;
}
if (index === constants.ALL && mode !== constants.MODE_PULSE) {
duration = duration / 8;
}
if (duration < 100) {
duration = 100;
}
return duration;
}
// parse the steps
function parseSteps(steps, duration) {
if (duration === undefined) {
duration = constants.DURATION_DEFAULT;
}
if (steps === undefined || steps === 0) {
steps = duration / 10;
}
return steps;
}
// parse the repetitions
function parseRepetitions(repeats, index) {
repeats = parseInt(repeats);
if (repeats !== repeats) {
repeats = 0;
}
return {done: 0, max: repeats};
}
// parse the delay
function parseDelay(delay) {
if (delay === undefined) {
delay = constants.DELAY_DEFAULT;
}
return delay;
}
// color / parser functions
function parseColor(value) {
if (value === undefined || value === constants.RANDOM) {
return constants.RANDOM;
}
let parsedColor = parseHexColor(value);
if (parsedColor !== undefined) {
return parsedColor;
}
return parseRGBColor(value) || constants.RANDOM;
}
function parseRGBColor(value) {
if (value.indexOf(',') === -1 && isRGBValue(value)) {
value = parseInt(value);
return convertRGBToHex(value, value, value);
}
const splittedValues = value.split(',');
let color = {};
for (let index = 0; index < splittedValues.length; index++) {
const value = splittedValues[index];
if (index === 0) {
color.red = parseInt(value) || 0;
} else if (index === 1) {
color.green = parseInt(value) || 0;
} else if (index === 2) {
color.blue = parseInt(value) || 0;
}
}
if (isRGBValue(color.red) && isRGBValue(color.green) && isRGBValue(color.blue)) {
return convertRGBToHex(color.red, color.green, color.blue);
}
}
function isRGBValue(value) {
return value !== undefined && !isNaN(value) && value >= 0 && value <= 255;
}
function convertRGBToHex(red, green, blue) {
return '#' + ((1 << 24) + (red << 16) + (green << 8) + blue).toString(16).slice(1);
}
function parseHexColor(value) {
if (value[0] !== '#') {
value = '#' + value;
}
if (value.length !== 7) {
return;
}
if (!hexcolor({strict: true}).test(value)) {
return;
}
return value;
}
// exports
module.exports = {
parseRequest
};