355 lines
12 KiB
JavaScript
355 lines
12 KiB
JavaScript
var db = require("../database/sqlite.database.js");
|
|
const logger = require("../utils/logger.util.js");
|
|
const Database = require("better-sqlite3");
|
|
const path = require("path");
|
|
const fs = require("fs");
|
|
const app_conf = require("../config/app.conf.js");
|
|
const db_conf = require("../config/db.conf.js");
|
|
const messages = require("../config/messages.conf.js");
|
|
|
|
const express = require('express');
|
|
const router = express.Router();
|
|
|
|
// Gets an Express response object an emoji code and a string message and renders as error message
|
|
function errorPageRenderer(res, emoji, message) {
|
|
res.render("error", {
|
|
page_title: app_conf.name,
|
|
program: app_conf.program,
|
|
app_url: app_conf.app_url,
|
|
css_path: path.join(app_conf.paths.css.web, "stylesheet.css"),
|
|
js_path: path.join(app_conf.paths.js.web, "error.js"),
|
|
error_emoji: emoji,
|
|
error_message: message
|
|
})
|
|
}
|
|
|
|
// Remove SQL row endpoint
|
|
router.delete("/remove", async (req, res) => {
|
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
|
|
|
// Get the row Name as request parameter
|
|
if (req.query["element"]) {
|
|
try {
|
|
// Create and run SQL statement to remove the row
|
|
const remove = db.getDB().prepare(`DELETE FROM ${db_conf.table_name} WHERE Name='${req.query["element"]}';`);
|
|
if (remove.run()["changes"]) {
|
|
res.status(200).send();
|
|
} else {
|
|
res.status(404).send();
|
|
}
|
|
} catch (error) {
|
|
res.status(500).send();
|
|
logger.error(error.message);
|
|
}
|
|
} else {
|
|
res.status(400).send();
|
|
}
|
|
});
|
|
|
|
// Upload SQL database
|
|
router.post("/upload", async (req, res) => {
|
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
|
|
|
// Check if file received
|
|
if (!req.files || !req.files.file) {
|
|
res.status(422).send();
|
|
} else {
|
|
const uploadedFile = req.files.file;
|
|
|
|
// Close current database
|
|
if (db.getDB()) {
|
|
db.getDB().close();
|
|
}
|
|
// Overwrite current database file with the new one
|
|
fs.copyFile(uploadedFile.tempFilePath, db_conf.path, (error) => {
|
|
if (error) {
|
|
logger.error(error);
|
|
} else {
|
|
// Create new database (connect to db) object and store it
|
|
try {
|
|
db.setDB(new Database(db_conf.path, { fileMustExist: true }));
|
|
} catch (error) {
|
|
logger.error(error);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
res.status(201).send();
|
|
});
|
|
|
|
// Download current database file
|
|
router.get("/download", async (req, res) => {
|
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
|
|
|
res.download(db_conf.path);
|
|
});
|
|
|
|
// Add row to database
|
|
router.post("/add", async (req, res) => {
|
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
|
|
|
// Check if row name and row data received
|
|
if (req.query["element"] && req.body) {
|
|
try {
|
|
// Constructing and executing SQL statement
|
|
let keys = Object.keys(req.body);
|
|
let values = `'${req.query["element"]}',`;
|
|
|
|
for (const k of keys) {
|
|
if (req.body[k] === "null") {
|
|
values += `NULL,`
|
|
} else {
|
|
values += `'${req.body[k]}',`;
|
|
}
|
|
}
|
|
|
|
if (values) {
|
|
values = values.slice(0, -1);
|
|
const update = db.getDB().prepare(`INSERT INTO ${db_conf.table_name} VALUES (${values});`);
|
|
update.run();
|
|
res.status(200).send();
|
|
} else {
|
|
res.status(400).send();
|
|
}
|
|
} catch (error) {
|
|
res.status(500).send();
|
|
logger.error(error.message);
|
|
}
|
|
} else {
|
|
res.status(400).send();
|
|
}
|
|
});
|
|
|
|
// Edit SQL row
|
|
router.post("/edit", async (req, res) => {
|
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
|
|
|
// Check if row name and row data received
|
|
if (req.query["element"] && req.body) {
|
|
try {
|
|
// Constructing and executing SQL statement
|
|
let keys = Object.keys(req.body);
|
|
let values = "";
|
|
|
|
for (const k of keys) {
|
|
if (req.body[k] === "null") {
|
|
values += `${k}=NULL,`
|
|
} else {
|
|
values += `${k}='${req.body[k]}',`;
|
|
}
|
|
}
|
|
|
|
if (values) {
|
|
values = values.slice(0, -1);
|
|
const update = db.getDB().prepare(`UPDATE ${db_conf.table_name} SET ${values} WHERE Name='${req.query["element"]}'`);
|
|
update.run();
|
|
res.status(200).send();
|
|
} else {
|
|
res.status(400).send();
|
|
}
|
|
} catch (error) {
|
|
res.status(500).send();
|
|
logger.error(error.message);
|
|
}
|
|
} else {
|
|
res.status(400).send();
|
|
}
|
|
});
|
|
|
|
// Add row to database page renderer
|
|
router.get("/add", async (req, res) => {
|
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
|
|
|
try {
|
|
// Get all SQL columns to create HTML table
|
|
const select_get = db.getDB().prepare(`SELECT * FROM ${db_conf.table_name};`);
|
|
const row = select_get.get();
|
|
|
|
const sql_header = Object.keys(row);
|
|
var table_header = `<th>${sql_header[0]}</th>\n`;
|
|
sql_header.splice(0, 1);
|
|
|
|
/*
|
|
* Getting all distinct values for each column except the value from the
|
|
* current column to add as options to the HTML selects.
|
|
*/
|
|
if (row) {
|
|
var column_options = {};
|
|
for (const key of sql_header) {
|
|
table_header += `<th>${key}</th>\n`;
|
|
|
|
const select_distinct = db.getDB().prepare(`
|
|
SELECT DISTINCT ${key}
|
|
FROM ${db_conf.table_name};
|
|
`);
|
|
values = select_distinct.all();
|
|
|
|
for (v of values) {
|
|
if (column_options[key] == null) {
|
|
column_options[key] = Object.values(v);
|
|
} else {
|
|
column_options[key] = column_options[key].concat(Object.values(v));
|
|
}
|
|
}
|
|
}
|
|
|
|
var table_data = "";
|
|
const sql_row_values = Object.values(row);
|
|
|
|
table_data += `<tr><td><input type="text" placeholder="Sensor name"></td>\n`;
|
|
for (let i = 1; i < sql_row_values.length; i++) {
|
|
table_data += `<td><select></select></td>\n`;
|
|
}
|
|
|
|
table_data += "</tr>";
|
|
res.render("add", {
|
|
page_title: app_conf.name,
|
|
program: app_conf.program,
|
|
app_url: app_conf.app_url,
|
|
css_path: path.join(app_conf.paths.css.web, "stylesheet.css"),
|
|
js_path: path.join(app_conf.paths.js.web, "add.js"),
|
|
column_options: JSON.stringify(column_options),
|
|
table_header: table_header,
|
|
table_data: table_data
|
|
});
|
|
} else {
|
|
errorPageRenderer(res, "❓", messages.empty_db);
|
|
}
|
|
} catch (error) {
|
|
errorPageRenderer(res, "🌋💥", messages.internal_server_error);
|
|
logger.error(error.message);
|
|
}
|
|
});
|
|
|
|
// Edit SQL row page
|
|
router.get("/edit", async (req, res) => {
|
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
|
|
|
// Same as ADD GET REQUEST but Name is constant as it identifies the row
|
|
if (req.query["element"]) {
|
|
try {
|
|
const select_get = db.getDB().prepare(`SELECT * FROM ${db_conf.table_name} WHERE Name='${req.query["element"]}';`);
|
|
const row = select_get.get();
|
|
|
|
if (row) {
|
|
const sql_header = Object.keys(row);
|
|
var table_header = `<th>${sql_header[0]}</th>\n`;
|
|
sql_header.splice(0, 1);
|
|
|
|
var column_options = {};
|
|
for (const key of sql_header) {
|
|
table_header += `<th>${key}</th>\n`;
|
|
|
|
const select_distinct = db.getDB().prepare(`
|
|
SELECT DISTINCT ${key}
|
|
FROM ${db_conf.table_name}
|
|
WHERE ${key} IS NOT NULL
|
|
AND ${key} NOT IN (
|
|
SELECT ${key}
|
|
FROM ${db_conf.table_name}
|
|
WHERE Name='${req.query["element"]}'
|
|
AND ${key} IS NOT NULL);
|
|
`);
|
|
values = select_distinct.all();
|
|
|
|
for (v of values) {
|
|
if (column_options[key] == null) {
|
|
column_options[key] = Object.values(v);
|
|
} else {
|
|
column_options[key] = column_options[key].concat(Object.values(v));
|
|
}
|
|
}
|
|
}
|
|
|
|
var table_data = "";
|
|
const sql_row_values = Object.values(row);
|
|
table_data += `<tr><td>${sql_row_values[0]}</td>\n`;
|
|
sql_row_values.splice(0, 1);
|
|
|
|
for (const v of sql_row_values) {
|
|
table_data += `<td><select><option selected="selected">${v}</option></select></td>\n`;
|
|
}
|
|
|
|
table_data += "</tr>";
|
|
|
|
res.render("edit", {
|
|
page_title: app_conf.name,
|
|
program: app_conf.program,
|
|
app_url: app_conf.app_url,
|
|
css_path: path.join(app_conf.paths.css.web, "stylesheet.css"),
|
|
js_path: path.join(app_conf.paths.js.web, "edit.js"),
|
|
column_options: JSON.stringify(column_options),
|
|
table_header: table_header,
|
|
table_data: table_data
|
|
});
|
|
} else {
|
|
errorPageRenderer(res, "🔍❌", messages.not_found);
|
|
}
|
|
} catch (error) {
|
|
errorPageRenderer(res, "🌋💥", messages.internal_server_error);
|
|
logger.error(error.message);
|
|
}
|
|
} else {
|
|
errorPageRenderer(res, "✋⛔", messages.bad_request);
|
|
}
|
|
});
|
|
|
|
// Main page
|
|
router.get("/", async (req, res) => {
|
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
|
|
|
try {
|
|
// Get all rows from SQL and creating HTML table
|
|
const select = db.getDB().prepare(`SELECT * FROM ${db_conf.table_name}`);
|
|
const rows = select.all();
|
|
|
|
if (rows[0]) {
|
|
const sql_header = Object.keys(rows[0]);
|
|
|
|
var table_header = "";
|
|
for (const key of sql_header) {
|
|
table_header += `<th>${key}</th>\n`;
|
|
}
|
|
|
|
var table_data = "";
|
|
for (const row of rows) {
|
|
const sql_row_values = Object.values(row);
|
|
table_data += "<tr>";
|
|
|
|
for (const v of sql_row_values) {
|
|
table_data += `<td>${v}</td>\n`;
|
|
}
|
|
|
|
table_data += "</tr>";
|
|
}
|
|
|
|
res.render("index", {
|
|
page_title: app_conf.name,
|
|
program: app_conf.program,
|
|
app_url: app_conf.app_url,
|
|
css_path: path.join(app_conf.paths.css.web, "stylesheet.css"),
|
|
js_path: path.join(app_conf.paths.js.web, "index.js"),
|
|
table_header: table_header,
|
|
table_data: table_data
|
|
});
|
|
} else {
|
|
errorPageRenderer(res, "❓", messages.empty_db);
|
|
}
|
|
} catch (error) {
|
|
errorPageRenderer(res, "🌋💥", messages.internal_server_error);
|
|
logger.error(error.message);
|
|
}
|
|
});
|
|
|
|
// About page for github
|
|
router.get("/about", (req, res) => {
|
|
res.render("about", {
|
|
page_title: app_conf.name,
|
|
program: app_conf.program,
|
|
app_url: app_conf.app_url,
|
|
css_path: path.join(app_conf.paths.css.web, "stylesheet.css"),
|
|
version: app_conf.version
|
|
});
|
|
});
|
|
|
|
module.exports = router; |