Custom Calendar
This commit is contained in:
@ -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.
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
11
init.py
@ -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.
|
||||||
|
|||||||
65
routing.py
65
routing.py
@ -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")
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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"}
|
||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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"}
|
||||||
@ -89,6 +89,11 @@ nav li .bottom {
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
font-size: 110%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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 %}
|
||||||
12
templates/restore-events.html
Normal file
12
templates/restore-events.html
Normal 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 %}
|
||||||
Reference in New Issue
Block a user