Compare commits
6
Commits
v1.1
..
21333592ac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21333592ac | ||
|
|
8b673c67d3 | ||
|
|
0c76b852eb | ||
|
|
1e5cd0790b | ||
|
|
c85b918f71 | ||
|
|
8d75338676 |
@@ -2,8 +2,10 @@ const Database = require("better-sqlite3");
|
|||||||
const logger = require("../utils/logger.util");
|
const logger = require("../utils/logger.util");
|
||||||
const db_conf = require("../config/db.conf");
|
const db_conf = require("../config/db.conf");
|
||||||
|
|
||||||
|
// Holds the database class object
|
||||||
var db;
|
var db;
|
||||||
|
|
||||||
|
// Connect to SQLite database
|
||||||
function connect() {
|
function connect() {
|
||||||
try {
|
try {
|
||||||
logger.info("Connecting to Database...");
|
logger.info("Connecting to Database...");
|
||||||
@@ -14,10 +16,12 @@ function connect() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Database object getter
|
||||||
function getDB() {
|
function getDB() {
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Database object setter
|
||||||
function setDB(newDb) {
|
function setDB(newDb) {
|
||||||
db = newDb;
|
db = newDb;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,12 @@ const messages = require("../config/messages.conf.js");
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
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) {
|
function errorPageRenderer(res, emoji, message) {
|
||||||
res.render("error", {
|
res.render("error", {
|
||||||
page_title: app_conf.name,
|
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"),
|
css_path: path.join(app_conf.paths.css.web, "stylesheet.css"),
|
||||||
js_path: path.join(app_conf.paths.js.web, "error.js"),
|
js_path: path.join(app_conf.paths.js.web, "error.js"),
|
||||||
error_emoji: emoji,
|
error_emoji: emoji,
|
||||||
@@ -20,11 +23,14 @@ function errorPageRenderer(res, emoji, message) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove SQL row endpoint
|
||||||
router.delete("/remove", async (req, res) => {
|
router.delete("/remove", async (req, res) => {
|
||||||
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
||||||
|
|
||||||
|
// Get the row Name as request parameter
|
||||||
if (req.query["element"]) {
|
if (req.query["element"]) {
|
||||||
try {
|
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"]}';`);
|
const remove = db.getDB().prepare(`DELETE FROM ${db_conf.table_name} WHERE Name='${req.query["element"]}';`);
|
||||||
if (remove.run()["changes"]) {
|
if (remove.run()["changes"]) {
|
||||||
res.status(200).send();
|
res.status(200).send();
|
||||||
@@ -40,21 +46,26 @@ router.delete("/remove", async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Upload SQL database
|
||||||
router.post("/upload", async (req, res) => {
|
router.post("/upload", async (req, res) => {
|
||||||
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
||||||
|
|
||||||
|
// Check if file received
|
||||||
if (!req.files || !req.files.file) {
|
if (!req.files || !req.files.file) {
|
||||||
res.status(422).send();
|
res.status(422).send();
|
||||||
} else {
|
} else {
|
||||||
const uploadedFile = req.files.file;
|
const uploadedFile = req.files.file;
|
||||||
|
|
||||||
|
// Close current database
|
||||||
if (db.getDB()) {
|
if (db.getDB()) {
|
||||||
db.getDB().close();
|
db.getDB().close();
|
||||||
}
|
}
|
||||||
|
// Overwrite current database file with the new one
|
||||||
fs.copyFile(uploadedFile.tempFilePath, db_conf.path, (error) => {
|
fs.copyFile(uploadedFile.tempFilePath, db_conf.path, (error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
logger.error(error);
|
logger.error(error);
|
||||||
} else {
|
} else {
|
||||||
|
// Create new database (connect to db) object and store it
|
||||||
try {
|
try {
|
||||||
db.setDB(new Database(db_conf.path, { fileMustExist: true }));
|
db.setDB(new Database(db_conf.path, { fileMustExist: true }));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -66,17 +77,21 @@ router.post("/upload", async (req, res) => {
|
|||||||
res.status(201).send();
|
res.status(201).send();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Download current database file
|
||||||
router.get("/download", async (req, res) => {
|
router.get("/download", async (req, res) => {
|
||||||
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
||||||
|
|
||||||
res.download(db_conf.path);
|
res.download(db_conf.path);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add row to database
|
||||||
router.post("/add", async (req, res) => {
|
router.post("/add", async (req, res) => {
|
||||||
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
||||||
|
|
||||||
|
// Check if row name and row data received
|
||||||
if (req.query["element"] && req.body) {
|
if (req.query["element"] && req.body) {
|
||||||
try {
|
try {
|
||||||
|
// Constructing and executing SQL statement
|
||||||
let keys = Object.keys(req.body);
|
let keys = Object.keys(req.body);
|
||||||
let values = `'${req.query["element"]}',`;
|
let values = `'${req.query["element"]}',`;
|
||||||
|
|
||||||
@@ -105,11 +120,14 @@ router.post("/add", async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Edit SQL row
|
||||||
router.post("/edit", async (req, res) => {
|
router.post("/edit", async (req, res) => {
|
||||||
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
||||||
|
|
||||||
|
// Check if row name and row data received
|
||||||
if (req.query["element"] && req.body) {
|
if (req.query["element"] && req.body) {
|
||||||
try {
|
try {
|
||||||
|
// Constructing and executing SQL statement
|
||||||
let keys = Object.keys(req.body);
|
let keys = Object.keys(req.body);
|
||||||
let values = "";
|
let values = "";
|
||||||
|
|
||||||
@@ -138,10 +156,12 @@ router.post("/edit", async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add row to database page renderer
|
||||||
router.get("/add", async (req, res) => {
|
router.get("/add", async (req, res) => {
|
||||||
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Get all SQL columns to create HTML table
|
||||||
const select_get = db.getDB().prepare(`SELECT * FROM ${db_conf.table_name};`);
|
const select_get = db.getDB().prepare(`SELECT * FROM ${db_conf.table_name};`);
|
||||||
const row = select_get.get();
|
const row = select_get.get();
|
||||||
|
|
||||||
@@ -149,6 +169,10 @@ router.get("/add", async (req, res) => {
|
|||||||
var table_header = `<th>${sql_header[0]}</th>\n`;
|
var table_header = `<th>${sql_header[0]}</th>\n`;
|
||||||
sql_header.splice(0, 1);
|
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) {
|
if (row) {
|
||||||
var column_options = {};
|
var column_options = {};
|
||||||
for (const key of sql_header) {
|
for (const key of sql_header) {
|
||||||
@@ -180,6 +204,8 @@ router.get("/add", async (req, res) => {
|
|||||||
table_data += "</tr>";
|
table_data += "</tr>";
|
||||||
res.render("add", {
|
res.render("add", {
|
||||||
page_title: app_conf.name,
|
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"),
|
css_path: path.join(app_conf.paths.css.web, "stylesheet.css"),
|
||||||
js_path: path.join(app_conf.paths.js.web, "add.js"),
|
js_path: path.join(app_conf.paths.js.web, "add.js"),
|
||||||
column_options: JSON.stringify(column_options),
|
column_options: JSON.stringify(column_options),
|
||||||
@@ -195,9 +221,11 @@ router.get("/add", async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Edit SQL row page
|
||||||
router.get("/edit", async (req, res) => {
|
router.get("/edit", async (req, res) => {
|
||||||
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
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"]) {
|
if (req.query["element"]) {
|
||||||
try {
|
try {
|
||||||
const select_get = db.getDB().prepare(`SELECT * FROM ${db_conf.table_name} WHERE Name='${req.query["element"]}';`);
|
const select_get = db.getDB().prepare(`SELECT * FROM ${db_conf.table_name} WHERE Name='${req.query["element"]}';`);
|
||||||
@@ -246,6 +274,8 @@ router.get("/edit", async (req, res) => {
|
|||||||
|
|
||||||
res.render("edit", {
|
res.render("edit", {
|
||||||
page_title: app_conf.name,
|
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"),
|
css_path: path.join(app_conf.paths.css.web, "stylesheet.css"),
|
||||||
js_path: path.join(app_conf.paths.js.web, "edit.js"),
|
js_path: path.join(app_conf.paths.js.web, "edit.js"),
|
||||||
column_options: JSON.stringify(column_options),
|
column_options: JSON.stringify(column_options),
|
||||||
@@ -264,10 +294,12 @@ router.get("/edit", async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Main page
|
||||||
router.get("/", async (req, res) => {
|
router.get("/", async (req, res) => {
|
||||||
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
logger.info(`${req.method}: "${req.url}" => ${req.get("User-Agent")}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Get all rows from SQL and creating HTML table
|
||||||
const select = db.getDB().prepare(`SELECT * FROM ${db_conf.table_name}`);
|
const select = db.getDB().prepare(`SELECT * FROM ${db_conf.table_name}`);
|
||||||
const rows = select.all();
|
const rows = select.all();
|
||||||
|
|
||||||
@@ -293,6 +325,8 @@ router.get("/", async (req, res) => {
|
|||||||
|
|
||||||
res.render("index", {
|
res.render("index", {
|
||||||
page_title: app_conf.name,
|
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"),
|
css_path: path.join(app_conf.paths.css.web, "stylesheet.css"),
|
||||||
js_path: path.join(app_conf.paths.js.web, "index.js"),
|
js_path: path.join(app_conf.paths.js.web, "index.js"),
|
||||||
table_header: table_header,
|
table_header: table_header,
|
||||||
@@ -307,9 +341,12 @@ router.get("/", async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// About page for github
|
||||||
router.get("/about", (req, res) => {
|
router.get("/about", (req, res) => {
|
||||||
res.render("about", {
|
res.render("about", {
|
||||||
page_title: app_conf.name,
|
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"),
|
css_path: path.join(app_conf.paths.css.web, "stylesheet.css"),
|
||||||
version: app_conf.version
|
version: app_conf.version
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,15 +8,11 @@ router.use(app_conf.paths.css.web, express.static(path.join(path.dirname(require
|
|||||||
router.use(app_conf.paths.js.web, express.static(path.join(path.dirname(require.main.filename), app_conf.paths.js.src)));
|
router.use(app_conf.paths.js.web, express.static(path.join(path.dirname(require.main.filename), app_conf.paths.js.src)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main endpoint - might implement authentication step here...
|
* Main endpoint - authentication happens here
|
||||||
|
* Rewritting the whole url to fix logout bug
|
||||||
*/
|
*/
|
||||||
router.get("/", (req, res) => {
|
router.get("/", (req, res) => {
|
||||||
res.render("auth", {
|
res.redirect(`${app_conf.protocol}://${app_conf.host}:${app_conf.port}${app_conf.app_url}`);
|
||||||
page_title: app_conf.name,
|
|
||||||
css_path: path.join(app_conf.paths.css.web, "stylesheet.css"),
|
|
||||||
protocol: app_conf.protocol,
|
|
||||||
host: app_conf.host
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
+5
-2
@@ -17,7 +17,10 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="control_div" style="display: flex; flex-direction: row; justify-content: space-between;">
|
<div class="control_div" style="display: flex; flex-direction: row; justify-content: space-between;">
|
||||||
<label style="font-size: 200%;">CRTelemetry SQLite3</label>
|
<label style="font-size: 200%;">
|
||||||
|
<%= page_title%>
|
||||||
|
<%= program %>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="main_div">
|
<div class="main_div">
|
||||||
<center>
|
<center>
|
||||||
@@ -27,7 +30,7 @@
|
|||||||
style="font-size: 150%;">GitHub</a>
|
style="font-size: 150%;">GitHub</a>
|
||||||
</center>
|
</center>
|
||||||
<br>
|
<br>
|
||||||
<a href="/app"><span>🢀 </span>Return</a>
|
<a href="<%= app_url %>"><span>🢀 </span>Return</a>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
+9
-2
@@ -16,12 +16,16 @@
|
|||||||
<script src="<%= js_path %>" defer></script>
|
<script src="<%= js_path %>" defer></script>
|
||||||
<script defer>
|
<script defer>
|
||||||
var column_options = '<%- column_options %>';
|
var column_options = '<%- column_options %>';
|
||||||
|
var app_url = '<%= app_url %>';
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="control_div">
|
<div class="control_div">
|
||||||
<label style="font-size: 200%;">CRTelemetry SQLite3</label>
|
<label style="font-size: 200%;">
|
||||||
|
<%= page_title%>
|
||||||
|
<%= program %>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="main_div">
|
<div class="main_div">
|
||||||
<center><label>Add record</label></center>
|
<center><label>Add record</label></center>
|
||||||
@@ -32,10 +36,13 @@
|
|||||||
<%- table_data %>
|
<%- table_data %>
|
||||||
</table>
|
</table>
|
||||||
<div style="display: flex; flex-direction: row; justify-content: space-between;">
|
<div style="display: flex; flex-direction: row; justify-content: space-between;">
|
||||||
<a href="/app"><span>🢀 </span>Return</a>
|
<a href="<%= app_url %>"><span>🢀 </span>Return</a>
|
||||||
<label id="commit" style="cursor: pointer;"><span>✅ </span>Commit</label>
|
<label id="commit" style="cursor: pointer;"><span>✅ </span>Commit</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="about_div">
|
||||||
|
<center><a href="<%= app_url %>/about">About</label></center>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
<%= page_title %>
|
|
||||||
</title>
|
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"
|
|
||||||
rel="stylesheet">
|
|
||||||
<link rel="stylesheet" href="<%= css_path %>">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="control_div">
|
|
||||||
<label
|
|
||||||
style='font-family: "Ubuntu", sans-serif; font-weight: 500; font-style: normal; font-size: 200%;'>Centaurus
|
|
||||||
Racing Team</label>
|
|
||||||
</div>
|
|
||||||
<div class="main_div"
|
|
||||||
style="display: flex; flex-direction: column; justify-content: space-between; font-size: 150%; margin-top: 15px; margin-bottom: 15px;">
|
|
||||||
<div style="display: flex; flex-direction: row; justify-content: space-evenly;">
|
|
||||||
<label>CRTelemetry SQLite3</label>
|
|
||||||
<a href="<%= protocol %>://<%= host %>/app">Enter</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
+9
-2
@@ -16,12 +16,16 @@
|
|||||||
<script src="<%= js_path %>" defer></script>
|
<script src="<%= js_path %>" defer></script>
|
||||||
<script defer>
|
<script defer>
|
||||||
var column_options = '<%- column_options %>';
|
var column_options = '<%- column_options %>';
|
||||||
|
var app_url = '<%= app_url %>';
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="control_div" style="display: flex; flex-direction: row; justify-content: space-between;">
|
<div class="control_div" style="display: flex; flex-direction: row; justify-content: space-between;">
|
||||||
<label style="font-size: 200%;">CRTelemetry SQLite3</label>
|
<label style="font-size: 200%;">
|
||||||
|
<%= page_title%>
|
||||||
|
<%= program %>
|
||||||
|
</label>
|
||||||
<div style="display: flex;align-items: center;">
|
<div style="display: flex;align-items: center;">
|
||||||
<label id="remove" style="cursor: pointer; margin-right: 10px;"><span>- </span>Remove</label>
|
<label id="remove" style="cursor: pointer; margin-right: 10px;"><span>- </span>Remove</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -35,10 +39,13 @@
|
|||||||
<%- table_data %>
|
<%- table_data %>
|
||||||
</table>
|
</table>
|
||||||
<div style="display: flex; flex-direction: row; justify-content: space-between;">
|
<div style="display: flex; flex-direction: row; justify-content: space-between;">
|
||||||
<a href="/app"><span>🢀 </span>Return</a>
|
<a href="<%= app_url %>"><span>🢀 </span>Return</a>
|
||||||
<label id="commit" style="cursor: pointer;"><span>✅ </span>Commit</label>
|
<label id="commit" style="cursor: pointer;"><span>✅ </span>Commit</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="about_div">
|
||||||
|
<center><a href="<%= app_url %>/about">About</label></center>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
+8
-2
@@ -14,12 +14,18 @@
|
|||||||
rel="stylesheet">
|
rel="stylesheet">
|
||||||
<link rel="stylesheet" href="<%= css_path %>">
|
<link rel="stylesheet" href="<%= css_path %>">
|
||||||
<script src="<%= js_path %>" defer></script>
|
<script src="<%= js_path %>" defer></script>
|
||||||
|
<script defer>
|
||||||
|
var app_url = '<%= app_url %>';
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<input type="file" id="file_input" accept=".db" style="display: none;" />
|
<input type="file" id="file_input" accept=".db" style="display: none;" />
|
||||||
<div class="control_div" style="display: flex; flex-direction: row; justify-content: space-between;">
|
<div class="control_div" style="display: flex; flex-direction: row; justify-content: space-between;">
|
||||||
<label style="font-size: 200%;">CRTelemetry SQLite3</label>
|
<label style="font-size: 200%;">
|
||||||
|
<%= page_title%>
|
||||||
|
<%= program %>
|
||||||
|
</label>
|
||||||
<div style="display: flex;align-items: center;">
|
<div style="display: flex;align-items: center;">
|
||||||
<label id="upload" style="cursor: pointer; margin-left: 10px; margin-right: 10px;"><span>🡅
|
<label id="upload" style="cursor: pointer; margin-left: 10px; margin-right: 10px;"><span>🡅
|
||||||
</span>Upload</label>
|
</span>Upload</label>
|
||||||
@@ -36,7 +42,7 @@
|
|||||||
<%= error_message %>
|
<%= error_message %>
|
||||||
</label>
|
</label>
|
||||||
<br>
|
<br>
|
||||||
<a href="/app"><span>🢀 </span>Return</a>
|
<a href="<%= app_url %>"><span>🢀 </span>Return</a>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -14,12 +14,18 @@
|
|||||||
rel="stylesheet">
|
rel="stylesheet">
|
||||||
<link rel="stylesheet" href="<%= css_path %>">
|
<link rel="stylesheet" href="<%= css_path %>">
|
||||||
<script src="<%= js_path %>" defer></script>
|
<script src="<%= js_path %>" defer></script>
|
||||||
|
<script defer>
|
||||||
|
var app_url = '<%= app_url %>';
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<input type="file" id="file_input" accept=".db" style="display: none;" />
|
<input type="file" id="file_input" accept=".db" style="display: none;" />
|
||||||
<div class="control_div" style="display: flex; flex-direction: row; justify-content: space-between;">
|
<div class="control_div" style="display: flex; flex-direction: row; justify-content: space-between;">
|
||||||
<label style="font-size: 200%;">CRTelemetry SQLite3</label>
|
<label style="font-size: 200%;">
|
||||||
|
<%= page_title%>
|
||||||
|
<%= program %>
|
||||||
|
</label>
|
||||||
<div style="display: flex;align-items: center;">
|
<div style="display: flex;align-items: center;">
|
||||||
<label id="add" style="cursor: pointer; margin-right: 10px;"><span>+ </span>Add</label>
|
<label id="add" style="cursor: pointer; margin-right: 10px;"><span>+ </span>Add</label>
|
||||||
<label id="upload" style="cursor: pointer; margin-left: 10px; margin-right: 10px;"><span>🡅
|
<label id="upload" style="cursor: pointer; margin-left: 10px; margin-right: 10px;"><span>🡅
|
||||||
@@ -39,7 +45,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="about_div">
|
<div class="about_div">
|
||||||
<center><a href="/app/about">About</label></center>
|
<center><a href="<%= app_url %>/about">About</label></center>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
Generated
+4
-3
@@ -4,6 +4,7 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
|
"name": "database_editor",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"better-sqlite3": "^11.10.0",
|
"better-sqlite3": "^11.10.0",
|
||||||
"ejs": "^3.1.10",
|
"ejs": "^3.1.10",
|
||||||
@@ -1525,9 +1526,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tar-fs": {
|
"node_modules/tar-fs": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz",
|
||||||
"integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==",
|
"integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chownr": "^1.1.1",
|
"chownr": "^1.1.1",
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
version: "1.0",
|
version: "1.0",
|
||||||
name: "CRTelemetry",
|
name: "CRTelemetry",
|
||||||
|
program: "SQLite3",
|
||||||
host: "localhost",
|
host: "localhost",
|
||||||
protocol: "http",
|
protocol: "http",
|
||||||
port: 80,
|
port: 8080,
|
||||||
|
app_url: "/app",
|
||||||
username: "admin",
|
username: "admin",
|
||||||
password: "password",
|
password: "password",
|
||||||
logger: {
|
logger: {
|
||||||
|
|||||||
@@ -18,15 +18,15 @@ var shutting_down = false;
|
|||||||
* Static middleware - serve css and js files to public
|
* Static middleware - serve css and js files to public
|
||||||
*/
|
*/
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
// Set temp directory and upload size limit
|
||||||
app.use(fileUpload({
|
app.use(fileUpload({
|
||||||
limits: { fileSize: 102400 },
|
limits: { fileSize: 102400 },
|
||||||
useTempFiles: true,
|
useTempFiles: true,
|
||||||
tempFileDir: path.join(__dirname, app_conf.temp_directory)
|
tempFileDir: path.join(__dirname, app_conf.temp_directory)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
app.use("/", public_routes);
|
app.use(`/`, public_routes);
|
||||||
|
app.use(`${app_conf.app_url}`, basicAuth({
|
||||||
app.use("/app", basicAuth({
|
|
||||||
users: {
|
users: {
|
||||||
[app_conf.username]: app_conf.password
|
[app_conf.username]: app_conf.password
|
||||||
},
|
},
|
||||||
@@ -39,8 +39,8 @@ app.use("/app", basicAuth({
|
|||||||
*/
|
*/
|
||||||
app.set("view engine", "ejs");
|
app.set("view engine", "ejs");
|
||||||
app.set("views", path.join(__dirname, app_conf.views_directory));
|
app.set("views", path.join(__dirname, app_conf.views_directory));
|
||||||
const server = app.listen(app_conf.port, () => {
|
const server = app.listen(app_conf.port, (error) => {
|
||||||
logger.info("Starting Database Editor.");
|
logger.info(`Starting ${app_conf.name} ${app_conf.program}.`);
|
||||||
db.connect();
|
db.connect();
|
||||||
fs.rm(path.join(__dirname, app_conf.temp_directory, "/."), { recursive: true }, (error) => {
|
fs.rm(path.join(__dirname, app_conf.temp_directory, "/."), { recursive: true }, (error) => {
|
||||||
if (error == null) {
|
if (error == null) {
|
||||||
@@ -51,7 +51,13 @@ const server = app.listen(app_conf.port, () => {
|
|||||||
logger.error(error.message);
|
logger.error(error.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
logger.error(error.message);
|
||||||
|
shutdown();
|
||||||
|
} else {
|
||||||
logger.info(`Listening to port ${app_conf.port}.`);
|
logger.info(`Listening to port ${app_conf.port}.`);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -2,9 +2,6 @@ const sql_table = document.getElementById("sql_table");
|
|||||||
const sql_row = sql_table.rows;
|
const sql_row = sql_table.rows;
|
||||||
const commit = document.getElementById("commit");
|
const commit = document.getElementById("commit");
|
||||||
|
|
||||||
column_options = JSON.parse(column_options);
|
|
||||||
console.log(column_options);
|
|
||||||
|
|
||||||
commit.onmouseenter = async function () {
|
commit.onmouseenter = async function () {
|
||||||
this.style.backgroundColor = "blue";
|
this.style.backgroundColor = "blue";
|
||||||
}
|
}
|
||||||
@@ -18,12 +15,13 @@ commit.ondblclick = async function () {
|
|||||||
if (sql_row[1].cells[0].firstChild.value) {
|
if (sql_row[1].cells[0].firstChild.value) {
|
||||||
let req_body = {};
|
let req_body = {};
|
||||||
|
|
||||||
|
// Constructing request body by getting the values of each HTML select
|
||||||
for (let i = 1; i < sql_row[1].cells.length; i++) {
|
for (let i = 1; i < sql_row[1].cells.length; i++) {
|
||||||
req_body[sql_row[0].cells[i].firstChild.textContent] = sql_row[1].cells[i].firstChild[sql_row[1].cells[i].firstChild.selectedIndex].text;
|
req_body[sql_row[0].cells[i].firstChild.textContent] = sql_row[1].cells[i].firstChild[sql_row[1].cells[i].firstChild.selectedIndex].text;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/app/add?element=${sql_row[1].cells[0].firstChild.value}`, {
|
const response = await fetch(`${app_url}/add?element=${sql_row[1].cells[0].firstChild.value}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(req_body),
|
body: JSON.stringify(req_body),
|
||||||
headers: {
|
headers: {
|
||||||
@@ -31,21 +29,23 @@ commit.ondblclick = async function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
alert(`Add unsuccessful. ${response.status}`);
|
|
||||||
throw new Error(`Response status: ${response.status}`);
|
throw new Error(`Response status: ${response.status}`);
|
||||||
} else {
|
} else {
|
||||||
this.style.backgroundColor = "blue";
|
this.style.backgroundColor = "blue";
|
||||||
window.location.href = "/app";
|
window.location.href = app_url;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert(`Add unsuccessful. ${error.message}`);
|
alert(`Add unsuccessful. ${error.message}`);
|
||||||
console.error(error.message);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert("Sensor name can't be null.");
|
alert("Sensor name can't be null.");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Parsing distinct SQL values from backend
|
||||||
|
column_options = JSON.parse(column_options);
|
||||||
|
|
||||||
|
// Adding options to HTML selects
|
||||||
for (let i = 1; i < sql_row[1].cells.length; i++) {
|
for (let i = 1; i < sql_row[1].cells.length; i++) {
|
||||||
let opts = column_options[sql_row[0].cells[i].textContent];
|
let opts = column_options[sql_row[0].cells[i].textContent];
|
||||||
|
|
||||||
@@ -55,6 +55,7 @@ for (let i = 1; i < sql_row[1].cells.length; i++) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// On right click add custom value - custom value is always the last one in HTML select
|
||||||
sql_row[1].cells[i].firstChild.oncontextmenu = async function (ev) {
|
sql_row[1].cells[i].firstChild.oncontextmenu = async function (ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
let new_value = prompt("Enter a new value");
|
let new_value = prompt("Enter a new value");
|
||||||
|
|||||||
+7
-11
@@ -4,8 +4,6 @@ const commit = document.getElementById("commit");
|
|||||||
const remove = document.getElementById("remove");
|
const remove = document.getElementById("remove");
|
||||||
var changes = 0;
|
var changes = 0;
|
||||||
|
|
||||||
column_options = JSON.parse(column_options);
|
|
||||||
|
|
||||||
function setEventListeners(element, cb) {
|
function setEventListeners(element, cb) {
|
||||||
element.onmouseenter = async function () {
|
element.onmouseenter = async function () {
|
||||||
this.style.backgroundColor = "blue";
|
this.style.backgroundColor = "blue";
|
||||||
@@ -24,18 +22,16 @@ function setEventListeners(element, cb) {
|
|||||||
|
|
||||||
setEventListeners(remove, async () => {
|
setEventListeners(remove, async () => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/app/remove?element=${sql_row[1].cells[0].firstChild.textContent}`, {
|
const response = await fetch(`${app_url}/remove?element=${sql_row[1].cells[0].firstChild.textContent}`, {
|
||||||
method: "DELETE"
|
method: "DELETE"
|
||||||
});
|
});
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
alert(`Remove unsuccessful. ${response.status}`);
|
|
||||||
throw new Error(`Response status: ${response.status}`);
|
throw new Error(`Response status: ${response.status}`);
|
||||||
} else {
|
} else {
|
||||||
window.location.href = "/app";
|
window.location.href = app_url;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert(`Remove unsuccessful. ${error.message}`);
|
alert(`Remove unsuccessful. ${error.message}`);
|
||||||
console.error(error.message);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -43,6 +39,7 @@ setEventListeners(commit, async () => {
|
|||||||
if (changes) {
|
if (changes) {
|
||||||
let req_body = {};
|
let req_body = {};
|
||||||
|
|
||||||
|
// Constructing request body by adding ONLY updated values
|
||||||
for (let i = 1; i < sql_row[1].cells.length; i++) {
|
for (let i = 1; i < sql_row[1].cells.length; i++) {
|
||||||
if (sql_row[1].cells[i].firstChild.selectedIndex != 0) {
|
if (sql_row[1].cells[i].firstChild.selectedIndex != 0) {
|
||||||
req_body[sql_row[0].cells[i].firstChild.textContent] = sql_row[1].cells[i].firstChild[sql_row[1].cells[i].firstChild.selectedIndex].text;
|
req_body[sql_row[0].cells[i].firstChild.textContent] = sql_row[1].cells[i].firstChild[sql_row[1].cells[i].firstChild.selectedIndex].text;
|
||||||
@@ -50,7 +47,7 @@ setEventListeners(commit, async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/app/edit?element=${sql_row[1].cells[0].firstChild.textContent}`, {
|
const response = await fetch(`${app_url}/edit?element=${sql_row[1].cells[0].firstChild.textContent}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(req_body),
|
body: JSON.stringify(req_body),
|
||||||
headers: {
|
headers: {
|
||||||
@@ -58,20 +55,20 @@ setEventListeners(commit, async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
alert(`Edit unsuccessful. ${response.status}`);
|
|
||||||
throw new Error(`Response status: ${response.status}`);
|
throw new Error(`Response status: ${response.status}`);
|
||||||
} else {
|
} else {
|
||||||
window.location.href = "/app";
|
window.location.href = app_url;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert(`Edit unsuccessful. ${error.message}`);
|
alert(`Edit unsuccessful. ${error.message}`);
|
||||||
console.error(error.message);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert("Nothing to commit.");
|
alert("Nothing to commit.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
column_options = JSON.parse(column_options);
|
||||||
|
|
||||||
for (let i = 1; i < sql_row[1].cells.length; i++) {
|
for (let i = 1; i < sql_row[1].cells.length; i++) {
|
||||||
let opts = column_options[sql_row[0].cells[i].textContent];
|
let opts = column_options[sql_row[0].cells[i].textContent];
|
||||||
|
|
||||||
@@ -97,7 +94,6 @@ for (let i = 1; i < sql_row[1].cells.length; i++) {
|
|||||||
|
|
||||||
sql_row[1].cells[i].firstChild.onchange = async function () {
|
sql_row[1].cells[i].firstChild.onchange = async function () {
|
||||||
if (this.selectedIndex) {
|
if (this.selectedIndex) {
|
||||||
console.log(this);
|
|
||||||
this.parentElement.style.backgroundColor = "blue";
|
this.parentElement.style.backgroundColor = "blue";
|
||||||
changes++;
|
changes++;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -18,13 +18,14 @@ function setEventListeners(element, cb) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Upload SQL database
|
||||||
setEventListeners(upload, async () => {
|
setEventListeners(upload, async () => {
|
||||||
const input = document.getElementById("file_input");
|
const input = document.getElementById("file_input");
|
||||||
const upload = (file) => {
|
const upload = (file) => {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
|
|
||||||
fetch('/app/upload', {
|
fetch(`${app_url}/upload`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formData
|
body: formData
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
@@ -41,7 +42,7 @@ setEventListeners(upload, async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setEventListeners(download, () => {
|
setEventListeners(download, () => {
|
||||||
window.location.href = "/app/download";
|
window.location.href = `${app_url}/download`;
|
||||||
});
|
});
|
||||||
|
|
||||||
setEventListeners(logout, () => {
|
setEventListeners(logout, () => {
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ const download = document.getElementById("download");
|
|||||||
const logout = document.getElementById("logout");
|
const logout = document.getElementById("logout");
|
||||||
const add = document.getElementById("add");
|
const add = document.getElementById("add");
|
||||||
|
|
||||||
const sql_rows = sql_table.rows;
|
|
||||||
|
|
||||||
function setEventListeners(element, cb) {
|
function setEventListeners(element, cb) {
|
||||||
element.onmouseenter = async function () {
|
element.onmouseenter = async function () {
|
||||||
this.style.backgroundColor = "blue";
|
this.style.backgroundColor = "blue";
|
||||||
@@ -28,7 +26,7 @@ setEventListeners(upload, async () => {
|
|||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
|
|
||||||
fetch('/app/upload', {
|
fetch(`${app_url}/upload`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formData
|
body: formData
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
@@ -45,19 +43,21 @@ setEventListeners(upload, async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setEventListeners(add, () => {
|
setEventListeners(add, () => {
|
||||||
window.location.href = "/app/add";
|
window.location.href = `${app_url}/add`;
|
||||||
});
|
});
|
||||||
|
|
||||||
setEventListeners(download, () => {
|
setEventListeners(download, () => {
|
||||||
window.location.href = "/app/download";
|
window.location.href = `${app_url}/download`;
|
||||||
});
|
});
|
||||||
|
|
||||||
setEventListeners(logout, () => {
|
setEventListeners(logout, () => {
|
||||||
window.location.href = `${window.location.protocol}//logout@${window.location.host}/`;
|
window.location.href = `${window.location.protocol}//logout@${window.location.host}/`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const sql_rows = sql_table.rows;
|
||||||
|
|
||||||
for (let i = 1; i < sql_rows.length; i++) {
|
for (let i = 1; i < sql_rows.length; i++) {
|
||||||
setEventListeners(sql_rows[i], () => {
|
setEventListeners(sql_rows[i], () => {
|
||||||
window.location.href = `/app/edit?element=${sql_rows[i].cells[0].innerText}`;
|
window.location.href = `${app_url}/edit?element=${sql_rows[i].cells[0].innerText}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user