La date choisie est maintenant conservée lorsqu'on enregistre ou supprime des favoris, de même pour les favoris, lorsqu'on change de date.

Correction diverses sur la rédaction des pages et du README.
Ajout des fonctionnalités à la page d'accueil.
This commit is contained in:
antux18 2022-06-18 13:12:43 +02:00
parent 450d77f762
commit 4e49eb5bd6
7 changed files with 85 additions and 50 deletions

View File

@ -9,13 +9,13 @@ Cette application dispose d'une interface Web fonctionnant avec Flask. Une versi
- 🔎 Visualiser les salles libres de plusieurs départements en même temps (par exemple : l'UFR de Math-Info et l'EOST). - 🔎 Visualiser les salles libres de plusieurs départements en même temps (par exemple : l'UFR de Math-Info et l'EOST).
- ⏰ Connaître la période de disponibilité d'une salle. - ⏰ Connaître la période de disponibilité d'une salle.
- 🔜 Les salles prochainement libres sont également affichées, avec l'heure de début de disponibilité. - 🔜 Les salles prochainement libres sont également affichées, avec leur prochaine disponibilité.
- ⭐ Marquer des salles comme favorites, pour les afficher en haut de la page. - ⭐ Marquer des salles comme favorites, pour les afficher en haut de la page.
* Les favoris sont stockés dans l'URL de la page. Cela permet de le partager simplement, puisqu'il suffit de partager l'URL * Les favoris sont stockés dans l'URL de la page. Cela permet de les partager ou de les enregistrer simplement, puisqu'il suffit de partager l'URL ou de l'ajouter aux marque-pages.
* 📅 Rechercher les salles libres à une date précise. * 📅 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, tous 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

71
app.py
View File

@ -128,29 +128,27 @@ def free_rooms() :
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 = list(request.args.getlist("dept"))
if len(dident_list)>MAX_DEPT: if len(dident_list) > MAX_DEPT :
return render_template("error.html", error="Trop de départements sélectionnés ! Vous pouvez en sélectionner "+str(MAX_DEPT)+" au maximum.") return render_template("error.html", error="Trop de départements sélectionnés ! Vous pouvez en sélectionner "+str(MAX_DEPT)+" au maximum.")
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 = str(request.args.get("date"))
if date_uf == None : date_uf_sav = date_uf
if date_uf == "None" :
date_uf = [""] date_uf = [""]
else : else :
date_uf = date_uf.split("-") date_uf = date_uf.split("-")
time_uf = request.args.get("time") time_uf = str(request.args.get("time"))
if time_uf == None : time_uf_sav = time_uf
if time_uf == "None" :
time_uf = [""] time_uf = [""]
else : else :
time_uf = time_uf.split(":") time_uf = time_uf.split(":")
# Récupére les IDs des salles favorites
favs_ids = request.args.getlist("favs")
if favs_ids == None:
favs_ids = []
date = dti.datetime.now() date = dti.datetime.now()
@ -163,15 +161,21 @@ def free_rooms() :
if time_uf != [""] : if time_uf != [""] :
date = date.replace(hour = int(time_uf[0]), minute = int(time_uf[1])) date = date.replace(hour = int(time_uf[0]), minute = int(time_uf[1]))
date_str += ", à " + time_uf[0] + ":" + time_uf[1] date_str += ", à " + time_uf[0] + ":" + time_uf[1]
# Récupération des IDs des salles favorites :
favs_ids = list(request.args.getlist("favs"))
if favs_ids == [None] :
favs_ids = []
# Récupération de la liste des départements : # Récupération de la liste des départements existants :
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)
# Vérifie qu'il n'y a pas de mauvais départements demandés : # Vérification qu'il n'y a pas de mauvais départements demandés :
for d in dident_list: for d in dident_list :
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)
@ -194,9 +198,10 @@ def free_rooms() :
ignore_list = ["salle non définie", "salle en Distanciel"] ignore_list = ["salle non définie", "salle en Distanciel"]
free_rooms = ro.getrooms(date, depts, ignore_list) free_rooms = ro.getrooms(date, depts, ignore_list)
# Création d'un dictionnaire avec les infos des salles :
frooms_disp = dict() # Mise en forme des infos pour la page Web frooms_disp = dict() # Mise en forme des infos pour la page Web
i = 0 i = 0
for r in free_rooms : for r in free_rooms :
remain_time_str = "" remain_time_str = ""
@ -209,7 +214,8 @@ def free_rooms() :
"end":date_tools.hour_disp(r.end), "end":date_tools.hour_disp(r.end),
"rtime":remain_time_str} "rtime":remain_time_str}
# Ajout des arguments favoris, et départements à l'URL :
change_date_str = "?" change_date_str = "?"
i = 0 i = 0
if favs_ids != [] : if favs_ids != [] :
@ -219,7 +225,7 @@ def free_rooms() :
if i < len(favs_ids) - 1: if i < len(favs_ids) - 1:
change_date_str += "&" change_date_str += "&"
i+=1 i+=1
change_date_str += "&" change_date_str += "&"
for v in dident_list: for v in dident_list:
change_date_str += "dept="+str(v) change_date_str += "dept="+str(v)
if i<len(dident_list)-1: if i<len(dident_list)-1:
@ -227,13 +233,20 @@ def free_rooms() :
i+=1 i+=1
# Générer le lien pour enlever les favoris séléctionnés # Génération du lien pour enlever les favoris séléctionnés :
nofavslink = "/app/free-rooms?" nofavslink = "/app/free-rooms?"
for dept in dident_list: for dept in dident_list:
nofavslink+="dept="+str(dept)+"&" nofavslink+="dept="+str(dept)+"&"
nofavslink = nofavslink[:-1] # Enlever le dernier & # Ajout des éventuels date et heure :
if date_uf_sav != "None" :
nofavslink += "date=" + date_uf_sav + "&"
if time_uf_sav != "None" :
nofavslink += "time=" + time_uf_sav
# Suppression de l'éventuel '&' en trop :
if nofavslink[:-1] == "&" :
nofavslink = nofavslink[:-1]
# Trier les salles selon leurs catégories # Tri des salles selon leurs catégories :
favs_free_rooms = [] favs_free_rooms = []
favs_soon_rooms = [] favs_soon_rooms = []
soon_rooms = [] soon_rooms = []
@ -245,15 +258,17 @@ def free_rooms() :
context = {"favs_free_rooms":favs_free_rooms, "favs_soon_rooms":favs_soon_rooms, context = {"favs_free_rooms":favs_free_rooms, "favs_soon_rooms":favs_soon_rooms,
"free_rooms":final_rooms, "soon_rooms":soon_rooms, "frooms_disp":frooms_disp, "free_rooms":final_rooms, "soon_rooms":soon_rooms, "frooms_disp":frooms_disp,
"depts_str":depts_str, "dident_list":dident_list, "date_str":date_str, "depts_str":depts_str, "dident_list":dident_list, "date_str":date_str,
"change_date_str":change_date_str, "favs":len(favs_ids)>0,"nofavslink":nofavslink} "date_uf_sav":date_uf_sav, "time_uf_sav":time_uf_sav, "change_date_str":change_date_str,
"favs":len(favs_ids)>0,"nofavslink":nofavslink}
# Crée un log de la date et des départements demandés ( pour des futures statistiques ) # Création d'un log de la date et des départements demandés (pour les stats du site) :
log = {} log = {}
log["timestamp"] = dti.datetime.now().timestamp() log["timestamp"] = dti.datetime.now().timestamp()
log["depts"] = depts log["depts"] = depts
logs.append(log) logs.append(log)
# Vide les logs vieux de MAX_LOG_DAYS
while (log["timestamp"]-logs[0]["timestamp"])/(60*60*24)>MAX_LOG_DAYS: # Suppression des logs vieux de MAX_LOG_DAYS :
while (log["timestamp"] - logs[0]["timestamp"]) / (60*60*24) > MAX_LOG_DAYS :
del(logs[0]) del(logs[0])
url_for("static", filename="style.css") url_for("static", filename="style.css")
@ -274,8 +289,8 @@ def date_select() :
------- -------
flask.render_template flask.render_template
""" """
dident_list = request.args.getlist("dept") dident_list = list(request.args.getlist("dept"))
favs_ids = request.args.getlist("favs") favs_ids = list(request.args.getlist("favs"))
context = {"dident_list":dident_list, "favs_ids":favs_ids} context = {"dident_list":dident_list, "favs_ids":favs_ids}

View File

@ -10,7 +10,7 @@
{% include "base.html" %} {% include "base.html" %}
<main> <main>
<form action="/app/free-rooms" method="get"> <form action="/app/free-rooms" method="get">
<div class="flex"><p>Choisisssez une date</p></div> <div class="flex"><p>Choisisssez une date :</p></div>
<div class="flex"> <div class="flex">
<input type="date" id="froom-date" name="date"/> <input type="date" id="froom-date" name="date"/>
</div> </div>
@ -20,6 +20,7 @@
<div class="flex"> <div class="flex">
<input type="submit" value="Valider"> <input type="submit" value="Valider">
</div> </div>
<!-- Magie noire pour conserver les départements et favoris séléctionnés (FIXME !!!!) -->
{% for d in dident_list : %} {% for d in dident_list : %}
<span style="display: none;"><input type="text" name="dept" value="{{ d }}"/></span> <span style="display: none;"><input type="text" name="dept" value="{{ d }}"/></span>
{% endfor %} {% endfor %}

View File

@ -9,7 +9,7 @@
<body> <body>
{% include "base.html" %} {% include "base.html" %}
<main> <main>
<div class="flex"><p>Sélectionnez des départements dans la liste</p></div> <div class="flex"><p>Sélectionnez des départements dans la liste :</p></div>
<form action="/app/free-rooms" method="get"> <form action="/app/free-rooms" method="get">
<div class="flex"> <div class="flex">
<input type="submit" value="Valider"> <input type="submit" value="Valider">

View File

@ -21,7 +21,7 @@
{% endif %} {% endif %}
</div> </div>
<div class="flex" style="margin: 10px"> <div class="flex" style="margin: 10px">
<a class="button" href='/app/date-select{{change_date_str}}'>Choisir une date</a> <a class="button" href='/app/date-select{{ change_date_str }}'>Choisir une date</a>
</div> </div>
{% if favs: %} {% if favs: %}
<div class="flex" style="margin: 10px"> <div class="flex" style="margin: 10px">
@ -29,9 +29,9 @@
</div> </div>
{% endif %} {% endif %}
<form action="/app/free-rooms" method="get"> <form action="/app/free-rooms" method="get">
<div class="flex" style="margin: 10px"> <div class="flex" style="margin: 10px">
<input style="font-size: 16px;" type="submit" value="Enregistrer les favoris"> <input style="font-size: 16px;" type="submit" value="Enregistrer les favoris">
</div> </div>
{% if favs: %} {% if favs: %}
<div class="flex-pc"> <div class="flex-pc">
{% if favs_free_rooms|length>0: %} {% if favs_free_rooms|length>0: %}
@ -143,9 +143,12 @@
{% endif %} {% endif %}
</div> </div>
<div class="flex"> <div class="flex">
{% for d in dident_list : %} <!-- Magie noire pour conserver les départements séléctionnés --> <!-- Magie noire pour conserver les départements et date-heure séléctionnés (FIXME !!!!) -->
<span style="display: none;"><input type="text" name="dept" value="{{ d }}"/></span> {% for d in dident_list : %}
{% endfor %} <span style="display: none;"><input type="text" name="dept" value="{{ d }}"/></span>
{% endfor %}
<span style="display: none;"><input type="text" name="date" value="{{ date_uf_sav }}"/></span>
<span style="display: none;"><input type="text" name="time" value="{{ time_uf_sav }}"/></span>
</div> </div>
</form> </form>
</main> </main>

View File

@ -18,10 +18,26 @@
UniSquat est une application qui permet de trouver des salles libres à l'Université de Strasbourg. Sélectionnez des départements de l'université, et les salles de ces départements qui sont libres, et prochainement libres, s'afficheront.<br> UniSquat est une application qui permet de trouver des salles libres à l'Université de Strasbourg. Sélectionnez des départements de l'université, et les salles de ces départements qui sont libres, et prochainement libres, s'afficheront.<br>
Cela vous permet par exemple, si vous êtes élève, de chercher un endroit pour travailler, ou si vous êtes enseignant, de trouver une salle libre en cas de changement d'emploi du temps. Cela vous permet par exemple, si vous êtes élève, de chercher un endroit pour travailler, ou si vous êtes enseignant, de trouver une salle libre en cas de changement d'emploi du temps.
</p> </p>
<h2>Comment ça marche ?</h2> <h2>Fonctionnalités</h2>
<p>L'Université de Strasbourg met à disposition l'emploi du temps des salles en ligne, et permet de télécharger ces emplois du temps sous la forme d'un fichier ICalendar. UniSquat télécharge les fichiers en lien avec le(s) département(s) sélectionné(s), les met en commun, et les analyse pour trouver des salles libres et les afficher.</p> <ul>
<h2>Et c'est développé par qui ?</h2> <li>🔎 Visualiser les salles libres de plusieurs départements en même temps (par exemple : l'UFR de Math-Info et l'EOST).</li>
<p><a href="{{CREDITSLINK}}">{{CREDITSNAME}}</a>, une organisation de deux étudiants. Le code source est disponible <a href="{{SOURCE}}">ici</a> :)</p> <li>⏰ Connaître la période de disponibilité d'une salle.</li>
<li>🔜 Les salles prochainement libres sont également affichées, avec leur prochaine disponibilité.</li>
<li>⭐ Marquer des salles comme favorites, pour les afficher en haut de la page.</li>
<ul>
<li>Les favoris sont stockés dans l'URL de la page. Cela permet de les partager ou de les enregistrer simplement, puisqu'il suffit de partager l'URL ou de l'ajouter aux marque-pages.</li>
</ul>
<li>📅 Rechercher les salles libres à une date choisie.</li>
<li>🪶 Application légère pour l'utilisateur :</li>
<ul>
<li>Pas de JavaScript, tous les calculs sont fait coté serveur.</li>
<li>Pas de <i>Local Storage</i>, <i>cookies</i> ou autres <i>bibliothèques CSS</i>.</li>
</ul>
</ul>
<h2>Comment ça marche ?</h2>
<p>L'Université de Strasbourg met à disposition l'emploi du temps des salles en ligne, et permet de télécharger ces emplois du temps sous la forme d'un fichier ICalendar. UniSquat télécharge les fichiers en lien avec le(s) département(s) sélectionné(s), les met en commun, et les analyse pour trouver des salles libres et les afficher.</p>
<h2>Et c'est développé par qui ?</h2>
<p><a href="{{CREDITSLINK}}">{{CREDITSNAME}}</a>, une organisation de deux étudiants. Le code source est disponible <a href="{{SOURCE}}">ici</a> :)</p>
</main> </main>
{% include "footer.html" %} {% include "footer.html" %}
</body> </body>

View File

@ -9,15 +9,15 @@
<body> <body>
{% include "base.html" %} {% include "base.html" %}
<main> <main>
<h1>Statistiques d'utilisation de l'instance</h1> <h1>Statistiques d'utilisation du site</h1>
<p>Ces {{MAX_LOG_DAYS}} derniers jours, cette instance a recherché des salles {{nbping}} fois !</p> <p>Ces {{MAX_LOG_DAYS}} derniers jours, des salles ont été recherchées {{nbping}} fois.</p>
{% if nbping>PING_WARN %} {% if nbping>PING_WARN %}
<p>⚠ L'instance commence a être <strong>surchargée</strong>, considérez le fait d'en <a href="https://forge.chapril.org/Wantoo/UniSquat_Python">créer une vous même</a></p> <p>⚠ Ce site commence a être <strong>surchargé</strong> ! N'hésitez pas à héberger votre propre instance d'UniSquat :) <a href="https://forge.chapril.org/Wantoo/UniSquat_Python">En savoir plus</a></p>
{% endif %} {% endif %}
<h1>Départements les plus demandés</h1> <h1>Départements les plus recherchés</h1>
<ul> <ul>
{% for dept in depts: %} {% for dept in depts: %}
<li><strong>{{ dept[0] }}</strong> (demandé {{dept[1]}} fois)</li> <li><strong>{{ dept[0] }}</strong> (recherché {{dept[1]}} fois)</li>
{% endfor %} {% endfor %}
</ul> </ul>
</main> </main>