Last active
September 19, 2023 19:39
-
-
Save chuangzhu/f9b78ea3d7718fd96626e4dece2f1652 to your computer and use it in GitHub Desktop.
Convert DGUT courses table to iCalendar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# SPDX-License-Identifier: AGPL-3.0 | |
# Convert courses table from https://jw.dgut.edu.cn → 学生服务→ 网上选课→ 选课结果 to iCalendar | |
# Usage: copy the query result to a spreadsheet application, export it as CSV, then run: | |
# ./dgutcourses2ics.py 2023-09-04 < courses.csv > courses.ics | |
# ^ first monday of the semester | |
import csv | |
import sys | |
from datetime import datetime, date, time, timedelta | |
from textwrap import dedent | |
import uuid | |
import re | |
# https://jwdy.dgut.edu.cn/zxsj/ | |
SCHEDULE = [[time(8, 30), time(9, 15)], | |
[time(9, 25), time(10, 10)], | |
[time(0, 25), time(11, 10)], | |
[time(1, 15), time(12, 0)], | |
[time(4, 30), time(15, 15)], | |
[time(5, 25), time(16, 10)], | |
[time(6, 25), time(17, 10)], | |
[time(7, 20), time(18, 5)], | |
[time(9, 30), time(20, 15)], | |
[time(0, 25), time(21, 10)], | |
[time(1, 15), time(22, 0)]] | |
DAYS = '一二三四五六日' | |
mon1 = date.fromisoformat(sys.argv[1]) | |
reader = list(csv.reader(sys.stdin)) | |
print('BEGIN:VCALENDAR') | |
print('PRODID:-//Chuang Zhu//dgutcourses2ics.py//EN') | |
print('VERSION:2.0') | |
for i, row in enumerate(reader): | |
课程, 学分, 课程类别, 任课老师, 上课班号, 上课班级名称, 选课方式, 选课状态, 已选免听, 限选人数, 可选人数, 上课时间上课地点 = row | |
周次上课时间, 上课地点 = 上课时间上课地点.split() | |
周次, 上课时间 = 周次上课时间[1:].split(']', 1) | |
上课时间 = 上课时间.replace('[', '(').replace(']', ')') | |
# 课程, 学分, 总学时, 课程类别, 承担单位, 上课班号, 上课班组, 限选人数, 已选免听, 可选人数, 周次, 授课方式, 任课老师, 上课时间, 上课地点 = row | |
# if not 课程: | |
# 课程, 学分, 总学时, 课程类别, 承担单位, 上课班号, 上课班组, 限选人数, 已选免听, 可选人数 = reader[i-1][:10] | |
for recur in 周次.split(','): # 2,4-12 | |
m = re.match(r'周(\S)\((\d+)-(\d+)节\)', 上课时间) # 周五(1-2节) | |
weekday = DAYS.find(m.group(1)) | |
starttime = SCHEDULE[int(m.group(2)) - 1][0] | |
endtime = SCHEDULE[int(m.group(3)) - 1][1] | |
if '-' in recur: | |
startweek, endweek = map(int, recur.split('-')) | |
count = endweek - startweek + 1 | |
else: | |
startweek = int(recur) | |
count = 1 | |
startdate = mon1 + timedelta((startweek-1)*7+weekday) | |
start = datetime.combine(startdate, starttime) | |
end = datetime.combine(startdate, endtime) | |
description = '\\n'.join([f'课程: {课程}', | |
f'学分: {学分}', | |
# f'总学时: {总学时}', | |
f'课程类别: {课程类别}', | |
# f'承担单位: {承担单位}', | |
f'上课班号: {上课班号}', | |
# f'上课班组: {上课班组}', | |
f'限选人数: {限选人数}', | |
f'已选免听: {已选免听}', | |
f'可选人数: {可选人数}', | |
f'周次: {周次}', | |
# f'授课方式: {授课方式}', | |
f'任课老师: {任课老师}', | |
f'上课时间: {上课时间}', | |
f'上课地点: {上课地点}']) | |
event = f""" | |
BEGIN:VEVENT | |
DTSTAMP:{datetime.utcnow().strftime('%Y%m%dT%H%M%S')}Z | |
DTSTART;TZID=Asia/Shanghai:{start.strftime('%Y%m%dT%H%M%S')} | |
DTEND;TZID=Asia/Shanghai:{end.strftime('%Y%m%dT%H%M%S')} | |
UID:{uuid.uuid4()} | |
SUMMARY:{课程} | |
LOCATION:{上课地点} | |
RRULE:FREQ=WEEKLY;COUNT={count} | |
SEQUENCE:0 | |
DESCRIPTION:{description} | |
END:VEVENT | |
""" | |
print(dedent(event).strip()) | |
print('END:VCALENDAR') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment