From 24709fa862636702fd0430e832463b751fce323e Mon Sep 17 00:00:00 2001 From: JoelHMikael Date: Sat, 8 Jan 2022 16:49:37 +0200 Subject: Parsing the shifts (not classes) to the database + some GUI improvements --- dbparse.js | 365 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 dbparse.js (limited to 'dbparse.js') 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; -- cgit v1.2.3 From 21e79dcc1eabebfd661a2fd38681348ae9428c4e Mon Sep 17 00:00:00 2001 From: JoelHMikael Date: Sun, 9 Jan 2022 20:17:16 +0200 Subject: Database implemented Some polishing wouldn't do bad though... --- dbparse.js | 175 +++++++++++++------------------------------------------------ 1 file changed, 35 insertions(+), 140 deletions(-) (limited to 'dbparse.js') 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; -- cgit v1.2.3 From 1a1b117cc9eae2cc2ecfb3695bebe21daf08741b Mon Sep 17 00:00:00 2001 From: JoelHMikael Date: Thu, 13 Jan 2022 09:36:07 +0200 Subject: Made the parsing more inclusive --- dbparse.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'dbparse.js') diff --git a/dbparse.js b/dbparse.js index ec2d434..5f495e5 100644 --- a/dbparse.js +++ b/dbparse.js @@ -167,7 +167,7 @@ async function parseDay(data, day, DB) async function writeShifts(data, DB) { - weekdays = ["MAANANTAISIN", "TIISTAISIN", "KESKIVIIKKOISIN", "TORSTAISIN", "PERJANTAISIN"]; + weekdays = ["MAANANTAI", "TIISTAI", "KESKIVIIKKO", "TORSTAI", "PERJANTAI"]; let deletions = Promise.all([ DB.query_raw("DELETE FROM shifts"), DB.query_raw("DELETE FROM shiftnames") @@ -178,7 +178,7 @@ async function writeShifts(data, DB) 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)); + i = getNextChar(data, "\n", findExpression(data, weekdays[day], i)) + 1; // find the end of the shifts of the day let end = [ -- cgit v1.2.3 From 28e4f1cf0dbd1c14a9724d17cf9127d223d85289 Mon Sep 17 00:00:00 2001 From: JoelHMikael Date: Sun, 16 Jan 2022 16:50:44 +0200 Subject: Actual class parsing Really messy, feel free to improve, or even rewrite. --- dbparse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dbparse.js') diff --git a/dbparse.js b/dbparse.js index 5f495e5..2be3f96 100644 --- a/dbparse.js +++ b/dbparse.js @@ -225,7 +225,7 @@ function getIndexType(index) return "course"; if (/^[A-Za-zåäöÅÄÖ]{4}$/.test(index)) return "teacher"; - if (/^\w\d{3}$/.test(index)) + if (/^\w\d{3}R?$/.test(index)) return "class"; } -- cgit v1.2.3