diff --git a/reservations/tasks/sync_google_calendar.py b/reservations/tasks/sync_google_calendar.py index 6af498d..1281cf0 100644 --- a/reservations/tasks/sync_google_calendar.py +++ b/reservations/tasks/sync_google_calendar.py @@ -63,6 +63,45 @@ def insert_calendar_event(service, resource: Resource, reservation: Reservation) reservation.save() +def insert_or_update_calendar_event( + service, resource: Resource, reservation: Reservation +): + if not reservation.google_calendar_event_id: + logger.info( + "Event in database has no Google Calendar event ID: inserting | %s", + reservation.google_calendar_event_id, + ) + insert_calendar_event(service, resource, reservation) + + else: + # this event was in Google Calendar at some point (possibly for a different + # resource/calendar), but did not appear in list(). Try to update it, then + # fall back to insert + logger.info( + "Reservation with event id not in Google Calendar: trying update | %s", + reservation.google_calendar_event_id, + ) + try: + event = ( + service.events() + .get( + calendarId=resource.google_calendar, + eventId=reservation.google_calendar_event_id, + ) + .execute() + ) + update_calendar_event(service, resource, event, reservation) + except HttpError as error: + if error.status_code == HTTPStatus.NOT_FOUND: + logger.info( + "Event in database not in Google Calendar: inserting | %s", + reservation.google_calendar_event_id, + ) + insert_calendar_event(service, resource, reservation) + else: + raise + + def sync_resource_from_google_calendar( service, resource: Resource, now: datetime ) -> set[str]: @@ -129,54 +168,31 @@ def sync_resource_from_google_calendar( return {event["id"] for event in events} +def sync_reservation_from_database(service, reservation: Reservation): + for resource in reservation.resources.all(): + insert_or_update_calendar_event(service, resource, reservation) + + def sync_resource_from_database( service, resource: Resource, now: datetime, existing_event_ids: set[str] ): - reservations = resource.reservation_set.filter(end__gt=now).select_subclasses() + reservations = ( + resource.reservation_set.filter(end__gt=now) + # skip events we already pulled from Google Calendar during this sync + .exclude(google_calendar_event_id__in=existing_event_ids) + .select_subclasses() + ) # TODO: this could probably be more efficient? for reservation in reservations: - if not reservation.google_calendar_event_id: + if isinstance(reservation, ExternalReservation): logger.info( - "Event in database has no Google Calendar event ID: inserting | %s", + "External event in database did not exist in future of Google Calendar: deleting locally | %s", reservation.google_calendar_event_id, ) - insert_calendar_event(service, resource, reservation) + reservation.delete() - # reservation has an event id, so check if we already handled it earlier - elif reservation.google_calendar_event_id not in existing_event_ids: - if isinstance(reservation, ExternalReservation): - logger.info( - "External event in database did not exist in future of Google Calendar: deleting locally | %s", - reservation.google_calendar_event_id, - ) - reservation.delete() - else: - # this event was in Google Calendar at some point (possibly for a different - # resource/calendar), but did not appear in list(). Try to update it, then - # fall back to insert - logger.info( - "Reservation with event id not in Google Calendar: trying update | %s", - reservation.google_calendar_event_id, - ) - try: - event = ( - service.events() - .get( - calendarId=resource.google_calendar, - eventId=reservation.google_calendar_event_id, - ) - .execute() - ) - update_calendar_event(service, resource, event, reservation) - except HttpError as error: - if error.status_code == HTTPStatus.NOT_FOUND: - logger.info( - "Event in database not in Google Calendar: inserting | %s", - reservation.google_calendar_event_id, - ) - insert_calendar_event(service, resource, reservation) - else: - raise + else: + insert_or_update_calendar_event(service, resource, reservation) def sync_resource(service, resource: Resource, now: datetime):