Compare commits

...

6 Commits

11 changed files with 175 additions and 121 deletions

View File

@ -1,21 +1,22 @@
# UniSquat # UniSquat
Une 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.
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 ## Fonctionnalités
- 🔎 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 faits 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
@ -32,7 +33,7 @@ Vous pouvez aussi installer directement les dépendances avec cette commande :
pip install -r requirements.txt pip install -r requirements.txt
``` ```
## Comment lancer la version Web (Flask) ## Comment lancer l'interface Web (Flask)
Dans la racine du dossier : Dans la racine du dossier :
@ -40,23 +41,21 @@ Dans la racine du dossier :
flask run 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 ## 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 ### 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 : Pour la lancer :
```python ```python
python main_cli.py python main_cli.py
``` ```
### Interface Qt5 ### Interface graphique (Qt5)
Une 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`.

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

@ -1,122 +1,122 @@
UFR de Mathématiques-Informatique 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 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 Atrium
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=5208&projectId=8&calType=ical 5208
Escarpe Escarpe
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=336&projectId=8&calType=ical 336
Faculté de Chimie Faculté de Chimie
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=336&projectId=8&calType=ical 336
Faculté de Droit 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 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 Institut Le Bel
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=5188&projectId=8&calType=ical 5188
Le Portique Le Portique
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=8824&projectId=8&calType=ical 8824
Pangloss Pangloss
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=4480&projectId=8&calType=ical 4480
Patio Patio
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=4484&projectId=8&calType=ical 4484
Plateforme de biologie Plateforme de biologie
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=5333&projectId=8&calType=ical 5333
Athena Athena
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=33171&projectId=8&calType=ical 33171
Collège Doctoral Européen 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 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 MDP - Maison des personnels
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=39466&projectId=8&calType=ical 39466
Présidence Présidence
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=10310&projectId=8&calType=ical 10310
Faculté de Géographie 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 Faculté de Psychologie
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30612&projectId=8&calType=ical 30612
Institut botanique Institut botanique
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=5144&projectId=8&calType=ical 5144
Institut de Physique Institut de Physique
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30597&projectId=8&calType=ical 30597
Institut de Zoologie Institut de Zoologie
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30696&projectId=8&calType=ical 30696
Palais universitaire Palais universitaire
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=4474&projectId=8&calType=ical 4474
Médecine Médecine
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=10172&projectId=8&calType=ical 10172
Dentaire Dentaire
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=25353&projectId=8&calType=ical 25353
Cardo Cardo
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=7429&projectId=8&calType=ical 7429
Ensemble Saint Georges Ensemble Saint Georges
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=311&projectId=8&calType=ical 311
Galiléo 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 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 É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 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 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 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 E.C.P.M - Cronenbourg
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=316&projectId=8&calType=ical 316
ENGEES ENGEES
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30705&projectId=8&calType=ical 30705
IUT Hagenau IUT Hagenau
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30607&projectId=8&calType=ical 30607
EOST - Rue Blessig EOST - Rue Blessig
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30633&projectId=8&calType=ical 30633
Goethe 43 Goethe 43
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=9899&projectId=8&calType=ical 9899
IUT Louis Pasteur 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 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 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é 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) 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) 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) 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. S.F.C.
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30665&projectId=8&calType=ical 30665
IUT Informatique - Illkirch IUT Informatique - Illkirch
https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30678&projectId=8&calType=ical 30678
IUT Leonardo - Illkirch 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 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 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 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 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 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 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 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 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 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 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 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 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 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) : def __init__(self, ident, name, link, rooms) :
self.ident = ident self.ident = ident
self.name = name self.name = name
self.link = link self.link = self.genlink(link)
self.rooms = rooms 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 : # Constantes :
CACHE_DIR = "cache" 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 # Globales
last_cache_init = -999 last_cache_init = -999
@ -142,6 +143,9 @@ def sched_get(date, link, enddate = None, nocache = False) :
elapsed = time.time() - last_cache_init elapsed = time.time() - last_cache_init
if elapsed>CACHE_TTL*60: if elapsed>CACHE_TTL*60:
reinit_cache() 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 # 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))

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 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> </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>