# Calendar: `calendar.ical`, `calendar.google` ## `calendar.ical` Fetches and parses a public ICS feed. This is the calendar source actually in use (see `configs/dev.yml`'s `stanstorp`/`school_work` sources). ```yaml sources: school_work: source: calendar.ical params: url: https://cal.vklass.se/....ics ``` ### Params ```{eval-rst} .. autopydantic_model:: todays_paper_web.widgets.calendar.ical.ICalendarParams ``` ### Returns An `ICalendarModel` wrapping the parsed feed, with: - `.walk(name=None)` — delegates straight to `icalendar.Calendar.walk()`. `ical.walk('vevent')` iterates every `VEVENT` component as-is, **without** expanding recurring events (a weekly `RRULE` event appears once, at its original occurrence, however far in the past). - `.eventsOn(day)` / `.eventsBetween(start, end)` — use these instead when a screen needs "what's happening today/this week": they expand recurring events into their concrete occurrences within the given range via `recurring_ical_events`, and return them sorted by start time. ```xml+jinja {% for event in source("school_work").walk('vevent') %} {{ event.get('summary') }} {% endfor %} ``` ## `calendar.google` Reads events from a Google Calendar via the Calendar API. Requires a one-time local OAuth login before it will return anything. ### One-time setup 1. Create an OAuth client (Desktop app) in the Google Cloud Console for the Calendar API, and download its credentials as `google_client_secret.json` in the server's working directory. 2. Run `uv run python todays_paper_web/widgets/calendar/google-cli.py` once. It opens a browser login flow and writes `token.json` next to it, which is what `calendar.google` reads at runtime; the token is refreshed automatically as long as it stays valid. ### Params ```{eval-rst} .. autopydantic_model:: todays_paper_web.widgets.calendar.google.GoogleCalendarParams ``` ### Returns A list of raw event dicts as returned by the Google Calendar API's `events.list`, ordered by start time, with each event's `start.dateTime` parsed into a `datetime`. Returns `{}` if `token.json` doesn't exist yet (setup not done) or if the API call fails.