aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoelHMikael <joel.h.kronqvist@gmail.com>2022-01-08 16:49:37 +0200
committerJoelHMikael <joel.h.kronqvist@gmail.com>2022-01-08 16:49:37 +0200
commit24709fa862636702fd0430e832463b751fce323e (patch)
tree8bd4eabbf2c7fe4525f66bfe55e3c47994214d79
parent4e5fe4711fe46a6af740aadbf23bde86bb5acf69 (diff)
downloadLYLLRuoka-24709fa862636702fd0430e832463b751fce323e.tar.gz
LYLLRuoka-24709fa862636702fd0430e832463b751fce323e.zip
Parsing the shifts (not classes) to the database + some GUI improvements
-rw-r--r--404/index.css3
-rw-r--r--404/index.html16
-rw-r--r--Cont/404/index.css3
-rw-r--r--Cont/404/index.html26
-rw-r--r--Cont/Images/back.pngbin0 -> 3528 bytes
-rw-r--r--Cont/Images/help.png (renamed from help.png)bin2347 -> 2347 bytes
-rw-r--r--Cont/devs/index.css18
-rw-r--r--Cont/devs/index.html26
-rw-r--r--Cont/index.css (renamed from index.css)0
-rw-r--r--Cont/index.html (renamed from index.html)6
-rw-r--r--Cont/non-main.css26
-rw-r--r--README.md18
-rw-r--r--database.js52
-rw-r--r--dbparse.js365
-rw-r--r--package.json29
-rw-r--r--parse.js1
-rw-r--r--server.js82
17 files changed, 619 insertions, 52 deletions
diff --git a/404/index.css b/404/index.css
deleted file mode 100644
index ceb8016..0000000
--- a/404/index.css
+++ /dev/null
@@ -1,3 +0,0 @@
-body {
- padding-top: calc(30vh);
-}
diff --git a/404/index.html b/404/index.html
deleted file mode 100644
index e6771ad..0000000
--- a/404/index.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="utf-8">
- <title>Page not found</title>
- <link href="/index.css" rel="stylesheet" type="text/css">
- <link href="/404/index.css" rel="stylesheet" type="text/css">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- </head>
- <body>
- <div class="float-block">
- <h1>404: sivua \(path\) ei löytynyt.</h1>
- <p>Voi myös olla, että sinulla ei ole oikeuksia sivun tarkasteluun tai että palvelimella on tapahtunut virhe. Jos epäilet jälkimmäistä, otathan yhteyttä joel.kronqvist@edu.lohja.fi</p>
- </div>
- </body>
-</html>
diff --git a/Cont/404/index.css b/Cont/404/index.css
new file mode 100644
index 0000000..664d7fb
--- /dev/null
+++ b/Cont/404/index.css
@@ -0,0 +1,3 @@
+body {
+ padding-top: 30vh;
+}
diff --git a/Cont/404/index.html b/Cont/404/index.html
new file mode 100644
index 0000000..5b01684
--- /dev/null
+++ b/Cont/404/index.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html lang="fi">
+ <head>
+ <meta charset="utf-8">
+ <title>Page not found</title>
+ <link href="/index.css" rel="stylesheet" type="text/css">
+ <link href="/non-main.css" rel="stylesheet" type="text/css">
+ <link href="/404/index.css" rel="stylesheet" type="text/css">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ </head>
+ <body>
+ <div class="float-block">
+ <h1>404: sivua \(path\) ei löytynyt.</h1>
+ <p>Voi myös olla, että palvelimella on tapahtunut virhe. Jos epäilet jälkimmäistä, otathan yhteyttä palvelusta vastaaviin henkilöihin.</p>
+ </div>
+
+ <a class="back" href="/"><img src="/Images/back.png" alt="Takaisin etusivulle"></a>
+
+ <footer>
+ <a href="https://www.github.com/JoelHMikael/FoodJS">Lähdekoodi</a>
+ <span>|</span>
+ <a href="/devs">Ota yhteyttä</a>
+ </footer>
+
+ </body>
+</html>
diff --git a/Cont/Images/back.png b/Cont/Images/back.png
new file mode 100644
index 0000000..01b9bc7
--- /dev/null
+++ b/Cont/Images/back.png
Binary files differ
diff --git a/help.png b/Cont/Images/help.png
index 51d84df..51d84df 100644
--- a/help.png
+++ b/Cont/Images/help.png
Binary files differ
diff --git a/Cont/devs/index.css b/Cont/devs/index.css
new file mode 100644
index 0000000..1cce621
--- /dev/null
+++ b/Cont/devs/index.css
@@ -0,0 +1,18 @@
+.column {
+ display: inline-block;
+ padding: 0;
+ margin: .5em;
+ box-sizing: border-box;
+ vertical-align: middle;
+ overflow-wrap: break-word;
+ width: 100%;
+}
+
+
+@media screen and (min-width: 700px)
+{
+ .column {
+ width: calc(33% - 2em);
+ }
+}
+
diff --git a/Cont/devs/index.html b/Cont/devs/index.html
new file mode 100644
index 0000000..69116c6
--- /dev/null
+++ b/Cont/devs/index.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html lang="fi">
+ <head>
+ <meta charset="utf-8">
+ <title>Developers</title>
+ <link href="/index.css" rel="stylesheet" type="text/css">
+ <link href="/non-main.css" rel="stylesheet" type="text/css">
+ <link href="/devs/index.css" rel="stylesheet" type="text/css">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ </head>
+ <body>
+ <h1 class="shadow">Sivun kehittäjät</h1>
+ <p>Jos muokkaat/lisäät jotain tähän projektiin, voit pyytää serverin ylläpidosta vastaavilta, että nimesi lisätään tietokantaan.</p>
+
+ \(devs\)
+
+ <a class="back" href="/"><img src="/Images/back.png" alt="Takaisin etusivulle"></a>
+
+ <footer>
+ <a href="https://www.github.com/JoelHMikael/FoodJS">Lähdekoodi</a>
+ <span>|</span>
+ <a href="/devs">Ota yhteyttä</a>
+ </footer>
+
+ </body>
+</html>
diff --git a/index.css b/Cont/index.css
index 1f5a422..1f5a422 100644
--- a/index.css
+++ b/Cont/index.css
diff --git a/index.html b/Cont/index.html
index 90e4a9b..c35b7c1 100644
--- a/index.html
+++ b/Cont/index.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html>
+<html lang="fi">
<head>
<meta charset="utf-8">
<title>LYLL-ruokailuvuoro</title>
@@ -19,7 +19,7 @@
<label for="index" class="shadow">Opettaja, kurssi tai luokka:</label>
<br>
<input type="text" name="index" placeholder="\(example-input\)">
- <img src="/help.png" class="info" alt="Siis häh?">
+ <img src="/Images/help.png" class="info" alt="Siis häh?">
<span><p class="infoblock highlight">Syötä tähän kenttään yhdeltätoista alkavan tuntisi opettaja, kurssikoodi tai luokka. Älä syötä useampaa edellä mainituista, yksi on tarpeeksi.</p></span>
<br>
<label for="day">Päivä:</label>
@@ -57,7 +57,7 @@
<footer>
<a href="https://www.github.com/JoelHMikael/FoodJS">Lähdekoodi</a>
<span>|</span>
- <a href="https://www.example.com">Ota yhteyttä</a>
+ <a href="/devs">Ota yhteyttä</a>
</footer>
</body>
</html>
diff --git a/Cont/non-main.css b/Cont/non-main.css
new file mode 100644
index 0000000..d8003ef
--- /dev/null
+++ b/Cont/non-main.css
@@ -0,0 +1,26 @@
+.back {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.back > * {
+}
+
+.back > img {
+ width: 4rem;
+ height: 4rem;
+ margin: 1rem;
+ filter: drop-shadow(.125rem .125rem 0 black);
+ position: relative;
+ bottom: .125rem;
+ right: .125rem;
+ vertical-align: middle;
+ display: inline;
+}
+
+.back > img:hover {
+ filter: drop-shadow(.20rem .20rem 0 black);
+ bottom: .20rem;
+ right: .20rem;
+}
diff --git a/README.md b/README.md
index 7c60f52..5ac073c 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,24 @@ Readme coming soon!
## Setup
If you want to set up the server, you will have to get a SSL certificate or generate one yourself. If you want to run a dedicated server that can update, you also need to add the cron jobs from crontab\_add. You must create a MySQL DB and give its login info in ../dblogin.txt. The database should have the following tables set up:
+CREATE TABLE shiftnames (
+ day INT,
+ id INT,
+ name VARCHAR(128) NOT NULL,
+ PRIMARY KEY (day, id)
+);
+CREATE TABLE classes (
+ course VARCHAR(6) PRIMARY KEY,
+ class VARCHAR(4)
+);
+CREATE TABLE shifts (
+ day INT,
+ shift INT,
+ course VARCHAR(6),
+ teacher VARCHAR(4),
+ class VARCHAR(4),
+ PRIMARY KEY (day, course)
+);
CREATE TABLE devs (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(30) NOT NULL,
diff --git a/database.js b/database.js
index 3a2822a..30396fe 100644
--- a/database.js
+++ b/database.js
@@ -1,35 +1,55 @@
+const mysql = require("mysql2");
+
class Database
{
- constructor(credentials, log)
+ constructor(credentials)
{
this.connection = mysql.createConnection(credentials);
- this.log = log;
}
- query(q)
+ query(query, values)
{
- return new Promise((resolve, reject), () =>
+ return new Promise((resolve, reject) =>
{
- this.connection.query(q, (err, res, fields) =>
+ this.connection.query(query, values, (err, res, fields) =>
{
- if (err)
- {
- this.log(err);
- reject(err);
- }
+ if (err) reject(err);
+ resolve(res);
+ });
+ });
+ }
+ execute(query, values)
+ {
+ return new Promise((resolve, reject) =>
+ {
+ this.connection.execute(query, values, (err, res, fields) =>
+ {
+ if (err) reject(err);
resolve(res);
});
});
+
+ }
+ query_raw(query)
+ {
+ return new Promise((resolve, reject) =>
+ {
+ this.connection.query(query, (err, res, fields) =>
+ {
+ if (err)
+ reject(err)
+ resolve(res);
+ });
+ })
}
close()
{
- this.connection.end(err =>
+ return new Promise((resolve, reject) =>
{
- if (err)
+ this.connection.end(err =>
{
- this.log(err);
- reject(err);
- }
- resolve();
+ if (err) reject(err);
+ resolve();
+ });
});
}
}
diff --git a/dbparse.js b/dbparse.js
new file mode 100644
index 0000000..b260d50
--- /dev/null
+++ b/dbparse.js
@@ -0,0 +1,365 @@
+
+
+// String searching
+function getCharAmount(s, c)
+{
+ let n = 0;
+ for (let c_i = 0; c_i < s.length; c_i++)
+ {
+ n += +(s[c_i] === c);
+ }
+ return n;
+}
+function getNextChar(s, c, i = 0)
+{
+ if (!(Number.isInteger(i) && (i >= 0)))
+ return -1;
+ for (; i < s.length; i++)
+ {
+ if (s[i] === c)
+ return i;
+ }
+ return -1;
+}
+function getNextLine(s, i)
+{
+ i = getNextChar(s, "\n", i);
+ i += +(i !== -1) * 1;
+ return i;
+}
+function getToLineStartingWith(s, ss, start = 0)
+{
+ if (!(Number.isInteger(start) && (start >= 0)))
+ return -1
+
+ let i = start;
+ do
+ {
+ if (s.substring(i, i + ss.length) === ss)
+ break;
+ i = getNextLine(s, i);
+ } while(i !== -1)
+
+ return i;
+}
+function findExpression(data, expr, start = 0)
+{
+ if (start == -1)
+ return -1;
+ if (!(Number.isInteger(start) && (start >= 0)))
+ throw new TypeError("Start must be a positive integer!");
+ if (typeof expr !== "string")
+ return -1;
+ while ((data.substring(start, start + expr.length) !== expr) && (start + expr.length < data.length))
+ start++;
+ if (data.substring(start, start + expr.length) !== expr)
+ return -1;
+ return start;
+}
+
+// Normalizing
+function parseCluttered(s)
+{
+ if (!(typeof s === "string"))
+ return "";
+ return s.replaceAll(".", "").replaceAll(" ", "").toUpperCase();
+}
+
+// Class parsing
+async function writeClasses(classData, DB)
+{
+ classData = parseCluttered(classData) + "\n"; // newline so that loop can find last value
+ await DB.query_raw("DELETE FROM classes");
+ // parse data to dict
+ let i = 0;
+ while (i < classData.length)
+ {
+ let separator = getNextChar(classData, ":", i);
+ if (separator === -1)
+ break;
+ let lineEnd = getNextChar(classData, "\n", i);
+ let key = classData.substring(i, separator);
+ let val = classData.substring(separator + 1, lineEnd);
+ i = lineEnd + 1;
+ let res = await DB.execute("INSERT INTO classes VALUES (?, ?)", [key, val]);
+ }
+}
+/*
+function parseShift(data, weekdays = ["MAANANTAISIN", "TIISTAISIN", "KESKIVIIKKOISIN", "TORSTAISIN", "PERJANTAISIN"])
+{
+
+ let i = 0;
+ let db = [];
+ while (db.length < weekdays.length)
+ {
+ let day = [];
+
+ i = getNextChar(data, "\n", findExpression(data, weekdays[db.length]));
+ let end;
+ if (db.length === weekdays.length - 1)
+ end = data.length;
+ else
+ end = findExpression(data, weekdays[db.length + 1]);
+ let unparsedDay = data.substring(i + 1, end);
+ day = parseDay(unparsedDay);
+
+ db.push(day);
+ }
+ return db;
+}
+
+function parseDay(day)
+{
+ let shifts = {};
+ let i = getToLineStartingWith(day, "RUOKAILUVUORO");
+ do
+ {
+ let endOfLine = getNextChar(day, "\n", i);
+ let shiftDesc = day.substring(i, endOfLine);
+ i = getNextChar(day, "\n", i) + 1;
+ i = getNextChar(day, "\n", i) + 1;
+ if (getNextChar(day, "\n", i) === -1)
+ endOfLine = day.length;
+ else
+ endOfLine = getNextChar(day, "\n", i);
+ let unparsedIndexes = day.substring(i, endOfLine);
+ shifts[shiftDesc] = parseLine(unparsedIndexes);
+ i = getToLineStartingWith(day, "RUOKAILUVUORO", i);
+ } while (i !== -1);
+ return shifts;
+}
+function parseLine(line, toRemove = " ja KAHDEN TUTKINNON OPINNOT 1., 2. ja 3. VUOSITASON RYHMÄT ")
+{
+ let i = 0;
+ let courses = [];
+ let teachers = [];
+ // get to the teachers & courses
+ let nextSpace = 0;
+
+ if (line.substring(line.length - toRemove.length, line.length) === toRemove)
+ line = line.substring(0, line.length - toRemove.length);
+ line = line.replaceAll(",", "").replaceAll("ja ", "").replaceAll(" + ", "+");
+
+ while (i < line.length)
+ {
+ if (line[i] === "+")
+ {
+
+ nextSpace = getNextChar(line, " ", i);
+ let nextNextSpace = getNextChar(line, " ", nextSpace + 1);
+ if (nextNextSpace === -1)
+ nextNextSpace = line.length;
+ line = `${line.substring(0, i)} ${line.substring(nextSpace + 1, nextNextSpace)} ${line.substring(i + 1, line.length)}`;
+ i = nextNextSpace - 1;
+ }
+ i++;
+ }
+ nextSpace = 0;
+ i = 0;
+
+ const getElement = list =>
+ {
+ nextSpace = getNextChar(line, " ", i);
+ if (nextSpace === -1)
+ nextSpace = line.length;
+ list.push(line.substring(i, nextSpace));
+ i = nextSpace + 1;
+ }
+
+ do
+ {
+ getElement(courses);
+ getElement(teachers);
+ } while (i < line.length)
+
+ return [courses, teachers];
+}
+
+*/
+async function parseLine(data, day, shift, DB)
+{
+ // "preprocessing"
+ let i = 0;
+ let courses = [];
+ let teachers = [];
+ const toRemove = " ja KAHDEN TUTKINNON OPINNOT 1., 2. ja 3. VUOSITASON RYHMÄT ";
+ if (data.substring(data.length - toRemove.length, data.length) === toRemove)
+ data = data.substring(0, data.length - toRemove.length);
+ data = data.replaceAll(",", "").replaceAll("ja ", "").replaceAll(" + ", "+");
+
+ while (i < data.length)
+ {
+ if (data[i] === "+")
+ {
+
+ nextSpace = getNextChar(data, " ", i);
+ let nextNextSpace = getNextChar(data, " ", nextSpace + 1);
+ if (nextNextSpace === -1)
+ nextNextSpace = data.length;
+ data = `${data.substring(0, i)} ${data.substring(nextSpace + 1, nextNextSpace)} ${data.substring(i + 1, data.length)}`;
+ i = nextNextSpace - 1;
+ }
+ i++;
+ }
+ nextSpace = 0;
+ i = 0;
+
+ const getElement = list =>
+ {
+ nextSpace = getNextChar(data, " ", i);
+ if (nextSpace === -1)
+ nextSpace = data.length;
+ list.push(data.substring(i, nextSpace));
+ i = nextSpace + 1;
+ }
+
+ do
+ {
+ getElement(courses);
+ getElement(teachers);
+ } while (i < data.length)
+
+ let values = "VALUES";
+ for(let el = 0; el < courses.length; el++)
+ {
+ values += ` ROW(${day}, ${shift}, '${courses[el]}', '${teachers[el]}', NULL),`;
+ }
+ values = values.substring(0, values.length - 1);
+ return DB.execute(`INSERT INTO shifts ${values}`, []);
+}
+
+async function parseDay(data, day, DB)
+{
+ let i = getToLineStartingWith(data, "RUOKAILUVUORO");
+ let indexOfShift = 1;
+ while (i !== -1)
+ {
+ let endOfLine = getNextChar(data, "\n", i);
+ // Insert the food shift name
+ let shiftName = DB.execute("INSERT INTO shiftnames VALUES (?, ?, ?)", [day, indexOfShift, data.substring(i, endOfLine)]);
+ // get to the teachers & courses
+ i = endOfLine + 1;
+ i = getNextChar(data, "\n", i) + 1;
+ if (getNextChar(data, "\n", i) === -1)
+ endOfLine = data.length;
+ else
+ endOfLine = getNextChar(data, "\n", i);
+ let unparsedIndexes = data.substring(i, endOfLine);
+
+ // do the magic
+ let lineParse = parseLine(unparsedIndexes, day, indexOfShift, DB);
+
+ i = getToLineStartingWith(data, "RUOKAILUVUORO", i);
+ indexOfShift++;
+ await Promise.all([shiftName, lineParse]);
+ }
+ return 0;
+}
+
+async function writeShifts(data, DB)
+{
+ weekdays = ["MAANANTAISIN", "TIISTAISIN", "KESKIVIIKKOISIN", "TORSTAISIN", "PERJANTAISIN"];
+ let deletions = Promise.all([
+ DB.query_raw("DELETE FROM shifts"),
+ DB.query_raw("DELETE FROM shiftnames")
+ ]);
+
+ // iterate over the weekdays
+ let i = 0;
+ for (let day = 0; day < weekdays.length; day++)
+ {
+ // find the start of the shifts of the day
+ i = getNextChar(data, "\n", findExpression(data, weekdays[day], i));
+
+ // find the end of the shifts of the day
+ let end = [
+ data.length,
+ findExpression(data, weekdays[day + 1], i)
+ ][+(day !== weekdays.length - 1)];
+
+ await deletions; // wait for deletion to get completed before proceeding to write new data to the table
+
+ // do the magic:
+ let shifts = data.substring(i, end);
+ await parseDay(shifts, day, DB);
+
+ i = end;
+ }
+ return 0;
+}
+
+/*
+function getIndexType(index)
+{
+ if (/^[A-Za-zåäöÅÄÖ]{2,3}\d{2,3}$/.test(index))
+ return "course";
+ if (/^[A-Za-zåäöÅÄÖ]{4}$/.test(index))
+ return "teacher";
+ if (/^\w\d{3}$/.test(index))
+ return "class";
+}
+
+function getShift(day, index, db) // day: int, 1 = monday; index: string of course/teacher; db: parsed shifts
+{
+ if ((typeof day !== "number") || isNaN(day) || (typeof index !== "string"))
+ return -1;
+
+ let shifts = db[day - 1];
+
+ let _endOfIndex = parseInt(index.substring(2, 4));
+ let type = getIndexType(index);
+ if (type === undefined)
+ return {};
+ let type_index = +(type === "teacher") + (+(type === "class") * 2);
+
+ let res = {};
+ for (const [key, val] of Object.entries(shifts))
+ {
+ let indexes = val[type_index];
+ for (let i = 0; i < indexes.length; i++)
+ {
+ if (indexes[i] === index)
+ res[key] = [val[0][i], val[1][i], val[2][i]];
+ }
+ }
+ return res;
+}
+
+function randInt(start, stop)
+{
+ return start + Math.floor(Math.random() * (stop - start));
+}
+
+function getIndexes(db, day, shift, type)
+{
+ let d = db[day];
+ let sh = Object.values(d)[shift][type];
+ return Object.values(db[day])[shift][type];
+}
+
+function getRandomIndex(db, day = randInt(0, 5), shift = randInt(0, 3), type = randInt(0, 3))
+{
+ let el;
+ let i = 0;
+ let indexes = getIndexes(db, day, shift, type);
+ while ((el === undefined) && (i < indexes.length))
+ {
+ el = indexes[i];
+ i++;
+ }
+ if (el == undefined)
+ return getRandomIndex(db);
+ return el;
+}
+
+exports.build = parseShift;
+exports.indexType = getIndexType;
+exports.classes = parseClasses;
+exports.get = getShift;
+exports.cluttered = parseCluttered;
+exports.find = findExpression;
+exports.getNextChar = getNextChar;
+exports.randomIndex = getRandomIndex;*/
+
+exports.classes = writeClasses;
+exports.build = writeShifts;
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..cad9a81
--- /dev/null
+++ b/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "lyll-ruoka",
+ "version": "1.0.0",
+ "description": "Server to serve information about the food shifts and foods in LYLL",
+ "main": "server.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "start": "node server.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/JoelHMikael/FoodJS.git"
+ },
+ "keywords": [
+ "food",
+ "server",
+ "database",
+ "school"
+ ],
+ "author": "Joel Kronqvist",
+ "license": "UNLICENSED",
+ "bugs": {
+ "url": "https://github.com/JoelHMikael/FoodJS/issues"
+ },
+ "homepage": "https://github.com/JoelHMikael/FoodJS#readme",
+ "dependencies": {
+ "mysql2": "^2.3.3"
+ }
+}
diff --git a/parse.js b/parse.js
index 81269e7..a776f13 100644
--- a/parse.js
+++ b/parse.js
@@ -261,4 +261,5 @@ exports.classes = parseClasses;
exports.get = getShift;
exports.cluttered = parseCluttered;
exports.find = findExpression;
+exports.getNextChar = getNextChar;
exports.randomIndex = getRandomIndex;
diff --git a/server.js b/server.js
index 4b1e8a3..26ab9bb 100644
--- a/server.js
+++ b/server.js
@@ -3,7 +3,8 @@ const fs = require("fs");
const url = require("url");
const parse = require("./parse.js");
const scrape = require("./scrape.js");
-const mysql = require("mysql2");
+const SQL_DBS = require("./database.js");
+const DBPARSE = require("./dbparse.js");
async function init()
@@ -11,24 +12,36 @@ async function init()
const weekdays = [undefined, "MAANANTAI", "TIISTAI", "KESKIVIIKKO", "TORSTAI", "PERJANTAI", undefined];
const build = {
- "./index.html": buildMain,
- "./index.css": buildDefault,
- "./404/index.css": buildDefault,
- "./help.png": buildImage
+ "./Cont/index.html": buildMain,
+ "./Cont/index.css": buildDefault,
+ "./Cont/devs/index.html": buildDevs,
+ "./Cont/devs/index.css": buildDefault,
+ "./Cont/404/index.css": buildDefault,
+ "./Cont/non-main.css": buildDefault,
+ "./Cont/Images/help.png": buildImage,
+ "./Cont/Images/back.png": buildImage
};
- const errorPath = "./404/index.html";
+ const errorPath = "./Cont/404/index.html";
// await for needed things in async
- let [shiftCont, classCont, foodsThisWeek, foodsNextWeek] = await Promise.all([
+ let [shiftCont, classCont, foodsThisWeek, foodsNextWeek, dbcredentials] = await Promise.all([
openFile("./shifts.txt"),
openFile("./classes.txt"),
scrape.food(scrape.link(1)),
- scrape.food(scrape.link(2))
+ scrape.food(scrape.link(2)),
+ openFile("../dblogin.txt")
]);
+ // get the MySQL DB connection
+ const SQLDB = new SQL_DBS.Database(JSON.parse(dbcredentials));
+
// get the food shift "database"
shiftCont = shiftCont.toString("utf-8").replaceAll("\r", ""); // \r because of the \r\n newline on windows which creates problems
classCont = classCont.toString("utf-8").replaceAll("\r", "");
+
+ await DBPARSE.classes(classCont, SQLDB);
+ await DBPARSE.build(shiftCont, SQLDB);
+
let DB = parse.build(shiftCont);
parse.classes(classCont, DB);
@@ -54,9 +67,9 @@ async function init()
index: ind,
day: d
};
- let path = "." + antiXSS(q.pathname);
- if (path == "./")
- path = "./index.html";
+ let path = "./Cont" + antiXSS(q.pathname);
+ if (isDir(path))
+ path += ["/index.html", "index.html"][+(path[path.length - 1] === "/")];
// pack the data required by the builders
let data;
@@ -65,7 +78,8 @@ async function init()
"path404": errorPath,
"query": q.query,
"db": DB,
- "foods": foods
+ "foods": foods,
+ "sqldb": SQLDB
};
// build the page
@@ -77,10 +91,21 @@ async function init()
}
// start server
- http.createServer(server).listen(8080);
+ const runningServer = http.createServer(server).listen(8080);
+
+ // stop server
+ function closeServer() {
+ SQLDB.close();
+ runningServer.close();
+ }
+ process.on("SIGINT", closeServer);
+ process.on("SIGQUIT", closeServer);
+ process.on("SIGTERM", closeServer);
}
+
+
function validateIndex(sus)
{
return antiXSS(parse.cluttered(sus));
@@ -93,6 +118,12 @@ function antiXSS(sus)
return replace(sus, ["<", ">", "(", ")"], ["&lt;", "&gt;", "&#40;", "&#41;"]);
}
+function isDir(path)
+{
+ return (parse.getNextChar(path.substring(1), ".") === -1);
+}
+
+
function replace(s, from, to)
{
for (let i = 0; i < from.length; i++)
@@ -131,7 +162,7 @@ async function buildMain(args)
let day = d.getDay();
const actualDay = day;
day = +((day === 0) || (day === 6)) + (+(!(day === 0) && !(day === 6)) * day);
- if ((typeof query.day === "string") && (parseInt(query.day).toString() === query.day) && (!isNaN(parseInt(query.day))) && (parseInt(query.day) > 0) && (parseInt(query.day) < 7))
+ if ((typeof query.day === "string") && (parseInt(query.day).toString() === query.day) && (!isNaN(parseInt(query.day))) && (parseInt(query.day) > 0) && (parseInt(query.day) < 6))
day = parseInt(query.day);
data_string = data_string.replace(`<option value=\"${day}\">`, `<option value=\"${day}\" selected>`);
@@ -197,8 +228,31 @@ async function buildMain(args)
return data_string;
}
+async function buildDevs(args)
+{
+ const path = args["path"];
+ const data = await openFile(path);
+ const DB = args["sqldb"];
+
+ let res = "";
+ let devs = await DB.query_raw("SELECT name, description, contact FROM devs");
+ for (let dev = 0; dev < devs.length; dev++)
+ {
+ let devInfo = devs[dev];
+ res += '<div class="float-block">' +
+ `<p class="column">${devInfo.name}</p>` +
+ `<p class="column">${devInfo.description}</p>` +
+ `<a href="mailto:${devInfo.contact}" class="column" style="white-space: nowrap; overflow: hidden; overflow-wrap: normal; text-overflow: ellipsis;">${devInfo.contact}</a>` +
+ '</div>';
+ }
+
+ return build_replace(data.toString("utf-8"), {"devs": res});
+}
+
+
async function build404(args)
{
+ args["path"] = args["path"].substring("./Cont".length);
const data = await openFile(args["path404"]);
const data_string = data.toString("utf-8");
return data_string.replace("\\(path\\)", args["path"]);