From f2da15784bc93afd718af2fdb1c6d46eb9dca9d9 Mon Sep 17 00:00:00 2001 From: Guido Schmit Date: Wed, 8 Apr 2026 21:49:24 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20Wochenkalender-Filter=20und=20per-Kalend?= =?UTF-8?q?er=20Fehlerbehandlung=20Der=20Wochenkalender=20von=20Google=20h?= =?UTF-8?q?at=20locale-spezifische=20IDs=20(z.B.=20de.german#weeknum@...)?= =?UTF-8?q?=20die=20nicht=20im=20alten=20exakten=20Set-Filter=20gefangen?= =?UTF-8?q?=20wurden.=20Dadurch=20wurde=20er=20in=20die=20DB=20gespeichert?= =?UTF-8?q?=20und=20verursachte=20beim=20Event-Abruf=20einen=20API-Fehler.?= =?UTF-8?q?=20Da=20der=20try/except=20die=20gesamte=20Kalender-Schleife=20?= =?UTF-8?q?umschloss,=20wurden=20bei=20einem=20einzigen=20fehlerhaften=20K?= =?UTF-8?q?alender=20alle=20anderen=20Events=20ebenfalls=20verloren=20?= =?UTF-8?q?=E2=80=94=20Ursache=20f=C3=BCr=20keine=20Termine=20trotz=20korr?= =?UTF-8?q?ektem=20Token.=20-=20=5Fis=5Fsystem=5Fcalendar():=20pr=C3=BCft?= =?UTF-8?q?=20jetzt=20auch=20'weeknum'=20als=20Substring=20-=20=5Fsync=5Fg?= =?UTF-8?q?oogle=5Fcalendars():=20bereinigt=20bereits=20gespeicherte=20Sys?= =?UTF-8?q?tem-Kalender=20-=20get=5Fgoogle=5Fevents():=20try/except=20ist?= =?UTF-8?q?=20jetzt=20pro=20Kalender,=20nicht=20global?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/routers/google_router.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/backend/routers/google_router.py b/backend/routers/google_router.py index 0a1c443..dbcf9c8 100644 --- a/backend/routers/google_router.py +++ b/backend/routers/google_router.py @@ -32,6 +32,11 @@ SKIP_GOOGLE_CALENDAR_IDS = { } +def _is_system_calendar(cal_id: str) -> bool: + """Return True for virtual/system calendars that should be hidden.""" + return cal_id in SKIP_GOOGLE_CALENDAR_IDS or "weeknum" in cal_id.lower() + + def _google_configured() -> bool: return bool(GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET) @@ -139,7 +144,7 @@ def _account_dict(a: models.GoogleAccount) -> dict: "sidebar_hidden": bool(c.sidebar_hidden), } for c in a.calendars - if c.cal_id not in SKIP_GOOGLE_CALENDAR_IDS + if not _is_system_calendar(c.cal_id) ], } @@ -149,12 +154,16 @@ def _sync_google_calendars(account: models.GoogleAccount, db: Session): try: token = _refresh_access_token(account, db) cal_list = _google_api(token, "/users/me/calendarList") - existing = {c.cal_id: c for c in account.calendars} + # Remove any previously stored system calendars (e.g. locale-specific weeknum variants) + for c in list(account.calendars): + if _is_system_calendar(c.cal_id): + db.delete(c) + existing = {c.cal_id: c for c in account.calendars if not _is_system_calendar(c.cal_id)} for cal in cal_list.get("items", []): if cal.get("deleted"): continue cal_id = cal["id"] - if cal_id in SKIP_GOOGLE_CALENDAR_IDS: + if _is_system_calendar(cal_id): continue if cal_id not in existing: db.add(models.GoogleCalendar( @@ -378,12 +387,12 @@ def get_google_events(account: models.GoogleAccount, start_dt: datetime, end_dt: raise all_events = [] - try: - for gcal in account.calendars: - if not gcal.enabled: - continue - if gcal.cal_id in SKIP_GOOGLE_CALENDAR_IDS: - continue + for gcal in account.calendars: + if not gcal.enabled: + continue + if _is_system_calendar(gcal.cal_id): + continue + try: events_resp = _google_api(token, f"/calendars/{gcal.cal_id}/events", params={ "timeMin": start_dt.isoformat(), "timeMax": end_dt.isoformat(), @@ -394,8 +403,8 @@ def get_google_events(account: models.GoogleAccount, start_dt: datetime, end_dt: if ev.get("status") == "cancelled": continue all_events.append(_parse_google_event(ev, gcal.id, gcal.name, gcal.color or "#4285f4")) - except Exception as exc: - logger.error("Error fetching Google Calendar for %s: %s", account.email, exc) + except Exception as exc: + logger.error("Error fetching events for calendar %s (%s): %s", gcal.name, gcal.cal_id, exc) return all_events