Adds communication with MySQL

This commit is contained in:
TheGreyDiamond
2021-05-23 20:48:30 +02:00
parent 2d5553d901
commit 959c8812ad
8 changed files with 389 additions and 4 deletions

View File

@ -1,2 +1,2 @@
# elevatormap Rewritten
# Elevatormap Rewritten
The elevator map at thegreydiamond.de/elevatormap has been offline for some time now, as it was very ineffective and didn't accept user contributions. This is an attempted my the original author to rewrite the project in Node.js.

View File

@ -0,0 +1,9 @@
{
"fontAwesome": "",
"mapboxAccessToken": "",
"mysql": {
"user": "",
"password": "",
"allowCreation": true
}
}

146
index.js
View File

@ -3,11 +3,13 @@ const express = require("express");
const fs = require("fs");
const Eta = require("eta");
const winston = require("winston");
const { log } = require("util");
const mysql = require('mysql');
// Inting the logger
const logger = winston.createLogger({
level: "info",
level: "debug",
format: winston.format.json(),
defaultMeta: { service: "user-service" },
transports: [
@ -32,6 +34,7 @@ app.use(express.static("static"));
// Settings
const port = 3000;
const startUpTime = Math.floor(new Date().getTime() / 1000);
// Load config
try {
@ -46,6 +49,8 @@ try {
jsonConfig = JSON.parse(data);
}
var fontawesomeKey = jsonConfig.fontAwesome;
var mapboxAccessToken = jsonConfig.mapboxAccessToken;
var mysqlData = jsonConfig.mysql;
} catch (error) {
logger.error(
"While reading the config an error occured. The error was: " + error
@ -56,6 +61,58 @@ try {
const author = "TheGreydiamond";
const desc = "Elevatormap";
const sitePrefix = "Elevatormap - ";
let mysqlIsUpAndOkay = false;
let mySQLstate = 0; // 0 -> Default failure 1 -> Missing strucutre
// Prepare MYSQL
var con = mysql.createConnection({
host: "localhost",
user: mysqlData.user,
password: mysqlData.password,
database: mysqlData.database
});
function checkIfMySQLStructureIsReady(){
if(mysqlIsUpAndOkay){
// Only if MySQL is ready
logger.debug("Checking MySQL strucutre")
con.query("SHOW TABLES;", function (err, result, fields) {
if (err) throw err;
if(result.length == 0){
// There are no tables. Not good.
logger.warn("There are no tables found")
if(mysqlData.allowCreation){
// Lets create it then
logger.warn("Creating a new table")
const sql = 'CREATE TABLE `' + mysqlData.database + '`.`elevators` ( `id` INT NOT NULL AUTO_INCREMENT , `lat` FLOAT NOT NULL , `lng` FLOAT NOT NULL , `manufacturer` VARCHAR(512) NOT NULL , `info` VARCHAR(512) NOT NULL , `visitabilty` INT NOT NULL , `technology` INT NOT NULL , `images` JSON NOT NULL , `amountOfFloors` INT NOT NULL , `maxPassangers` INT NOT NULL , `maxWeight` INT NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;';
con.query(sql, function (err, result) {
if (err) throw err;
logger.info("Table created");
});
}else{
// We cannot do that. Welp.
logger.warn("MySQL tables are missing and the config denies creation of new ones.")
mysqlIsUpAndOkay = false;
mySQLstate = 1;
}
}
});
}else{
logger.warn("Tried checking the tables even though MySQL wasn't ready.");
}
}
con.connect(function(err) {
if (err){
mysqlIsUpAndOkay = false;
logger.error("Connction to MySQL failed")
}else{
logger.info("Mysql is ready.");
mysqlIsUpAndOkay = true;
checkIfMySQLStructureIsReady();
}
});
// Routes
app.get("/", function (req, res) {
@ -70,6 +127,91 @@ app.get("/", function (req, res) {
);
});
app.get("/map", function (req, res) {
if(mysqlIsUpAndOkay){
const data = fs.readFileSync("templates/map.html", "utf8");
res.send(
Eta.render(data, {
author: author,
desc: desc,
siteTitel: sitePrefix + "Map",
fontawesomeKey: fontawesomeKey,
mapboxAccessToken: mapboxAccessToken
})
);
}else{
const data = fs.readFileSync("templates/dbError.html", "utf8");
var displayText = "This might be an artifact of a recent restart. Maybe wait a few minutes and reload this page.";
if(startUpTime + 60 <= Math.floor(new Date().getTime() / 1000)){
displayText = "The server failed to connect to the MySQL server. This means it was unable to load any data.";
}
if(mySQLstate == 1){
displayText = "There is a problem with the database servers setup. Please check the log for more info.";
}
res.send(
Eta.render(data, {
author: author,
desc: desc,
siteTitel: sitePrefix + "Error",
fontawesomeKey: fontawesomeKey,
displayText: displayText
})
);
}
});
app.get("/api/getElevators", function (req, res) {
console.log(req.query)
if(req.query.lan != undefined && req.query.lat != undefined && req.query.radius != undefined){
// All parameters are there
res.setHeader('Content-Type', 'application/json');
try {
var lan = parseFloat(req.query.lan)
var lat = parseFloat(req.query.lat)
var radius = parseFloat(req.query.radius)
} catch (error) {
res.send(JSON.stringify({ state: "Failed", "message": "Invalid arguments" }));
res.status(400);
return
}
var lan = parseFloat(req.query.lan)
var lat = parseFloat(req.query.lat)
var radius = parseFloat(req.query.radius)
res.send(JSON.stringify({ state: "Ok", "message": ""}));
res.status(200);
}else{
// Welp something is missing
res.status(400);
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ state: "Failed", "message": "Missing arguments" }));
}
});
// Some loops for handeling stuff
setInterval(() => {
if(mysqlIsUpAndOkay == false){
logger.warn("Retrying to connect to MySQL")
con = mysql.createConnection({
host: "localhost",
user: mysqlData.user,
password: mysqlData.password,
database: mysqlData.database
});
con.connect(function(err) {
if (err){
mysqlIsUpAndOkay = false;
logger.error("Connction to MySQL failed")
}else{
logger.info("Mysql is ready.")
mysqlIsUpAndOkay = true;
}
});
}
}, 60000);
// App start
app.listen(port, () => {
logger.info(`Elevator map ready at http://localhost:${port}`);

View File

@ -20,6 +20,7 @@
"dependencies": {
"eta": "^1.12.1",
"express": "^4.17.1",
"mysql": "^2.18.1",
"winston": "^3.3.3"
}
}

34
static/css/mainMap.css Normal file
View File

@ -0,0 +1,34 @@
.inspector {
margin: 0px;
background-color: greenyellow;
height: 100vh;
width: 20%;
float: right;
position: fixed;
right: 0px;
top: 0px;
}
.map {
margin: 0px;
background-color: red;
height: 100vh;
width: 80%;
z-index: 1;
/*float: left;*/
}
aside {
padding: 10px;
position: absolute;
z-index: 100;
left: 1rem;
bottom: 1rem;
width: 20px;
padding: 0 1.5rem;
background-color: rgba(97, 97, 97, 0.486);
}
aside h2 {
font-size: 1.5rem;
line-height: 1.05em;
}

65
templates/dbError.html Normal file
View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Basic Page Needs
-->
<meta charset="utf-8">
<title><%= it.siteTitel %></title>
<meta name="description" content="<%= it.desc %>">
<meta name="author" content="<%= it.author %>">
<!-- Mobile Specific Metas
-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- FONT
-->
<link href="//fonts.googleapis.com/css?family=Raleway:400,300,600" rel="stylesheet" type="text/css">
<!-- CSS
-->
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/barebones.css">
<!-- Favicon
-->
<link rel="icon" type="image/png" href="images/favicon-16.png">
<script async defer src="/js/site.js"></script>
<script src="https://kit.fontawesome.com/<%= it.fontawesomeKey %>.js" crossorigin="anonymous"></script>
</head>
<body>
<!-- Primary Page Layout
-->
<div class="grid-container thirds" style="margin-top: 5%;">
<div></div>
<div>
<h1><i style="color: red;" class="fas fa-exclamation-triangle"></i></h1>
</div>
</div>
</div>
<div class="grid-container thirds" style="margin-top: 5%;">
<div></div>
<div>
<h1>Oh no!</h1>
<p>This page can currently not be displayed.
<%= it.displayText %>
<br>
<a href="/"><button class="button-primary">
Return to the startpage
</button>
</a>
</p>
</div>
</div>
</div>
<!-- End Document
-->
</body>
</html>

View File

@ -44,6 +44,17 @@
</div>
</div>
<div class="grid-container thirds" style="margin-top: 5%;">
<div></div>
<div>
<h5>
Check it out now <br>
<a href= "/map" ><button class="button-primary">Visit the map <i class="fas fa-arrow-right"></i> </button></a>
</h5>
</div>
</div>
<div class="grid-container thirds" style="margin-top: 5%;">
<div>
<h3> <i class="fas fa-rocket"></i><br>
@ -54,12 +65,24 @@
Comunity driven</h3>
</div>
<div>
<h3> <i class="fas fa-node-js"></i><br>
<h3> <i class="fab fa-node-js"></i><br>
Built on node.js</h3>
</div>
</div>
</div>
<div class="grid-container thirds" style="margin-top: 5%;">
<div></div>
<div>
<h3>
<i class="fas fa-atlas"></i><br>
With currently <%= it.elevatorCount %> elevators in the map
</h3>
</div>
</div>
<!-- End Document
-->
</body>

111
templates/map.html Normal file
View File

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Basic Page Needs
-->
<meta charset="utf-8" />
<title><%= it.siteTitel %></title>
<meta name="description" content="<%= it.desc %>" />
<meta name="author" content="<%= it.author %>" />
<!-- Mobile Specific Metas
-->
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- FONT
-->
<link
href="//fonts.googleapis.com/css?family=Raleway:400,300,600"
rel="stylesheet"
type="text/css"
/>
<!-- CSS
-->
<link rel="stylesheet" href="css/normalize.css" />
<link rel="stylesheet" href="css/barebones.css" />
<link rel="stylesheet" href="css/skeleton-legacy.css" />
<link rel="stylesheet" href="css/mainMap.css" />
<!-- Favicon
-->
<link rel="icon" type="image/png" href="images/favicon-16.png" />
<script async defer src="/js/site.js"></script>
<script
src="https://kit.fontawesome.com/<%= it.fontawesomeKey %>.js"
crossorigin="anonymous"
></script>
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""
/>
<!-- Make sure you put this AFTER Leaflet's CSS -->
<script
src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""
></script>
</head>
<body>
<!-- Primary Page Layout
-->
<div style="margin: 0px">
<div class="map" id="map"></div>
<div class="inspector"></div>
</div>
<aside>
<i
style="color: black; cursor: pointer"
class="fas fa-map-marker-alt"
onclick="home()"
></i>
</aside>
<!-- End Document
-->
<script type="text/javascript">
var mymap = L.map("map").setView([51.505, -0.09], 50);
L.tileLayer(
"https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=<%= it.mapboxAccessToken %>",
{
attribution:
'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: "mapbox/streets-v11",
tileSize: 512,
zoomOffset: -1,
accessToken: "<%= it.mapboxAccessToken %>",
}
).addTo(mymap);
function showPosition(position) {
console.log(position.coords);
mymap.setView(
new L.LatLng(position.coords.latitude, position.coords.longitude),
10
);
// mymap.setView(new L.LatLng(10.737, -73.923), 8);
}
function home() {
if (navigator.geolocation) {
setTimeout(function () {
navigator.geolocation.getCurrentPosition(showPosition);
}, 200);
} else {
console.warn("Geolocation of user could not be fetched");
}
}
home();
</script>
</body>
</html>