mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-29 12:03:00 +00:00
* fix(web): list calendar endpoint works without a running plugin instance
The web service (ledmatrix-web) and display service (ledmatrix) run in
separate processes. The web process discovers plugins but never
instantiates them — only the display process does. Consequently
api_v3.plugin_manager.get_plugin('calendar') always returns None in the
web process, and /api/v3/plugins/calendar/list-calendars responded with
404 "Calendar plugin is not running. Enable it and save config first."
even when the plugin was enabled, saved, and authenticated.
Fall back to reading token.pickle + credentials.json directly from the
calendar plugin directory and calling the Google Calendar API from the
web process. A live plugin instance is still preferred when available
(e.g. local dev where web and display share a process).
Also surface clearer, actionable error messages for missing/expired
tokens so users know to re-run the authentication step.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(web): address review feedback on calendar list endpoint
- Remove unused creds_path local
- Prefer google-auth JSON token (token.json) via Credentials.from_authorized_user_file; keep pickle fallback for backward compat, guarded by a size check and a comment describing the trust boundary (owner-only file inside the plugin dir, not user-supplied input)
- Do NOT persist refreshed credentials from the web request path; the display service owns token.pickle and concurrent writes could corrupt it. Refresh happens in memory only for the duration of the request
- Add explicit timeouts to token refresh (via Request(timeout=...)) and to the Calendar API list call (num_retries=1), and return a retryable user-facing message on socket.timeout / TimeoutError
- Import socket at module scope
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(web): apply real socket timeout to Google Calendar API calls
googleapiclient's execute() does not accept a timeout kwarg — the
timeout comes from the httplib2.Http the service was built with.
Build an AuthorizedHttp wrapping httplib2.Http(timeout=15) so
calendarList().list().execute() cannot hang the Flask worker on
flaky connectivity. Disable discovery doc caching to avoid the
default file-cache warning in this ephemeral request path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: ChuckBuilds <ChuckBuilds@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>