Skip to content

feat(calendar): 校历改用教务处页面的校历图片 - #77

Merged
fyc09 merged 2 commits into
yan-xiaoo:mainfrom
fyc09:feat/calendar-image
Sep 21, 2026
Merged

fyc09 merged 2 commits into
yan-xiaoo:mainfrom
fyc09:feat/calendar-image

Conversation

@fyc09

@fyc09 fyc09 commented Sep 20, 2026

Copy link
Copy Markdown
Collaborator

变更说明

修复 #74。one2020 的校历 JSON 接口目前固定返回 {"code": 200, "data": []},而客户端把 code == 200 当作成功,于是校历页面出现「提示查询成功,学期下拉与表格却是空的」。

实测确认(与代码完全相同的方式调用):

POST http://one2020.xjtu.edu.cn/EIP/schoolcalendar/terms.htm
→ HTTP 200  {"code":200,"msg":"success","data":[]}

教务处已改为在 https://dean.xjtu.edu.cn/xxfw/xl.htm 上以图片形式发布各学年校历(最新一学年即 https://dean.xjtu.edu.cn/2026-2027.jpg,951 KB / 4581×2056,全分辨率足够放大)。

修改内容

  • jwxt/calendar.py:解析页面上的 <a href="图片"><img></a>,产出 CalendarImage(year, url)。学年优先取锚点 title(如"2015-2016学年校历"),其次取图片文件名(如 2026-2027.jpg),其余按页面顺序推定 —— 页面按学年倒序排列:以已知学年作锚点,其后每张依次减一年,遇到下一个已知学年时重新对齐;开头的若干张若仍未知,再从后面第一个已知学年往前推。相对地址按页面地址补全,http:// 统一升级为 https。删除已失效的 CalendarTerm / CalendarHoliday / get_terms 及 JSON 接口封装。
  • app/SchoolCalendarInterface.py:改为校历图片查看器,不需要登录(教务处页面是公开的,不再经过 jwxt 会话登录、也不要求账号)。图片交互与图书馆可视化选座(VisualSeatView)保持一致:滚轮缩放、按住拖动平移、双击还原,没有额外的缩放按钮。
  • app/components/CampusPage.py:让 start_job(..., need_login=False) 真正可用。此前该参数没有任何调用方,而且走这条路径时没有账号会让结果被 _guarded 静默丢弃(死参数);同时把重复两份的守卫收成一个 _stale()

验证

  • 每个 bug 修复都新增或更新了可复现旧问题的回归测试。
  • 与已知 Issue 相关的程序错误已有明确的回归测试,并出现在 Actions 日志中。
  • 已运行相关本地测试,并在下方列出无法运行的测试或环境。
  • 合并前 PR Tests / CI Gate 已通过。
  • 平台相关行为已由现有矩阵覆盖,或已在下方解释额外验证范围。

测试证据

真实页面(校园网直连):解析出 14 张,全部得到学年且严格递减:

 1 2026-2027    2 2025-2026    3 2024-2025    4 2023-2024
 5 2022-2023    6 2021-2022    7 2020-2021    8 2019-2020
 9 2018-2019   10 2017-2018   11 2016-2017   12 2015-2016
13 2014-2015   14 2013-2014

页面 16 个图片锚点里只有 5 个自带学年,其余靠顺序推定。两个已知锚点(#2 2025-2026#12 2015-2016)之间的 9 张正好补成 2024-2025 … 2016-2017与两个锚点都吻合,可作为推定正确性的交叉验证。

无账号端到端accounts.current = None,真实网络):

success 回调正常触发(不再被守卫丢弃)
下拉框 14 项,首项 2026-2027 学年,末项 2013-2014 学年
视图内图片 4581x2056,缩放因子 0.2506(自动适配 1200x800 视口)

本地分片:ai 71 / qt-ui 121 / notification 28 / auth-session 67 / schedule 53 全部 OK,check_test_contract 通过(27 个产品测试模块),Existing bug regressions 137 项通过。

未运行的测试:test/ci/test_pr_workflow.py::test_gate_accepts_only_all_success 在本机失败(该用例用 subprocess.run(["bash", ...]) 执行 CI gate 脚本,本机是 Git-Bash 而非 ubuntu runner),已确认在干净 main 上同样失败。

校外访问

教务处站点在校外可以正常访问(已确认),因此不需要为公开抓取再补 WebVPN 路径;校历页也不再经过会话管理器。

Fixes yan-xiaoo#74

one2020 的校历 JSON 接口(/EIP/schoolcalendar/terms.htm)目前固定返回
{"code": 200, "data": []},而客户端把 code==200 当作成功,于是校历页面出现
“提示查询成功、学期下拉与表格却是空的”。教务处已改为在
https://dean.xjtu.edu.cn/xxfw/xl.htm 上以图片形式发布各学年校历。

- jwxt/calendar.py 改为解析页面上的 <a href="图片"><img></a>,产出
  CalendarImage(year, url)。学年优先取锚点 title(如“2015-2016学年校历”),
  其次取图片文件名(如 2026-2027.jpg);教务处没有标注学年的图片保留为
  year=None,不按顺序猜测。相对地址按页面地址补全,http:// 统一升级为 https。
  删除已失效的 CalendarTerm / CalendarHoliday / get_terms 及 JSON 接口封装。
- app/SchoolCalendarInterface.py 改为校历图片查看器:学年下拉框 +
  适应窗口 / 原始大小 / 缩小 / 放大 + 百分比,图片支持滚轮缩放与拖拽平移。
  没有解析到图片时给出警告,而不是“查询成功”。
- 测试:test_calendar_api.py 改为覆盖新的页面解析(用真实页面结构的内联
  fixture,覆盖 title 取学年、文件名取学年、未标注学年、相对地址补全、
  http→https、重复地址去重、无图锚点跳过、HTTP 错误传播);test_calendar_week.py
  随 CalendarTerm 一并删除;test_campus_pages.py 的校历用例改为覆盖图片选择器
  与“空数据不再报成功”。

缩放与平移刻意做成 QLabel 子类自身的事件处理,而不是给 ScrollArea 的 viewport
装 eventFilter:qfluentwidgets 的 ScrollArea 内部也有事件过滤器,两者叠加会让
进程直接崩溃且没有 Python 异常。

未覆盖:教务处页面有 10 张图片没有标注学年(页面纯文本里没有任何学年标题,
只能按 title/文件名取),这些图片在下拉框中显示为“未标注学年”;页面里还混有
一个非校历图片(upload.png)也会作为一个未标注学年的条目出现。
按 review 反馈调整:

- 教务处校历页面是公开的,去掉登录相关的部分:不再经过 jwxt 会话登录,也不再要求
  账号。为此让 CampusPage.start_job 的 need_login=False 真正可用(此前该分支没有
  账号时结果会被 _guarded 静默丢弃,所以是个死参数),并把重复的两份守卫收成一个
  _stale()。
- 页面按学年倒序排列各张校历,因此用已知学年作锚点按顺序补齐没有标注学年的图片:
  锚点之后每张依次减一年,遇到下一个已知学年时重新对齐;开头的若干张若仍未知,再从
  后面第一个已知学年往前推。实测真实页面 14 张全部得到学年(2026-2027 … 2013-2014,
  严格递减):两个已知锚点之间的 9 张正好补成 2024-2025…2016-2017,与两个锚点都
  吻合。此前被当成"非校历图片"的 upload.png 因此确认是 2024-2025 的真校历。
- 图片交互改为与图书馆可视化选座(VisualSeatView)完全一致:QGraphicsView +
  ScrollHandDrag 拖拽平移 + AnchorUnderMouse 滚轮缩放 + 双击还原,去掉全部缩放按钮
  与百分比标签。原实现手动改滚动条,所以拖动卡顿。
- 测试:新增学年推定的用例(锚点之间补齐、开头向前推、遇到已知学年重新对齐、严格
  递减、完全没有锚点时为未标注);校历页的自动加载用例单独拆出,并显式覆盖"没有
  账号也能自动加载"。
@fyc09
fyc09 marked this pull request as ready for review September 21, 2026 07:09
@fyc09
fyc09 merged commit 8706aab into yan-xiaoo:main Sep 21, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant