From 55778039fb3f75445084f36be00c92d9e7f288aa Mon Sep 17 00:00:00 2001 From: Jonas Hahn Date: Sun, 6 Sep 2026 14:41:23 +0200 Subject: [PATCH] initial --- .gitignore | 1 + fetch.py | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ justfile | 2 ++ mensa.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ pretty.py | 21 ++++++++++++++++ 5 files changed, 164 insertions(+) create mode 100644 .gitignore create mode 100644 fetch.py create mode 100644 justfile create mode 100644 mensa.py create mode 100644 pretty.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98e6ef6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.db diff --git a/fetch.py b/fetch.py new file mode 100644 index 0000000..9b64780 --- /dev/null +++ b/fetch.py @@ -0,0 +1,71 @@ +""" +Try to input dishes from the coming week. +""" + +import json +import sqlite3 +import subprocess +from datetime import date, timedelta + +DB = "mensa.db" +MENSEN = ["cgin", "mensa_am_turm", "zentralmensa"] + +db = sqlite3.connect(DB) + +db.execute(""" +CREATE TABLE IF NOT EXISTS dishes ( + date TEXT NOT NULL, + mensa TEXT NOT NULL, + type TEXT NOT NULL, + title TEXT, + description TEXT, + category TEXT, + allergens TEXT, + UNIQUE(date, mensa, type) +) +""") + +TODAY = date.today() + +for i in range(7): + day = TODAY + timedelta(days=i) + + for mensa in MENSEN: + result = subprocess.run( + ["python", "mensa.py", day.isoformat(), mensa], + capture_output=True, + text=True, + ) + + if not result.stdout: + print(f"no results: {day} {mensa}") + continue + + dishes = json.loads(result.stdout) + + for dish in dishes: + try: + db.execute( + """ + INSERT INTO dishes + (date, mensa, type, title, description, category, allergens) + VALUES (?, ?, ?, ?, ?, ?, ?) + """, + ( + dish["date"], + dish["mensa"], + dish["type"], + dish["title"], + dish["description"], + json.dumps(dish["category"], ensure_ascii=False), + json.dumps(dish["allergens"], ensure_ascii=False), + ), + ) + print(f"registered: {dish['date']} {dish['mensa']} {dish['type']}") + except sqlite3.IntegrityError: + print( + f"already registered: {dish['date']} {dish['mensa']} {dish['type']}" + ) + +db.commit() +db.close() diff --git a/justfile b/justfile new file mode 100644 index 0000000..d3be8aa --- /dev/null +++ b/justfile @@ -0,0 +1,2 @@ +fetch: + python fetch.py diff --git a/mensa.py b/mensa.py new file mode 100644 index 0000000..665f162 --- /dev/null +++ b/mensa.py @@ -0,0 +1,69 @@ +""" +When there is an error there is no output but an error. +All in german. +""" + +import json +import re +import sys + +import requests +from bs4 import BeautifulSoup + +DATE, MENSA = sys.argv[1:3] +URL = f"https://www.studierendenwerk-goettingen.de/fileadmin/templates/php/mensaspeiseplan/cached/de/{DATE}/{MENSA}.html" + +r = requests.get(URL) +if r.status_code == 404: + sys.exit(1) + +soup = BeautifulSoup(r.text, "html.parser") +table = soup.select_one("table.sp_tab") + +if not table or "kein Angebot" in table.get_text(): + sys.exit(1) + +dishes = [] + +for row in table.select("tr")[1:]: + cells = row.select("td") + if len(cells) != 3: + continue + + typ, bez, hin = cells + strong = bez.select_one("strong") + raw_title = strong.get_text(" ", strip=True) if strong else "" + + title = re.sub(r"\s*\([^)]*\)", "", raw_title) + + description = bez.get_text(" ", strip=True).removeprefix(raw_title).strip() + angebot = bez.select_one("i.smaller") + if angebot: + description = description.removesuffix( + angebot.get_text(" ", strip=True) + ).strip() + + allergens = [ + x.strip() + for group in re.findall(r"\(([^()]*)\)", raw_title + " " + description) + for x in group.split(",") + ] + + category = [ + str(img["src"]).rsplit("/", 1)[-1].rsplit(".", 1)[0] + for img in hin.select("img") + ] + + dishes.append( + { + "date": DATE, + "mensa": MENSA, + "type": typ.get_text(strip=True), + "title": title, + "description": description, + "category": category, + "allergens": allergens, + } + ) + +print(json.dumps(dishes, ensure_ascii=False)) diff --git a/pretty.py b/pretty.py new file mode 100644 index 0000000..e72b5d9 --- /dev/null +++ b/pretty.py @@ -0,0 +1,21 @@ +import json +import sqlite3 + +db = sqlite3.connect("mensa.db") + +rows = db.execute(""" + SELECT date, mensa, type, title, description, category, allergens + FROM dishes + ORDER BY rowid DESC + LIMIT 3 +""").fetchall() + +for date, mensa, typ, title, description, category, allergens in rows: + print(f"{date} | {mensa} | {typ}") + print(f" {title}") + print(f" {description}") + print(f" category: {', '.join(json.loads(category))}") + print(f" allergens: {', '.join(json.loads(allergens))}") + print() + +db.close()