From 838be4d080d3d2f5484a26b7b36eea4183801fe7 Mon Sep 17 00:00:00 2001 From: Matthew Hague <matthew.hague@rhul.ac.uk> Date: Fri, 7 Jun 2024 10:33:20 +0100 Subject: [PATCH] add(timetable): Improve Bedford handling and read mulitple tt files --- timetabling/timetable-ics.py | 136 ++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 59 deletions(-) diff --git a/timetabling/timetable-ics.py b/timetabling/timetable-ics.py index edebaa1..604eb16 100644 --- a/timetabling/timetable-ics.py +++ b/timetabling/timetable-ics.py @@ -10,21 +10,22 @@ from datetime import datetime, timedelta from typing import Generator BASE_DATE = datetime(2024, 9, 23, 0, 0, 0, 0, pytz.timezone("Europe/London")) +BEDFORD = 100 # not a year if len(sys.argv) < 2: - print("Usage: timetable-ics.py timetable.csv") + print("Usage: timetable-ics.py timetable1.csv [timetable2.csv..]") -timetable_csv = sys.argv[1] +timetable_csvs = sys.argv[1:] -cals = { str(year): Calendar() for year in range(0, 6) } -cals.update({ "Bedford": Calendar() }) +cals = { year: Calendar() for year in range(0, 6) } +cals.update({ BEDFORD : Calendar() }) -def get_years(name : str) -> Generator[str, None, None]: +def get_years(name : str) -> Generator[int, None, None]: # remove CS2900 assessment weird names name = re.sub(r"<[^<]*>", "", name) for sess in name.split(","): year = int(sess.strip()[2]) - yield str(year) + yield year def get_weeks(weeks : str) -> Generator[int, None, None]: for period in weeks.split(","): @@ -61,59 +62,76 @@ def get_end_time(start : datetime, duration : str) -> datetime: hours = int(duration.split(":")[0]) return start + timedelta(hours=hours) - -with open(timetable_csv) as f: - for row in csv.DictReader(f): - day = None - start = None - name = row["Name"] - if "Suggested Days" in row: - day = row["Suggested Days"] - elif "Scheduled Days" in row: - day = row["Scheduled Days"] - elif "Day(s)" in row: - day = row["Day(s)"] - if "Suggested Time" in row: - start = row["Suggested Time"] - elif "Scheduled Start Time" in row: - start = row["Scheduled Start Time"] - elif "Start Time" in row: - start = row["Start Time"] - duration_hours = row["Duration"] - weeks = get_weeks(row["Teaching Week Pattern"]) - - location = "" - if "PROVISIONAL Location Name" in row: - location = row["PROVISIONAL Location Name"] - - if day is None: - print("Could not find timetabled day column, aborting") - exit() - - if start is None: - print("Could not find timetabled start time column, aborting") - exit() - - if "TUT" in name: - continue - - for week in weeks: - offset = get_day_offset(day) - if offset < 0: - print(f"Warning: ignoring day {day} of {row}") - else: - start_time = get_time(week, offset, start) - end_time = get_end_time(start_time, duration_hours) - event = Event() - event.name = name - event.begin = start_time - event.end = end_time - for year in get_years(name): - cals[year].events.add(event) - if "bedford" in location.lower(): - cals["Bedford"].events.add(event) +for csvfile in timetable_csvs: + with open(csvfile) as f: + for row in csv.DictReader(f): + day = None + start = None + name = row["Name"] + if "Suggested Days" in row: + day = row["Suggested Days"] + elif "Scheduled Days" in row: + day = row["Scheduled Days"] + elif "Day(s)" in row: + day = row["Day(s)"] + if "Suggested Time" in row: + start = row["Suggested Time"] + elif "Scheduled Start Time" in row: + start = row["Scheduled Start Time"] + elif "Start Time" in row: + start = row["Start Time"] + duration_hours = row["Duration"] + weeks = get_weeks(row["Teaching Week Pattern"]) + + location = "" + if "PROVISIONAL Location Name" in row: + location = row["PROVISIONAL Location Name"] + if "Required Location Name" in row: + location = row["PROVISIONAL Location Name"] + + if day is None: + print("Could not find timetabled day column, aborting") + exit() + + if start is None: + print("Could not find timetabled start time column, aborting") + exit() + + if "TUT" in name: + continue + + for week in weeks: + offset = get_day_offset(day) + if offset < 0: + print(f"Warning: ignoring day {day} of {row}") + else: + start_time = get_time(week, offset, start) + end_time = get_end_time(start_time, duration_hours) + event = Event() + event.name = name + event.begin = start_time + event.end = end_time + for year in get_years(name): + cals[year].events.add(event) + if "bedford" in location.lower(): + if "04-06" in location: + event.name = f"ALL {name}" + elif "04" in location: + event.name = f"4 {name}" + elif "05" in location: + event.name = f"5 {name}" + elif "06" in location: + event.name = f"6 {name}" + else: + event.name = f"? {name}" + + cals[BEDFORD].events.add(event) for year in cals: - with open(f"Year{year}.ics", 'w') as icsfile: - icsfile.writelines(cals[year].serialize_iter()) + if year != BEDFORD: + with open(f"Year{year}.ics", 'w') as icsfile: + icsfile.writelines(cals[year].serialize_iter()) + +with open(f"Bedford.ics", 'w') as icsfile: + icsfile.writelines(cals[BEDFORD].serialize_iter()) -- GitLab