106 lines
3.4 KiB
Python
106 lines
3.4 KiB
Python
"""
|
|
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() |