schedule.py
convert data from university schedule to iCal
01:
02:
03: import datetime as dt
04: import requests as rq
05: from bs4 import BeautifulSoup
06: import uuid
07: import icalendar
08: UUID_NS=uuid.UUID('d7440a20-0018-4292-bb37-0a6ae62e61c3')
09:
10: API_URL =\
11:
12:
13: soup = BeautifulSoup(rq.get(API_URL).text,features='lxml')
14: def get_week_day(weeknum,weekday=0):
15: semester_start_year = 2023
16: first_sept = dt.datetime(semester_start_year,9,1)
17: first_week_monday = first_sept - dt.timedelta(days=first_sept.weekday())
18: return (first_week_monday + dt.timedelta(weeks=weeknum-1,days=weekday)).date()
19: day_of_week=-1
20: cal = icalendar.Calendar()
21: cal.add('prodid','-//USATU Schedule//NONSGML v1.0//RU')
22: cal.add('version','2.0')
23: for row in soup.tbody.find_all('tr'):
24: if 'dayheader' in row['class']:
25: day_of_week+=1
26: if 'noinfo' in row['class']:
27: continue
28: dow_name,time,weeks,subject,class_type,prof,lecture_hall,comments,*_=row.find_all('td')
29:
30: for week_str in weeks.get_text().split():
31: weeknum = int(week_str)
32: start_str,end_str = time.get_text().split('-')
33: day = get_week_day(weeknum,day_of_week)
34: start_time = dt.time.fromisoformat(start_str)
35: end_time = dt.time.fromisoformat(end_str)
36: start_dt = dt.datetime.combine(day,start_time)
37: end_dt = dt.datetime.combine(day,end_time)
38: lesson_evt = icalendar.Event()
39: subj_name = subject.get_text()
40: if not subj_name:
41: subj_name = class_type.get_text()
42:
43: summary = f"{subj_name} {class_type.get_text()} {lecture_hall.get_text()}"
44: lesson_evt.add('summary',summary)
45: lesson_evt.add('dtstart',start_dt)
46: lesson_evt.add('dtend',end_dt)
47: lesson_evt.add('uid',uuid.uuid3(UUID_NS,f"{subj_name} {start_dt}"))
48: cal.add_component(lesson_evt)
49:
50: with open('schedule.ics','wb') as f:
51: f.write(cal.to_ical())
52: print(cal.to_ical().decode('utf-8'))
53:
54:
55:
56: