#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Thu Feb 24 08:51:58 2022 @author: antoine """ ################ ### UniSquat ### ################ """ Indique toutes les salles disponibles dans les différents départements de l'Université de Strasbourg. """ # Modules : import requests import icalendar import datetime # Fonctions : def room(name, occupied_at, free_at): """ Retourne un dictionnaire contenant le nom, la prochaine date à laquelle elle est occupée, ainsi que la prochaine date à laquelle elle est libre Parameters ---------- name : str Le nom de la salle. occupied_at : datetime.datetime or None La prochaine heure à laquelle elle est occupée, ou None si salle déjà occupée. free_at : datetime.datetime or None La prochaine heure à laquelle est est libre, ou None, si elle est déjà libre. Returns ------- dict Un dictionnaire contenant ces trois informations, avec le même nom en clef, en plus de si elle est actuellement libre. """ free = False # Indique si la salle est libre ou non if free_at == None : free = True # return {"name":name, "occupied_at":occupied_at, "free_at":free_at, "free":free_at.timestamp() > occupied_at.timestamp()} return {"name":name, "occupied_at":occupied_at, "free_at":free_at, "free":free} def sched_get(date, link=None) : """ Récupère l'emploi du temps de toutes les salles (pour le moment, juste de l'UFR) sur ADE depuis le site de l'Unistra. Parameters ---------- date : datetime.datetime() Date au format datetime. Optionnels: link: Un lien vers lequel effectuer la recherche, des informations seront remplacées : $YEAR$ : l'année $MONTH$ : le mois $DAY$ : le jour Par défaut, sera un lien des salles de l'UFR. Returns ------- bytes Le texte du résultat de la requête. """ if not link: link = "https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30626&projectId=8&calType=ical&firstDate=$YEAR$-$MONTH$-$DAY$&lastDate=$YEAR$-$MONTH$-$DAY$" day = str(date.day) month = str(date.month) year = str(date.year) finallink = link.replace("$DAY$",day) finallink = finallink.replace("$MONTH$",month) finallink = finallink.replace("$YEAR$",year) r = requests.get(finallink) return r.content def getrooms(datet, links=[]) : """ Crée une liste de toutes les salles, avec des informations si elles sont libres ou non. Parameters ---------- datet : datetime.datetime() Date au format datetime. Returns ------- total_rooms : dict Dictionnaire des salles, indexées par leur nom. Toutes les salles mentionnées dans le fichier, avec des informations. """ # Récupération des informations sur l'EDT téléchargé : cals = [] for i in links: cals.append(icalendar.Calendar.from_ical(sched_get(datet), link = i)) if len(links)==0: # Par défaut, ne mets pas de lien, ce qui retourne celui de l'UFR cals = [icalendar.Calendar.from_ical(sched_get(datet))] total_rooms = {} # default_hour_margin = 2 for cal in cals : # Bâtiments 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")) # Soit l'événement se passe maintenant (salle occupée maintenant) : if datestart.timestamp() <= datet.timestamp() and dateend.timestamp() > datet.timestamp() : occupied_at = None free_at = dateend total_rooms[roomname] = room(roomname, occupied_at, free_at) # Soit l'événement se passe prochainement (salle occupée à l'occasion de cet événement) : elif datestart.timestamp() > datet.timestamp() : if roomname not in total_rooms.keys() : occupied_at = datestart free_at = None total_rooms[roomname] = room(roomname, occupied_at, free_at) elif total_rooms[roomname]["occupied_at"] != None : # Dans ce cas, il n'y a pas d'événement en cours, donc la salle est libre maintenant if datestart.timestamp() < total_rooms[roomname]["occupied_at"].timestamp() : occupied_at = datestart free_at = None total_rooms[roomname] = room(roomname, occupied_at, free_at) # Dans les autres cas, l'événement est passé, donc on l'ignore et on passe au suivant. # # On ignore si c'est avant la date actuelle (avec une valeur loin dans le futur) # if datestart.timestamp() < datet.timestamp() : # datestart = datet + datetime.timedelta(hours = default_hour_margin) # Par défaut, si il n'y a rien de précisé pour sa prochaine occupation, elle sera occupée dans 1 ans # if dateend.timestamp() < datet.timestamp() : # dateend = datestart + datetime.timedelta(hours = default_hour_margin) # Par défaut, si il n'y a rien de précisé pour sa prochaine occupation, elle sera occupée dans 1 an après son occupation # Enregistrement dans le dictionnaire : # Plus nécessaire, car on ne s'occupe plus des événements passés : # if roomname in total_rooms.keys() : # if datestart.timestamp() > total_rooms[roomname]["occupied_at"].timestamp() : # occupied_at = total_rooms[roomname]["occupied_at"] # if dateend.timestamp() > total_rooms[roomname]["free_at"].timestamp() : # free_at = total_rooms[roomname]["free_at"] return total_rooms