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(), 'blinkstick': parseBlinkstick(requestBody.blinkstick), '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 blinkstick function parseBlinkstick(blinkstick) { if (blinkstick === undefined) { return undefined; } return blinkstick; } // 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, parseBlinkstick, parseIndex };