Files
hermes-scripts-backup/skills/productivity/briefing-quotidien/scripts/agenda_all_calendars.py
T
2026-08-28 11:43:34 -04:00

130 lines
4.0 KiB
Python

#!/usr/bin/env python3
"""List today's events from ALL Google Calendars (not just primary).
Usage:
python3 agenda_all_calendars.py [YYYYMMDD] # default: today
Outputs JSON array of events with added 'calendar' field.
"""
import json
import os
import sys
from datetime import datetime, timedelta, timezone
from pathlib import Path
# ----------------------------------------------------------------
# Paths
# ----------------------------------------------------------------
HERMES_HOME = Path(os.environ.get("HERMES_HOME", os.path.expanduser("~/.hermes")))
TOKEN_PATH = HERMES_HOME / "google_token.json"
CLIENT_SECRET_PATH = HERMES_HOME / "google_client_secret.json"
SCOPES = [
"https://www.googleapis.com/auth/calendar",
"https://www.googleapis.com/auth/gmail.readonly",
"https://www.googleapis.com/auth/gmail.send",
"https://www.googleapis.com/auth/gmail.modify",
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/contacts.readonly",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/documents",
]
def get_credentials():
"""Load and refresh credentials."""
from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request
if not TOKEN_PATH.exists():
print("[]", file=sys.stderr)
sys.exit(1)
creds = Credentials.from_authorized_user_file(str(TOKEN_PATH), SCOPES)
if creds.expired and creds.refresh_token:
creds.refresh(Request())
# Save refreshed token
TOKEN_PATH.write_text(
json.dumps(
{**json.loads(creds.to_json()), "type": "authorized_user"},
indent=2,
)
)
return creds
def get_all_calendar_events(date_id_str=None):
"""
Discover all calendars and get today's events from each.
Returns list of events with 'calendar' field added.
"""
from googleapiclient.discovery import build
if not date_id_str:
date_id_str = datetime.now().strftime("%Y%m%d")
dt = datetime.strptime(date_id_str, "%Y%m%d")
# Use Toronto timezone
from zoneinfo import ZoneInfo
tz = ZoneInfo("America/Toronto")
# Start of day in Toronto time
start_dt = datetime(dt.year, dt.month, dt.day, tzinfo=tz)
end_dt = start_dt + timedelta(days=1)
time_min = start_dt.isoformat()
time_max = end_dt.isoformat()
creds = get_credentials()
service = build("calendar", "v3", credentials=creds)
# 1. Discover all calendars
cal_list = service.calendarList().list().execute()
calendars = cal_list.get("items", [])
all_events = []
for cal in calendars:
cal_id = cal["id"]
cal_name = cal.get("summary", cal_id)
cal_selected = cal.get("selected", True) # user has this calendar visible
if not cal_selected:
continue # skip hidden calendars
try:
result = service.events().list(
calendarId=cal_id,
timeMin=time_min,
timeMax=time_max,
singleEvents=True,
orderBy="startTime",
maxResults=50,
).execute()
except Exception:
continue # skip inaccessible calendars
for ev in result.get("items", []):
ev["calendar"] = cal_name # add calendar name
all_events.append({
"id": ev["id"],
"summary": ev.get("summary", "(no title)"),
"start": ev.get("start", {}).get("dateTime", ev.get("start", {}).get("date", "")),
"end": ev.get("end", {}).get("dateTime", ev.get("end", {}).get("date", "")),
"location": ev.get("location", ""),
"description": ev.get("description", ""),
"calendar": cal_name,
})
return all_events
def main():
date_id_str = sys.argv[1] if len(sys.argv) > 1 else None
events = get_all_calendar_events(date_id_str)
print(json.dumps(events, indent=2, ensure_ascii=False))
if __name__ == "__main__":
main()