"""Google Calendar integration service.""" from datetime import datetime from typing import Optional from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from googleapiclient.discovery import build from sqlalchemy.orm import Session from app.core.config import settings from app.models.booking import Booking from app.models.google_calendar_token import GoogleCalendarToken def get_google_calendar_service(db: Session, user_id: int): """ Get authenticated Google Calendar service for user. Args: db: Database session user_id: User ID Returns: Google Calendar service object or None if not connected """ token_record = ( db.query(GoogleCalendarToken) .filter(GoogleCalendarToken.user_id == user_id) .first() ) if not token_record: return None # Create credentials creds = Credentials( token=token_record.access_token, refresh_token=token_record.refresh_token, token_uri="https://oauth2.googleapis.com/token", client_id=settings.google_client_id, client_secret=settings.google_client_secret, ) # Refresh if expired if creds.expired and creds.refresh_token: try: creds.refresh(Request()) # Update tokens in DB token_record.access_token = creds.token # type: ignore[assignment] if creds.expiry: token_record.token_expiry = creds.expiry # type: ignore[assignment] db.commit() except Exception as e: print(f"Failed to refresh Google token: {e}") return None # Build service try: service = build("calendar", "v3", credentials=creds) return service except Exception as e: print(f"Failed to build Google Calendar service: {e}") return None def create_calendar_event( db: Session, booking: Booking, user_id: int ) -> Optional[str]: """ Create Google Calendar event for booking. Args: db: Database session booking: Booking object user_id: User ID Returns: Google Calendar event ID or None if failed """ try: service = get_google_calendar_service(db, user_id) if not service: return None # Create event event = { "summary": f"{booking.space.name}: {booking.title}", "description": booking.description or "", "start": { "dateTime": booking.start_datetime.isoformat(), # type: ignore[union-attr] "timeZone": "UTC", }, "end": { "dateTime": booking.end_datetime.isoformat(), # type: ignore[union-attr] "timeZone": "UTC", }, } created_event = service.events().insert(calendarId="primary", body=event).execute() return created_event.get("id") except Exception as e: print(f"Failed to create Google Calendar event: {e}") return None def update_calendar_event( db: Session, booking: Booking, user_id: int, event_id: str ) -> bool: """ Update Google Calendar event for booking. Args: db: Database session booking: Booking object user_id: User ID event_id: Google Calendar event ID Returns: True if successful, False otherwise """ try: service = get_google_calendar_service(db, user_id) if not service: return False # Update event event = { "summary": f"{booking.space.name}: {booking.title}", "description": booking.description or "", "start": { "dateTime": booking.start_datetime.isoformat(), # type: ignore[union-attr] "timeZone": "UTC", }, "end": { "dateTime": booking.end_datetime.isoformat(), # type: ignore[union-attr] "timeZone": "UTC", }, } service.events().update( calendarId="primary", eventId=event_id, body=event ).execute() return True except Exception as e: print(f"Failed to update Google Calendar event: {e}") return False def delete_calendar_event(db: Session, event_id: str, user_id: int) -> bool: """ Delete Google Calendar event. Args: db: Database session event_id: Google Calendar event ID user_id: User ID Returns: True if successful, False otherwise """ try: service = get_google_calendar_service(db, user_id) if not service: return False service.events().delete(calendarId="primary", eventId=event_id).execute() return True except Exception as e: print(f"Failed to delete Google Calendar event: {e}") return False