diff options
-rw-r--r-- | parser.py | 39 | ||||
-rw-r--r-- | static/index.html | 123 | ||||
-rw-r--r-- | static/script.js | 131 |
3 files changed, 293 insertions, 0 deletions
diff --git a/parser.py b/parser.py new file mode 100644 index 0000000..784d637 --- /dev/null +++ b/parser.py @@ -0,0 +1,39 @@ +import urllib.request +import pydsb +from flask import Flask, jsonify, render_template, send_from_directory +from bs4 import BeautifulSoup + +app = Flask(__name__) + + +@app.route("/api") +def get(): + dsb = pydsb.PyDSB("~", "~") + dsb.login() + + data = { + "Montag": [], + "Dienstag": [], + "Mittwoch": [], + "Donnerstag": [], + "Freitag": [] + } + + url = dsb.get_plans()[0]["url"] + contents = urllib.request.urlopen(url).read() + parsed = BeautifulSoup(contents, "lxml") + tables = parsed.find_all("table", {"class": "mon_list"}) + for table in tables: + rows = table.find_all("tr") + for row in rows: + table_data = row.find_all("td") + if len(table_data) > 0: + if "TGM12/1" in table_data[0].b.text: + data[rows[1].b.text].append({ + "Woche": table.parent.find("div", {"class": "mon_title"}).text[-1:], + "Stunde": table_data[1].b.text, + "Fach": table_data[2].text, + "Raum": table_data[3].text, + "Typ": table_data[4].text, + }) + return jsonify(data) diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..891f219 --- /dev/null +++ b/static/index.html @@ -0,0 +1,123 @@ +<!doctype html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> + <meta http-equiv="X-UA-Compatible" content="ie=edge"> + <title>Schule</title> +</head> +<body> + +<table id="timetable"> + <colgroup id="weekdays"> + <col /> + <col /> + <col /> + <col /> + <col /> + </colgroup> + <thead> + <tr> + <td>Stunde</td> + <td>Montag</td> + <td>Dienstag</td> + <td>Mittwoch</td> + <td>Donnerstag</td> + <td>Freitag</td> + </tr> + </thead> + <tbody> + <tr id="1"> + <td>1</td> + <td data-subject="inf" data-teacher="hz" data-room="b7-1.09"></td> + <td data-subject="wil" data-teacher="hz" data-room="b7-1.09"></td> + <td data-subject="ch|ph|ph|ph" data-teacher="pa|gm|tf|wh" data-room="b6-434|b6-420|b6-423|b6-424"></td> + <td data-subject="d" data-teacher="os" data-room="b7-1.09"></td> + <td data-subject="m" data-teacher="mj" data-room="b7-1.09"></td> + </tr> + <tr id="2"> + <td>2</td> + <td data-subject="inf" data-teacher="hz" data-room="b7-1.09"></td> + <td data-subject="wil" data-teacher="hz" data-room="b7-1.09"></td> + <td data-subject="ch|ph|ph|ph" data-teacher="pa|gm|tf|wh" data-room="b6-434|b6-420|b6-423|b6-424"></td> + <td data-subject="d" data-teacher="os" data-room="b7-1.09"></td> + <td data-subject="m" data-teacher="mj" data-room="b7-1.09"></td> + </tr> + <tr id="3"> + <td>3</td> + <td data-subject="d" data-teacher="os" data-room="b7-1.09"></td> + <td data-subject="m" data-teacher="mj" data-room="b7-1.09"></td> + <td data-subject="ggk" data-teacher="wo" data-room="b7-1.09"></td> + <td data-subject="ch|ph|ph|ph" data-teacher="pa|gm|tf|wh" data-room="b6-434|b6-420|b6-423|b6-424"></td> + <td data-subject="e" data-teacher="wo" data-room="b7-1.09"></td> + </tr> + <tr id="4"> + <td>4</td> + <td data-subject="d" data-teacher="os" data-room="b7-1.09"></td> + <td data-subject="m" data-teacher="mj" data-room="b7-1.09"></td> + <td data-subject="ggk" data-teacher="wo" data-room="b7-1.09"></td> + <td data-subject="ch|ph|ph|ph" data-teacher="pa|gm|tf|wh" data-room="b6-434|b6-420|b6-423|b6-424"></td> + <td data-subject="e" data-teacher="wo" data-room="b7-1.09"></td> + </tr> + <tr id="5"> + <td>5</td> + <td data-subject="e" data-teacher="wo" data-room="b7-1.09"></td> + <td data-subject="eth|evr|krl" data-teacher="os|gei|mm" data-room="b7-1.09|b7-1.12|b7-1.15"></td> + <td data-subject="f|f|f|s|s|s" data-teacher="rt|ste|su|gi|ta|at" data-room="b6-422|b6-420|b6-337|h3|h4|h11"></td> + <td data-subject="ct" data-teacher="sm" data-room="b7-1.08"></td> + <td data-subject="inf-l" data-teacher="hz" data-room="b7-1.06"></td> + </tr> + <tr id="6"> + <td>6</td> + <td data-subject="e" data-teacher="wo" data-room="b7-1.09"></td> + <td data-subject="eth|evr|krl" data-teacher="os|gei|mm" data-room="b7-1.09|b7-1.12|b7-1.15"></td> + <td data-subject="f|f|f|s|s|s" data-teacher="rt|ste|su|gi|ta|at" data-room="b6-422|b6-420|b6-337|h3|h4|h11"></td> + <td data-subject="ct" data-teacher="sm" data-room="b7-1.08"></td> + <td data-subject="inf-l" data-teacher="hz" data-room="b7-1.06"></td> + </tr> + <tr id="7"> + <td>7</td> + <td data-subject="-" data-teacher="-" data-room="-"></td> + <td data-subject="-" data-teacher="-" data-room="-"></td> + <td data-subject="-" data-teacher="-" data-room="-"></td> + <td data-subject="-" data-teacher="-" data-room="-"></td> + <td data-subject="se" data-teacher="sd|hom" data-room="b6-336|b6-426"></td> + </tr> + <tr id="8"> + <td>8</td> + <td data-subject="b|m+|bk|sgt" data-teacher="pr|pa|hag|sd" data-room="b6-434|b6-426|b6-522|b6-336|b6-331"></td> + <td data-subject="inf@bdfh|f@aceg|f@aceg|f@aceg" data-teacher="hz|rt|ste|su" data-room="b7-1.09|b6-422|b6-420|b6-337"></td> + <td data-subject="s|s|s" data-teacher="gi|ta|at" data-room="h3|h4|h11" data-flag="f"></td> + <td data-subject="m@abef|phl@cg|phl@cg|phl@dh|chl@dh" data-teacher="mj|gm|tf|wh|pa" data-room="b7-1.09|b6-424|b6-423|b6-424|b6-434"></td> + <td data-subject="se" data-teacher="sd|hom" data-room="b6-336|b6-426"></td> + </tr> + <tr id="9"> + <td>9</td> + <td data-subject="b|m+|bk|sgt" data-teacher="pr|pa|hag|sd" data-room="b6-434|b6-426|b6-522|b6-336|b6-331"></td> + <td data-subject="inf@bdfh|f@aceg|f@aceg|f@aceg" data-teacher="hz|rt|ste|su" data-room="b7-1.09|b6-422|b6-420|b6-337"></td> + <td data-subject="s|s|s" data-teacher="gi|ta|at" data-room="h3|h4|h11" data-flag="f"></td> + <td data-subject="m@abef|phl@cg|phl@cg|phl@dh|chl@dh" data-teacher="mj|gm|tf|wh|pa" data-room="b7-1.09|b6-424|b6-423|b6-424|b6-434"></td> + <td data-subject="se" data-teacher="sd|hom" data-room="b6-336|b6-426"></td> + </tr> + </tbody> +</table> + +<style> + /* Don't do inline CSS! ;) */ + table { + border-collapse: collapse; + text-align: center; + } + + table, th, td { + border: 1px solid black; + } + + td { + padding: 5px; + } +</style> + +<script src="/static/script.js"></script> +</body> +</html>
\ No newline at end of file diff --git a/static/script.js b/static/script.js new file mode 100644 index 0000000..edd399a --- /dev/null +++ b/static/script.js @@ -0,0 +1,131 @@ +const xmlHttp = new XMLHttpRequest(); +xmlHttp.onreadystatechange = function () { + if (xmlHttp.readyState === 4 && xmlHttp.status === 200) + renderTable(JSON.parse(xmlHttp.responseText)); +}; +xmlHttp.open("GET", "http://127.0.0.1:5000/api", true); +xmlHttp.send(); + +function renderTable(data) { + const configs = getConfigs(); + console.log(configs); + console.log(data); // TODO: Use DSB data + const cells = document.querySelector("#timetable tbody").getElementsByTagName('td'); + for (let i = 0, cell; cell = cells[i]; i++) { + try { + const available = []; + const subjects = cell.getAttribute("data-subject").split("|"); + const teachers = cell.getAttribute("data-teacher").split("|"); + const rooms = cell.getAttribute("data-room").split("|"); + + subjects.forEach((elem, index) => { + if ((elem.split("@").length > 1 && elem.split("@")[1].includes(getWeekType())) || elem.split("@").length === 1) { + const subject = elem.split("@")[0]; + if ( + (subject === "f" && !configs.f) || (subject === "f" && teachers[index] !== configs.f) || + (subject === "ph" && !configs.ph) || (subject === "ph" && teachers[index] !== configs.ph) || + (subject === "ch" && !configs.ch) || (subject === "ch" && teachers[index] !== configs.ch) || + (subject === "s" && teachers[index] !== configs.s) || + (subject === "eth" && configs.e !== "eth") || + (subject === "evr" && configs.e !== "evr") || + (subject === "krl" && configs.e !== "krl") || + (cell.getAttribute("data-flag") === "f" && !configs.f) || + (["b", "m+", "bk", "sgt"].includes(subject) && !configs.w) + ) { + console.log("skipped", subject, teachers[index]) + } else { + available.push({ + subject: subject.toUpperCase(), + teacher: teachers[index].toUpperCase(), + room: rooms[index].toUpperCase() + }) + } + } + }); + + cell.innerHTML = `<b>${available[0].subject}</b><br>${available[0].teacher}<br><small>${available[0].room}</small><br>`; + } catch (e) { + // + } + } + + document.querySelectorAll("#weekdays col")[(new Date()).getDay()].style.backgroundColor = "rgba(250,255,0,0.42)"; +} + +function getConfigs() { + // Defaults to personal preferences + const url = new URL(window.location.href); + const french = url.searchParams.get("f") || false; + const sports = url.searchParams.get("s") || "at"; + const physics = url.searchParams.get("p") || "gm"; + const chemistry = url.searchParams.get("c") || false; + const elective = url.searchParams.get("w") || false; + const ethnicity = url.searchParams.get("e") || "eth"; + + return { + f: french === "false" ? false : french, + s: sports, + ph: physics === "false" ? false : physics, + ch: chemistry === "false" ? false : chemistry, + w: elective === "false" ? false : elective, + e: ethnicity + } +} + +Date.prototype.getWeek = function () { + const firstJan = new Date(this.getFullYear(), 0, 1); + return Math.ceil((((this - firstJan) / 86400000) + firstJan.getDay() + 1) / 7); +}; + +function getWeekType() { + const table = { + 37: "a", + 38: "b", + 39: "c", + 40: "d", + 41: "e", + 42: "f", + 43: "g", + 45: "h", + 46: "a", + 47: "b", + 48: "c", + 49: "d", + 50: "e", + 51: "f", + 2: "g", + 3: "h", + 4: "a", + 5: "b", + 6: "c", + 7: "d", + 8: "e", + 10: "f", + 11: "g", + 12: "h", + 13: "a", + 14: "b", + 17: "c", + 18: "d", + 19: "e", + 20: "f", + 21: "g", + 22: "h", + 25: "a", + 26: "b", + 27: "c", + 28: "d", + 29: "e", + 30: "f", + 31: "g" + }; + + const date = new Date(); + + try { + return table[date.getWeek()] + } catch (e) { + alert("Ferien!"); + return "a" + } +}
\ No newline at end of file |