Repository navigation
Releases: TFoxik/pyedookit
Releases · TFoxik/pyedookit
Release list
v0.7.0
Changes
get_grades()returns the current term'sGrades:gradesnewest first (mark, weight, category, topic, teacher, entered date, subject and code) andsubjectswith teacher and attendance.Grades.average(course_id)weights each grade by its weight; marks other than 1–5 are kept as text and left out.Grade.short/Subject.shortgive the subject abbreviation ("Aj").- The current term is chosen by its heading ("2. pololetí" over "1. pololetí"). A grades page whose rows can't be read raises
ParseErrorinstead of returning no grades. CAPTURE_PAGESgainsevaluation_overall, to catch the term report's markup once it is published.scripts/capture_fixtures.py --evaluationsaves the grades pages for building parsers.
v0.6.0
Changes
get_inbox()lists the messages in Schránka: subject, sender, sent time, preview and whether each is unread.get_message(id)returns one message in full; fetching it marks the message read on the portal. The body comes as a sanitised node tree (paragraphs, line breaks, bold, italics, underline, lists and http(s) links); scripts, styles, media and event handlers are dropped.- The inbox and message pages are fetched without the AJAX headers: to an AJAX request the portal answers with the inbox's first-run guide and its sample items instead of the real messages.
- A page answered with the sign-in page counts as an expired session, so the session is renewed.
Breaking changes
"inbox"is no longer inCAPTURE_PAGES, sofetch_page("inbox")raisesValueError. Useget_inbox().
v0.5.1
Changes
refresh()raisesAuthErroronly when Plus4U asks for a new login: an OIDClogin_required,interaction_required,consent_requiredoraccount_selection_requiredanswer, or a redirect to the Plus4U sign-in page. Any other renewal failure (Plus4U or portal errors, 429/5xx, a maintenance page, a rejected callback or a session that doesn't settle) raisesEdookitConnectionError, so callers retry instead of asking for the password.- Renewal errors name the HTTP status, host, path and OIDC error, never the code or state. A needed login is logged at warning level.
- README: the Plus4U sign-in cookie is set for 30 days from
login(), not about 19.
No breaking changes.
v0.5.0
Changes
Lesson.codeholds the subject abbreviation the portal shows (Čj, M, ČaS…).get_timetable_week(week_offset=0)returns aTimetableWeekwith the week's lessons and its bell schedule (Period(number, start, end)), from one page load.- A week whose page has a bell schedule but no lessons (holidays) comes back from
get_timetable_weekas an empty week instead of raisingParseError.get_timetableis unchanged.
No breaking changes.
v0.4.0
Breaking changes
Sessionis nowSession(school, cookies)and holds aCookieStore(session.cookies) instead of theedookit_cookies,plus4u_cookiesandcsrf_tokenfields. Build one withSession.from_cookies(school, edookit=…, plus4u=…).edookit_expires_atandis_edookit_expiredare gone;csrf_tokenis now a read-only property taken from theuu.app.csrfcookie.EdookitClientrenews an expired session by itself and retries once. Passon_session_updateto persist each renewed session.SessionExpirednow only surfaces when the session is still expired right after a renewal;AuthErrormeans the Plus4U sign-in expired andlogin()is needed.EdookitClient.sessionreturns a newSessionobject after each renewal, so don't hold on to it.- Any redirect from the portal on a page request (HTTP or the portal's JSON redirect, including the
/oidc/logoutone) now counts as an expired session. - Removed from
pyedookit.auth:build_headers,http_session,REQUEST_TIMEOUT,REDIRECT_STATUSESandCookiesByHost. HTTP now lives inpyedookit.transport.
Sessions stored by 0.3.x still load with Session.from_json(). Sessions written by 0.4.0 use a new JSON format that 0.3.x can't read, so downgrading after a renewal means signing in again.
Improvements
- One transport for every request: cookies rotated by the portal are kept, and cookies the server deletes (
Max-Age=0or a pastExpires) stop being sent. session.plus4u_expires_atshows when the Plus4U sign-in runs out, orNonewhen that's unknown. Plus4U doesn't send an expiry on a silent refresh, so it staysNonefor sessions carried over from 0.3.x until the nextlogin().- Sessions are renewed when the portal reports them expired, instead of on a fixed 30-minute timer. Against a real portal, an idle Edookit session lasted under 30 minutes: polling every 30 minutes gave 4 renewals in 2 hours, all successful.
v0.3.2
Fixes
- Expired sessions are detected correctly. For an expired session the portal answers with HTTP 200 and a JSON
{"redirect": ".../user/login"}instead of an HTTP redirect. pyedookit used to report that asParseError; it now raisesSessionExpired, so callers refresh and retry.
Security
Sessionvalidates the school subdomain when it's created, including inSession.from_json(). A tampered stored session can no longer send cookies to another host.- Every hop of the login and refresh flow must be https on
plus4u.netoredookit.net. repr(Session)no longer includes cookies or the CSRF token.- Minimum versions raised to
aiohttp>=3.14.3andlxml>=6.1.0, which include their security fixes.yarlis now a declared dependency.
Changes
- Pages are parsed in a worker thread, so a large timetable doesn't block the event loop.
EdookitClientwithout anhttpsession now uses the same cookieless session aslogin().- Removed the unused
Studentmodel. - Ships
py.typed. CI tests Python 3.12 and 3.14.