576 lines
22 KiB
JavaScript
Executable File
576 lines
22 KiB
JavaScript
Executable File
"use strict";
|
|
var path = require("path");
|
|
var bodyParser = require("body-parser");
|
|
var util = require("util");
|
|
var urlencodedParser = bodyParser.urlencoded({ extended: false });
|
|
// ----- SERVER
|
|
var express = require("express");
|
|
var app = express();
|
|
const port = 8080;
|
|
// ----- DATA
|
|
var ejs = require("ejs");
|
|
app.set("view engine", "ejs");
|
|
var mysql = require("mysql");
|
|
var { Client } = require("pg");
|
|
var con;
|
|
var query;
|
|
|
|
app.use(express.static(path.join(__dirname, 'views')));
|
|
|
|
/*
|
|
host: "ctcap09",
|
|
user: "ets_exm",
|
|
password: "",
|
|
database: "guez1",
|
|
*/
|
|
|
|
// Hostname: ctcap02
|
|
// Username: ets_exm
|
|
// Database: guez_20210926
|
|
|
|
// If the user presses "GetData" button, they get saved here:
|
|
let data = {};
|
|
let tempData = {};
|
|
// If the user presses "GetAllData" button, they get saved here:
|
|
let allData = [];
|
|
// Timelabels (01:00, 01:30, 02:00, ...) get saved here:
|
|
let time = [];
|
|
// Inputfields get saved here:
|
|
|
|
let inputs = {
|
|
// Database settings
|
|
host: "ctcap09",
|
|
user: "ets_exm",
|
|
password: "",
|
|
database: "guez1",
|
|
|
|
startDay: 1,
|
|
endDay: 1,
|
|
|
|
selectedEvents: [],
|
|
eventtypes: [],
|
|
exercise: {},
|
|
};
|
|
let processStatus = "";
|
|
let progressCount = {
|
|
cur: 0,
|
|
max: 0
|
|
};
|
|
// All Exercises get saved here:
|
|
let allExercises = [];
|
|
let exerciseTable = "";
|
|
// All Eventtypes get saved here:
|
|
let allEventtypes = [];
|
|
// All distinct eventtypes on selected exercise
|
|
let exerciseEventtypes = [];
|
|
// Days that the user can select get saved here:
|
|
let days = ["YYYY-MM-DD"];
|
|
// If user presses "Connect" button to connect to database. If successfull it gets set to true:
|
|
let connectedToDatabase = false;
|
|
|
|
let selectedExercise = {};
|
|
// Error array (should be 0)
|
|
let error = 0;
|
|
/*
|
|
1 = Database settings error
|
|
2 =
|
|
3 =
|
|
4 =
|
|
5 =
|
|
|
|
*/
|
|
// Settings that can be changed in /settings
|
|
let settings = {};
|
|
|
|
const color = {
|
|
reset: "\x1b[0m",
|
|
bright: "\x1b[1m",
|
|
dim: "\x1b[2m",
|
|
underscore: "\x1b[4m",
|
|
blink: "\x1b[5m",
|
|
reverse: "\x1b[7m",
|
|
hidden: "\x1b[8m",
|
|
|
|
fg_black: "\x1b[30m",
|
|
fg_red: "\x1b[31m",
|
|
fg_green: "\x1b[32m",
|
|
fg_yellow: "\x1b[33m",
|
|
fg_blue: "\x1b[34m",
|
|
fg_magenta: "\x1b[35m",
|
|
fg_cyan: "\x1b[36m",
|
|
fg_white: "\x1b[37m",
|
|
|
|
bg_black: "\x1b[40m",
|
|
bg_red: "\x1b[41m",
|
|
bg_green: "\x1b[42m",
|
|
bg_yellow: "\x1b[43m",
|
|
bg_blue: "\x1b[44m",
|
|
bg_magenta: "\x1b[45m",
|
|
bg_cyan: "\x1b[46m",
|
|
bg_white: "\x1b[47m"
|
|
}
|
|
|
|
function loadSiteFunc(siteRenderer){
|
|
loadSite(siteRenderer, data, time, inputs, days, allExercises, error);
|
|
}
|
|
async function loadSite(siteRenderer, dataSet, timeSet, inputsSet, daysSet, allExercisesSet, errorNum) {
|
|
siteRenderer.render("index", {
|
|
data: dataSet,
|
|
time: timeSet,
|
|
inputs: inputsSet,
|
|
days: daysSet,
|
|
allExercises: allExercisesSet,
|
|
exerciseEventtypes: exerciseEventtypes,
|
|
error: errorNum
|
|
});
|
|
}
|
|
|
|
async function getExercises() {
|
|
try {
|
|
let allExercises = [];
|
|
const result = await query("SELECT * FROM exm.exercise ORDER BY start_time DESC");
|
|
for (let i = 0; i < result.rows.length; i++) {
|
|
allExercises[i] = {};
|
|
allExercises[i]["name"] = result.rows[i].name;
|
|
if(result.rows[i].start_time == 0){
|
|
allExercises[i]["start_time"] = await getStringDay(result.rows[i].begin_time);
|
|
}else{
|
|
allExercises[i]["start_time"] = await getStringDay(result.rows[i].start_time);
|
|
}
|
|
if(result.rows[i].stop_time == 0){
|
|
allExercises[i]["stop_time"] = await getStringDay(0)
|
|
}else{
|
|
allExercises[i]["stop_time"] = await getStringDay(result.rows[i].stop_time);
|
|
}
|
|
allExercises[i]["id"] = result.rows[i].id;
|
|
}
|
|
return allExercises;
|
|
//loadSite(siteRenderer, {}, time, inputs, days, allExercises, error);
|
|
} catch (err) {
|
|
errOutput(err);
|
|
return err
|
|
}
|
|
}
|
|
|
|
async function getExerciseDays() {
|
|
days = [];
|
|
// Converting selected exercise start time to unix timestamp
|
|
let mintime = new Date(inputs.exercise.start_time) * 1;
|
|
// Converting selected exercise stop time to unix timestamp
|
|
let maxtime = new Date(inputs.exercise.stop_time) * 1;
|
|
|
|
// Calculate time difference
|
|
let timeDifference = maxtime - mintime;
|
|
// Calculate day difference from time difference
|
|
let dayDifference = Math.floor(timeDifference / (1000 * 3600 * 24));
|
|
days[0] = await getStringDay(mintime);
|
|
// Filling the day difference with days
|
|
for (let i = 0; i < dayDifference ; i++) {
|
|
let day = new Date(days[i])
|
|
day.setDate(day.getDate() + 1);
|
|
// Converting Unixtimestamp to readable format (YYYY-MM-DD) and inserting it
|
|
days[i + 1] = await getStringDay(parseInt(day * 1));
|
|
}
|
|
return days;
|
|
}
|
|
async function getData(startTime, endTime, dayDif) {
|
|
try {
|
|
// Gets correct timelabels for x axis
|
|
time = [];
|
|
// 1 Day: 00:00 - 24:00, 2 Days: 00:00 - 24:00 - 00:00 - 24:00, ...
|
|
for (let i = 0; i < dayDif; i++) {
|
|
time = time.concat(await getTimeInSteps(startTime, endTime, 23, i));
|
|
}
|
|
data = {};
|
|
// For every eventtype in exercise
|
|
progressCount.max = inputs.eventtypes.length;
|
|
for (const el of inputs.eventtypes) {
|
|
if(inputs.selectedEvents.includes(el.id.toString())){
|
|
processStatus = el.name; // For showing what the server does on the client
|
|
progressCount.cur++; // For showing what the server does on the client
|
|
process.stdout.clearLine(0);
|
|
process.stdout.cursorTo(0);
|
|
process.stdout.write("Adding \"" + el.name + "\" to dataset..."); // For showing what the server does on the server
|
|
|
|
data[el.id] = [[], el.name];
|
|
// Init data set to zero
|
|
for (let i = 0; i < 24 * dayDif; i++) {
|
|
data[el.id][0][i] = 0;
|
|
}
|
|
// Get start and end day from user inputs
|
|
let startDay = new Date(days[parseInt(inputs.startDay)]);
|
|
let endDay = new Date(days[parseInt(inputs.endDay)]);
|
|
// Convert to unixtimestamp
|
|
startDay *= 1;
|
|
endDay = (endDay * 1) + 86400000; // Plus 24 hours
|
|
|
|
// Sql query to database. Every sample_time from the selected exercise table where the event type is el.id and the sample time between start and endday from user inputs
|
|
const res2 = await query("SELECT sample_time FROM " + exerciseTable + " WHERE event_type_id = " + el.id + " AND sample_time BETWEEN " + startDay + " AND " + endDay);
|
|
|
|
// For every row from the query result
|
|
for (const row of res2.rows) {
|
|
let date = new Date(parseInt(row.sample_time)); // Converts current sample_time to javascript date
|
|
data[el.id][0][date.getHours() + (24 * Math.floor(Math.abs(date - startDay) / (1000 * 60 * 60 * 24)))]++;
|
|
/*
|
|
* date.getHours() - gives a value between 0 and 23
|
|
*
|
|
* Math.floor(Math.abs(date - startDay) / (1000 * 60 * 60 * 24)) - gives the day difference between the start day and the currentday
|
|
*
|
|
* The day difference is then multiplied by 24 to give the correct index in the data array
|
|
*
|
|
* Datenstruktur:
|
|
* data = {event_type.id: [[0,0,0,0,0,0,0,0,0,0,0,0,...], event_type.name, [latitude, longitude]], ...}
|
|
* 24 zeros, every zero stands for a time (first zero = 0:00, second = 1:00,...), if an
|
|
* event is found at 1:00 that zero is incremented to 1, if another event is found the 1 is incremented to 2.
|
|
* This is done for every zero on every event_type.
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
|
|
process.stdout.clearLine(0);
|
|
process.stdout.cursorTo(0);
|
|
successOutput("Filled \"dataset\" with data!");
|
|
successOutput("Sending data to \"index.ejs\"...");
|
|
progressCount.cur = 0;
|
|
progressCount.max = 0;
|
|
|
|
return data;
|
|
} catch (err) {
|
|
console.log(err);
|
|
errOutput(err);
|
|
data.errorcode = 600;
|
|
data.errorinfo = "Something went wrong while the Server processed the data! Please try again later!"
|
|
return data;
|
|
}
|
|
}
|
|
|
|
app.get("/", (req, res2) => {
|
|
//sendFile(__dirname + "/views/index.html") // -> input field sind nicht richtig
|
|
loadSiteFunc(res2);
|
|
//loadSite(res2, data, time, inputs, days, allExercises, error);
|
|
});
|
|
app.get("/settings", (req, res) => {
|
|
res.render("settings", {
|
|
settings: settings,
|
|
error: error
|
|
});
|
|
})
|
|
app.get("/processstatus", async (req, res) => {
|
|
let data = {
|
|
curElement: processStatus,
|
|
count: {
|
|
cur: parseInt(progressCount.cur),
|
|
max: parseInt(progressCount.max)
|
|
}
|
|
}
|
|
res.send(data);
|
|
processStatus = "";
|
|
});
|
|
app.get("/connectdatabase", async function(req, res){
|
|
let data = {};
|
|
if (req.query.host && req.query.user && req.query.database) {
|
|
inputs["host"] = req.query.host;
|
|
inputs["user"] = req.query.user;
|
|
inputs["password"] = req.query.password;
|
|
inputs["database"] = req.query.database;
|
|
// Create connection from user inputs
|
|
con = new Client({
|
|
user: inputs["user"],
|
|
host: inputs["host"],
|
|
database: inputs["database"],
|
|
password: inputs["password"]
|
|
});
|
|
|
|
// Check connection to database
|
|
infoOutput("Connecting to \"" + inputs["database"] + "\"...")
|
|
await con.connect()
|
|
.then(async () => {
|
|
successOutput("Connected to new Database (\"" + inputs["database"] + "\")!");
|
|
query = util.promisify(con.query).bind(con);
|
|
data.errorcode = 0;
|
|
data.allExercises = await getExercises();
|
|
allExercises = data.allExercises; // Save all Exercises
|
|
})
|
|
.catch((err) => {
|
|
console.log(err);
|
|
if(err.code == "ENOTFOUND"){ // Hostname wrong
|
|
data.errorcode = 501;
|
|
data.errorinfo = "Hostname (" + err.hostname + ") is incorrect! Please check your inputfields and try again!";
|
|
}else if(err.code == "28000"){ // Username wrong
|
|
data.errorcode = 502;
|
|
data.errorinfo = "Username (" + inputs.user + ") is incorrect! Please check your inputfields and try again!";
|
|
}else if(err.code == "WRONG PASSWORD"){ // Not working (Has to be correct err.code)
|
|
data.errorcode = 503;
|
|
data.errorinfo = "Password is incorrect! Please check your inputfields and try again!";
|
|
}else if(err.code == "3D000"){ // Databasename wrong
|
|
data.errorcode = 504;
|
|
data.errorinfo = "Database (" + inputs.database + ") is incorrect! Please check your inputfields and try again!";
|
|
}
|
|
errOutput(err);
|
|
});
|
|
}else{
|
|
if(!req.query.host){ // Host inputfield empty
|
|
data.errorcode = 505;
|
|
data.errorinfo = "Host inputfield is empty! Please try again!";
|
|
}else if(!req.query.user){ // User inputfield empty
|
|
data.errorcode = 506;
|
|
data.errorinfo = "User inputfield is empty! Please try again!";
|
|
}else if(!req.query.database){ // Database inputfield empty
|
|
data.errorcode = 508;
|
|
data.errorinfo = "Database inputfield is empty! Please try again!";
|
|
}else{ // Something else
|
|
data.errorcode = 500;
|
|
data.errorinfo = "Internal server error!";
|
|
}
|
|
}
|
|
// Send data to client
|
|
res.send(data);
|
|
});
|
|
app.get("/selectexercise", async function(req, res){
|
|
let data = {};
|
|
inputs.startDay = req.query.startDay;
|
|
inputs.endDay = req.query.endDay;
|
|
|
|
inputs.eventtypes = await getEventtypes(req.query.id);
|
|
|
|
inputs.days = await getExerciseDays();
|
|
data.errorcode = 0;
|
|
data.data = await getData(0, 23, (inputs.endDay - inputs.startDay)+1);
|
|
data.time = time;
|
|
|
|
data.inputs = inputs;
|
|
|
|
res.send(data);
|
|
});
|
|
app.get("/getdata", async function(req, res){
|
|
let data = {};
|
|
inputs.startDay = req.query.startDay;
|
|
inputs.endDay = req.query.endDay;
|
|
|
|
data.errorcode = 0;
|
|
inputs.selectedEvents = req.query.eventtypes;
|
|
data.data = await getData(0, 23, (inputs.endDay - inputs.startDay)+1);
|
|
data.time = time;
|
|
|
|
data.inputs = inputs;
|
|
|
|
res.send(data);
|
|
});
|
|
|
|
|
|
app.post("/", urlencodedParser, async function (req, res) {
|
|
let button_id = req.body.button_id; // 1 -> Connect, 2 -> Get Data, 3 -> Get All Data, 6 -> Select Exercise
|
|
|
|
if (button_id == 1) { // Connect Button
|
|
if (req.body.host && req.body.user && req.body.database) {
|
|
inputs["host"] = req.body.host;
|
|
inputs["user"] = req.body.user;
|
|
inputs["password"] = req.body.password;
|
|
inputs["database"] = req.body.database;
|
|
// Create connection from user inputs
|
|
con = new Client({
|
|
user: inputs["user"],
|
|
host: inputs["host"],
|
|
database: inputs["database"],
|
|
password: inputs["password"]
|
|
});
|
|
|
|
// Check connection to database
|
|
infoOutput("Connecting to \"" + inputs["database"] + "\"...")
|
|
con.connect()
|
|
.then(async () => {
|
|
connectedToDatabase = true;
|
|
inputs["button_id"] = button_id;
|
|
successOutput("Connected to new Database (\"" + inputs["database"] + "\")!");
|
|
query = util.promisify(con.query).bind(con);
|
|
error = 0;
|
|
getExercises(res);
|
|
})
|
|
.catch((err) => {
|
|
connectedToDatabase = false;
|
|
errOutput(err);
|
|
error = 1;
|
|
loadSiteFunc(res);
|
|
});
|
|
}
|
|
}
|
|
|
|
if (connectedToDatabase) {
|
|
if (button_id == 2) { // Get Data Button
|
|
let startTime = 0, endTime = 23;
|
|
if (req.body.startTime && req.body.endTime) {
|
|
startTime = parseInt(req.body.startTime);
|
|
endTime = parseInt(req.body.endTime);
|
|
// If end time is smaller/earlier than start time
|
|
if (endTime < startTime) {
|
|
endTime = startTime + 1;
|
|
}
|
|
} else if (req.body.startTime && !req.body.endTime) {
|
|
startTime = parseInt(req.body.startTime);
|
|
} else if (!req.body.start && req.body.endTime) {
|
|
endTime = parseInt(req.body.endTime);
|
|
}
|
|
// If user selected eventtypes
|
|
if (req.body.eventtypes) {
|
|
// Insert them into inputs
|
|
inputs["selectedEvents"] = req.body.eventtypes;
|
|
} else {
|
|
// Insert "random" number so .length is not 0
|
|
inputs["selectedEvents"] = ["1", "7"];
|
|
}
|
|
// Save user inputs into inputs{}
|
|
inputs["startTime"] = startTime;
|
|
inputs["endTime"] = endTime;
|
|
inputs["days"][0] = req.body.startDay;
|
|
inputs["days"][1] = req.body.endDay;
|
|
inputs["button_id"] = button_id;
|
|
// Check if start day is higher than end days
|
|
if (inputs["days"][0] > inputs["days"][1]) {
|
|
inputs["days"][0] = inputs["days"][1];
|
|
}
|
|
if (inputs["days"][0] == inputs["days"][1]) {
|
|
getData(startTime, endTime, 1, res);
|
|
} else {
|
|
let dayDif = inputs["days"][1] - inputs["days"][0] + 1;
|
|
getData(startTime, 23, dayDif, res);
|
|
}
|
|
}
|
|
|
|
if (button_id == 6) { // Select exercise
|
|
inputs["button_id"] = button_id;
|
|
// Find exercise information
|
|
selectedExercise = allExercises.find(el => el.id == req.body.exercise)
|
|
selectedExerciseTable = "ex_" + selectedExercise.id + ".eem_event";
|
|
inputs["selectedExercise"] = selectedExercise.name + ", " + selectedExercise.id + ", " + selectedExercise.start_time + ", " + selectedExercise.stop_time;
|
|
successOutput("Selected exercise: \"" + selectedExercise.name + ", " + selectedExercise.id + ", " + selectedExercise.start_time + ", " + selectedExercise.stop_time + "\"");
|
|
// Select all event types
|
|
const RESULTeventtypes = await query("SELECT * FROM pdm.pdm_event_type"); // all event types
|
|
allEventtypes = RESULTeventtypes.rows;
|
|
/*
|
|
exerciseEventtypes = allEventtypes;
|
|
let count = 0;
|
|
for(let el in allEventtypes){
|
|
inputs["selectedEvents"][count] = el.toString();
|
|
count++;
|
|
}*/
|
|
|
|
// Get all distinct event types from selected exercise
|
|
const RESULTexerciseEventtypesid = await query("SELECT DISTINCT event_type_id FROM " + selectedExerciseTable + " ORDER BY event_type_id ASC" ); // all event types in selected exercise
|
|
const exerciseEventtypesid = RESULTexerciseEventtypesid.rows;
|
|
exerciseEventtypes = [];
|
|
for (let i = 0; i < exerciseEventtypesid.length; i++) {
|
|
// Activate all checkboxes
|
|
inputs["selectedEvents"][i] = parseInt(exerciseEventtypesid[i].event_type_id).toString();
|
|
exerciseEventtypes[i] = {};
|
|
// Get name via id from allEventtypes
|
|
exerciseEventtypes[i] = allEventtypes.find(el => el.id == exerciseEventtypesid[i].event_type_id);
|
|
}
|
|
// Empty allExercises so pop up window does not show up
|
|
allExercises = [];
|
|
getExerciseDays(res);
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
async function getEventtypes(exerciseId){
|
|
let eventtypes = [];
|
|
// Set exercise table
|
|
exerciseTable = "ex_" + exerciseId + ".eem_event";
|
|
|
|
// Find selected exercise information
|
|
let exercise = allExercises.find(el => el.id == exerciseId)
|
|
// Save information in inputs
|
|
inputs.exercise.name = exercise.name;
|
|
inputs.exercise.id = exercise.id;
|
|
inputs.exercise.start_time = exercise.start_time;
|
|
inputs.exercise.stop_time = exercise.stop_time;
|
|
successOutput("Selected exercise: \"" + inputs.exercise.name + ", " + inputs.exercise.id + ", " + inputs.exercise.start_time + ", " + inputs.exercise.stop_time + "\"");
|
|
|
|
// Select all event types
|
|
allEventtypes = (await query("SELECT * FROM pdm.pdm_event_type")).rows;
|
|
|
|
// Get all distinct event types from selected exercise
|
|
const exerciseEventtypesid = (await query("SELECT DISTINCT event_type_id FROM " + exerciseTable + " ORDER BY event_type_id ASC" )).rows;
|
|
|
|
for (let i = 0; i < exerciseEventtypesid.length; i++) {
|
|
// Activate all checkboxes
|
|
inputs.selectedEvents[i] = parseInt(exerciseEventtypesid[i].event_type_id).toString();
|
|
eventtypes[i] = {};
|
|
// Get name via id from allEventtypes
|
|
eventtypes[i] = allEventtypes.find(el => el.id == exerciseEventtypesid[i].event_type_id);
|
|
}
|
|
return eventtypes;
|
|
}
|
|
|
|
async function getTimeInSteps(start, end, steps, curDayIndex) {
|
|
let times = []; // Where times are stored
|
|
let hour = start;
|
|
|
|
let startDay = new Date(days[parseInt(inputs["startDay"])])
|
|
let dayDate = await getStringDay(startDay.setDate(startDay.getDate() + curDayIndex) * 1);
|
|
// First and last entry are the start and end time
|
|
times[0] = dayDate + " " +("0" + hour).substr(-2) + ":00";
|
|
times[steps] = ("0" + end).substr(-2) + ":00";
|
|
|
|
let dif = end - start; // Difference between start time and end time
|
|
let step = dif / steps * 60; // Calculate steps
|
|
|
|
let minutes = 0, printMin, printHour;
|
|
for (let i = 0; i < steps - 1; i++) {
|
|
|
|
minutes += step;
|
|
if (minutes >= 60) { // If minutes are over or 60 minutes
|
|
hour++; // Hour gets incremented
|
|
minutes -= 60; // Minutes minus 60
|
|
}
|
|
printMin = ("0" + Math.trunc(minutes)).substr(-2);
|
|
printHour = ("0" + Math.trunc(hour)).substr(-2);
|
|
|
|
times[i + 1] = printHour + ":" + printMin;
|
|
}
|
|
|
|
return times; // Return times
|
|
}
|
|
|
|
async function getStringDay(InputTime) {
|
|
let unixTimestamp = 0;
|
|
let seperator = "-";
|
|
if (InputTime > 0) {
|
|
unixTimestamp = new Date(parseInt(InputTime));
|
|
} else {
|
|
unixTimestamp = new Date(new Date().getTime())
|
|
}
|
|
return unixTimestamp.getFullYear() + seperator + ("0" + (unixTimestamp.getMonth() + 1)).substr(-2) + seperator + ("0" + unixTimestamp.getDate()).substr(-2);
|
|
}
|
|
|
|
function infoOutput(message, returnText){
|
|
let firstWord = message.split(' ')[0];
|
|
let quoteIndex = message.indexOf("\"");
|
|
let text = color.fg_yellow + color.bg_black + "Message:" + color.reset + " " + color.fg_green + firstWord + color.fg_green + message.substring(firstWord.length, quoteIndex) +
|
|
"\"" +color.fg_white + message.substring(quoteIndex+1, message.indexOf("\"", quoteIndex+1)) + color.fg_green + message.substring(message.indexOf("\"", quoteIndex+1), message.length+1) + color.reset + color.fg_white;
|
|
if(returnText)
|
|
return text;
|
|
console.log(text);
|
|
}
|
|
|
|
function successOutput(message){
|
|
let firstWord = message.split(' ')[0];
|
|
let quoteIndex = message.indexOf("\"");
|
|
console.log(color.fg_white + color.bg_green + "Successfully:" + color.bg_black + " " + color.fg_yellow + firstWord + color.fg_green + message.substring(firstWord.length, quoteIndex) +
|
|
"\"" +color.fg_white + message.substring(quoteIndex+1, message.indexOf("\"", quoteIndex+1)) + color.fg_green + message.substring(message.indexOf("\"", quoteIndex+1), message.length+1) + color.reset + color.fg_white);
|
|
}
|
|
|
|
function errOutput(error) {
|
|
// Prints error message with red color
|
|
console.log(color.bg_red + "ERROR CAUGHT:" + color.bg_black + " " + color.fg_red + error + color.fg_white + color.reset);
|
|
}
|
|
|
|
app.listen(port, () => {
|
|
infoOutput("Server: \"http://localhost:" + port + "/\"");
|
|
infoOutput("Settings: \"http://localhost:" + port + "/settings\"");
|
|
});
|
|
|