Compare commits

...

6 Commits

11 changed files with 175 additions and 121 deletions

View File

@ -1,21 +1,22 @@
# UniSquat
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.
Cette application dispose d'une interface Web fonctionnant avec Flask. Une version en ligne est disponible [ici][homepage].
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.
Cette application dispose d'une interface Web fonctionnant avec Flask. Une instance de cette application est disponible en ligne [ici][homepage].
## Fonctionnalités
- 🔎 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.
- 🔜 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.
* 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.
- 🪶 Application légère pour l'utilisateur :
* Pas de JavaScript, tout les calculs sont fait coté serveur
* Pas de *Local Storage*, *Cookies* ou autres *bibliothèques CSS*
* Pas de JavaScript, tous les calculs sont faits coté serveur.
* Pas de *Local Storage*, *cookies* ou autres *bibliothèques CSS*.
## Dépendances
@ -32,7 +33,7 @@ Vous pouvez aussi installer directement les dépendances avec cette commande :
pip install -r requirements.txt
```
## Comment lancer la version Web (Flask)
## Comment lancer l'interface Web (Flask)
Dans la racine du dossier :
@ -40,23 +41,21 @@ Dans la racine du dossier :
flask run
```
C'est la version la plus utilisable, n'hésitez pas à héberger votre propre version.
C'est l'interface qui est activement supportée. N'hésitez pas à héberger votre propre instance d'UniSquat.
## Interfaces obsolètes
Ces interfaces ont été crées à des fins de test. Elles peuvent être instables, et ne sont plus mises à jour.
Ces interfaces ont été crées à des fins de test. Elles ne sont plus mises à jour, et peuvent être instables.
### Interface en ligne de commande
Une interface en ligne de commande est disponible. Elle ne nécessite pas de dépendances supplémentaires.
Pour la lancer :
```python
python main_cli.py
```
### Interface Qt5
### Interface graphique (Qt5)
Une interface graphique utilisant la bibliothèque Qt. Elle nécessite le module `PyQt5`.

71
app.py
View File

@ -128,29 +128,27 @@ def free_rooms() :
flask.render_template
"""
# Récupération des ID des départements depuis le formulaire :
dident_list = request.args.getlist("dept")
if len(dident_list)>MAX_DEPT:
dident_list = list(request.args.getlist("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.")
if len(dident_list)==0:
if len(dident_list) == 0 :
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) :
date_uf = request.args.get("date")
if date_uf == None :
date_uf = str(request.args.get("date"))
date_uf_sav = date_uf
if date_uf == "None" :
date_uf = [""]
else :
date_uf = date_uf.split("-")
time_uf = request.args.get("time")
if time_uf == None :
time_uf = str(request.args.get("time"))
time_uf_sav = time_uf
if time_uf == "None" :
time_uf = [""]
else :
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()
@ -163,15 +161,21 @@ def free_rooms() :
if time_uf != [""] :
date = date.replace(hour = int(time_uf[0]), minute = int(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_list = ro.get_depts(dept_filen)
# Vérifie qu'il n'y a pas de mauvais départements demandés :
for d in dident_list:
try:
# Vérification qu'il n'y a pas de mauvais départements demandés :
for d in dident_list :
try :
int(d)
except:
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"]
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
i = 0
for r in free_rooms :
remain_time_str = ""
@ -209,7 +214,8 @@ def free_rooms() :
"end":date_tools.hour_disp(r.end),
"rtime":remain_time_str}
# Ajout des arguments favoris, et départements à l'URL :
change_date_str = "?"
i = 0
if favs_ids != [] :
@ -219,7 +225,7 @@ def free_rooms() :
if i < len(favs_ids) - 1:
change_date_str += "&"
i+=1
change_date_str += "&"
change_date_str += "&"
for v in dident_list:
change_date_str += "dept="+str(v)
if i<len(dident_list)-1:
@ -227,13 +233,20 @@ def free_rooms() :
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?"
for dept in dident_list:
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_soon_rooms = []
soon_rooms = []
@ -245,15 +258,17 @@ def free_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,
"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["timestamp"] = dti.datetime.now().timestamp()
log["depts"] = depts
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])
url_for("static", filename="style.css")
@ -274,8 +289,8 @@ def date_select() :
-------
flask.render_template
"""
dident_list = request.args.getlist("dept")
favs_ids = request.args.getlist("favs")
dident_list = list(request.args.getlist("dept"))
favs_ids = list(request.args.getlist("favs"))
context = {"dident_list":dident_list, "favs_ids":favs_ids}

View File

@ -1,122 +1,122 @@
UFR de Mathématiques-Informatique
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30626&projectId=8&calType=ical
30626
EOST - École et Observatoire des Sciences de la Terre
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30773&projectId=8&calType=ical
30773
Atrium
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=5208&projectId=8&calType=ical
5208
Escarpe
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=336&projectId=8&calType=ical
336
Faculté de Chimie
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=336&projectId=8&calType=ical
336
Faculté de Droit
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=304&projectId=8&calType=ical
304
I.P.C.B
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30695&projectId=8&calType=ical
30695
Institut Le Bel
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=5188&projectId=8&calType=ical
5188
Le Portique
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=8824&projectId=8&calType=ical
8824
Pangloss
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=4480&projectId=8&calType=ical
4480
Patio
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=4484&projectId=8&calType=ical
4484
Plateforme de biologie
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=5333&projectId=8&calType=ical
5333
Athena
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=33171&projectId=8&calType=ical
33171
Collège Doctoral Européen
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=22444&projectId=8&calType=ical
22444
M.I.S.H.A
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=4472&projectId=8&calType=ical
4472
MDP - Maison des personnels
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=39466&projectId=8&calType=ical
39466
Présidence
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=10310&projectId=8&calType=ical
10310
Faculté de Géographie
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30614&projectId=8&calType=ical
30614
Faculté de Psychologie
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30612&projectId=8&calType=ical
30612
Institut botanique
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=5144&projectId=8&calType=ical
5144
Institut de Physique
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30597&projectId=8&calType=ical
30597
Institut de Zoologie
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30696&projectId=8&calType=ical
30696
Palais universitaire
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=4474&projectId=8&calType=ical
4474
Médecine
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=10172&projectId=8&calType=ical
10172
Dentaire
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=25353&projectId=8&calType=ical
25353
Cardo
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=7429&projectId=8&calType=ical
7429
Ensemble Saint Georges
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=311&projectId=8&calType=ical
311
Galiléo
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=50&projectId=8&calType=ical
50
C.R.L - Pôle Lansad
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=11715&projectId=8&calType=ical
11715
École de Management
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30694&projectId=8&calType=ical
30694
Faculté des Sciences Économiques et de Gestion
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=96&projectId=8&calType=ical
96
Institut Mécanique des Fluides
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30594&projectId=8&calType=ical
30594
INSPÉ Colmar
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30622&projectId=8&calType=ical
30622
E.C.P.M - Cronenbourg
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=316&projectId=8&calType=ical
316
ENGEES
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30705&projectId=8&calType=ical
30705
IUT Hagenau
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30607&projectId=8&calType=ical
30607
EOST - Rue Blessig
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30633&projectId=8&calType=ical
30633
Goethe 43
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=9899&projectId=8&calType=ical
9899
IUT Louis Pasteur
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30619&projectId=8&calType=ical
30619
INSPÉ Séléstat
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30600&projectId=8&calType=ical
30600
4, rue Boussingault
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30593&projectId=8&calType=ical
30593
7, rue de l'Université
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=5166&projectId=8&calType=ical
5166
Boulevard Lefebvre S.F.C. (ex. IPST)
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=8108&projectId=8&calType=ical
8108
INSPÉ Meinau (nouveau bâtiment)
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30605&projectId=8&calType=ical
30605
INSPÉ Neudorf (école annexe)
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=98&projectId=8&calType=ical
98
S.F.C.
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30665&projectId=8&calType=ical
30665
IUT Informatique - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30678&projectId=8&calType=ical
30678
IUT Leonardo - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30610&projectId=8&calType=ical
30610
IUT Génie Civil - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30667&projectId=8&calType=ical&
30667
IUT Chimie - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30661&projectId=8&calType=ical
30661
IUT - Bloc Central - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30658&projectId=8&calType=ical
30658
ISU - Ext - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=209&projectId=8&calType=ical
209
Faculté de Pharmacie - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=5095&projectId=8&calType=ical
5095
Bibliothèque IUT Pharmacie - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=37765&projectId=8&calType=ical
37765
API - Bâtiment A (central) - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30602&projectId=8&calType=ical
30602
API - Bâtiment B (télécom) - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=18442&projectId=8&calType=ical
18442
API - Bâtiment C (télécom) - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30653&projectId=8&calType=ical
30653
API - Bâtiment D (ESBS) - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30634&projectId=8&calType=ical
30634
API - Bâtiment E (CEBGS) - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30651&projectId=8&calType=ical
30651
API - Bâtiment I (laboratoire SERTIT) - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=19336&projectId=8&calType=ical
19336
API - Bâtiment J (hall techno) - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30688&projectId=8&calType=ical
30688

View File

@ -86,5 +86,8 @@ class Dept :
def __init__(self, ident, name, link, rooms) :
self.ident = ident
self.name = name
self.link = link
self.link = self.genlink(link)
self.rooms = rooms
def genlink(self,link):
return "https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources="+link.strip()+"&projectId=8&calType=ical"

13
push_to_server.sh Normal file
View File

@ -0,0 +1,13 @@
#!/bin/bash
# Ce script permet d'envoyer l'application sur le serveur
scp -r data unisquat@ssh-unisquat.alwaysdata.net:www/flask
scp -r static unisquat@ssh-unisquat.alwaysdata.net:www/flask
scp -r templates unisquat@ssh-unisquat.alwaysdata.net:www/flask
scp app.py unisquat@ssh-unisquat.alwaysdata.net:www/flask
scp date_tools.py unisquat@ssh-unisquat.alwaysdata.net:www/flask
scp objects.py unisquat@ssh-unisquat.alwaysdata.net:www/flask
scp rooms_get.py unisquat@ssh-unisquat.alwaysdata.net:www/flask
ssh unisquat@ssh-unisquat.alwaysdata.net

View File

@ -32,7 +32,8 @@ from objects import Dept
# Constantes :
CACHE_DIR = "cache"
CACHE_TTL = 3 # Intervalle de temps entre les réinitialisations du cache, en minutes
CACHE_TTL = 5 # Intervalle de temps entre les réinitialisations du cache, en minutes
CACHE_SIZE = 10 # Nombres maximum de fichier dans le cache
# Globales
last_cache_init = -999
@ -142,6 +143,9 @@ def sched_get(date, link, enddate = None, nocache = False) :
elapsed = time.time() - last_cache_init
if elapsed>CACHE_TTL*60:
reinit_cache()
# Vérifie que le nombre total de fichiers dans le cache n'est pas dépassé
if len(os.listdir(CACHE_DIR))>CACHE_SIZE:
reinit_cache()
# Vérifie que le lien est dans le cache
cachepath = os.path.join(CACHE_DIR,trim(finallink))

View File

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

View File

@ -9,7 +9,7 @@
<body>
{% include "base.html" %}
<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">
<div class="flex">
<input type="submit" value="Valider">

View File

@ -21,7 +21,7 @@
{% endif %}
</div>
<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>
{% if favs: %}
<div class="flex" style="margin: 10px">
@ -29,9 +29,9 @@
</div>
{% endif %}
<form action="/app/free-rooms" method="get">
<div class="flex" style="margin: 10px">
<input style="font-size: 16px;" type="submit" value="Enregistrer les favoris">
</div>
<div class="flex" style="margin: 10px">
<input style="font-size: 16px;" type="submit" value="Enregistrer les favoris">
</div>
{% if favs: %}
<div class="flex-pc">
{% if favs_free_rooms|length>0: %}
@ -143,9 +143,12 @@
{% endif %}
</div>
<div class="flex">
{% for d in dident_list : %} <!-- Magie noire pour conserver les départements séléctionnés -->
<span style="display: none;"><input type="text" name="dept" value="{{ d }}"/></span>
{% endfor %}
<!-- Magie noire pour conserver les départements et date-heure séléctionnés (FIXME !!!!) -->
{% for d in dident_list : %}
<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>
</form>
</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>
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>
<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>
<h2>Fonctionnalités</h2>
<ul>
<li>🔎 Visualiser les salles libres de plusieurs départements en même temps (par exemple : l'UFR de Math-Info et l'EOST).</li>
<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 faits 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>
{% include "footer.html" %}
</body>

View File

@ -9,15 +9,15 @@
<body>
{% include "base.html" %}
<main>
<h1>Statistiques d'utilisation de l'instance</h1>
<p>Ces {{MAX_LOG_DAYS}} derniers jours, cette instance a recherché des salles {{nbping}} fois !</p>
<h1>Statistiques d'utilisation du site</h1>
<p>Ces {{MAX_LOG_DAYS}} derniers jours, des salles ont été recherchées {{nbping}} fois.</p>
{% 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 %}
<h1>Départements les plus demandés</h1>
<h1>Départements les plus recherchés</h1>
<ul>
{% 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 %}
</ul>
</main>