Réglage du fuseau horaire (enfin !).

Commentaires.
Amélioration des pages web.
This commit is contained in:
Antoine Waehren 2022-05-12 15:32:12 +02:00
parent 38184deae1
commit 560868a7b8
10 changed files with 120 additions and 108 deletions

2
app.py
View File

@ -8,7 +8,7 @@
""" """
### Interface Web (Flask) ### ### Fichier de l'interface Web Flask ###
# Modules : # Modules :

View File

@ -6,15 +6,19 @@ Created on Thu Feb 24 16:36:32 2022
@author: antoine @author: antoine
""" """
######################## ################
### Module datetools ### ### UniSquat ###
######################## ################
""" """
Diverses fonctions relatives à la date du jour et à l'heure. Indique toutes les salles disponibles dans les différents départements de
l'Université de Strasbourg.
""" """
### Fichier contenant diverses fonctions relatives à la date du jour et à l'heure ##
# Modules : # Modules :
import datetime import datetime

View File

@ -16,6 +16,9 @@ Created on Thu Feb 24 17:14:05 2022
""" """
### Fichier de l'interface en ligne de commande ###
# Modules : # Modules :
import datetime import datetime
import time import time
@ -45,10 +48,10 @@ def main() :
print("~~~ UniSquat ~~~\n") print("~~~ UniSquat ~~~\n")
hdelay = 1 #TODO : décalage horaire (pb de fuseau ?) #hdelay = 1 #TODO : décalage horaire (pb de fuseau ?)
if time.localtime().tm_isdst != 0 : #if time.localtime().tm_isdst != 0 :
hdelay = 2 #hdelay = 2
ignore_list = ["salle non définie", "salle en Distanciel"] ignore_list = ["salle non définie", "salle en Distanciel"]
@ -70,7 +73,7 @@ def main() :
while choice not in range(len(dept_list)) : while choice not in range(len(dept_list)) :
choice = int(input("Entrez le numéro du département.\n> ")) choice = int(input("Entrez le numéro du département.\n> "))
dept = dept_list[choice] dept = dept_list[choice] # TODO : proposer plusieurs départements
date_choice = -1 date_choice = -1
@ -85,7 +88,7 @@ def main() :
print("\nRecherche des salles disponibles, veuillez patienter...\n") print("\nRecherche des salles disponibles, veuillez patienter...\n")
available_rooms = ro.getrooms(date, dept, ignore_list) available_rooms = ro.getrooms(date, [dept], ignore_list)
# Salles libres à la date indiquée : # Salles libres à la date indiquée :
print("\nLes salles suivantes sont disponibles à " + str(date.hour) + ":" + str(date.minute) + ", le " + str(date.date()) + " :\n") print("\nLes salles suivantes sont disponibles à " + str(date.hour) + ":" + str(date.minute) + ", le " + str(date.date()) + " :\n")
@ -99,12 +102,11 @@ def main() :
remain_time_str = str(deltasec[0]) + " heures" remain_time_str = str(deltasec[0]) + " heures"
if deltasec[1] > 0 : if deltasec[1] > 0 :
remain_time_str += " " + str(deltasec[1]) + " minutes" remain_time_str += " " + str(deltasec[1]) + " minutes"
# print(" - " + room["name"]+" | occupée dans : "+str(int(deltasec/60+0.5))+" minutes")
if room.end.hour == 23 and room.end.minute == 59 and room.end.second == 59 : if room.end.hour == 23 and room.end.minute == 59 and room.end.second == 59 :
print(" - " + room.name) print(" - " + room.name)
else : else :
print(" - " + room.name + " | Occupée à : " + str(room.end.hour + hdelay) + ":" + str(room.end.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?) print(" - " + room.name + " | Occupée à : " + str(room.end.hour) + ":" + str(room.end.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?)
# Salles libres prochainement : # Salles libres prochainement :
print("\nLes salles suivantes seront disponibles prochainement : \n") print("\nLes salles suivantes seront disponibles prochainement : \n")
@ -118,12 +120,11 @@ def main() :
remain_time_str = str(deltasec[0]) + " heures" remain_time_str = str(deltasec[0]) + " heures"
if deltasec[1] > 0 : if deltasec[1] > 0 :
remain_time_str += " " + str(deltasec[1]) + " minutes" remain_time_str += " " + str(deltasec[1]) + " minutes"
# print(" - " + room["name"]+" | libre dans : "+str(int(deltasec/60+0.5))+" minutes")
if room.end.hour == 23 and room.end.minute == 59 and room.end.second == 59 : if room.end.hour == 23 and room.end.minute == 59 and room.end.second == 59 :
print(" - " + room.name + " | Libre à " + str(room.start.hour + hdelay) + ":" + str(room.start.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?) print(" - " + room.name + " | Libre à " + str(room.start.hour) + ":" + str(room.start.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?)
else : else :
print(" - " + room.name + " | Libre de " + str(room.start.hour + hdelay) + ":" + str(room.start.minute) + " à " + str(room.end.hour + hdelay) + ":" + str(room.end.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?) print(" - " + room.name + " | Libre de " + str(room.start.hour) + ":" + str(room.start.minute) + " à " + str(room.end.hour) + ":" + str(room.end.minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?)
if __name__=="__main__": if __name__=="__main__":
main() main()

View File

@ -16,17 +16,21 @@ Created on Thu Mar 3 08:47:47 2022
""" """
# Modules : ### Fichier de l'interface graphique Qt ###
# Modules :
import sys import sys
import PyQt5 as qt import PyQt5 as qt
import rooms_get as ro import rooms_get as ro
import datetime import datetime
import date_tools import date_tools
favorites = ["C"+str(i)+" MATH" for i in range(1,10)]+["C42-CMI"]
favorites = ["C"+str(i)+" MATH" for i in range(1,10)]+["C42-CMI"] # TODO : à enlever
links = [] links = []
def main() : def main() :
app = qt.QtWidgets.QApplication(sys.argv) app = qt.QtWidgets.QApplication(sys.argv)
windows = qt.QtWidgets.QWidget() windows = qt.QtWidgets.QWidget()
@ -76,7 +80,6 @@ def main() :
if deltasec[1] > 0 : if deltasec[1] > 0 :
remain_time_str += " " + str(deltasec[1]) + " minutes" remain_time_str += " " + str(deltasec[1]) + " minutes"
# print(" - " + room["name"]+" | libre dans : "+str(int(deltasec/60+0.5))+" minutes")
if room["end"].hour == 23 and room["end"].minute == 59 : if room["end"].hour == 23 and room["end"].minute == 59 :
listwidget2.addItem(room["name"] + "\nLibre à " + str(room["start"].hour + 1) + ":" + str(room["start"].minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?) listwidget2.addItem(room["name"] + "\nLibre à " + str(room["start"].hour + 1) + ":" + str(room["start"].minute) + " (dans " + remain_time_str + ")") # TODO : Obligé d'ajouter 1h (problème de fuseau horaire ?)
else : else :
@ -92,5 +95,6 @@ def main() :
windows.show() windows.show()
sys.exit(app.exec_()) sys.exit(app.exec_())
if __name__=="__main__": if __name__=="__main__":
main() main()

View File

@ -16,6 +16,9 @@ Created on Sat May 7 17:29:11 2022
""" """
### Fichier contenant les classes des salles et des départements ###
# Objets : # Objets :
class Room : class Room :
@ -28,11 +31,11 @@ class Room :
name : string name : string
Le nom de la salle. Le nom de la salle.
start : Date start : datetime.datetime
Salle occupée : heure de début de la prochaine période de disponibilité. Salle occupée : heure de début de la prochaine période de disponibilité.
Salle libre : inutilisé (vaut la date du jour à 00:00). Salle libre : inutilisé (vaut la date du jour à 00:00).
end : Date end : datetime.datetime
Salle occupée : heure de fin de la prochaine période de disponibilité. Salle occupée : heure de fin de la prochaine période de disponibilité.
Salle libre : heure de fin de disponibilité. Salle libre : heure de fin de disponibilité.
@ -52,7 +55,7 @@ class Room :
class Dept : class Dept :
""" """
Structure des départements. Classe des départements.
Attributes Attributes
---------- ----------
@ -66,7 +69,7 @@ class Dept :
link : string link : string
Lien qui permet d'accéder au fichier iCal du département. Lien qui permet d'accéder au fichier iCal du département.
rooms : vector<Room> rooms : list
La liste des salles de ce département La liste des salles de ce département
""" """

View File

@ -15,43 +15,20 @@ Created on Thu Feb 24 08:51:58 2022
""" """
### Fichier du backend (récupération des salles libres et de départements ###
# Modules : # Modules :
import requests import requests
import icalendar import icalendar
import pytz
# Fichiers locaux :
from objects import Room from objects import Room
from objects import Dept from objects import Dept
# Fonctions : # Fonctions :
# def room(name, start, end, is_free):
# """
# Retourne un dictionnaire contenant le nom, la prochaine date à laquelle elle est occupée, ainsi que la prochaine date à laquelle elle est libre.
# Parameters
# ----------
# name : str
# Le nom de la salle.
# start : datetime.datetime
# Salle occupée : heure de début de la prochaine période de disponibilité.
# Salle libre : inutilisé (vaut la date du jour à 00:00).
# end : datetime.datetime
# Salle occupée : heure de fin de la prochaine période de disponibilité.
# Salle libre : heure de fin de disponibilité.
# is_free : bool
# Indique si la salle est libre ('True') ou non ('False').
# Returns
# -------
# dict
# Un dictionnaire contenant ces 4 informations, avec le même nom en clef.
# """
# # return {"name":name, "occupied_at":occupied_at, "free_at":free_at, "free":free_at.timestamp() > occupied_at.timestamp()}
# return {"name":name, "start":start, "end":end, "is_free":is_free}
def sched_get(date, link, enddate = None) : def sched_get(date, link, enddate = None) :
""" """
Récupère l'emploi du temps de toutes les salles (pour le moment, juste Récupère l'emploi du temps de toutes les salles (pour le moment, juste
@ -79,9 +56,6 @@ def sched_get(date, link, enddate = None) :
bytes bytes
Le texte du résultat de la requête. Le texte du résultat de la requête.
""" """
# if not link:
# link = "https://adecons.unistra.fr/jsp/custom/modules/plannings/anonymous_cal.jsp?resources=30626&projectId=8&calType=ical&firstDate=$YEAR1$-$MONTH1$-$DAY1$&lastDate=$YEAR2$-$MONTH2$-$DAY2$"
link += "&firstDate=$YEAR1$-$MONTH1$-$DAY1$&lastDate=$YEAR2$-$MONTH2$-$DAY2$" link += "&firstDate=$YEAR1$-$MONTH1$-$DAY1$&lastDate=$YEAR2$-$MONTH2$-$DAY2$"
@ -145,23 +119,6 @@ def get_depts(filename) :
for i in range(0, len(dfile_content) - 1, 2) : for i in range(0, len(dfile_content) - 1, 2) :
dept_list.append(Dept(ident, dfile_content[i], dfile_content[i + 1], [])) dept_list.append(Dept(ident, dfile_content[i], dfile_content[i + 1], []))
ident += 1 ident += 1
# for l in dfile_content :
# """
# Une fois sur 2, on va :
# - soit enregistrer le nom du département
# - soit enregistrer son lien, et stocker le département dans la liste
# """
# if i == 0 :
# print(l)
# dept.name = l
# i = 1
# else :
# print(l)
# dept.link = l
# dept_list.append(dept)
# i = 0
dept_file.close() dept_file.close()
@ -207,20 +164,36 @@ def get_tot_rooms(datet, depts, ignore_list) :
result = sched_get(datet, d.link, datet.replace(month = datet.month + margintime)) result = sched_get(datet, d.link, datet.replace(month = datet.month + margintime))
cals.append(icalendar.Calendar.from_ical(result)) cals.append(icalendar.Calendar.from_ical(result))
rnamelist = [] # 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"
# Parcours de ces calendriers, pour faire la liste de toutes les salles : # Parcours de ces calendriers, pour faire la liste de toutes les salles :
for cal in cals : for cal in cals :
for comp in cal.walk() : # Événements for comp in cal.walk() : # Événements
if comp.name == "VEVENT" : if comp.name == "VEVENT" :
# Ajout de la salle dans le dictionnaire, si elle n'y est pas : # Ajout de la salle dans le dictionnaire, si elle n'y est pas :
roomname = str(comp.get("location")) roomname = str(comp.get("location"))
if roomname not in rnamelist :
rnamelist = list() # Contient le nom de toutes les salles indiquées dans la section "LOCATION" (il peut y en avoir plusieurs, séparées par des virgules)
if "," in roomname :
rnamelist = roomname.split(",")
else :
rnamelist.append(roomname) rnamelist.append(roomname)
start = datet.replace(hour = 0, minute = 0, second=0) # Par défaut, l'heure de début de disponibilité est aujourd'hui à 00:00
end = datet.replace(hour = 23, minute = 59, second = 59) # Par défaut, l'heure de fin de la prochaine période disponibilité est aujourd'hui à 23:59 for rname in rnamelist :
is_free = True # Par défaut, la salle est libre if rname not in roomnames :
total_rooms.append(Room(roomname, start, end, is_free)) roomnames.append(rname)
start = datet.replace(hour = 0, minute = 0, second=0) # Par défaut, l'heure de début de disponibilité est aujourd'hui à 00:00
end = datet.replace(hour = 23, minute = 59, second = 59) # Par défaut, l'heure de fin de la prochaine période disponibilité est aujourd'hui à 23:59
is_free = True # Par défaut, la salle est libre
# Réglage du fuseau horaire :
start = start.astimezone(pytz.timezone('Europe/Paris'))
end = end.astimezone(pytz.timezone('Europe/Paris'))
total_rooms.append(Room(rname, start, end, is_free))
return total_rooms return total_rooms
@ -266,16 +239,30 @@ def getrooms(datet, depts, ignore_list) :
dateend = comp.decoded("dtend") dateend = comp.decoded("dtend")
roomname = str(comp.get("location")) roomname = str(comp.get("location"))
# L'événement se passe maintenant (salle occupée maintenant) : rnamelist = list() # Contient le nom de toutes les salles indiquées dans la section "LOCATION" (il peut y en avoir plusieurs, séparées par des virgules)
if datestart.timestamp() <= datet.timestamp() and dateend.timestamp() > datet.timestamp() :
start = dateend # L'heure de début de la prochaine période de disponibilité est la fin de l'événement if "," in roomname :
end = datet.replace(hour = 23, minute = 59, second = 59) # Par défaut, l'heure de fin de la prochaine période disponibilité est aujourd'hui à 23:59 rnamelist = roomname.split(",")
is_free = False else :
for r in total_rooms : rnamelist.append(roomname)
if r.name == roomname :
r.start = start for rname in rnamelist :
r.end = end # L'événement se passe maintenant (salle occupée maintenant) :
r.is_free = is_free if datestart.timestamp() <= datet.timestamp() and dateend.timestamp() > datet.timestamp() :
start = dateend # L'heure de début de la prochaine période de disponibilité est la fin de l'événement
end = datet.replace(hour = 23, minute = 59, second = 59) # Par défaut, l'heure de fin de la prochaine période disponibilité est aujourd'hui à 23:59
is_free = False
# Réglage du fuseau horaire :
start = start.astimezone(pytz.timezone('Europe/Paris'))
end = end.astimezone(pytz.timezone('Europe/Paris'))
for r in total_rooms :
if r.name == rname :
r.start = start
r.end = end
r.is_free = is_free
# Deuxième boucle, pour ajouter les heures de dispos des salles : # Deuxième boucle, pour ajouter les heures de dispos des salles :
for comp in cal.walk() : # Événements for comp in cal.walk() : # Événements
@ -285,18 +272,31 @@ def getrooms(datet, depts, ignore_list) :
dateend = comp.decoded("dtend") dateend = comp.decoded("dtend")
roomname = str(comp.get("location")) roomname = str(comp.get("location"))
# L'événement se passe prochainement (salle occupée à l'occasion de cet événement) : rnamelist = list() # Contient le nom de toutes les salles indiquées dans la section "LOCATION" (il peut y en avoir plusieurs, séparées par des virgules)
if datestart.timestamp() > datet.timestamp() :
for r in total_rooms : if "," in roomname :
if r.name == roomname : rnamelist = roomname.split(",")
if datestart.timestamp() < r.end.timestamp() : else :
if datestart.timestamp() == r.start.timestamp() : rnamelist.append(roomname)
start = dateend
end = r.end for rname in rnamelist :
else : # L'événement se passe prochainement (salle occupée à l'occasion de cet événement) :
start = r.end if datestart.timestamp() > datet.timestamp() :
end = datestart for r in total_rooms :
r.start = start if r.name == roomname :
r.end = end if datestart.timestamp() < r.end.timestamp() :
if datestart.timestamp() == r.start.timestamp() :
start = dateend
end = r.end
else :
start = r.end
end = datestart
# Réglage du fuseau horaire :
start = start.astimezone(pytz.timezone('Europe/Paris'))
end = end.astimezone(pytz.timezone('Europe/Paris'))
r.start = start
r.end = end
return total_rooms return total_rooms

View File

@ -1,4 +1,4 @@
<header>Unisquat</header> <header>UniSquat</header>
<style> <style>
:root { :root {
--bg: #191919; --bg: #191919;

View File

@ -2,7 +2,7 @@
<html lang=""> <html lang="">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Unisquat</title> <title>UniSquat</title>
<link rel="stylesheet" type="text/css" href="../static/style.css"> <link rel="stylesheet" type="text/css" href="../static/style.css">
<meta name="viewport" content="width=300, initial-scale=1" /> <meta name="viewport" content="width=300, initial-scale=1" />
</head> </head>

View File

@ -2,7 +2,7 @@
<html lang=""> <html lang="">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Unisquat</title> <title>UniSquat</title>
<link rel="stylesheet" type="text/css" href="../static/style.css"> <link rel="stylesheet" type="text/css" href="../static/style.css">
<meta name="viewport" content="width=300, initial-scale=1" /> <meta name="viewport" content="width=300, initial-scale=1" />
</head> </head>

View File

@ -2,14 +2,14 @@
<html lang=""> <html lang="">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Unisquat</title> <title>UniSquat</title>
<link rel="stylesheet" type="text/css" href="style.css"> <link rel="stylesheet" type="text/css" href="style.css">
<meta name="viewport" content="width=300, initial-scale=1" /> <meta name="viewport" content="width=300, initial-scale=1" />
</head> </head>
<body> <body>
{% include "base.html" %} {% include "base.html" %}
<main> <main>
<p id="greet">Bienvenue sur Unisquat !</p> <p id="greet">Bienvenue sur UniSquat !</p>
<a style="text-align: center;" href="/app">Accès à l'application</a> <a style="text-align: center;" href="/app">Accès à l'application</a>
</main> </main>
<footer></footer> <footer></footer>