Releases: tjuse/tju-python
Releases · tjuse/tju-python
Release list
v0.3.0
Changed
- TUI redesigned with a lazygit / nvim-inspired two-pane layout: bordered menu
and content panels, accent border that follows keyboard focus, the
tokyo-nighttheme, and vim-style navigation (j/k,Tab,r,g/G) - TUI profile view now shows every non-empty field (works for both
undergraduate and graduate records), and semester views (课表 / 考试安排 /
实验成绩) gained an inline semester input withEnter-to-refresh
Fixed
Profile.Schema().dump()(and therefore the TUI profile view and the MCP
get_profiletool) no longer crashes withAttributeErrorwhen a typed
field —stu_type,gender, a date, or exam-time — isNone(common for
graduate accounts whose 学生类别 value is not a recognised enum); these
fields now serialise to an empty value- TUI no longer raises
DuplicateIdswhen switching between menu items: content
is now swapped only after the previous widgets are fully removed - TUI course library view now reads the paged result correctly (it previously
iterated the result dict's keys instead of the course list) - TUI data tables are now built on the UI thread, fixing a
NoActiveAppError
that could occur when a worker thread constructed the widget - TUI startup no longer crashes on systems without an OS keyring backend;
auto-login is skipped and the user is warned that the password cannot be saved - Rapidly switching menu items no longer renders a stale result over a newer one
v0.2.0
Added
- Interactive full-screen TUI (
tjucommand,pip install 'tju[tui]'extra)
for browsing profile, schedule, courses, exams, scores and free classrooms - Local MCP server (
tju-mcpcommand,pip install 'tju[mcp]'extra) exposing
all read-only EAMS queries as MCP tools over stdio; compatible with Claude
Desktop, Claude Code, and any MCP host - Credentials stored securely: username in
~/.config/tju/config.toml,
password in the OS keyring (macOS Keychain / Windows Credential Manager /
Linux Secret Service) — password never written to disk in plaintext; shared
between the TUI and MCP server viatju.config - MCP server security model: password is a hard secret — no tool accepts or
returns it; profile PII (student ID, phone, address, email) masked by default;
masking controlled server-side (mcp_reveal_piiconfig flag), never by a
tool argument
v0.1.2
Changed
- Migrated repository to https://github.com/tjuse/tju-python
- Docs site moved to custom domain https://python.tjuse.com/
- CI badge switched to shields.io for reliable rendering on PyPI
- Chinese README link in PyPI description now uses absolute GitHub URL (fixes 404)
- Docs deployment no longer triggered on version tags (fixes GitHub Pages
environment protection rejection)
v0.1.1
Fixed
- Set
requires-python = ">= 3.11"—onnxruntime≥ 1.24 (pulled in byddddocr) no longer
ships cp310 wheels, so Python 3.10 was never actually supported - Updated classifiers to reflect supported versions (3.11 / 3.12 / 3.13) and CI matrix to match
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