diff --git a/app.py b/app.py new file mode 100644 index 0000000..8b6ab61 --- /dev/null +++ b/app.py @@ -0,0 +1,91 @@ +################ +### UniSquat ### +################ + +""" + Indique toutes les salles disponibles dans les différents départements de + l'Université de Strasbourg. +""" + +from flask import Flask +from flask import render_template +from flask import url_for +from flask import request + +import rooms_get as ro +import datetime as dti + +app = Flask(__name__) + +# Modules : +import datetime +import time + +# Fichiers locaux : +import date_tools +import rooms_get as ro +# import definitions as lib # TODO : À quoi ça sert ? + + +@app.route("/") +def select_dept() : + """ + Permet de sélectionner un ou plusieurs départements dans lesquels + chercher des salles libres. + + Parameters + ---------- + None. + + Returns + ------- + flask.render_template + """ + + dept_filen = "data/dept_list.txt" + + dept_list = ro.get_depts(dept_filen) + content = {"dept_list":dept_list} + + url_for("static", filename="style.css") + return render_template("dept-select.html", **content) + + +@app.route("/free-rooms", methods=["POST", "GET"]) +def free_rooms() : + """ + Affiche les salles libres dans les départements sélectionnés + dans la page précédente. + + Parameters + ---------- + None. + + Returns + ------- + flask.render_template + """ + + depts = request.form["dept"] + + print(depts) + + #hdelay = 1 #TODO : décalage horaire (pb de fuseau ?) + + #if time.localtime().tm_isdst != 0 : + #hdelay = 2 + + #ignore_list = ["salle non définie", "salle en Distanciel"] + + ##dept = dept_list[0] #TODO : proposer d'autres départements + + #date = dti.datetime(2022, 5, 5, 10, 30) + + #available_rooms = ro.getrooms(date, depts, ignore_list) + + #context = {"available_rooms":available_rooms, "hdelay":hdelay} + + context = {} + + url_for("static", filename="style.css") + return render_template("free-rooms.html", **context) \ No newline at end of file diff --git a/main_cli.py b/main_cli.py index 828c649..37c5333 100644 --- a/main_cli.py +++ b/main_cli.py @@ -18,13 +18,15 @@ Created on Thu Feb 24 17:14:05 2022 # Modules : import datetime +import time + # Fichiers locaux : import date_tools import rooms_get as ro # import definitions as lib # TODO : À quoi ça sert ? # Globales -favorites = ["C" + str(i) + " MATH" for i in range(1,12)] + ["C42-CMI"] # TODO : Ne sera pas conservé +#favorites = ["C" + str(i) + " MATH" for i in range(1,12)] + ["C42-CMI"] # TODO : Ne sera pas conservé favorites = [] links = [] # Liens vers les calendriers des salles des différents bâtiments de l'université @@ -42,6 +44,11 @@ def main() : """ print("~~~ UniSquat ~~~\n") + + hdelay = 1 #TODO : décalage horaire (pb de fuseau ?) + + if time.localtime().tm_isdst != 0 : + hdelay = 2 ignore_list = ["salle non définie", "salle en Distanciel"] @@ -97,7 +104,7 @@ def main() : if room.end.hour == 23 and room.end.minute == 59 and room.end.second == 59 : print(" - " + room.name) else : - print(" - " + room.name + " | Occupée à : " + str(room.end.hour + 1) + ":" + str(room.end.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?) + print(" - " + room.name + " | Occupée à : " + str(room.end.hour + hdelay) + ":" + str(room.end.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?) # Salles libres prochainement : print("\nLes salles suivantes seront disponibles prochainement : \n") @@ -114,9 +121,9 @@ def main() : # print(" - " + room["name"]+" | libre dans : "+str(int(deltasec/60+0.5))+" minutes") if room.end.hour == 23 and room.end.minute == 59 and room.end.second == 59 : - print(" - " + room.name + " | Libre à " + str(room.start.hour + 1) + ":" + str(room.start.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?) + print(" - " + room.name + " | Libre à " + str(room.start.hour + hdelay) + ":" + str(room.start.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?) else : - print(" - " + room.name + " | Libre de " + str(room.start.hour + 1) + ":" + str(room.start.minute) + " à " + str(room.end.hour + 1) + ":" + str(room.end.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?) + print(" - " + room.name + " | Libre de " + str(room.start.hour + hdelay) + ":" + str(room.start.minute) + " à " + str(room.end.hour + hdelay) + ":" + str(room.end.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?) if __name__=="__main__": main() diff --git a/rooms_get.py b/rooms_get.py index bce736d..af02868 100644 --- a/rooms_get.py +++ b/rooms_get.py @@ -165,17 +165,17 @@ def get_depts(filename) : return dept_list -def get_tot_rooms(datet, dept, ignore_list) : +def get_tot_rooms(datet, depts, ignore_list) : """ - Crée une liste de toutes les salles du département choisi. + Crée une liste de toutes les salles des départements choisis. Parameters ---------- datet : datetime.datetime() Date pour la recherche de salles. - dept : Dept - Bâtiment dans lequel chercher des salles. + dept : list + Liste des départements dans lesquel chercher des salles. ignore_list : list Liste des noms de salles à ignorer. @@ -198,28 +198,31 @@ def get_tot_rooms(datet, dept, ignore_list) : else : cal_start.replace(month = cal_start.month - margintime) - # Récupération des calendriers correspondants au lien du département, sur une période de 'margintime' mois : - result = sched_get(datet, dept.link, datet.replace(month = datet.month + margintime)) - cal = icalendar.Calendar.from_ical(result) + # Récupération des calendriers correspondants aux liens des départements, sur une période de 'margintime' mois : + cals = list() # Liste des emplois du temps des départements choisis + for d in depts : + result = sched_get(datet, d.link, datet.replace(month = datet.month + margintime)) + cals.append(icalendar.Calendar.from_ical(result)) rnamelist = [] # Contient le nom de toutes les salles indiquées dans la section "LOCATION" # Parcours de ces calendriers, pour faire la liste de toutes les salles : - for comp in cal.walk() : # Événements - if comp.name == "VEVENT" : - # Ajout de la salle dans le dictionnaire, si elle n'y est pas : - roomname = str(comp.get("location")) - if roomname not in rnamelist : - rnamelist.append(roomname) - start = datet.replace(hour = 0, minute = 0, second=0) # Par défaut, l'heure de début de disponibilité est aujourd'hui à 00:00 - end = datet.replace(hour = 23, minute = 59, second = 59) # Par défaut, l'heure de fin de la prochaine période disponibilité est aujourd'hui à 23:59 - is_free = True # Par défaut, la salle est libre - total_rooms.append(Room(roomname, start, end, is_free)) + for cal in cals : + for comp in cal.walk() : # Événements + if comp.name == "VEVENT" : + # Ajout de la salle dans le dictionnaire, si elle n'y est pas : + roomname = str(comp.get("location")) + if roomname not in rnamelist : + rnamelist.append(roomname) + start = datet.replace(hour = 0, minute = 0, second=0) # Par défaut, l'heure de début de disponibilité est aujourd'hui à 00:00 + end = datet.replace(hour = 23, minute = 59, second = 59) # Par défaut, l'heure de fin de la prochaine période disponibilité est aujourd'hui à 23:59 + is_free = True # Par défaut, la salle est libre + total_rooms.append(Room(roomname, start, end, is_free)) return total_rooms -def getrooms(datet, dept, ignore_list) : +def getrooms(datet, depts, ignore_list) : """ Ajout des informations supplémentaires à la liste des salles (heures de début-fin de dispo, indicateur de dispo). @@ -229,8 +232,8 @@ def getrooms(datet, dept, ignore_list) : datet : datetime.datetime() Date pour la recherche de salles. - dept : Dept - Bâtiment dans lequel chercher des salles. + dept : list + Liste des départements dans lesquel chercher des salles. ignore_list : list Liste des noms de salles à ignorer. @@ -242,50 +245,55 @@ def getrooms(datet, dept, ignore_list) : """ # Création de la liste de toutes les salles : - total_rooms = get_tot_rooms(datet, dept, ignore_list) + total_rooms = get_tot_rooms(datet, depts, ignore_list) # Récupération des calendriers correspondants au lien du département : - result = sched_get(datet, dept.link) - cal = icalendar.Calendar.from_ical(result) + cals = list() # Liste des emplois du temps des départements choisis + for d in depts : + result = sched_get(datet, d.link, datet.replace(month = datet.month + margintime)) + cals.append(icalendar.Calendar.from_ical(result)) # Ajout des infos supplémentaires sur les salles (heures de début-fin de dispo, indicateur de dispo), s'il y en a : - # Première boucle, pour déterminer les salles occupées : - for comp in cal.walk() : # Événements - if comp.name == "VEVENT" : - # Récupération des infos : - datestart = comp.decoded("dtstart") - dateend = comp.decoded("dtend") - roomname = str(comp.get("location")) + for cal in cals : + # Première boucle, pour déterminer les salles occupées : + for comp in cal.walk() : # Événements + if comp.name == "VEVENT" : + # Récupération des infos : + datestart = comp.decoded("dtstart") + dateend = comp.decoded("dtend") + roomname = str(comp.get("location")) - # L'événement se passe maintenant (salle occupée maintenant) : - if datestart.timestamp() <= datet.timestamp() and dateend.timestamp() > datet.timestamp() : - start = dateend # L'heure de début de la prochaine période de disponibilité est la fin de l'événement - end = datet.replace(hour = 23, minute = 59, second = 59) # Par défaut, l'heure de fin de la prochaine période disponibilité est aujourd'hui à 23:59 - is_free = False - for r in total_rooms : - if r.name == roomname : - r = Room(roomname, start, end, is_free) + # L'événement se passe maintenant (salle occupée maintenant) : + if datestart.timestamp() <= datet.timestamp() and dateend.timestamp() > datet.timestamp() : + start = dateend # L'heure de début de la prochaine période de disponibilité est la fin de l'événement + end = datet.replace(hour = 23, minute = 59, second = 59) # Par défaut, l'heure de fin de la prochaine période disponibilité est aujourd'hui à 23:59 + is_free = False + for r in total_rooms : + if r.name == roomname : + r.start = start + r.end = end + r.is_free = is_free - # Deuxième boucle, pour ajouter les heures de dispos des salles : - for comp in cal.walk() : # Événements - if comp.name == "VEVENT" : - # Récupération des infos : - datestart = comp.decoded("dtstart") - dateend = comp.decoded("dtend") - roomname = str(comp.get("location")) + # Deuxième boucle, pour ajouter les heures de dispos des salles : + for comp in cal.walk() : # Événements + if comp.name == "VEVENT" : + # Récupération des infos : + datestart = comp.decoded("dtstart") + dateend = comp.decoded("dtend") + roomname = str(comp.get("location")) - # L'événement se passe prochainement (salle occupée à l'occasion de cet événement) : - if datestart.timestamp() > datet.timestamp() : - for r in total_rooms : - if r.name == roomname : - if datestart.timestamp() < r.end.timestamp() : - if datestart.timestamp() == r.start.timestamp() : - start = dateend - end = r.end - else : - start = r.end - end = datestart - is_free = r.is_free - r = Room(roomname, start, end, is_free) + # L'événement se passe prochainement (salle occupée à l'occasion de cet événement) : + if datestart.timestamp() > datet.timestamp() : + for r in total_rooms : + if r.name == roomname : + if datestart.timestamp() < r.end.timestamp() : + if datestart.timestamp() == r.start.timestamp() : + start = dateend + end = r.end + else : + start = r.end + end = datestart + r.start = start + r.end = end return total_rooms diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..3afdb9f --- /dev/null +++ b/static/style.css @@ -0,0 +1,117 @@ +:root { + --bg: #191919; + --bg-dark: #252525; + --bg-light: #4b4b4b; + --fg: #ffffff; + --hl: #8080ff; +} + +* { + background: var(--bg); + padding-left: 5px; + padding-right: 5px; + font-family: "ubuntu", "sans"; + color: var(--fg); +} + +header { + background: var(--hl); + font-size: 250%; + font-weight: lighter; + text-align: center; + margin: 10px; + margin-left: calc(-50vw + 50%); + margin-right: calc(-50vw + 50%); + margin-top: calc(-50vw + 50%); + padding-top: 20px; + padding-bottom: 5px; +} + +main { + /*display: flex; + flex-direction: row;*/ + line-height: 1.7; +} + +nav { + vertical-align: top; + margin: 10px; + width: 50%; +} + +#body { + margin: 10px; +} + +p { + text-align: justify; + text-indent: 50px; +} + +.flex-container { + width: 100%; + display: flex; + flex-direction: column; +} + +h1, h2, h3, h4 { + font-weight: lighter; + border-left: solid; + border-width: 5px; + border-color: var(--hl); +} + +a { + color: var(--hl); +} + +img { + margin: 10px; + align-self: flex-start; + max-width: 200px; + border-radius: 10px; +} + +iframe { + max-width: 200px; + max-height: 500px; +} + +ul { + margin-bottom: 5px; +} + +dt { + font-weight: bold; + font-size: 90%; + border-bottom-style: solid; + border-bottom-width: 2px; + border-bottom-color: var(--bg-light); + padding: 10px; +} + +dt .details { + font-weight: normal; + font-size: 80%; +} + +button, input { + background: var(--bg-light); + border-style: solid; + border-width: 1px; + border-color: var(--bg); + padding: 10px; + border-radius: 10px; +} + +.done { + background: var(--bg-dark); + text-decoration: line-through; +} + +input { + background: var(--bg-dark); +} + +@media screen and (max-width: 769px) { +} \ No newline at end of file diff --git a/templates/dept-select.html b/templates/dept-select.html new file mode 100644 index 0000000..2e6c998 --- /dev/null +++ b/templates/dept-select.html @@ -0,0 +1,22 @@ + + +
+ +