add timezone to events

This commit is contained in:
joseph 2023-12-13 18:32:19 +01:00
parent 65d8b4a699
commit 696d3921cb
3 changed files with 111 additions and 36 deletions

View File

@ -0,0 +1,26 @@
BEGIN:VCALENDAR
PRODID:-//mp2i-vms//Stackity Bot Inc//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:EDT
X-WR-TIMEZONE:Europe/Paris
BEGIN:VTIMEZONE
TZID:Europe/Paris
X-LIC-LOCATION:Europe/Paris
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
END:VCALENDAR

View File

@ -1,6 +1,7 @@
import pandas import pandas
import datetime import datetime
import icalendar import icalendar
import uuid
from pathlib import Path from pathlib import Path
@ -11,6 +12,7 @@ np_eleves = pd_eleves.to_numpy()
pd_colles = pandas.read_csv('Resources/colles.csv') pd_colles = pandas.read_csv('Resources/colles.csv')
np_colles = pd_colles.to_numpy() np_colles = pd_colles.to_numpy()
local_tz = "Europe/Paris"
jour_to_delta = { jour_to_delta = {
"lundi": 0, "lundi": 0,
@ -33,6 +35,32 @@ option_langues = {
def display(cal): def display(cal):
return cal.to_ical().decode("utf-8").replace('\r\n', '\n').strip() return cal.to_ical().decode("utf-8").replace('\r\n', '\n').strip()
def open_ics(filename: str) -> icalendar.Calendar:
"""
Ouvre un fichier .ics et renvoie un objet Calendar
"""
p = Path(__file__).with_name('Resources')
p = Path(p, filename)
with p.open('r') as f:
opened_cal = icalendar.Calendar.from_ical(f.read())
return opened_cal
def add_events_from_ics(filename: str, new_cal: icalendar.Calendar):
"""
Ajoute des évènements depuis un fichier .ics vers un objet icalendar.Calendar
"""
cal_to_import = open_ics(filename=filename)
for event in cal_to_import.walk("vevent"):
new_cal.add_component(event)
return new_cal
def get_eleves(): def get_eleves():
""" """
Renvoie la liste des eleves avec leur groupe associés à leur groupe, a utiliser dans la /cmd Renvoie la liste des eleves avec leur groupe associés à leur groupe, a utiliser dans la /cmd
@ -80,15 +108,19 @@ def get_colles_groupe(np_colles, groupe, option_langue):
new_colle = icalendar.Event() new_colle = icalendar.Event()
new_colle.add("summary", f"Colle {row[0]}") new_colle.add("summary", f"Colle {row[0]}")
new_colle.add("description", f"{row[3]} {row[4]}") new_colle.add("description", f"{row[3]}")
new_colle.add("location", row[4])
new_colle.add("dtstamp", datetime.datetime.now())
new_colle.add("uid", str(uuid.uuid4()))
date = debut_semaine_to_datetime(np_colles[0][index+5]) date = debut_semaine_to_datetime(np_colles[0][index+5])
date += datetime.timedelta(days=jour_to_delta[row[1]]) date += datetime.timedelta(days=jour_to_delta[row[1]])
date += datetime.timedelta(hours=int(row[2][:-1])) date += datetime.timedelta(hours=int(row[2][:-1]))
new_colle.add("dtstart", date) new_colle.add("dtstart", date, parameters={"tzid": local_tz})
date += datetime.timedelta(hours=1) date += datetime.timedelta(hours=1)
new_colle.add("dtend", date) new_colle.add("dtend", date, parameters={"tzid": local_tz})
liste_colles.append(new_colle) liste_colles.append(new_colle)
@ -112,14 +144,16 @@ def get_cours_SI(np_colles, groupe):
cours_si = icalendar.Event() cours_si = icalendar.Event()
cours_si.add("summary", "TD SI") cours_si.add("summary", "TD SI")
cours_si.add("description", "M. Derumeaux R415") cours_si.add("description", "M. Derumeaux R415")
cours_si.add("dtstamp", datetime.datetime.now())
cours_si.add("uid", str(uuid.uuid4()))
date = debut_semaine_to_datetime(np_colles[0][index+5]) date = debut_semaine_to_datetime(np_colles[0][index+5])
date += datetime.timedelta(days=jour_to_delta["mardi"]) date += datetime.timedelta(days=jour_to_delta["mardi"])
date += datetime.timedelta(hours=heure) date += datetime.timedelta(hours=heure)
cours_si.add("dtstart", date) cours_si.add("dtstart", date, parameters={"tzid": local_tz})
date += datetime.timedelta(hours=1) date += datetime.timedelta(hours=1)
cours_si.add("dtend", date) cours_si.add("dtend", date, parameters={"tzid": local_tz})
liste_cours.append(cours_si) liste_cours.append(cours_si)
@ -143,7 +177,7 @@ def get_langues(langues):
return liste_langues return liste_langues
def get_calendar(groupe, langues): def get_calendar(groupe, langues, split: bool = False):
"""" """"
Renvoie un calendrier (icalendar.Calendar) pour un groupe avec des langues donné Renvoie un calendrier (icalendar.Calendar) pour un groupe avec des langues donné
""" """
@ -153,33 +187,32 @@ def get_calendar(groupe, langues):
moitie = row[3] moitie = row[3]
break break
new_cal = icalendar.Calendar() new_cal_edt = open_ics("Base_Calendar.ics")
p = Path(__file__).with_name('Resources')
p = Path(p, f"EDT_{moitie}.ics")
with p.open('r') as f: if split:
opened_cal = icalendar.Calendar.from_ical(f.read()) new_cal_colles = open_ics("Base_Calendar.ics")
for event in opened_cal.walk("vevent"):
new_cal.add_component(event)
p = Path(__file__).with_name('Resources')
p = Path(p, f"EDT_Base.ics")
with p.open('r') as f: new_cal_edt = add_events_from_ics(filename="EDT_Base.ics", new_cal=new_cal_edt)
opened_cal = icalendar.Calendar.from_ical(f.read()) new_cal_edt = add_events_from_ics(filename=f"EDT_{moitie}.ics", new_cal=new_cal_edt)
for event in opened_cal.walk("vevent"):
new_cal.add_component(event)
for event in get_langues(langues): for event in get_langues(langues):
new_cal.add_component(event) new_cal_edt.add_component(event)
for event in get_cours_SI(np_colles, groupe): for event in get_cours_SI(np_colles, groupe):
new_cal.add_component(event) new_cal_edt.add_component(event)
for event in get_colles_groupe(np_colles, groupe, langues): if split:
new_cal.add_component(event) for event in get_colles_groupe(np_colles, groupe, langues):
new_cal_colles.add_component(event)
return new_cal_edt.to_ical(), new_cal_colles.to_ical()
print(display(new_cal)) else:
return new_cal.to_ical() for event in get_colles_groupe(np_colles, groupe, langues):
new_cal_edt.add_component(event)
return [new_cal_edt.to_ical()]

30
main.py
View File

@ -47,20 +47,36 @@ async def on_ready():
) )
@app_commands.describe(groupe="Votre groupe de colle, groupe ∈ ⟦1, 15⟧") @app_commands.describe(groupe="Votre groupe de colle, groupe ∈ ⟦1, 15⟧")
@app_commands.describe(langues="Les options de langue que vous suivez. (Les langues suivies à H4 ne sont pas gérées, mettez 'Autres')") @app_commands.describe(langues="Les options de langue que vous suivez. (Les langues suivies à H4 ne sont pas gérées, mettez 'Autres')")
@app_commands.describe(split="Créer deux fichiers différentes, un pour les colles et un pour le rest de l'EDT.")
async def edt( async def edt(
interaction: discord.Interaction, interaction: discord.Interaction,
groupe: app_commands.Range[int, 1, 15], groupe: app_commands.Range[int, 1, 15],
langues: Choice[str]): langues: Choice[str],
split: bool = False):
""" """
Génère un emploi du temps prenant compte des colles, des langues et de la semaine. Génère un emploi du temps prenant compte des colles, des langues et de la semaine.
""" """
cal = get_calendar(str(groupe), langues.value) cal_list = get_calendar(str(groupe), langues.value, split)
calendrier = BytesIO(cal) fichiers = []
fichier = discord.File(fp=calendrier, filename=f"EDT-{groupe}-{langues.value}.ics")
await interaction.response.send_message( if split:
f"Bonjour, votre emploi du temps pour le groupe {groupe} ({langues.name}) au format `.ics` a bien été généré ! \n\n Vous pouvez l'importer dans la plupart des messageries, je vous recommande cependant de créer un nouveau calendrier avec de l'importer, au cas où vous vouliez l'enlever. \n\n*Si vous avez des retours à faire (bug, erreur,..), contactez Joseph.*", fichiers.append(discord.File(fp=BytesIO(cal_list[0]), filename=f"EDT-{groupe}-{langues.value}-WO.ics"))
file=fichier) fichiers.append(discord.File(fp=BytesIO(cal_list[1]), filename=f"Colles-{groupe}.ics"))
message = f"""
\nVotre emploi du temps (`EDT-{groupe}-{langues.value}-WO.ics`) pour le groupe `{groupe}`, `{langues.name}` au format `.ics` a bien été généré, **sans les colles**
\n\nLes colles ont été généré séparemment pour le groupe `{groupe}` : `Colles-{groupe}.ics`
\n\nVous pouvez importer ces fichiers dans la plupart des calendriers, mais il est recommandé de créer un nouveau sous-calendrier pour facilement pouvoir le changer.
"""
else:
fichiers.append(discord.File(fp=BytesIO(cal_list[0]), filename=f"EDT-{groupe}-{langues.value}.ics"))
message = f"""
\nVotre emploi du temps (`EDT-{groupe}-{langues.value}.ics`) pour le groupe `{groupe}`, `{langues.name}` au format `.ics` a bien été généré, **avec les colles**
\n\nVous pouvez importer ces fichiers dans la plupart des calendriers, mais il est recommandé de créer un nouveau sous-calendrier pour facilement pouvoir le changer.
"""
await interaction.response.send_message(message, files=fichiers)
client.run(getenv("TOKEN")) client.run(getenv("TOKEN"))