""" Objectif: déterminer les collisions dans un fichier .ics généré, afin de pouvoir 'valider' un colloscope. Pour cela, ce programme génère les colloscopes associés à chaque groupe de colle puis regarde s'il y a collision entre les évènements en faisant partie. """ from typing import List from attr import dataclass import icalendar import datetime from dateutil import rrule # https://dateutil.readthedocs.io/en/stable/rrule.html import recurring_ical_events from io import BytesIO import create_calendar @dataclass class DatesEvent: nom: str start: datetime.date end: datetime.date def recurring_events_to_events(cal: icalendar.Calendar) -> DatesEvent: at_date = 2024 events = recurring_ical_events.of(cal).at(at_date) return events def ical_to_dates(events: List[icalendar.Event]) -> DatesEvent: """ Renvoie la liste de dates et de durées de l'ensemble des évènements (SANS EVENEMENTS RECURSIFS, ecurring_events_to_events s'en étant déjà occupé !) """ output = [] for event in events: if not event.get("RRULE"): new_event = DatesEvent( nom=str(event.get("SUMMARY")) + " - " + str(event.get("DESCRIPTION")), start=event.get("DTSTART").dt, end=event.get("DTEND").dt ) output.append(new_event) return output def check_dates_collision(start1: datetime.date, start2: datetime.date, end1: datetime.timedelta, end2: datetime.timedelta): if start1 <= start2: if start2 < end1: return True elif start1 <= start2: # cas où dt1 commence après dt2 mais avant dt2+td2 if end2 > end2: return True return False def check_collisions(dates: DatesEvent): """ Fonction qui réalise réellement le check. Itère brutalement sur toutes les dates, par souci d'efficacité d'écriture de code, et surtout parce que ça marche ! """ for date_event1 in dates: for date_event2 in dates: if date_event1.nom != date_event2.nom: if check_dates_collision(date_event1.start, date_event2.start, date_event1.end, date_event2.end): print( f""" ---- Colision entre {date_event1.nom} et {date_event2.nom} {date_event1.nom}: {date_event1.start.strftime('%d-%m-%Y: %H:%M')} à {date_event1.end.strftime('%d-%m-%Y: %H:%M')} {date_event2.nom}: {date_event2.start.strftime('%d-%m-%Y: %H:%M')} à {date_event2.end.strftime('%d-%m-%Y: %H:%M')}""") def generate_calendars(): for groupe in range(1, 16): print( f""" ┌────────────────────────── │ │ GROUPE {groupe} """ ) generated_ical = create_calendar.get_calendar(str(groupe), "EN")[0] generated_ical = icalendar.Calendar.from_ical(generated_ical) events = list(generated_ical.walk("VEVENT")) events += recurring_events_to_events(generated_ical) check_collisions(ical_to_dates(events)) print( f""" │ └────────────────────────── """ ) generate_calendars()