Calendar Sync
Generate an importable .ics calendar from calendar-data.json for Google Calendar, Apple Calendar, or any CalDAV client, with ticket-drop alarms and itinerary events.
Three files:
calendar-data.jsonβ the structured source-of-truth (ticket drops, reservation windows, itinerary legs, dog-home-base windows). Edit this when dates/prices change. Mirrorsdestinations/calendar.md.make_ics.pyβ stdlib-only generator βtrip-calendar-2026-2027.ics.trip-calendar-2026-2027.icsβ the importable file.
How to get it on your phone
Option A β one-time import (editable, alarms work) β recommended
python3 make_ics.py- Desktop browser β calendar.google.com β Settings (β) β Import & export β Select file β pick
trip-calendar-2026-2027.icsβ choose or create a calendar (suggest a new βTravel Hubβ) β Import. - Imported alarms/reminders stay attached. Google auto-syncs to your phone app within minutes.
- When research updates (new dates), re-run the script and delete + re-import (or import into a fresh βTravel Hub 2028β calendar).
Option B β live subscription (read-only, auto-updates)
Host the .ics at a stable URL (GitHub raw, Gist, Dropbox public link), then Google Calendar β Add calendar β From URL β paste link. It re-fetches on its own schedule. Downside: you canβt edit events or rely on re-alarms from the phone side; use Option A for anything you must be notified about.
Option C β Google Calendar API (two-way, for automators)
Push via google-api-python-client with OAuth (creates/updates events programmatically). Only worth it if you want the write-back loop (buy a ticket β tick it off in Google β data stays clean). Not set up yet; ask if you want it β needs a GCP client_secret.json + scopes.
Data model cheat-sheet (calendar-data.json)
allDay: trueβDTSTART/DTEND;VALUE=DATE(date-only). JSONend= true last day.- For multi-day all-day events the script adds one day to DTEND (RFC all-day end is exclusive), e.g. Jan 6βJan 19 in JSON β DTEND 20270120.
minutes_beforeβ oneVALARMeach (Google keeps these on import).null= no alarm.- Multi-day all-day legs: JSON
endstores the true last day (e.g. Jan 19); the script emitsDTEND=end+1because RFC 5545 all-day DTEND is exclusive. tzidunused for allDay events; timed events are emitted UTC (DST-safe for AZ, close enough for NV/CO planning).
Keep in sync
calendar-data.json is the single source. Commit changes alongside destinations/calendar.md edits. Re-generate + re-import per trip season.