From d79af7ef9ba69ccebdc97b2a3c284e877b9c9f3b Mon Sep 17 00:00:00 2001 From: antux18 Date: Mon, 12 Feb 2024 13:06:53 +0100 Subject: [PATCH] =?UTF-8?q?Retour=20de=20get=5Ftot=5Frooms=20pour=20r?= =?UTF-8?q?=C3=A9gler=20le=20pb=20de=20parsing=20trop=20long=20(se=20fait?= =?UTF-8?q?=20uniquement=20pour=20le=20calendrier=20d'aujourd'hui,=20par?= =?UTF-8?q?=20du=20mois).=20Ajout=20d'une=20constante=20TIMEZONE.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rooms_get.py | 201 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 136 insertions(+), 65 deletions(-) diff --git a/rooms_get.py b/rooms_get.py index 34e9f66..9ae25c7 100644 --- a/rooms_get.py +++ b/rooms_get.py @@ -39,6 +39,9 @@ CACHE_SIZE = 10 # Flag pour utiliser le cache : NO_CACHE = False +# Fuseau horaire : +TIMEZONE = "Europe/Paris" + # Globales : last_cache_init = -999 @@ -87,7 +90,7 @@ def trim(link) : return result -def sched_get(date, link, enddate = None, nocache = False) : +def sched_get(date, link, enddate = None, nocache = False, sortcal = False) : """ Récupère l'emploi du temps de toutes les salles sur ADE depuis le site de l'Unistra. @@ -109,9 +112,12 @@ def sched_get(date, link, enddate = None, nocache = False) : Date de fin du calendrier à télécharger (par défaut, il s'agit de la date de début). - nocache : booléen + nocache : bool Si mis à 'True', ne lit et ne modifie pas le dossier CACHE_DIR. + sortcal : bool + Si 'True', trie le calendrier par ordre chronologique. + Returns ------- str @@ -143,12 +149,13 @@ def sched_get(date, link, enddate = None, nocache = False) : finallink = finallink.replace("$YEAR2$", year1) if nocache : - # Utilisation du module 'ics' pour le tri du calendrier dans l'ordre - # chronologique : result = requests.get(finallink).text - cal = ics.Calendar(result) - cal.events = sorted(cal.events) - result = cal.serialize() + if sortcal : + # Utilisation du module 'ics' pour le tri du calendrier dans l'ordre + # chronologique : + cal = ics.Calendar(result) + cal.events = sorted(cal.events) + result = cal.serialize() return result else : # Vérifie la TTL : @@ -169,11 +176,12 @@ def sched_get(date, link, enddate = None, nocache = False) : return result else : result = requests.get(finallink).text - # Utilisation du module 'ics' pour le tri du calendrier dans l'ordre - # chronologique : - cal = ics.Calendar(result) - cal.events = sorted(cal.events) - result = cal.serialize() + if sortcal : + # Utilisation du module 'ics' pour le tri du calendrier dans l'ordre + # chronologique : + cal = ics.Calendar(result) + cal.events = sorted(cal.events) + result = cal.serialize() with open(cachepath,'w') as f : f.write(result) return result @@ -209,10 +217,9 @@ def get_depts(filename) : return dept_list -def getrooms(datet, depts, ignore_list) : +def get_tot_rooms(datet, depts, ignore_list) : """ - Génération de la liste des salles avec heures de début et fin de dispo, - et indicateur de dispo. + Crée une liste de toutes les salles des départements choisis. Parameters ---------- @@ -220,7 +227,7 @@ def getrooms(datet, depts, ignore_list) : Date pour la recherche de salles. depts : list - Liste des départements dans lesquel chercher des salles. + Liste des départements dans lesquels chercher des salles. ignore_list : list Liste des noms de salles à ignorer. @@ -229,14 +236,12 @@ def getrooms(datet, depts, ignore_list) : ------- total_rooms : list Liste des salles. - """ total_rooms = list() # Marge de temps (en mois) pour le début du calendrier. # Certaines salles ne sont pas utilisées tous les jours, - # donc on télécharge l'EDT du reste du mois et du suivant - # pour être tranquille. + # donc on télécharge l'EDT pour 30 jours. margintime = 1 # Récupération du calendrier de chaque département, @@ -261,12 +266,10 @@ def getrooms(datet, depts, ignore_list) : # Parcours de ces calendriers : dept_index = 0 for cal in cals : - for comp in cal.walk() : # Événements - if comp.name == "VEVENT" : - # Récupération des infos : + for comp in cal.walk() : # Composants du calendrier + if comp.name == "VEVENT" : # Événements + # Récupération de l'emplacement : evtloc = str(comp.get("location")) - evtstart = comp.decoded("dtstart") - evtend = comp.decoded("dtend") # Contient le nom de toutes les salles indiquées # dans la section "LOCATION" : @@ -297,52 +300,120 @@ def getrooms(datet, depts, ignore_list) : # de disponibilité est aujourd'hui à 23:59. # - La salle est libre. r = Room(roomname, - datet.replace(hour = 0, minute = 0, second = 0), - datet.replace(hour = 23, minute = 59, second = 59), - True, - True, - True, - depts[dept_index].name + datet.replace(hour = 0, minute = 0, second = 0), + datet.replace(hour = 23, minute = 59, second = 59), + True, + True, + True, + depts[dept_index].name ) - # Si l'événement se passe aujourd'hui : - if evtstart.day == datet.day and \ - evtstart.month == datet.month and \ - evtstart.year == datet.year : - # Si l'événement se passe maintenant - # (salle occupée maintenant) : - if evtstart.timestamp() <= datet.timestamp() and \ - evtend.timestamp() > datet.timestamp() : - r.is_free = False - r.nostart = False - # L'heure de début de la prochaine dispo est - # la fin de l'événement : - r.start = evtend - # Si l'événement se passe prochainement - # (salle occupée à l'occasion de cet événement) - # et que le début de l'événement est avant la date - # de fin de dispo actuelle (on cherche la date la - # plus proche de maintenant) : - elif evtstart.timestamp() > datet.timestamp() and \ - evtstart.timestamp() < r.end.timestamp() : - if evtstart.timestamp() == r.start.timestamp() : - r.nostart = False - # Dans ce cas, l'événement en cours suit - # celui qui a défini le début de dispo - # de la salle. Alors, c'est la fin de cet - # événement qui marque le début de la dispo. - r.start = evtend - else : - r.noend = False - r.end = evtstart + # Réglage du fuseau horaire : + r.start = r.start.astimezone(pytz.timezone(TIMEZONE)) + r.end = r.end.astimezone(pytz.timezone(TIMEZONE)) - # Réglage du fuseau horaire : - r.start = r.start.astimezone(pytz.timezone('Europe/Paris')) - r.end = r.end.astimezone(pytz.timezone('Europe/Paris')) - - if not exists : total_rooms.append(r) dept_index += 1 + return total_rooms + +def getrooms(datet, depts, ignore_list) : + """ + Ajout des heures de début et fin de dispo aux salles, + et indicateur de dispo. + + Parameters + ---------- + datet : datetime.datetime() + Date pour la recherche de salles. + + depts : list + Liste des départements dans lesquel chercher des salles. + + ignore_list : list + Liste des noms de salles à ignorer. + + Returns + ------- + total_rooms : list + Liste des salles. + + """ + total_rooms = get_tot_rooms(datet, depts, ignore_list) + + # Récupération du calendrier de chaque département : + cals = list() # Liste des EDT des départements choisis + for d in depts : + result = sched_get(datet, d.link, datet, NO_CACHE, True) + cals.append(icalendar.Calendar.from_ical(result)) + # cals.append(icalendar.Calendar(result.decode("utf-8"))) + + # Parcours de ces calendriers : + dept_index = 0 + for cal in cals : + for comp in cal.walk() : # Événements + if comp.name == "VEVENT" : + # Récupération des infos : + evtloc = str(comp.get("location")) + evtstart = comp.decoded("dtstart") + evtend = comp.decoded("dtend") + + # Contient le nom de toutes les salles indiquées + # dans la section "LOCATION" : + rnamelist = list() + + # Séparation des salles multiples, le cas échéant : + if "," in evtloc : + rnamelist = evtloc.split(",") + else : + rnamelist.append(evtloc) + + for roomname in rnamelist : + roomname = roomname.strip() + if roomname not in ignore_list : + exists = False + for room in total_rooms : + if room.name == roomname : + exists = True + r = room + + if exists : + # Si l'événement se passe aujourd'hui : + if evtstart.day == datet.day and \ + evtstart.month == datet.month and \ + evtstart.year == datet.year : + # Si l'événement se passe maintenant + # (salle occupée maintenant) : + if evtstart.timestamp() <= datet.timestamp() and \ + evtend.timestamp() > datet.timestamp() : + r.is_free = False + r.nostart = False + # L'heure de début de la prochaine dispo est + # la fin de l'événement : + r.start = evtend + # Si l'événement se passe prochainement + # (salle occupée à l'occasion de cet événement) + # et que le début de l'événement est avant la date + # de fin de dispo actuelle (on cherche la date la + # plus proche de maintenant) : + elif evtstart.timestamp() > datet.timestamp() and \ + evtstart.timestamp() < r.end.timestamp() : + if evtstart.timestamp() == r.start.timestamp() : + r.nostart = False + # Dans ce cas, l'événement en cours suit + # celui qui a défini le début de dispo + # de la salle. Alors, c'est la fin de cet + # événement qui marque le début de la dispo. + r.start = evtend + else : + r.noend = False + r.end = evtstart + + # Réglage du fuseau horaire : + r.start = r.start.astimezone(pytz.timezone(TIMEZONE)) + r.end = r.end.astimezone(pytz.timezone(TIMEZONE)) + + dept_index += 1 + return total_rooms \ No newline at end of file