From 78675c72c2a11599b557eef01c354821f2ebcfd9 Mon Sep 17 00:00:00 2001 From: joseph Date: Sat, 30 Mar 2024 15:14:22 +0100 Subject: [PATCH] =?UTF-8?q?ajout=20d'un=20d=C3=A9tecteur=20de=20collisions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- check_collisions.py | 106 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 check_collisions.py diff --git a/check_collisions.py b/check_collisions.py new file mode 100644 index 0000000..ae8245c --- /dev/null +++ b/check_collisions.py @@ -0,0 +1,106 @@ +""" + 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() \ No newline at end of file