diff --git a/calendar_generation.py b/calendar_generation.py index dc639c5..38c6cad 100644 --- a/calendar_generation.py +++ b/calendar_generation.py @@ -1,3 +1,6 @@ +import time + +import asyncio import icalendar import datetime import recurring_ical_events @@ -10,7 +13,7 @@ months = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August" "November", "Dezember"] -def getWeek(weekstart: datetime, file: str, showsat: bool): +async def getWeek(weekstart: datetime, file: str, showsat: bool): """ Liefert alle Events einer Woche zurück. \n Wochenstart wird automatisch auf den Montag der Woche gelegt. \n @@ -67,10 +70,10 @@ def getWeek(weekstart: datetime, file: str, showsat: bool): "day": estart.day } eventl += [eventdict] - return eventl, daylist(start_date, showsat), prevw, nextw, mon + return eventl, await daylist(start_date, showsat), prevw, nextw, mon -def daylist(weekstart: datetime, showsat: bool): +async def daylist(weekstart: datetime, showsat: bool): """ Gibt die Essen einer Woche zurück. :param weekstart: @@ -83,15 +86,19 @@ def daylist(weekstart: datetime, showsat: bool): r = 6 else: r = 5 + essen = [] for i in range(r): - essen = getMeals(weekday) + essen += [getMeals(weekday)] dayl += [{ "day": weekday.day, "short": shortnames[i], "long": longnames[i], - "mensa": essen + "mensa": i }] weekday += datetime.timedelta(days=1) + essenl = await asyncio.gather(*essen, return_exceptions=True) + for day in range(r): + dayl[day]["mensa"] = essenl[day] return dayl diff --git a/fetchMENSA.py b/fetchMENSA.py index dd8e614..00acb8f 100644 --- a/fetchMENSA.py +++ b/fetchMENSA.py @@ -1,5 +1,5 @@ import json -from init import db, Meals#, scheduler +from init import db, Meals, scheduler import datetime import time import httpx @@ -7,7 +7,7 @@ import httpx nomeal = 'Essen nicht (mehr) verfügbar' -def getMeals(day: datetime): +async def getMeals(day: datetime): """ Liefert alle Mahlzeiten eines Tages. \n Befinden sie sich schon in der Datenbank, werden diese zurückgegeben. \n @@ -23,7 +23,7 @@ def getMeals(day: datetime): essen += [i.name] essen.sort(key=len, reverse=True) return essen - return getMealsFromAPI(day, dbentry=True) + return await getMealsFromAPI(day, dbentry=True) async def getMealsFromAPI(day: str, dbentry: bool = False): @@ -110,29 +110,29 @@ def formatDay(day: datetime): return day -#@scheduler.task('cron', id="refreshMeals", hour='8-11', day_of_week='*', minute='15', week='*', second='30') -def refreshMeals(): +@scheduler.task('cron', id="refreshMeals", hour='8-11', day_of_week='*', minute='*/15', week='*', second='30') +async def refreshMeals(): """ Aktualisiert immer vormittags alle Mahlzeiten in der Datenbank. \n Datenbankeinträge werden ersetzt, wenn die API andere Mahlzeiten liefert. """ print("Aktualisiere Essenspläne...\n") - #with scheduler.app.app_context(): - # table = Meals.query.all() - # dates = [] - # for i in table: - # if i.date not in dates: - # dates += [i.date] - # for i in range(len(dates)): - # dates[i] = formatDay(dates[i]) - # for i in dates: - # apinames = getMealsFromAPI(i) - # dbmeals = Meals.query.filter_by(date=i).all() - # dbnames = [] - # for m in dbmeals: - # dbnames += [m.name] - # if set(dbnames) != set(apinames) and nomeal not in apinames: - # for n in dbnames: - # db.session.delete(Meals.query.filter_by(date=i, name=n).first()) - # db.session.commit() - # getMealsFromAPI(i, True) + + table = Meals.query.all() + dates = [] + for i in table: + if i.date not in dates: + dates += [i.date] + for i in range(len(dates)): + dates[i] = formatDay(dates[i]) + for i in dates: + apinames = await getMealsFromAPI(i) + dbmeals = Meals.query.filter_by(date=i).all() + dbnames = [] + for m in dbmeals: + dbnames += [m.name] + if set(dbnames) != set(apinames) and nomeal not in apinames: + for n in dbnames: + db.session.delete(Meals.query.filter_by(date=i, name=n).first()) + db.session.commit() + await getMealsFromAPI(i, True) diff --git a/fetchRAPLA.py b/fetchRAPLA.py index 57cf7e3..c1a550f 100644 --- a/fetchRAPLA.py +++ b/fetchRAPLA.py @@ -3,6 +3,10 @@ from urllib.request import urlretrieve import icalendar import json import recurring_ical_events + +from init import scheduler + + #from init import scheduler @@ -93,7 +97,7 @@ def getRaplas(): return sorted(kursl), sorted(filel), sorted(urll) -#@scheduler.task("interval", id="refreshRapla", minutes=5) +@scheduler.task("interval", id="refreshRapla", minutes=5) def refreshRapla(): """ Aktualisiert alle 5 Minuten alle gespeicherten Raplas. @@ -102,4 +106,4 @@ def refreshRapla(): urll = getRaplas()[2] for i in range(len(filel)): print("Update Rapla: " + filel[i][:-5]) - urlretrieve(urll[i], "calendars/" + filel[i]) \ No newline at end of file + urlretrieve(urll[i], "calendars/" + filel[i]) diff --git a/init.py b/init.py index 0b4ec72..b9ee825 100644 --- a/init.py +++ b/init.py @@ -2,9 +2,10 @@ from flask import Flask from flask_login import LoginManager, UserMixin from flask_sqlalchemy import SQLAlchemy from flask_talisman import Talisman + from get_mysql import get_mysql import atexit -#from flask_apscheduler import APScheduler +from flask_apscheduler import APScheduler def create(): @@ -25,7 +26,7 @@ def create(): login_manager.login_view = "login" # Shut down the scheduler when exiting the app - #atexit.register(lambda: scheduler.shutdown()) + atexit.register(lambda: scheduler.shutdown()) @login_manager.user_loader def load_user(uid: int): @@ -79,11 +80,11 @@ class Meals(db.Model): schwein = db.Column(db.Boolean) -#scheduler = APScheduler() +scheduler = APScheduler() app = create() def_src = ["*.paulmartin.cloud", '\'self\''] Talisman(app, content_security_policy={"default-src": def_src, "script-src": def_src # + ["'unsafe-inline'"] }) -#scheduler.init_app(app) -#scheduler.start() -#scheduler.api_enabled = True +scheduler.init_app(app) +scheduler.start() +scheduler.api_enabled = True diff --git a/requesthelpers.py b/requesthelpers.py index 7e3ca89..0d873b3 100644 --- a/requesthelpers.py +++ b/requesthelpers.py @@ -1,4 +1,4 @@ -from init import Semesterlist +from init import Semesterlist, User def getCookie(cookies): @@ -13,10 +13,14 @@ def getCookie(cookies): return cookie -def semesterlist(uid): +def getSemesterList(uid): semesterlist = Semesterlist.query.filter_by(uid=uid).all() semester = [] for s in semesterlist: semester += [[s.semestername, s.semesterid]] semester.sort(key=lambda x: x[-1], reverse=True) return semester + + +def loadUser(uid): + return User.query.filter_by(id=uid).first() diff --git a/requirements.txt b/requirements.txt index 6cde40d..8d80570 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,4 +13,5 @@ bs4~=0.0.1 pytz~=2023.3.post1 asyncio~=3.4.3 -httpx~=1.0.0b0 \ No newline at end of file +httpx~=1.0.0b0 +celery~=5.4.0rc2 \ No newline at end of file diff --git a/routing.py b/routing.py index eb806f2..6659ef4 100644 --- a/routing.py +++ b/routing.py @@ -10,8 +10,9 @@ import time import random import fetchDUALIS +import fetchMENSA import fetchRAPLA -import requesthelpers +from requesthelpers import * from fetchRAPLA import * from calendar_generation import getWeek from init import * @@ -68,14 +69,14 @@ async def displayNoten(): timeout = fetchDUALIS.timeOut(d, c, "displayNoten") if timeout: return timeout - semester = requesthelpers.semesterlist(current_user.id) + semester = getSemesterList(current_user.id) noten = await fetchDUALIS.getResults(t, c, chosensemester) return render_template("noten.html", noten=noten, semester=semester, sel=chosensemester, s="n", praxis="hidden") @app.route("/plan", methods=["GET"]) @login_required -def displayRapla(): +async def displayRapla(): """ Zeigt den Stundenplan für eingeloggte User an. \n TODO: Persönliche Filter, Notizen, Essensvorlieben etc. berücksichtigen. @@ -91,14 +92,14 @@ def displayRapla(): samstag = request.args.get("samstag") if not samstag: samstag = False - events = getWeek(week, fetchRAPLA.getIcal(current_user.kurs), samstag) + events = await getWeek(week, fetchRAPLA.getIcal(current_user.kurs), samstag) return render_template("plan-user.html", events=events[0], eventdays=events[1], name=current_user.name, prev=str(events[2])[:10], next=str(events[3])[:10], mon=events[4], s="p", praxis="hidden") @app.route("/plan/") -def displayPlan(kurs): +async def displayPlan(kurs): """ Zeigt den Stundenplan ohne Login an. \n Präferenzen werden nicht berücksichtigt. @@ -121,7 +122,7 @@ def displayPlan(kurs): samstag = request.args.get("samstag") if not samstag: samstag = False - events = getWeek(week, plan, samstag) + events = await getWeek(week, plan, samstag) return render_template("plan-anon.html", events=events[0], eventdays=events[1], kurs=kurs, prev=str(events[2])[:10], next=str(events[3])[:10], mon=events[4], praxis="hidden") else: @@ -189,7 +190,7 @@ async def getSemester(): db.session.add(semitem) db.session.commit() else: - semester = requesthelpers.semesterlist(current_user.id) + semester = getSemesterList(current_user.id) return render_template("semester.html", semester=semester, s="s", theorie="hidden", praxis="hidden") @@ -232,7 +233,7 @@ def getRapla(): if file == url == "None": return redirect(url_for("chooseRaplas")) if file != "None": - User.query.filter_by(id=current_user.id).first().kurs = file[5:-5] + loadUser(current_user.id).kurs = file[5:-5] db.session.commit() elif url != "None": file = getNewRapla(url)