Export my schedule as an .ics file #30

Open
opened 2026-10-03 19:44:36 +00:00 by jalenluorion · 0 comments
Member

Goal
Many students live in Apple Calendar or Outlook. Add an "Export" button that downloads the current schedule as an .ics file they can import.

What you'll learn
Generating a file in a Flask route with the icalendar library, and downloading a file in the browser.

Resources

Where to start

  • api/app/api/schedule.py, get_schedule_route: already loads the caller's schedule (checking ownership), its orgs, and their occurrences. Add GET /api/schedule/export?schedule_id= next to it and reuse that query.
  • icalendar is already a dependency (api/pyproject.toml). api/app/services/ical.py uses it for importing.
  • Build a Calendar with one VEVENT per EventOccurrence (UID, DTSTART, DTEND, SUMMARY, LOCATION, DESCRIPTION). Return cal.to_ical() with mimetype="text/calendar" and Content-Disposition: attachment; filename="cmucal.ics".
  • web/src/app/components/ProfileSidebar.tsx or the schedule selector in Navbar.tsx: add the button.

Done when

  • Clicking Export downloads cmucal.ics for the selected schedule
  • Importing the file into Apple Calendar or Outlook shows the right events at the right local times
  • Another user's schedule_id returns 404
  • A pytest parses the response with icalendar.Calendar.from_ical and checks the event count
  • Works in light and dark mode

Notes
The API authenticates only with a bearer token, so a plain <a href> to the API will get a 401. Fetch the file with api.get(url, { responseType: "blob" }), make a URL with URL.createObjectURL, and click a temporary <a download>. Keep datetimes timezone-aware so the times do not shift.

**Goal** Many students live in Apple Calendar or Outlook. Add an "Export" button that downloads the current schedule as an `.ics` file they can import. **What you'll learn** Generating a file in a Flask route with the `icalendar` library, and downloading a file in the browser. **Resources** - [icalendar library usage](https://icalendar.readthedocs.io/en/latest/usage.html) - [Downloading a file with URL.createObjectURL](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL_static) **Where to start** - `api/app/api/schedule.py`, `get_schedule_route`: already loads the caller's schedule (checking ownership), its orgs, and their occurrences. Add `GET /api/schedule/export?schedule_id=` next to it and reuse that query. - `icalendar` is already a dependency (`api/pyproject.toml`). `api/app/services/ical.py` uses it for importing. - Build a `Calendar` with one `VEVENT` per `EventOccurrence` (`UID`, `DTSTART`, `DTEND`, `SUMMARY`, `LOCATION`, `DESCRIPTION`). Return `cal.to_ical()` with `mimetype="text/calendar"` and `Content-Disposition: attachment; filename="cmucal.ics"`. - `web/src/app/components/ProfileSidebar.tsx` or the schedule selector in `Navbar.tsx`: add the button. **Done when** - [ ] Clicking Export downloads `cmucal.ics` for the selected schedule - [ ] Importing the file into Apple Calendar or Outlook shows the right events at the right local times - [ ] Another user's `schedule_id` returns 404 - [ ] A pytest parses the response with `icalendar.Calendar.from_ical` and checks the event count - [ ] Works in light and dark mode **Notes** The API authenticates only with a bearer token, so a plain `<a href>` to the API will get a 401. Fetch the file with `api.get(url, { responseType: "blob" })`, make a URL with `URL.createObjectURL`, and click a temporary `<a download>`. Keep datetimes timezone-aware so the times do not shift.
jalenluorion added this to the Phase 2 milestone 2026-10-03 19:44:36 +00:00
jalenluorion added this to the CMUCal project 2026-10-03 19:45:09 +00:00
gsouto self-assigned this 2026-10-04 14:25:52 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ScottyLabs/cal#30
No description provided.