From bcf2bda397d91d7ce0d5ca63db81925e727b6aa7 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Tue, 19 May 2026 20:46:23 -0400 Subject: feat(calendar-sync): add Python helper for Google Calendar API sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Google's .ics export drops per-occurrence response statuses on recurring events. When OOO auto-declines a meeting, the master event keeps PARTSTAT=ACCEPTED and declined instances inherit it. The .ics path can't filter the declines out. The API path expands recurrences server-side via singleEvents=True, and each occurrence carries its own attendees[].self.responseStatus. scripts/calendar_sync_api.py fetches events and renders them as org entries. OAuth is one-time per account. The refresh token lives at ~/.config/calendar-sync/token-.json under 0600. Output matches the existing .ics shape: heading sanitization, LOCATION/ORGANIZER/STATUS/URL property drawer, HTML-stripped descriptions, org timestamps with weekday abbreviations. I wrote 30 stdlib-unittest tests against fixture JSON, covering rendering, filtering, timestamp formatting, and HTML cleanup. I left auth and HTTP uncovered — they're thin wrappers around the Google client libraries, best checked by running the script once after OAuth setup. docs/calendar-sync-api-setup.org walks through the Google Cloud OAuth client setup and the per-account auth bootstrap. .gitignore picks up Python bytecode now that the project has a Python helper. The Elisp dispatch (:fetcher 'api routing in calendar-sync.el) lands in a follow-up commit. --- tests/fixtures/calendar-sync-api/all-day-single.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/fixtures/calendar-sync-api/all-day-single.json (limited to 'tests/fixtures/calendar-sync-api/all-day-single.json') diff --git a/tests/fixtures/calendar-sync-api/all-day-single.json b/tests/fixtures/calendar-sync-api/all-day-single.json new file mode 100644 index 000000000..99d2a2a2c --- /dev/null +++ b/tests/fixtures/calendar-sync-api/all-day-single.json @@ -0,0 +1,7 @@ +{ + "id": "2jn8q2k837d2v29alsvcfqljek_20260519", + "summary": "Home", + "start": {"date": "2026-05-19"}, + "end": {"date": "2026-05-20"}, + "status": "confirmed" +} -- cgit v1.2.3