v0.1.0
Added
-
Session / Authentication (
tju.Session)- CAS SSO login at
sso.tju.edu.cnwith CAPTCHA solving viaddddocr - DES-encrypted password using embedded JavaScript (
tju.encrypt) - Automatic session renewal when EAMS redirects back to the login page
Session.logout()implementation- Context-manager support (
with Session() as s:)
- CAS SSO login at
-
Client (
tju.client.Client,tju.client.create_client)- Composable mixin architecture — one
Clientclass aggregates all feature mixins - Identity properties:
stu_id,stu_name,stu_type(UG/GS),has_minor,semester create_client()factory for one-line setup
- Composable mixin architecture — one
-
Student profile (
ProfileMixin.profile)- Scrapes the full EAMS personal-information page (~35 fields including enrollment dates,
supervisors, contact details, administrative class)
- Scrapes the full EAMS personal-information page (~35 fields including enrollment dates,
-
Personal timetable (
ScheduleMixin.schedule)- Fetches the EAMS course-table for a given semester
- Supports standard, class-level, and minor timetables
- Auto-detects graduate vs. undergraduate project
-
Public course library (
CourseMixin.query_courses)- Paginated query of the EAMS course catalogue
- Supports both undergraduate (project 1) and graduate (project 22) libraries
- Handles 12-column (GS) and 16-column (UG) HTML table formats automatically
-
Course detail & syllabus (
CourseMixin.query_course_info,query_syllabus)- Per-course metadata (semester, faculty)
- Syllabus HTML → Markdown conversion via
markdownify
-
Exam schedule (
ExamMixin.exam)- Full exam timetable including date, time range, location, and seat number
-
Academic scores (
ScoreMixin.score,ScoreMixin.exp_score)- Undergraduate and graduate score histories with per-semester summaries
- Experiment/lab course scores
-
Free classroom search (
ClassroomMixin.free_classrooms)- Queries available classrooms by date range, campus, building, room type, and seat count
- Supports both class-period (小节) and clock-time search modes
- Gracefully raises
DataErrorwhen the EAMS period schedule is unavailable
-
Typed data models (
tju.models)marshmallow-dataclassfrozen dataclasses for all returned entities- Chinese-keyed EAMS data transparently mapped to Python field names
-
Example scripts
examples/fetch_schedule.py— fetch personal timetable, print summary, save JSONexamples/fetch_all_courses.py— fetch full UG+GS course library (paginated), save JSON
-
Documentation
- Bilingual README (English
README.md+ ChineseREADME.zh-CN.md) AGENTS.md— architecture guide and contributor conventions- MkDocs + Material + mkdocstrings docs site (auto-generated from docstrings)
- Bilingual README (English
-
CI / release automation (GitHub Actions)
- CI workflow: runs pytest on Python 3.10 / 3.11 / 3.12
- Docs workflow: builds and deploys to GitHub Pages on every push to
main - Publish workflow: builds sdist + wheel and publishes to PyPI via OIDC trusted
publishing onv*tags; creates GitHub Release with changelog notes
Fixed
-
Course parser robustness
parse_courserebuilt with a dynamic column regex so the same function handles both
the older 16-column UG format and the newer 12-column GS format without hardcoding- Courses with no scheduled class slots (thesis supervision, online-only) no longer cause
HtmlParseError; theirarrangeis returned as an empty list
-
query_coursesproject-context bug- Fresh EAMS sessions default to project 1 (UG); querying the GS project (22) without
first setting the project context returnedAuthenticationException. A
COURSETABLE_INDEX_URL_PATHpre-flight request is now issued before every library query
- Fresh EAMS sessions default to project 1 (UG); querying the GS project (22) without
Changed
- Migrated project tooling from rye to uv (
[dependency-groups]inpyproject.toml) - Schema system refactored to use
LoadDumpSchemabase withpost_dumpkey restoration,
enabling clean Python-named serialised output from Chinese-keyed EAMS data