aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoelHMikael <joel.h.kronqvist@gmail.com>2022-01-09 20:17:16 +0200
committerJoelHMikael <joel.h.kronqvist@gmail.com>2022-01-09 20:17:16 +0200
commit21e79dcc1eabebfd661a2fd38681348ae9428c4e (patch)
tree5a3022d974155a403ee0e1e573a20db6f4ea3003
parent24709fa862636702fd0430e832463b751fce323e (diff)
downloadLYLLRuoka-21e79dcc1eabebfd661a2fd38681348ae9428c4e.tar.gz
LYLLRuoka-21e79dcc1eabebfd661a2fd38681348ae9428c4e.zip
Database implemented
Some polishing wouldn't do bad though...
-rw-r--r--Cont/index.css6
-rw-r--r--Cont/index.html14
-rw-r--r--dbparse.js175
-rw-r--r--parse.js265
-rw-r--r--scrape.js7
-rw-r--r--server.js74
6 files changed, 96 insertions, 445 deletions
diff --git a/Cont/index.css b/Cont/index.css
index 1f5a422..80e5dc6 100644
--- a/Cont/index.css
+++ b/Cont/index.css
@@ -107,10 +107,16 @@ footer > a {
}
/*** the info buttons & their animations ***/
+img.info:hover {
+ filter: drop-shadow(.125rem .125rem 0 black);
+ transform: translate(-0.125rem, -0.125rem);
+}
img.info {
width: 1em;
height: 1em;
vertical-align: middle;
+ filter: drop-shadow(.0625rem .0625rem 0 black);
+ transform: translate(-0.0625rem, -0.0625rem);
}
img.info + span {
diff --git a/Cont/index.html b/Cont/index.html
index c35b7c1..95dcb32 100644
--- a/Cont/index.html
+++ b/Cont/index.html
@@ -25,13 +25,13 @@
<label for="day">Päivä:</label>
<br>
<select name="day">
- <option value="1">ma</option>
- <option value="2">ti</option>
- <option value="3">ke</option>
- <option value="4">to</option>
- <option value="5">pe</option>
- <option value="6" disabled>la</option>
- <option value="0" disabled>su</option>
+ <option value="0">ma</option>
+ <option value="1">ti</option>
+ <option value="2">ke</option>
+ <option value="3">to</option>
+ <option value="4">pe</option>
+ <option value="5" disabled>la</option>
+ <option value="6" disabled>su</option>
</select>
<br>
<input type="submit" id="send" class="highlight" value="Löydä vuoro">
diff --git a/dbparse.js b/dbparse.js
index b260d50..ec2d434 100644
--- a/dbparse.js
+++ b/dbparse.js
@@ -84,98 +84,7 @@ async function writeClasses(classData, DB)
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"
@@ -285,10 +194,31 @@ async function writeShifts(data, DB)
i = end;
}
+
+ const courses = await DB.query_raw("SELECT * FROM classes");
+ const results = [];
+ for (let course = 0; course < courses.length; course++)
+ {
+ results.push(DB.query("UPDATE shifts SET class = ? WHERE course = ?", [courses[course].class, courses[course].course]));
+ }
+ await Promise.all(results);
return 0;
}
-/*
+async function getShift(day, index, DB)
+{
+ let shift = DB.execute("SELECT name FROM shiftnames WHERE day = ? and id = (SELECT shift FROM shifts WHERE (day = ?) AND (course = ? OR teacher = ? OR class = ?) LIMIT 1)", [day, day, index, index, index]);
+ let additional = DB.execute("SELECT course, teacher, class FROM shifts WHERE (day = ?) AND (course = ? OR teacher = ? OR class = ?)", [day, index, index, index]);
+ [shift, additional] = await Promise.all([shift, additional]);
+ if (shift.length !== 0)
+ {
+ shift.push(additional);
+ return shift;
+ }
+ return undefined;
+}
+
+
function getIndexType(index)
{
if (/^[A-Za-zåäöÅÄÖ]{2,3}\d{2,3}$/.test(index))
@@ -299,67 +229,32 @@ function getIndexType(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))
+async function getRandomIndex(day, DB)
{
- let el;
- let i = 0;
- let indexes = getIndexes(db, day, shift, type);
- while ((el === undefined) && (i < indexes.length))
+ let indexes = await DB.execute("SELECT course, teacher, class FROM shifts WHERE day = ? ORDER BY RAND() LIMIT 1", [day]);
+ indexes = Object.values(indexes[0]);
+ let start = randInt(0, indexes.length);
+ for (let test = 0; test < 3; test++)
{
- el = indexes[i];
- i++;
+ let i = (start + test) % indexes.length;
+ if (indexes[i] !== null)
+ return indexes[i];
}
- if (el == undefined)
- return getRandomIndex(db);
- return el;
+ console.log("Warning: row without class/teacher/course in database!");
+ return getRandomIndex(day, DB);
}
-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;
+exports.get = getShift;
+exports.randomIndex = getRandomIndex;
diff --git a/parse.js b/parse.js
deleted file mode 100644
index a776f13..0000000
--- a/parse.js
+++ /dev/null
@@ -1,265 +0,0 @@
-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!");
- 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;
-}
-
-function parseCluttered(s)
-{
- if (!(typeof s === "string"))
- return "";
- return s.replaceAll(".", "").replaceAll(" ", "").toUpperCase();
-}
-
-function parseClasses(classData, DB)
-{
- classData = parseCluttered(classData) + "\n"; // newline so that loop can find last value
- // parse data to dict
- let classes = {};
- let i = 0;
- while (i < classData.length)
- {
- let separator = getNextChar(classData, ":", i);
- let lineEnd = getNextChar(classData, "\n", i);
- let key = classData.substring(i, separator);
- let val = classData.substring(separator + 1, lineEnd);
- i = lineEnd + 1;
- classes[key] = val;
- }
-
- for (let day = 0; day < DB.length; day++)
- {
- let shifts = DB[day];
- for (const [key, val] of Object.entries(shifts))
- {
- DB[day][key].push([]);
- let indexes = val[0]; // use courses: the classes are paired to them and they are unique with a higher probability
- for (let i = 0; i < indexes.length; i++)
- {
- DB[day][key][2].push(classes[indexes[i]]);
- }
- }
- }
-
-}
-
-function parseLine(line, toRemove = " ja KAHDEN TUTKINNON OPINNOT 1., 2. ja 3. VUOSITASON RYHMÄT ")
-{
- let i = 0;
- let courses = [];
- let teachers = [];
- 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];
-}
-
-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 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;
-}
-
-/*
- * DB structure:
- * WEEKDAY - list
- * FOOD SHIFTS - dict
- * COURSE INDEXES - list
- * TEACHER INDEXES - list
- * maybe: CLASSES - list
- */
-
-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;
diff --git a/scrape.js b/scrape.js
index 64e00fb..0ae30aa 100644
--- a/scrape.js
+++ b/scrape.js
@@ -1,4 +1,7 @@
-const https = require("https"); const parse = require("./parse.js"); const fs = require("fs"); const events = require("events");
+const https = require("https");
+const parse = require("./DBPARSE.js");
+const fs = require("fs");
+const events = require("events");
async function urlOpen(path)
{
@@ -22,7 +25,7 @@ async function scrapeFood(url)
data = data.toString("utf-8");
let foodList = [];
- const weekdays = ["su", "ma", "ti", "ke", "to", "pe", "la"];
+ const weekdays = ["ma", "ti", "ke", "to", "pe", "la", "su"];
let titleTags = ["<title>", "</title>"];
let foodTags = ["<![CDATA[", "]]>"];
diff --git a/server.js b/server.js
index 26ab9bb..d92a8eb 100644
--- a/server.js
+++ b/server.js
@@ -1,7 +1,6 @@
const http = require("http");
const fs = require("fs");
const url = require("url");
-const parse = require("./parse.js");
const scrape = require("./scrape.js");
const SQL_DBS = require("./database.js");
const DBPARSE = require("./dbparse.js");
@@ -23,10 +22,11 @@ async function init()
};
const errorPath = "./Cont/404/index.html";
+
+
+
// await for needed things in async
- let [shiftCont, classCont, foodsThisWeek, foodsNextWeek, dbcredentials] = await Promise.all([
- openFile("./shifts.txt"),
- openFile("./classes.txt"),
+ let [foodsThisWeek, foodsNextWeek, dbcredentials] = await Promise.all([
scrape.food(scrape.link(1)),
scrape.food(scrape.link(2)),
openFile("../dblogin.txt")
@@ -35,16 +35,6 @@ async function init()
// 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);
-
// get the food "database"
const foods = [foodsThisWeek, foodsNextWeek];
@@ -77,7 +67,6 @@ async function init()
"path": path,
"path404": errorPath,
"query": q.query,
- "db": DB,
"foods": foods,
"sqldb": SQLDB
};
@@ -108,7 +97,7 @@ async function init()
function validateIndex(sus)
{
- return antiXSS(parse.cluttered(sus));
+ return antiXSS(DBPARSE.cluttered(sus));
}
function antiXSS(sus)
@@ -120,7 +109,7 @@ function antiXSS(sus)
function isDir(path)
{
- return (parse.getNextChar(path.substring(1), ".") === -1);
+ return (DBPARSE.getNextChar(path.substring(1), ".") === -1);
}
@@ -152,7 +141,7 @@ async function buildMain(args)
const query = args["query"];
const foods = args["foods"];
const index = query.index;
- const DB = args["db"];
+ const SQLDB = args["sqldb"];
const data = await openFile(path);
let data_string = data.toString("utf-8");
@@ -160,9 +149,10 @@ async function buildMain(args)
const d = new Date();
let day = d.getDay();
+ day = (day + +(day === 0) * 7) - 1;
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) < 6))
+ day = +(!(day === 5) && !(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) < 5))
day = parseInt(query.day);
data_string = data_string.replace(`<option value=\"${day}\">`, `<option value=\"${day}\" selected>`);
@@ -177,21 +167,26 @@ async function buildMain(args)
res["shift"] = "";
if (res["shift"] === undefined)
{
- let shift = parse.get(day, index, DB);
- let key = Object.keys(shift)[0];
- if (key !== undefined)
+ let shift = await DBPARSE.get(day, index, SQLDB);
+ if (shift !== undefined)
{
- res["shift"] = key;
- res["shift-header"] = `${shift[key][0]}/${shift[key][1]}`;
- if (shift[key][2] !== undefined)
- res["shift-header"] += `/${shift[key][2]}`
- res["index-type"] = "Kurssin";
+ res["shift"] = shift[0].name;
+ res["shift-header"] = "";
+ for (let i = 0; i < shift[1].length; i++)
+ {
+ res["shift-header"] += `${shift[1][i].course}/${shift[1][i].teacher}`;
+ if (shift[1][i].class !== null)
+ res["shift-header"] += `/${shift[1][i].class}`
+ if (i + 1 !== shift[1].length)
+ res["shift-header"] += " ja ";
+ }
+ res["index-type"] = ["Kurssin", "Kurssien"][+(shift[1].length > 1)];
}
else
{
res["shift"] = -1;
res["shift-header"] = `${index}`;
- res["index-type"] = indexTypes[parse.indexType(index)];
+ res["index-type"] = indexTypes[DBPARSE.indexType(index)];
if (res["index-type"] === undefined)
res["index-type"] = "";
}
@@ -200,10 +195,10 @@ async function buildMain(args)
res["shift"] = "Kurssilla/opettajalla/luokalla ei ole ruokailua päivällä tai kurssia ei ole olemassa!";
// get the example input
- res["example-input"] = parse.randomIndex(DB, day - 1);
+ res["example-input"] = await DBPARSE.randomIndex(day, SQLDB);
// get the day
- let weekdays = ["su", "ma", "ti", "ke", "to", "pe", "la"];
+ let weekdays = ["ma", "ti", "ke", "to", "pe", "la", "su"];
res["day"] = weekdays[day];
if (res["shift"] === "")
data_string = data_string.replace('<div id="shift-result" class="float-block">', '<div id="shift-result" class="float-block" style="display: none;">');
@@ -284,4 +279,21 @@ function build_replace(s, dict)
}
+// Run this if you want to build the database from text files
+async function buildDB(DB)
+{
+ let [shiftCont, classCont] = await Promise.all([
+ openFile("./shifts.txt"),
+ openFile("./classes.txt")
+ ]);
+ 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 Promise.all([
+ DBPARSE.classes(classCont, SQLDB),
+ DBPARSE.build(shiftCont, SQLDB)
+ ]);
+ return 0;
+}
+
+
init();