import urllib.error from urllib.request import urlretrieve import asyncio import httpx import icalendar import json import recurring_ical_events from init import scheduler, app async def fetchPlan(session, url): return await session.get(url=url) def writeToFile(filename, data): with open(filename, 'w+') as f: f.write(data.text) f.close() def parseURL(url: str): """ Konvertiert URLs ins korrekte Format. \n Konvertiert werden: http, www.; page=calendar \n In: https; page=ical :param url: :return str: """ rapla = url.find("rapla.") if rapla == -1: return 0 elif len(url[:rapla]) == 4 or len(url[:rapla]) > 6: url = url[rapla:] http = url.find(":") if url[:http] == "http": url = "https" + url[http:] elif http == -1: url = "https://" + url p = url.find("page=") u = url.find("&") if (url[p + 5:u]).lower() == "ical": return url elif p != -1: return url[:p + 5] + "ical" + url[u:] else: return 0 async def getNewRapla(url: str): """ Speichert den iCal eines Raplas auf dem Server. \n Gibt Namen der Datei zurück. \n TODO: Standort zu Dateibezeichner hinzufügen, um Konflikte zu vermeiden. :param url: :return str: """ url = parseURL(url) if url == 0: return 0 urlfile = url.find("file=") kurs = url[urlfile + 5:].upper() try: urlretrieve(url, "calendars/rapla" + kurs + ".ical") async with httpx.AsyncClient() as s: response = await fetchPlan(s, url) writeToFile(f"calendars/rapla{kurs}.ical", response) except urllib.error.URLError: return -1 file = open("calendars/list.json", "r+") jsoncal = json.load(file) jsoncal.update({kurs: [f"rapla{kurs}.ical", url]}) file.close() file = open("calendars/list.json", "w") json.dump(jsoncal, file, indent=4) return f"rapla{kurs}.ical" def getIcal(kurs: str): """ Liefert den Namen der Datei des mitgegebenen Kurses. :param kurs: :return str: """ file = open("calendars/list.json", "r") jf = json.load(file) try: return jf[kurs][0] except KeyError: return None def getRaplas(): """ Liefert alle auf dem Server gespeicherten Raplas. :return (Kursliste, Dateiliste, URL-Liste): """ file = open("calendars/list.json", "r") jsonf = json.load(file) kursl = [] filel = [] urll = [] for i in jsonf: kursl += [i] filel += [jsonf[i][0]] urll += [jsonf[i][1]] return sorted(kursl), sorted(filel), sorted(urll) async def refreshRapla(): """ Aktualisiert alle 5 Minuten alle gespeicherten Raplas. """ filel = getRaplas()[1] urll = getRaplas()[2] jobl = [] async with httpx.AsyncClient() as s: for i in range(len(filel)): print(f"Update Rapla: {filel[i][:-5]}") jobl += [fetchPlan(s, urll[i])] callist = await asyncio.gather(*jobl, return_exceptions=True) for cal in range(len(callist)): writeToFile(f"calendars/{filel[cal]}", callist[cal]) @scheduler.task('cron', id="raplaschedule", hour='*', day_of_week='*', minute='*/15', week='*') def raplaschedule(): with app.app_context(): asyncio.run(refreshRapla())