diff --git a/timetabling/timetable-ics.py b/timetabling/timetable-ics.py index 224a5ff686f4dbc5e6d493994a155ba06798e5b8..a5e7592fe3b848e047a775918645b25b03e28c65 100644 --- a/timetabling/timetable-ics.py +++ b/timetabling/timetable-ics.py @@ -8,7 +8,7 @@ import sys from icalendar import Calendar, Event from datetime import datetime, timedelta -from typing import Dict, Generator, Set +from typing import Dict, Generator, Optional, Set TIMEZONE = "Europe/London" BASE_DATE = datetime(2024, 9, 23, 0, 0, 0, 0, pytz.timezone(TIMEZONE)) @@ -67,10 +67,13 @@ def get_day_offset(day : str) -> int: except ValueError: return -1 -def get_time(week : int, day_offset : int, start : str) -> datetime: - day = BASE_DATE + timedelta(days=7 * (week - 1) + day_offset) - hour = int(start.split(":")[0]) - return day + timedelta(hours=hour) +def get_time(week : int, day_offset : int, start : str) -> Optional[datetime]: + try: + day = BASE_DATE + timedelta(days=7 * (week - 1) + day_offset) + hour = int(start.split(":")[0]) + return day + timedelta(hours=hour) + except ValueError: + return None def get_end_time(start : datetime, duration : str) -> datetime: hours = int(duration.split(":")[0]) @@ -83,7 +86,12 @@ def iter_rows(ttfile : str) -> Generator[Dict[str, str], None, None]: for row in csv.DictReader(f): yield row else: # try any excel - df = pd.read_excel(ttfile, dtype=str, na_filter=False) + df = pd.read_excel( + ttfile, + dtype=str, + na_filter=False, + sheet_name="Activities 2025_26", + ) for row in df.to_dict(orient="records"): yield row @@ -105,7 +113,13 @@ for ttfile in timetable_files: elif "Start Time" in row: start = row["Start Time"] duration_hours = row["Duration"] - weeks = list(get_weeks(row["Teaching Week Pattern"])) + + try: + weeks = list(get_weeks(row["Teaching Week Pattern"])) + except ValueError: + mod_name = row["Module Name"] + print(f"Warning: ignore because bad weeks for {mod_name}") + continue location = "" if "PROVISIONAL Location Name" in row: @@ -131,6 +145,9 @@ for ttfile in timetable_files: print(f"Warning: ignoring day {day} of {row}") else: start_time = get_time(week, offset, start) + if start_time is None: + print(f"Warning: ignore because no time for {name}") + continue end_time = get_end_time(start_time, duration_hours) event = Event() event.add("summary", name) @@ -159,6 +176,10 @@ for ttfile in timetable_files: print(f"Warning: ignoring day {day} of {row}") else: start_time = get_time(weeks[0], offset, start) + if start_time is None: + print(f"Warning: ignore because no time for {name}") + continue + end_time = get_end_time(start_time, duration_hours) year_weeks = list(map(