Correction d'un bug qui faisait planter l'app lorsqu'on choisissait une date en décembre.

Amélioration de l'affichage ("1 heure" au lieu de "1 heures", par exemple).
Amélioration du README.
Diverses corrections des commentaires.
This commit is contained in:
antux18 2022-06-17 19:12:29 +02:00
parent b7f6096aaf
commit 8306e33db0
7 changed files with 103 additions and 117 deletions

View File

@ -1,38 +1,38 @@
# UniSquat # UniSquat
Application pour trouver rapidement les salles disponibles dans l'Université de Strasbourg. Une application pour trouver rapidement les salles disponibles dans l'Université de Strasbourg.
C'est utile aux élèves qui cherchent un coin pour travailler ou manger, comme aux enseignants en détresse à cause d'un changement de salle imprévu. C'est utile aux élèves qui cherchent un coin pour travailler ou manger, comme aux enseignants en détresse à cause d'un changement de salle imprévu.
Cette application dispose d'une interface Web fonctionnant avec Flask ( [voir la demo][homepage] ). Cette application dispose d'une interface Web fonctionnant avec Flask. Une version en ligne est disponible [ici][homepage].
## Fonctionnalités ## Fonctionnalités
- 🔎 Visualiser les salles libres de plusieurs départements en même temps ( par exemple UFR de Math-Info et EOST ) - 🔎 Visualiser les salles libres de plusieurs départements en même temps (par exemple : l'UFR de Math-Info et l'EOST).
- ⏰ Pour les salles bientôt occupées, l'heure d'occupation est précisée - ⏰ Connaître la période de disponibilité d'une salle.
- 🔄 Affiche également les salles qui sont bientôt libres, avec l'heure en question - 🔜 Les salles prochainement libres sont également affichées, avec l'heure de début de disponibilité.
- ⭐ Permet de sélectionner des salles comme favorites - ⭐ Marquer des salles comme favorites, pour les afficher en haut de la page.
* Ces favoris ne sont conservés que sur la page en question ( les favoris sélectionnés sont stockés dans l'URL ) * Les favoris sont stockés dans l'URL de la page. Cela permet de le partager simplement, puisqu'il suffit de partager l'URL
* Ainsi, vous pouvez partager vos favoris simplement en partageant l'URL * 📅 Rechercher les salles libres à une date précise.
- 🪶 Application légère pour l'utilisateur : - 🪶 Application légère pour l'utilisateur :
* Pas de JavaScript, tout les calculs sont fait coté serveur * Pas de JavaScript, tout les calculs sont fait coté serveur
* Pas de *Local Storage*, *Cookies* ou autres *bibliothèques CSS* * Pas de *Local Storage*, *Cookies* ou autres *bibliothèques CSS*
## Dépendances ## Dépendances
Pour l'instant, ce programme utilise les modules suivants : Le modules Python suivant sont requis (ils peuvent être installés avec `pip`) :
- datetime
- icalendar
- requests
Pour la version Web (avec Flask) : - `datetime`
- flask - `icalendar`
- `requests`
- `flask` (requis pour l'interface Web)
Vous pouvez aussi installer directement les dépendances avec cette commande :
Vous pouvez aussi installer directement les dépendances avec `pip` :
```python ```python
pip install -r requirements.txt pip install -r requirements.txt
``` ```
## Comment lancer la version web/Flask ## Comment lancer la version Web (Flask)
Dans la racine du dossier : Dans la racine du dossier :
@ -42,15 +42,15 @@ flask run
C'est la version la plus utilisable, n'hésitez pas à héberger votre propre version. C'est la version la plus utilisable, n'hésitez pas à héberger votre propre version.
## Version antérieures ## Interfaces obsolètes
Ces versions sont plus anciennes, rudimentaires, et ne sont pas prévues pour être utilisables. Ces interfaces ont été crées à des fins de test. Elles peuvent être instables, et ne sont plus mises à jour.
### Interface en ligne de commande ### Interface en ligne de commande
Un interface en ligne de commande est disponible. Elle ne nécessite pas de dépendances supplémentaires. Une interface en ligne de commande est disponible. Elle ne nécessite pas de dépendances supplémentaires.
Pour le lancer : Pour la lancer :
```python ```python
python main_cli.py python main_cli.py
@ -58,9 +58,9 @@ python main_cli.py
### Interface Qt5 ### Interface Qt5
Interface graphique utilisant la bibliothèque Qt. Elle nécessite le module `PyQt5`. Une interface graphique utilisant la bibliothèque Qt. Elle nécessite le module `PyQt5`.
Pour le lancer : Pour la lancer :
```python ```python
python main_gui.py python main_gui.py
@ -70,10 +70,10 @@ python main_gui.py
Le code est sous licence [GPLv3](https://choosealicense.com/licenses/gpl-3.0/). Le code est sous licence [GPLv3](https://choosealicense.com/licenses/gpl-3.0/).
UniSquat est créé par deux étudiants de l'université, plus d'information sur [notre site][homepage]. UniSquat est créé par deux étudiants de l'université de Strasbourg. Rendez-vous sur [la page d'accueil d'UniSquat][homepage] pour plus d'informations.
Notre travail est fait bénévolement, mais si vous voulez nous soutenir, passez au campus d'esplanade nous offrir un chocolat chaud ❤ Notre travail est fait de façon bénévole, mais si vous souhaitez nous soutenir, n'hésitez pas à passer sur le campus de l'Esplanade pour nous offrir un chocolat chaud ❤
Vous pouvez nous contacter sur nos comptes gitea respectifs, ou vous pouvez aller voir sur le [blog de @ayte](https://webair.xyz/fr/contact) pour plus d'options. Vous pouvez nous contacter sur nos comptes Git respectifs. Vous pouvez aussi contacter @ayte [sur son blog](https://webair.xyz/fr/contact).
[homepage]: https://unisquat.alwaysdata.net [homepage]: https://unisquat.alwaysdata.net

32
app.py
View File

@ -3,8 +3,8 @@
################ ################
""" """
Indique toutes les salles disponibles dans les différents départements de Une application pour afficher les salles libres dans les différents
l'Université de Strasbourg. départements de l'Université de Strasbourg.
""" """
@ -13,7 +13,6 @@
# Modules : # Modules :
import datetime as dti import datetime as dti
import time
from flask import Flask from flask import Flask
from flask import render_template from flask import render_template
@ -41,6 +40,8 @@ logs = [] # Stoque les différentes requêtes faite sur la route /free_rooms/, s
app = Flask(__name__) app = Flask(__name__)
# Fonctions :
@app.route("/") @app.route("/")
def home() : def home() :
""" """
@ -48,13 +49,12 @@ def home() :
Parameters Parameters
---------- ----------
None. None
Returns Returns
------- -------
flask.render_template flask.render_template
""" """
return render_template("index.html", **GLOBAL_CONTEXT) return render_template("index.html", **GLOBAL_CONTEXT)
@ -66,13 +66,12 @@ def select_dept() :
Parameters Parameters
---------- ----------
None. None
Returns Returns
------- -------
flask.render_template flask.render_template
""" """
dept_filen = "data/dept_list.txt" dept_filen = "data/dept_list.txt"
dept_list = ro.get_depts(dept_filen) dept_list = ro.get_depts(dept_filen)
@ -82,6 +81,7 @@ def select_dept() :
url_for("static", filename="style.css") url_for("static", filename="style.css")
return render_template("dept-select.html", **content, **GLOBAL_CONTEXT) return render_template("dept-select.html", **content, **GLOBAL_CONTEXT)
@app.route("/stats") @app.route("/stats")
def stats(): def stats():
""" """
@ -89,14 +89,13 @@ def stats():
Parameters Parameters
---------- ----------
None. (Reads from the global "logs") None (utilise la variable globale 'log')
Returns Returns
------- -------
flask.render_template flask.render_template
""" """
# Compte le nombre de fois que les différents départements ont été cherchés
# Compte le nombre de fois que les différents départements ont été cherché
pings = 0 pings = 0
counts = {} counts = {}
for log in logs: for log in logs:
@ -118,17 +117,16 @@ def stats():
def free_rooms() : def free_rooms() :
""" """
Affiche les salles libres dans les départements sélectionnés Affiche les salles libres dans les départements sélectionnés
dans la page précédente. dans la page des départements.
Parameters Parameters
---------- ----------
None. None
Returns Returns
------- -------
flask.render_template flask.render_template
""" """
# Récupération des ID des départements depuis le formulaire : # Récupération des ID des départements depuis le formulaire :
dident_list = request.args.getlist("dept") dident_list = request.args.getlist("dept")
if len(dident_list)>MAX_DEPT: if len(dident_list)>MAX_DEPT:
@ -136,7 +134,7 @@ def free_rooms() :
if len(dident_list)==0: if len(dident_list)==0:
return render_template("error.html", error="Il faut choisir au moins un département !") return render_template("error.html", error="Il faut choisir au moins un département !")
# Récupération de l'éventuelle date personnalisée (depuis la page de sélection de date : # Récupération de l'éventuelle date personnalisée (depuis la page de sélection de date) :
date_uf = request.args.get("date") date_uf = request.args.get("date")
if date_uf == None : if date_uf == None :
date_uf = [""] date_uf = [""]
@ -175,9 +173,9 @@ def free_rooms() :
try: try:
int(d) int(d)
except: except:
return render_template("error.html",error="Identifiant de département invalide !", **GLOBAL_CONTEXT) return render_template("error.html", error="Identifiant de département invalide !", **GLOBAL_CONTEXT)
if int(d)<0 or int(d)>=len(dept_list): if int(d) < 0 or int(d) >= len(dept_list) :
return render_template("error.html",error="Identifiant de département invalide !", **GLOBAL_CONTEXT) return render_template("error.html", error="Identifiant de département invalide !", **GLOBAL_CONTEXT)
dident_list.sort() dident_list.sort()
# Récupération des départements choisis à partir des données du formulaire : # Récupération des départements choisis à partir des données du formulaire :

View File

@ -11,8 +11,8 @@ Created on Thu Feb 24 16:36:32 2022
################ ################
""" """
Indique toutes les salles disponibles dans les différents départements de Une application pour afficher les salles libres dans les différents
l'Université de Strasbourg. départements de l'Université de Strasbourg.
""" """
@ -36,13 +36,9 @@ def minutes_convert(time_min) :
Returns Returns
------- -------
int tuple
Temps en heures. Temps en heures et en minutes.
int
Temps en minutes.
""" """
return int(time_min // 60), int(time_min % 60) return int(time_min // 60), int(time_min % 60)
@ -60,9 +56,7 @@ def bissextile(year) :
------- -------
bool bool
'True' si 'year' est bissextile, 'False' sinon. 'True' si 'year' est bissextile, 'False' sinon.
""" """
return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
@ -81,9 +75,7 @@ def month_days(month, year) :
------- -------
int int
Nombre de jours dans 'month'. Nombre de jours dans 'month'.
""" """
if month == 2 : if month == 2 :
if bissextile(year) : if bissextile(year) :
return 29 return 29
@ -105,7 +97,6 @@ def date_input() :
datetime.datetime() datetime.datetime()
Date entrée au format datetime. Date entrée au format datetime.
""" """
year = int(input("Entrer l'année.\n> ")) year = int(input("Entrer l'année.\n> "))
month = 0 month = 0
@ -143,7 +134,6 @@ def hour_disp(time) :
time_str : str time_str : str
Heure en chaîne de caractères. Heure en chaîne de caractères.
""" """
time_str = str(time.hour) + ":" time_str = str(time.hour) + ":"
if time.minute < 10 : # Ajout du zéro au début du nombre de minutes if time.minute < 10 : # Ajout du zéro au début du nombre de minutes
@ -171,12 +161,17 @@ def remain_time(date, rdate) :
remain_time_str : str remain_time_str : str
Temps restant. Temps restant.
""" """
deltasec = rdate.timestamp() - date.timestamp() deltasec = rdate.timestamp() - date.timestamp()
remain_time_str = str(int(deltasec / 60 + 0.5)) + " minutes" if int(deltasec / 60 + 0.5) > 1 :
remain_time_str = str(int(deltasec / 60 + 0.5)) + " minutes"
else :
remain_time_str = str(int(deltasec / 60 + 0.5)) + " minute"
if deltasec / 60 + 0.5 >= 60 : # Conversion en heures:minutes si les minutes dépassent 60 if deltasec / 60 + 0.5 >= 60 : # Conversion en heures:minutes si les minutes dépassent 60
deltasec = minutes_convert(deltasec / 60 + 0.5) deltasec = minutes_convert(deltasec / 60 + 0.5)
remain_time_str = str(deltasec[0]) + " heures" if deltasec[0] > 1 :
remain_time_str = str(deltasec[0]) + " heures"
else :
remain_time_str = str(deltasec[0]) + " heure"
if deltasec[1] > 0 : if deltasec[1] > 0 :
remain_time_str += " " + str(deltasec[1]) + " minutes" remain_time_str += " " + str(deltasec[1]) + " minutes"

View File

@ -11,8 +11,8 @@ Created on Thu Feb 24 17:14:05 2022
################ ################
""" """
Indique toutes les salles disponibles dans les différents départements de Une application pour afficher les salles libres dans les différents
l'Université de Strasbourg. départements de l'Université de Strasbourg.
""" """
@ -21,7 +21,6 @@ Created on Thu Feb 24 17:14:05 2022
# Modules : # Modules :
import datetime import datetime
import time
# Fichiers locaux : # Fichiers locaux :
import date_tools import date_tools

View File

@ -11,8 +11,8 @@ Created on Thu Mar 3 08:47:47 2022
################ ################
""" """
Indique toutes les salles disponibles dans les différents départements de Une application pour afficher les salles libres dans les différents
l'Université de Strasbourg. départements de l'Université de Strasbourg.
""" """
@ -43,7 +43,6 @@ def main() :
date = datetime.datetime.today() date = datetime.datetime.today()
available_rooms = ro.getrooms(date,links=links) available_rooms = ro.getrooms(date,links=links)
button = qt.QtWidgets.QPushButton("Hello World !")
label1 = qt.QtWidgets.QLabel() label1 = qt.QtWidgets.QLabel()
label1.setText("Maintenant :") label1.setText("Maintenant :")
label2 = qt.QtWidgets.QLabel() label2 = qt.QtWidgets.QLabel()

View File

@ -11,10 +11,12 @@ Created on Sat May 7 17:29:11 2022
################ ################
""" """
Indique toutes les salles disponibles dans les différents départements de Une application pour afficher les salles libres dans les différents
l'Université de Strasbourg. départements de l'Université de Strasbourg.
""" """
### Définition des objets ###
# Modules # Modules
import random # Nécessaire pour la génération d'ID des salles import random # Nécessaire pour la génération d'ID des salles
@ -23,9 +25,6 @@ ID_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" # Ca
ID_LEN = 4 # Nombres de caractères composant l'ID ID_LEN = 4 # Nombres de caractères composant l'ID
### Fichier contenant les classes des salles et des départements ###
# Objets : # Objets :
class Room : class Room :
@ -34,7 +33,6 @@ class Room :
Attributes Attributes
---------- ----------
name : string name : string
Le nom de la salle. Le nom de la salle.
@ -48,14 +46,10 @@ class Room :
is_free : bool is_free : bool
Indique si la salle est libre ('True') ou non ('False'). Indique si la salle est libre ('True') ou non ('False').
count : int
Compte le nombre d'occurences de la salle dans l'emploi du temps;
id : string id : string
Identifiant 'unique' ( avec un très faible risque de collision ) de la salle ( généré à partir de son nom ) Identifiant 'unique' (avec un très faible risque de conflit) de la salle (généré à partir de son nom)
""" """
def __init__(self, name, start, end, is_free) : def __init__(self, name, start, end, is_free) :
self.name = name self.name = name
self.start = start self.start = start
@ -66,8 +60,8 @@ class Room :
def getId(self,name): def getId(self,name):
random.seed(name) random.seed(name)
id = "" id = ""
for i in range(ID_LEN): for i in range(ID_LEN) :
id+=random.choice(ID_CHARS) id += random.choice(ID_CHARS)
return id # A peu près une chance sur 15 millions d'être unique, je considère ça viable return id # A peu près une chance sur 15 millions d'être unique, je considère ça viable
@ -77,7 +71,6 @@ class Dept :
Attributes Attributes
---------- ----------
ident : int ident : int
Identifiant du département. Identifiant du département.
@ -90,7 +83,6 @@ class Dept :
rooms : list rooms : list
La liste des salles de ce département La liste des salles de ce département
""" """
def __init__(self, ident, name, link, rooms) : def __init__(self, ident, name, link, rooms) :
self.ident = ident self.ident = ident
self.name = name self.name = name

View File

@ -10,12 +10,12 @@ Created on Thu Feb 24 08:51:58 2022
################ ################
""" """
Indique toutes les salles disponibles dans les différents départements de Une application pour afficher les salles libres dans les différents
l'Université de Strasbourg. départements de l'Université de Strasbourg.
""" """
### Fichier du backend (récupération des salles libres et de départements ### ### Fichier du backend (récupération des salles libres et des départements ###
# Modules : # Modules :
@ -42,36 +42,39 @@ def reinit_cache() :
global last_cache_init global last_cache_init
""" """
Vide le dossier CACHE_DIR et l'initialise. Vide le dossier CACHE_DIR et l'initialise.
Modifie la variable globale last_cache_init Modifie la variable globale 'last_cache_init'.
Parameters Parameters
---------- ----------
Aucun None
Returns Returns
------- -------
Rien None
""" """
if os.path.isdir(CACHE_DIR): if os.path.isdir(CACHE_DIR):
shutil.rmtree(CACHE_DIR) shutil.rmtree(CACHE_DIR)
os.mkdir(CACHE_DIR) os.mkdir(CACHE_DIR)
last_cache_init = time.time() last_cache_init = time.time()
def trim(link) : def trim(link) :
""" """
Retourne le texte en minuscule, sans les caractères spéciaux. Retourne la chaîne de caractères 'link' en minuscule, sans les caractères
( Utilisé pour le cache des requêtes ) spéciaux (utilisé pour le cache des requêtes).
Parameters Parameters
---------- ----------
link: String link: str
Le lien à simplifier Le lien à simplifier
Returns Returns
------- -------
str
La chaine de caractères correspondante La chaine de caractères correspondante
""" """
result = "" result = ""
for i in link.lower(): for i in link.lower() :
if i not in "/:;\\'\" *?": if i not in "/:;\\'\" *?":
result+=i result+=i
@ -88,25 +91,26 @@ def sched_get(date, link, enddate = None, nocache = False) :
Date du calendrier à télécharger (date de début si une date de fin Date du calendrier à télécharger (date de début si une date de fin
'enddate' est indiquée). 'enddate' est indiquée).
Optionnels: link:
link: Un lien vers lequel effectuer la recherche, des informations seront remplacées :
Un lien vers lequel effectuer la recherche, des informations seront remplacées : $YEAR$ : l'année
$YEAR$ : l'année $MONTH$ : le mois
$MONTH$ : le mois $DAY$ : le jour
$DAY$ : le jour Par défaut, sera un lien des salles de l'UFR.
Par défaut, sera un lien des salles de l'UFR.
Optional :
enddate : datetime.datetime() enddate : datetime.datetime()
Date de fin du calendrier à télécharger (par défaut, il s'agit de Date de fin du calendrier à télécharger (par défaut, il s'agit de
la date de début). la date de début).
nocache : booléen nocache : booléen
Si mit à True, ne modifie pas, ni ne lit, le dossier CACHE_DIR Si mit à 'True', ne modifie pas, ni ne lit, le dossier CACHE_DIR
Returns Returns
------- -------
bytes bytes
Le texte du résultat de la requête. Le texte du résultat de la requête.
""" """
link += "&firstDate=$YEAR1$-$MONTH1$-$DAY1$&lastDate=$YEAR2$-$MONTH2$-$DAY2$" link += "&firstDate=$YEAR1$-$MONTH1$-$DAY1$&lastDate=$YEAR2$-$MONTH2$-$DAY2$"
day1 = str(date.day) day1 = str(date.day)
@ -133,33 +137,32 @@ def sched_get(date, link, enddate = None, nocache = False) :
if nocache: if nocache:
return requests.get(finallink).content return requests.get(finallink).content
else: else :
# Vérifie la TTL # Vérifie la TTL
elapsed = time.time()-last_cache_init elapsed = time.time() - last_cache_init
print(elapsed)
if elapsed>CACHE_TTL*60: if elapsed>CACHE_TTL*60:
reinit_cache() reinit_cache()
# Vérifie que le lien est dans le cache # Vérifie que le lien est dans le cache
cachepath = os.path.join(CACHE_DIR,trim(finallink)) cachepath = os.path.join(CACHE_DIR,trim(finallink))
if os.path.isfile(cachepath): if os.path.isfile(cachepath) :
result = "" result = ""
with open(cachepath,'rb') as f: with open(cachepath,'rb') as f :
result = f.read() result = f.read()
return result return result
else: else:
result = requests.get(finallink).content result = requests.get(finallink).content
with open(cachepath,'wb') as f: with open(cachepath,'wb') as f :
f.write(result) f.write(result)
return result return result
def get_depts(filename) : def get_depts(filename) :
""" """
Crée une liste de tous les départements disponibles. Crée une liste de tous les départements disponibles.
Parameters Parameters
---------- ----------
filename : str filename : str
Nom du fichier contenant les départements, et les liens Nom du fichier contenant les départements, et les liens
permettant d'accéder au fichier iCal des salles du département. permettant d'accéder au fichier iCal des salles du département.
@ -169,7 +172,6 @@ def get_depts(filename) :
dept_list : list dept_list : list
Liste des départements. Liste des départements.
""" """
dept_list = list() dept_list = list()
dept_file = open(filename, "r") dept_file = open(filename, "r")
@ -200,8 +202,8 @@ def get_tot_rooms(datet, depts, ignore_list) :
datet : datetime.datetime() datet : datetime.datetime()
Date pour la recherche de salles. Date pour la recherche de salles.
dept : list depts : list
Liste des départements dans lesquel chercher des salles. Liste des départements dans lesquels chercher des salles.
ignore_list : list ignore_list : list
Liste des noms de salles à ignorer. Liste des noms de salles à ignorer.
@ -211,7 +213,6 @@ def get_tot_rooms(datet, depts, ignore_list) :
total_rooms : list total_rooms : list
Liste des salles. Liste des salles.
""" """
total_rooms = list() total_rooms = list()
margintime = 1 # Marge de temps (en mois) pour le début du calendrier (il se peut que des salles existent et soient dispos, mais qu'elles ne sont pas affichées dans l'EDT du jour choisi, donc on prend l'EDT du mois) margintime = 1 # Marge de temps (en mois) pour le début du calendrier (il se peut que des salles existent et soient dispos, mais qu'elles ne sont pas affichées dans l'EDT du jour choisi, donc on prend l'EDT du mois)
@ -227,7 +228,10 @@ def get_tot_rooms(datet, depts, ignore_list) :
# Récupération des calendriers correspondants aux liens des départements, sur une période de 'margintime' mois : # 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 cals = list() # Liste des emplois du temps des départements choisis
for d in depts : for d in depts :
result = sched_get(datet, d.link, datet.replace(month = datet.month + margintime)) if datet.month < 12 :
result = sched_get(datet, d.link, datet.replace(month = datet.month + margintime))
else :
result = sched_get(datet, d.link, datet.replace(month = 1, year = datet.year + 1))
cals.append(icalendar.Calendar.from_ical(result)) cals.append(icalendar.Calendar.from_ical(result))
roomnames = [] # Contient le nom de toutes les salles indiquées dans la section "LOCATION" roomnames = [] # Contient le nom de toutes les salles indiquées dans la section "LOCATION"
@ -267,14 +271,14 @@ def get_tot_rooms(datet, depts, ignore_list) :
def getrooms(datet, depts, ignore_list) : def getrooms(datet, depts, ignore_list) :
""" """
Ajout des informations supplémentaires à la liste des salles Ajout des informations supplémentaires à la liste des salles
(heures de début-fin de dispo, indicateur de dispo). (heures de début et fin de dispo, indicateur de dispo).
Parameters Parameters
---------- ----------
datet : datetime.datetime() datet : datetime.datetime()
Date pour la recherche de salles. Date pour la recherche de salles.
dept : list depts : list
Liste des départements dans lesquel chercher des salles. Liste des départements dans lesquel chercher des salles.
ignore_list : list ignore_list : list
@ -285,7 +289,6 @@ def getrooms(datet, depts, ignore_list) :
total_rooms : list total_rooms : list
Liste des salles. Liste des salles.
""" """
# Création de la liste de toutes les salles : # Création de la liste de toutes les salles :
total_rooms = get_tot_rooms(datet, depts, ignore_list) total_rooms = get_tot_rooms(datet, depts, ignore_list)