去年开始,各地教委开始要求各大高校加强信息化建设,重点着眼于信息安全的建设。于是一些学校将核心业务系统,包括教务管理、第二课堂等全部放在了内网。这也就意味着广域网无法直接访问教务系统,直接导致了一些课程表软件的「罢工」

对于我来说,上学期的课又多又杂,每周换一次教室的频率让我全部记住是不太可能的;遇到一些涉及单双周排课、调课的情况时,连某些「大学生必备」的课程表应用也不便处理。因此在一学期忙碌的生活后,我开始思考课程表的其它可能性,比如:

  • Sorted 3、看板工具等结合,管理碎片化的时间
  • 展示个性化的字段,如备注、课程序号等一些学校很常用却不常规的信息
  • 对于单次调课(如调休、老师临时有事等)可以轻松地通过修改单次事件来实现
  • 对于校外上课可以设定准确的开始与结束时间
  • 脱离平台与软件的限制,可将课程表融入所需的生态服务中

前几周我在少数派上看到一篇使用 Python 导入课程表的 文章,突然对这事有了进一步想法。下面分享一下我的做法。

注:本项目最初受 @陈某豪 的文章《又到了每年此刻,教你把课程表导入日历》启发。原文的程序使用 Python 2.7 编写,现在在 Python 3 上已不能很好运行,部分模块参考了作者的思路重写了 Python 3 的版本。整个项目开源在 GitHub 上,遵循 GPLv3 协议。

效果展示

因为实际操作流程略为复杂,这里我先向感兴趣的同学展示一下实际使用效果,大家可以根据需求酌情选择是否采用本文介绍的工具和方法 。

在完成所有工作并成功导入系统后,日历看起来是这个样子的:

具体到用法,这样的一份课程表日历可以进一步满足以下两种需求:

结合其他工具管理任务

导入课程表后,在 Sorted 3 中即可看见一天的课程占用时间;由于是以日程的形式存在,在该软件中自动将这个日程锁住,不可移动。

在将一天的事情一一放入后,只需要使用「自动计划」即可最大化利用时间,不需要繁琐地纠结剩余的时间是否足够做完一件事。

同样地,由于我们制作的课程表直接导入系统日历,在 Fantastical、滴答清单等工具里也可以联动,进行忙碌 / 空闲的快速查看与管理。

单次调课

面对老师临时咕咕咕,「日历」里的课程表可以很方便地通过编辑单次重复事件完成处理与备忘。对于未来的某次调课,只需要找到需要调整的课程,编辑好时间,并在保存时选择「仅针对此日程存储」即可。

对课程进行备注也是类似的做法,对于不同范围的备注也可以通过选择「仅针对此次存储」与「针对将来日程存储」来区别。

主要思路

这套教程的主要思路是将教务系统中的课程抽象处理后填写到统一的 Excel 模板中,然后再使用 Python 转换成 iCalendar 格式的文件,即可用于导入 iOS、macOS、Outlook 或其他支持该格式的软件当中。

这样一来上下课时间、每日节数、提醒时间等可自定义,还支持单双周排课,这是我之前在寻找替代方案时较少 App 实现的部分。

制作流程

环境准备

先从 GitHub 上拉取程序:

git clone https://github.com/SunsetYe66/ClasstableToIcal.git

在确保本机有 Python 3 环境后先安装依赖:

pip install uuid xlrd

文件配置

在将文件克隆到本地后,目录应该有以下文件。其中 ​conf_classTime.json​、​temp_classInfo.xlsx​ 是需要手动配置的。

具体而言,时间设置​ conf_classTime.json​ 中的内容应该是这样的格式:

"1": {    "name": "第 1、2 节",    "startTime": "082000",    "endTime": "095500"}

这是一种名为 JSON 的数据格式,在本次的工具中选用的原因是它可以直接打包为 Python 中的 ​dict()​ 对象。

其中,各个属性的作用为:

  • ​"1"​:时间段代号,在录入时用于标识课程的节数
  • ​"name"​:时间段名称,主要是在修改 JSON 文件时做备忘用,在主程序中没有调用
  • ​"startTime"​:该时间段开始时间,遵循 ​HHmmss​ (时时分分秒秒,「时」一定是 24 小时制)
  • "endTime"​:该时段结束时间,同上


你可以自由修改该文件的内容,但请注意,JSON 文件中不能加入注释;格式需要与原先的内容一致。你可以使用 JSON 合法性校验工具 来检查新文件在语法上是否有错误。

而用于录入课程的 ​temp_classInfo.xlsx​ 则需要复制一份,改名为 ​classInfo.xlsx​,打开模板文件后可看到如下字段:

其中,各个字段的含义为:

  • className - 课程名称
  • startWeek - 开始周数
  • endWeek - 结束周数
  • weekday - 课程日期(周几)
  • classTime - ​conf_classTime.json​ 中定义的时间段代号
  • classroom - 教室
  • weekStatus - 是否单双周排课:正常排课 = 0,单周排课 = 1,双周排课 = 2
  • classSerial - 可选,课程序号
  • classTeacher - 可选,教师名

最后两个可选字段如果不需要可以关闭,只需在 ​excel_reader.py​ 中的 27 和 28 行将:

self.config["isClassSerialEnabled"] = [1, 7]self.config["isClassTeacherEnabled"] = [1, 8]

后方的方框中,要关闭的功能的 1 改成 0 即可(即 [0, 7] 或 ​[0, 8]​)。

注意:若课程有不同排课方式或一周有多节课,需要分多条记录录入。

生成文件

打开命令提示符或终端,定位到该项目根目录下。

然后执行 ​main.py​:

python main.py

首先选 2 进入课程信息读取工具:若未修改过 Excel 文件结构,直接回车即可;若提示成功,文件夹中将多出一个新的 JSON 文件。

此时,再输入 3 进入 iCal 生成工具,按提示输入必需信息后即可生成最终文件。请注意此处输入的日期必须严格按照提示输入开学第一周周一的日期,且该日期的格式是 ​YYYYMMDD​,即 年年年年月月日日,中间不加符号。

周数生成器

为了更方便查看课程表,本项目还附带一个「周数指示器」生成器。只需要在运行 ​main.py​ 选择 1 即可进入。

请注意,与之前必须输入第一周周一的逻辑不同,若以第一周的工作日为 2020.3.2-3.6 为例,该处输入日期的逻辑为:

  • 若你的习惯是将周一当作一周的第一天,则输入第一周周一的日期,即 20200302
  • 若你的习惯是将周日当作一周的第一天,请输入周一前的那个周日的日期,即20200301

导入设备

你可能注意到,在课程表成功生成后,底部会有一个导入提示。这是利用了 Python 自带的 simpleHTTP 组件进行 iCal 文件的传输。

具体步骤如下:

  1. 确认电脑和 iOS 设备处在同一个 WiFi 下,且 WiFi 没有开启客户端隔离(家用环境下默认关闭,公共 WiFi 可能开启)
  2. 在刚刚生成课程表文件的目录下打开终端,输入 ​python -m http.server 8000​ 搭建 HTTP 服务器
  3. 在 iOS 设备上打开文件生成成功时给出的地址(上图为 ​​http://192.168.3.94:8000/​​)
  4. 在设备上点击给出的文件名,选择导入日历(上图为 ​res-979.ics​)

注:在右图中选择日历时,建议选择左下角的「添加日历」,新建一个课程表专用的日历,并选择不同的颜色易于区分;这么做也可以让课程需要整体修改时可以直接删除整个日历后再导入,更加方便。

至此日历便导入成功了。

小结

受疫情影响,此前各个学校都未转入线下学习阶段,而全部使用网课的教学模式对学生的任务管理能力却是一个全新的挑战:少了舍友、传统上下课的学习环境,全部自己安排的时间可能就变成了「签到大挑战」。恰逢最近不少地区陆续宣布开学,希望本项目可以对尝试时间管理/日程管理的小伙伴有所帮助。

本项目在以下环境中测试通过:

  • Python 3.7.2,Windows 10 x64
  • Python 3.8.1,Manjaro 18

本项目将会在(我用到或是收到反馈时)持续更新,你可以通过作者签名档中的邮箱或是 GitHub Issues 联系到我。若未来程序用法发生改变,将在 GitHub 主页中进行更新。

如 GitHub 访问困难,也可点击 这里 查看该项目。

> 下载少数派 客户端、关注 少数派公众号 ,了解更多有趣的应用 🚀