SEQTA Link
Self-hosted SEQTA timetable sync. Extract lessons in the browser, keep them in SQLite, subscribe once to an ICS feed.
2026Active
- Calendar
- Self-hosted
- Python
Overview
SEQTA Link is a personal timetable bridge. A Tampermonkey userscript reads the SEQTA Learn timetable in the browser, a Flask app stores the lessons, and Apple or Google Calendar subscribe to a stable ICS feed. The subscription URL stays put after each sync.
The backend never sees a SEQTA password.
Problem
The timetable is fine in SEQTA and awkward everywhere else. Repeated exports create duplicates, cancelled lessons linger, and a partial week fetch should not wipe the rest of the term.
How it works
- The userscript pairs with a device token and posts lessons to
/api/v2. - Sync is idempotent: stable UIDs, natural keys, and deletes only when coverage is complete.
- Calendar clients hit an opaque
/calendar/sl_cal_….icsURL with ETag /304support. - A small Jinja portal covers login, devices, and feed rotation. Registration is invite-only.
Implementation
Python 3.11, Flask 3, SQLAlchemy 2, SQLite in WAL mode. Tests run under pytest. An older Node / Fastify / PostgreSQL stack is gone; v3 is this Flask app.
