import pandas import datetime import icalendar import uuid from pathlib import Path pd_eleves = pandas.read_csv('Resources/eleves.csv') np_eleves = pd_eleves.to_numpy() pd_colles = pandas.read_csv('Resources/colles.csv') np_colles = pd_colles.to_numpy() local_tz = "Europe/Paris" jour_to_delta = { "lundi": 0, "mardi": 1, "mercredi": 2, "jeudi": 3, "vendredi": 4, } langues = ["Anglais", "Allemand", "Espagnol"] option_langues = { "EN": ["Anglais LV1"], "EN-DE": ["Anglais LV1", "Allemand LV2"], "EN-ES": ["Anglais LV1", "Espagnol LV2"], "DE-EN": ["Allemand LV1", "Anglais LV2"], "ES-EN": ["Espangol LV1", "Anglais LV2"] } def display(cal): 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(): """ Renvoie la liste des eleves avec leur groupe associés à leur groupe, a utiliser dans la /cmd """ liste = {} for row in np_eleves[1:]: liste[f"{row[0]} {row[1]} - {row[2]}"] = row[2] return liste def debut_semaine_to_datetime(date_string: str) -> datetime.time: """ Transforme un string de debut de semaine au format dd/mm/yyyy en datetime.time """ return datetime.datetime.strptime(date_string, "%d/%m/%y") def get_colles_groupe(np_colles, groupe, option_langue): """ Renvoie les colles pour un groupe sous la forme d'une liste d'évènements ICS np_colles: l'array 2D numpy contenant le colloscope groupe: str, le numéro du groupe option_langue: str, les options de langue """ liste_colles = [] for row in np_colles[1:]: if pandas.isnull(row[0]) or row[0] == "pas de colle": # il n'y a pas de colle, on skip ! continue # Si la colle n'est pas la LV1 de l'élève, on skip if row[0] == "Anglais" and not option_langue.startswith("EN"): continue elif row[0] == "Allemand" and not option_langue.startswith("DE"): continue elif row[0] == "Espagnol" and not option_langue.startswith("ES"): continue for index, colle in enumerate(row[5:]): # les quatre premières cases ne sont pas if pandas.isnull(colle) or colle != groupe: continue new_colle = icalendar.Event() new_colle.add("summary", f"Colle {row[0]}") 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 += datetime.timedelta(days=jour_to_delta[row[1]]) date += datetime.timedelta(hours=int(row[2][:-1])) new_colle.add("dtstart", date, parameters={"tzid": local_tz}) date += datetime.timedelta(hours=1) new_colle.add("dtend", date, parameters={"tzid": local_tz}) liste_colles.append(new_colle) return liste_colles def get_cours_SI(np_colles, groupe): """ Renvoie les colles pour un groupe sous la forme d'une liste d'évènements ICS, cad icalendar.Event np_colles: l'array 2D numpy contenant le colloscope groupe: str, le numéro du groupe """ liste_cours = [] for index, cell in enumerate(np_colles[-1][5:]): heure = 17 groupes = cell.split("§") if groupe in groupes or f"\n{groupe}" in groupes: heure = 16 cours_si = icalendar.Event() cours_si.add("summary", "TD SI") 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 += datetime.timedelta(days=jour_to_delta["mardi"]) date += datetime.timedelta(hours=heure) cours_si.add("dtstart", date, parameters={"tzid": local_tz}) date += datetime.timedelta(hours=1) cours_si.add("dtend", date, parameters={"tzid": local_tz}) liste_cours.append(cours_si) return liste_cours def get_langues(langues): """ Renvoie la liste de cours de langue associés list[icalendar.Event] """ liste_langues = [] p = Path(__file__).with_name('Resources') p = Path(p, f"EDT_Langues.ics") with p.open('r') as f: opened_cal = icalendar.Calendar.from_ical(f.read()) for event in opened_cal.walk("vevent"): if event.get("summary") in option_langues[langues]: liste_langues.append(event) return liste_langues def get_calendar(groupe, langues, split: bool = False): """" Renvoie un calendrier (icalendar.Calendar) pour un groupe avec des langues donné """ moitie = None for row in np_eleves[1:]: if row[2] == int(groupe): moitie = row[3] break new_cal_edt = open_ics("Base_Calendar.ics") if split: new_cal_colles = open_ics("Base_Calendar.ics") new_cal_edt = add_events_from_ics(filename="EDT_Base.ics", new_cal=new_cal_edt) new_cal_edt = add_events_from_ics(filename=f"EDT_{moitie}.ics", new_cal=new_cal_edt) for event in get_langues(langues): new_cal_edt.add_component(event) for event in get_cours_SI(np_colles, groupe): new_cal_edt.add_component(event) if split: 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() else: for event in get_colles_groupe(np_colles, groupe, langues): new_cal_edt.add_component(event) return [new_cal_edt.to_ical()]