Custom Calendar

This commit is contained in:
2024-09-29 19:21:20 +02:00
parent b0bda20baa
commit 85c129b602
14 changed files with 159 additions and 34 deletions

View File

@ -6,6 +6,7 @@ import datetime
import recurring_ical_events import recurring_ical_events
from fetchMENSA import getMeals from fetchMENSA import getMeals
import pytz import pytz
from init import *
shortnames = ["mon", "tue", "wed", "thu", "fri", "sat"] shortnames = ["mon", "tue", "wed", "thu", "fri", "sat"]
longnames = ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"] longnames = ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"]
@ -78,11 +79,32 @@ async def getWeek(weekstart: datetime, file: str, showsat: bool):
"weekday": estart.weekday(), "weekday": estart.weekday(),
"day": estart.day, "day": estart.day,
"teacher": teacher, "teacher": teacher,
"id": event["UID"]
} }
eventl += [eventdict] eventl += [eventdict]
return eventl, await MensaDayList(start_date, showsat), prevw, nextw, mon return eventl, await MensaDayList(start_date, showsat), prevw, nextw, mon
async def createCustomCalendar (uid: int):
hiddenEvents = HiddenVL.query.filter_by(uid=uid).all()
hiddenEventIDs = {event.eventid for event in hiddenEvents}
kurs = User.query.filter_by(id=uid).first().kurs
raplaFile = Rapla.query.filter_by(name=kurs).first().file
with open(f"calendars/{raplaFile}") as f:
calendar = icalendar.Calendar.from_ical(f.read())
newCalendar = icalendar.Calendar()
for component in calendar.walk():
if component.name != "VEVENT":
if component.name != "VCALENDAR":
newCalendar.add_component(component)
elif component["UID"] not in hiddenEventIDs:
newCalendar.add_component(component)
byteText = newCalendar.to_ical()
with open(f"calendars/{uid}.ical", 'w+') as f:
f.write(byteText.decode("utf-8"))
return uid
async def MensaDayList(weekstart: datetime, showsat: bool): async def MensaDayList(weekstart: datetime, showsat: bool):
""" """
Gibt die Essen einer Woche zurück. Gibt die Essen einer Woche zurück.

View File

@ -30,7 +30,7 @@ async def checkUser(email: str, password: str):
content = (f"usrname={formattedEmail}&pass={formattedPassword}&ARGUMENTS=clino%2Cusrname%2Cpass%2C" content = (f"usrname={formattedEmail}&pass={formattedPassword}&ARGUMENTS=clino%2Cusrname%2Cpass%2C"
f"menuno%2Cmenu_type%2Cbrowser%2Cplatform&APPNAME=CampusNet&PRGNAME=LOGINCHECK") f"menuno%2Cmenu_type%2Cbrowser%2Cplatform&APPNAME=CampusNet&PRGNAME=LOGINCHECK")
response = await s.post(url=url, headers=headers, content=content) response = await s.post(url=url, headers=headers, content=content)
header = response.headers header = response.headers
try: try:
refresh = header["REFRESH"] refresh = header["REFRESH"]
arg = refresh.find("=-N") + 3 arg = refresh.find("=-N") + 3

View File

@ -11,8 +11,8 @@ from dateutil.relativedelta import relativedelta
from icalendar import Calendar, Event from icalendar import Calendar, Event
import json import json
from init import scheduler, flaskApp, Rapla, db from init import scheduler, flaskApp, Rapla, db, HiddenVL, User
from calendar_generation import createCustomCalendar
async def fetchPlan(session, url): async def fetchPlan(session, url):
""" """
@ -121,12 +121,18 @@ async def getNewRapla(url: str, testing=False):
return url return url
def getIcal(kurs: str): def getIcal(uid: int | None = None, kurs: str | None = None):
""" """
Liefert den Namen der Datei des mitgegebenen Kurses. Liefert den Namen der Datei des mitgegebenen Users.
:param uid:
:param kurs: :param kurs:
:return str: :return str:
""" """
if uid:
if HiddenVL.query.filter_by(uid=uid).first():
return f"{uid}.ical"
else:
kurs = User.query.filter_by(id=uid).first().kurs
rapla = Rapla.query.filter(Rapla.name == kurs).first() rapla = Rapla.query.filter(Rapla.name == kurs).first()
try: try:
return rapla.file return rapla.file
@ -164,6 +170,11 @@ async def refreshRapla():
for calendar in range(len(calendarList)): for calendar in range(len(calendarList)):
if calendarList[calendar] != 200: if calendarList[calendar] != 200:
writeToFile(f"calendars/{fileList[calendar]}", calendarList[calendar]) writeToFile(f"calendars/{fileList[calendar]}", calendarList[calendar])
hiddenEvents = HiddenVL.query.all()
hiddenUsers = {event.uid for event in hiddenEvents}
for user in hiddenUsers:
uid = await createCustomCalendar(user)
print (f"Update custom calendar: {uid}")
@scheduler.task('cron', id="raplaSchedule", hour='*', day_of_week='*', minute='*/3', week='*', second='40') @scheduler.task('cron', id="raplaSchedule", hour='*', day_of_week='*', minute='*/3', week='*', second='40')

11
init.py
View File

@ -87,6 +87,17 @@ class Rapla(db.Model):
link = db.Column(db.String(255), unique=True) link = db.Column(db.String(255), unique=True)
class HiddenVL(db.Model):
"""
Datenbank-Modell für ausgeblendete Vorlesungen.
"""
__tablename__ = 'hiddenVL'
uid = db.Column(db.Integer, ForeignKey('dualis.uid', ondelete='CASCADE'))
eventid = db.Column(db.String(255))
id = db.Column(db.String(255), primary_key=True)
name = db.Column(db.String(255))
class Meals(db.Model): class Meals(db.Model):
""" """
Datenbank-Modell für Meals. Datenbank-Modell für Meals.

View File

@ -1,8 +1,9 @@
#!/usr/bin/env python3.6 #!/usr/bin/env python3.6
from flask import make_response from flask import make_response
from flask import render_template, url_for, redirect, request from flask import render_template, url_for, redirect, request, send_from_directory
from flask_login import (login_user as loginUser, login_required as loginRequired, from flask_login import (login_user as loginUser, login_required as loginRequired,
logout_user as logoutUser, current_user as currentUser) logout_user as logoutUser, current_user as currentUser)
from sqlalchemy.exc import IntegrityError
from werkzeug.exceptions import HTTPException from werkzeug.exceptions import HTTPException
import hashlib import hashlib
import datetime import datetime
@ -12,7 +13,7 @@ import fetchDUALIS
import fetchRAPLA import fetchRAPLA
from requesthelpers import * from requesthelpers import *
from fetchRAPLA import * from fetchRAPLA import *
from calendar_generation import getWeek from calendar_generation import getWeek, createCustomCalendar
from init import * from init import *
@ -87,18 +88,18 @@ def initRoutes(app: Flask):
if not currentUser.kurs: if not currentUser.kurs:
return redirect(url_for("getKurs", next=url_for(request.endpoint))) return redirect(url_for("getKurs", next=url_for(request.endpoint)))
week = request.args.get("week") week = request.args.get("week")
if week: if week and week!="today":
week = datetime.strptime(week, "%Y-%m-%d") week = datetime.strptime(week, "%Y-%m-%d")
else: else:
week = "today" week = "today"
samstag = request.args.get("samstag") samstag = request.args.get("samstag")
if not samstag: if not samstag:
samstag = False samstag = False
events = await getWeek(week, fetchRAPLA.getIcal(currentUser.kurs), samstag) events = await getWeek(week, fetchRAPLA.getIcal(uid=currentUser.id), samstag)
return render_template("plan-user.html", events=events[0], eventdays=events[1], return render_template("plan-user.html", events=events[0], eventdays=events[1],
name=currentUser.name, prev=str(events[2])[:10], next=str(events[3])[:10], uid=currentUser.id, name=currentUser.name, prev=str(events[2])[:10],
mon=events[4], next=str(events[3])[:10], mon=events[4], login=True, s="p", date=str(week)[:10],
s="p", praxis="hidden") praxis="hidden")
@app.route("/plan/<string:kurs>") @app.route("/plan/<string:kurs>")
async def displayPlan(kurs: str): async def displayPlan(kurs: str):
@ -119,17 +120,29 @@ def initRoutes(app: Flask):
except AttributeError: except AttributeError:
pass pass
kurs = kurs.upper() kurs = kurs.upper()
plan = fetchRAPLA.getIcal(kurs) plan = fetchRAPLA.getIcal(kurs=kurs)
if plan: if plan:
samstag = request.args.get("samstag") samstag = request.args.get("samstag")
if not samstag: if not samstag:
samstag = False samstag = False
events = await getWeek(week, plan, samstag) events = await getWeek(week, plan, samstag)
return render_template("plan-anon.html", events=events[0], eventdays=events[1], kurs=kurs, 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") login=False, prev=str(events[2])[:10], next=str(events[3])[:10],
mon=events[4], praxis="hidden")
else: else:
return redirect(url_for("login")) return redirect(url_for("login"))
@app.route("/plan/restore")
@loginRequired
async def restoreVL():
events = HiddenVL.query.filter_by(uid=currentUser.id).all()
return render_template("restore-events.html", events=events, praxis="hidden")
@app.route("/plan/calendar/<int:uid>", methods=["GET"])
async def deliverCalendar(uid: int):
calstring = fetchRAPLA.getIcal(uid=uid)
return send_from_directory("calendars", calstring, as_attachment=False)
@app.route("/set-up") @app.route("/set-up")
def redKurs(): def redKurs():
""" """
@ -156,7 +169,7 @@ def initRoutes(app: Flask):
if not currentUser.kurs: if not currentUser.kurs:
kurs = await fetchDUALIS.getKurs(dualisUser.token, cookie) kurs = await fetchDUALIS.getKurs(dualisUser.token, cookie)
if kurs != 0: if kurs != 0:
if not fetchRAPLA.getIcal(kurs): if not fetchRAPLA.getIcal(kurs=kurs):
return render_template('kurs.html', detected=(kurs, dualisError), s="s", return render_template('kurs.html', detected=(kurs, dualisError), s="s",
theorie="hidden", praxis="hidden", file=False) theorie="hidden", praxis="hidden", file=False)
currentUser.kurs = kurs currentUser.kurs = kurs
@ -251,6 +264,33 @@ def initRoutes(app: Flask):
""" """
return render_template("login.html", theorie="hidden", praxis="hidden", s="s") return render_template("login.html", theorie="hidden", praxis="hidden", s="s")
@app.route("/plan/delete", methods=["POST"])
@loginRequired
async def removeEvent():
day = request.args.get("day")
id = str(request.args.get("id"))
uid = currentUser.id
name = request.args.get("name")
idDB = HiddenVL(uid=uid, eventid=id, id=str(uid) + id, name=name)
db.session.add(idDB)
try:
db.session.commit()
except IntegrityError:
return redirect(url_for("displayRapla", week=day))
await createCustomCalendar(currentUser.id)
return redirect(url_for("displayRapla", week=day))
@app.route("/plan/restore/event")
@loginRequired
async def restoreEvent():
id = str(request.args.get("id"))
uid = currentUser.id
entry = HiddenVL.query.filter_by(id=str(uid) + id).first()
db.session.delete(entry)
db.session.commit()
await createCustomCalendar(currentUser.id)
return redirect(url_for("restoreVL"))
@app.route("/log-in", methods=["POST"]) @app.route("/log-in", methods=["POST"])
async def login_post(): async def login_post():
""" """
@ -315,8 +355,9 @@ def initRoutes(app: Flask):
logoutUser() logoutUser()
redirection = make_response(redirect(url_for("login", code=1, next=url_for("welcome")))) redirection = make_response(redirect(url_for("login", code=1, next=url_for("welcome"))))
redirection.set_cookie("cnsc", value="Logged out! Your temporary token " redirection.set_cookie("cnsc", value="Logged out! Your temporary token "
"on our server and the cookie on your device have been deleted.", httponly=True, "on our server and the cookie on your device have been deleted.",
secure=True) httponly=True,
secure=True)
return redirection return redirection
@app.route("/error") @app.route("/error")

View File

@ -68,6 +68,11 @@ h2 {
justify-content: space-evenly; justify-content: space-evenly;
} }
a {
color: white;
font-size: 100%;
}
button { button {
border-radius: 5px; border-radius: 5px;
border-color: white; border-color: white;

View File

@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["cal.scss"],"names":[],"mappings":"AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;AAAA;EAEE;;;AAKF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAKF;EACI;EACA;;;AAIJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;;;AAIJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACE;;;AAQF;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAKA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAKA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAKA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA","file":"cal.css"} {"version":3,"sourceRoot":"","sources":["cal.scss"],"names":[],"mappings":"AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;AAAA;EAEE;;;AAKF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAKF;EACI;EACA;;;AAIJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;;;AAIJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACE;;;AAQF;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAKA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAKA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAKA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA;;;AAEA;EACA","file":"cal.css"}

View File

@ -68,6 +68,11 @@ h2 {
justify-content: space-evenly; justify-content: space-evenly;
} }
a {
color: white;
font-size: 100%;
}
button { button {
border-radius: 5px; border-radius: 5px;
border-color: white; border-color: white;

View File

@ -89,6 +89,11 @@ nav li .bottom {
padding: 20px; padding: 20px;
} }
a {
color: white;
font-size: 110%;
}
.container { .container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["style.scss"],"names":[],"mappings":"AAAA;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAIJ;EACI;EACA;;;AAGJ;AACA;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACH;;;AAGD;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACE;;;AAGF;EACI;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA","file":"style.css"} {"version":3,"sourceRoot":"","sources":["style.scss"],"names":[],"mappings":"AAAA;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAIJ;EACI;EACA;;;AAGJ;AACA;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;EACH;;;AAGD;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACE;;;AAGF;EACI;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA","file":"style.css"}

View File

@ -89,6 +89,11 @@ nav li .bottom {
padding: 20px; padding: 20px;
} }
a {
color: white;
font-size: 110%;
}
.container { .container {
display: flex; display: flex;

View File

@ -62,15 +62,26 @@
<div class="events"> <div class="events">
{% for i in events %} {% for i in events %}
{% if i["weekday"] == e %} {% if i["weekday"] == e %}
<div class="event start-{{ i["start"][:2]+i["start"][3:] }} end-{{ i["end"][:2]+i["end"][3:]}}"> {% with event=i %}
{% block event %} {% endblock %} <div class="event start-{{ event["start"][:2]+event["start"][3:] }} end-{{ event["end"][:2]+event["end"][3:]}}">
<p class="title">{{ i["name"] }}</p> {% if login %}
<p class="room">{{ i["room"] }}</p> <div class="userbuttons">
{% for teacher in i["teacher"] %} <form method="post" action={{ url_for ("removeEvent", id=event["id"], day=date, name=event["name"]) }}>
<p class="teacher">{{ teacher }}</p> <button>👁</button>
{% endfor %} </form>
<p class="time">{{ i["start"] }} - {{ i["end"] }} ({{ i["dur"] }}h)</p> <form>
</div> <button class="plusbutton">+</button>
</form>
</div>
{% endif %}
<p class="title">{{ event["name"] }}</p>
<p class="room">{{ event["room"] }}</p>
{% for teacher in event["teacher"] %}
<p class="teacher">{{ teacher }}</p>
{% endfor %}
<p class="time">{{ event["start"] }} - {{ event["end"] }} ({{ event["dur"] }}h)</p>
</div>
{% endwith %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</div> </div>

View File

@ -5,11 +5,8 @@
{% block startcontent %} {% block startcontent %}
<h2>{{ name }}s Vorlesungsplan</h2> <h2>{{ name }}s Vorlesungsplan</h2>
{% endblock %} {% endblock %}
{% block event %}
<div class="userbuttons">
<button>👁</button>
<button class="plusbutton">+</button>
</div>
{% endblock %}
{% block endcontent %} {% block endcontent %}
<a href={{ url_for("deliverCalendar", uid=uid) }}>Kalender-Abo</a>
<br>
<a href={{ url_for("restoreVL") }}>Ausgeblendete Vorlesungen wieder einblenden</a>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,12 @@
{% extends "index.html" %}
{% block content %}
<h2>Ausgeblendete Vorlesungen</h2>
{% for event in events %}
<li>
<a href={{ url_for("restoreEvent", id=event.eventid) }}>{{ event.name }}</a>
</li>
{% endfor %}
{% if events | length == 0 %}
<a href = {{ url_for("displayRapla") }}>Zurück zum Stundenplan (keine ausgeblendeten Vorlesungen) </a>
{% endif %}
{% endblock %}