summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--parser.py39
-rw-r--r--static/index.html123
-rw-r--r--static/script.js131
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