mirror of
https://github.com/TheGreyDiamond/elevatormapRewritten.git
synced 2025-07-18 02:23:50 +02:00
Adds communication with MySQL
This commit is contained in:
@ -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.
|
||||
|
9
config/default.json.example
Normal file
9
config/default.json.example
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"fontAwesome": "",
|
||||
"mapboxAccessToken": "",
|
||||
"mysql": {
|
||||
"user": "",
|
||||
"password": "",
|
||||
"allowCreation": true
|
||||
}
|
||||
}
|
146
index.js
146
index.js
@ -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}`);
|
||||
|
@ -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
34
static/css/mainMap.css
Normal 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
65
templates/dbError.html
Normal 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>
|
@ -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
111
templates/map.html
Normal 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 © <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>
|
Reference in New Issue
Block a user