Skip to content
Snippets Groups Projects
Commit 6aea3796 authored by Hague Matthew UXAC009's avatar Hague Matthew UXAC009
Browse files

add(timetabling): script for turning timetabling s/s to ics

parent c21b115b
Branches
No related tags found
No related merge requests found
# Timetabling Scripts
* `timetable-ics.py` -- convert the Timetabling team spreadsheets into ICS format. This is a rough and ready script and will probably need tweaks to your particular spreadsheet.
import csv
import re
import sys
from ics import Calendar, Event
from datetime import datetime, timedelta
from typing import Generator
BASE_DATE = datetime(2023, 9, 18)
if len(sys.argv) < 2:
print("Usage: timetable-ics.py timetable.csv")
timetable_csv = sys.argv[1]
cals = { year: Calendar() for year in range(0, 6) }
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 year
def get_weeks(weeks : str) -> Generator[int, None, None]:
for period in weeks.split(","):
bounds = period.strip().split("-")
if len(bounds) == 1:
yield int(bounds[0])
elif len(bounds) == 2:
for week in range(int(bounds[0]), int(bounds[1]) + 1):
yield week
else:
raise ValueError("Unknown weeks pattern {period}")
def get_day_offset(day : str) -> int:
# assume if multiple days then first is "strike out"
days = day.split()
if len(days) > 0:
day = days[-1]
else:
return -1
try:
return [
"monday", "tuesday", "wednesday", "thursday", "friday"
].index(day.lower())
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_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):
name = row["Name"]
day = row["Suggested Days"]
start = row["Suggested Time"]
duration_hours = row["Duration"]
weeks = get_weeks(row["Teaching Week Pattern"])
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)
for year in cals:
with open(f"Year{year}.ics", 'w') as icsfile:
icsfile.writelines(cals[year].serialize_iter())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment