mirror of
https://github.com/MODSetter/SurfSense.git
synced 2025-09-01 10:09:08 +00:00
get all primary calendar event by default
This commit is contained in:
parent
1c9f857d00
commit
44d2338663
1 changed files with 261 additions and 0 deletions
261
surfsense_backend/app/connectors/google_calendar_connector.py
Normal file
261
surfsense_backend/app/connectors/google_calendar_connector.py
Normal file
|
@ -0,0 +1,261 @@
|
|||
"""
|
||||
Google Calendar Connector Module | Google OAuth Credentials | Google Calendar API
|
||||
|
||||
A module for retrieving calendar events from Google Calendar using Google OAuth credentials.
|
||||
Allows fetching events from specified calendars within date ranges using Google OAuth credentials.
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from google.auth.transport.requests import Request
|
||||
from google.oauth2.credentials import Credentials
|
||||
from googleapiclient.discovery import build
|
||||
|
||||
|
||||
class GoogleCalendarConnector:
|
||||
"""Class for retrieving data from Google Calendar using Google OAuth credentials."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
credentials: Credentials,
|
||||
):
|
||||
"""
|
||||
Initialize the GoogleCalendarConnector class.
|
||||
|
||||
Args:
|
||||
credentials: Google OAuth Credentials object
|
||||
"""
|
||||
self._credentials = credentials
|
||||
self.service = None
|
||||
|
||||
def _get_credentials(self) -> Credentials:
|
||||
"""
|
||||
Get valid Google OAuth credentials.
|
||||
|
||||
Returns:
|
||||
Google OAuth credentials
|
||||
|
||||
Raises:
|
||||
ValueError: If credentials have not been set
|
||||
Exception: If credential refresh fails
|
||||
"""
|
||||
if not all(
|
||||
[
|
||||
self._credentials.client_id,
|
||||
self._credentials.client_secret,
|
||||
self._credentials.refresh_token,
|
||||
]
|
||||
):
|
||||
raise ValueError(
|
||||
"Google OAuth credentials (client_id, client_secret, refresh_token) must be set"
|
||||
)
|
||||
|
||||
if self._credentials and not self._credentials.expired:
|
||||
return self._credentials
|
||||
|
||||
# Create credentials from refresh token
|
||||
self._credentials = Credentials(
|
||||
token=self._credentials.token,
|
||||
refresh_token=self._credentials.refresh_token,
|
||||
token_uri=self._credentials.token_uri,
|
||||
client_id=self._credentials.client_id,
|
||||
client_secret=self._credentials.client_secret,
|
||||
scopes=self._credentials.scopes,
|
||||
)
|
||||
|
||||
# Refresh the token if needed
|
||||
if self._credentials.expired or not self._credentials.valid:
|
||||
try:
|
||||
self._credentials.refresh(Request())
|
||||
except Exception as e:
|
||||
raise Exception(
|
||||
f"Failed to refresh Google OAuth credentials: {e!s}"
|
||||
) from e
|
||||
|
||||
return self._credentials
|
||||
|
||||
def _get_service(self):
|
||||
"""
|
||||
Get the Google Calendar service instance using Google OAuth credentials.
|
||||
|
||||
Returns:
|
||||
Google Calendar service instance
|
||||
|
||||
Raises:
|
||||
ValueError: If credentials have not been set
|
||||
Exception: If service creation fails
|
||||
"""
|
||||
if self.service:
|
||||
return self.service
|
||||
|
||||
try:
|
||||
credentials = self._get_credentials()
|
||||
self.service = build("calendar", "v3", credentials=credentials)
|
||||
return self.service
|
||||
except Exception as e:
|
||||
raise Exception(f"Failed to create Google Calendar service: {e!s}") from e
|
||||
|
||||
def get_calendars(self) -> tuple[list[dict[str, Any]], str | None]:
|
||||
"""
|
||||
Fetch list of user's calendars using Google OAuth credentials.
|
||||
|
||||
Returns:
|
||||
Tuple containing (calendars list, error message or None)
|
||||
"""
|
||||
try:
|
||||
service = self._get_service()
|
||||
calendars_result = service.calendarList().list().execute()
|
||||
calendars = calendars_result.get("items", [])
|
||||
|
||||
# Format calendar data
|
||||
formatted_calendars = []
|
||||
for calendar in calendars:
|
||||
formatted_calendars.append(
|
||||
{
|
||||
"id": calendar.get("id"),
|
||||
"summary": calendar.get("summary"),
|
||||
"description": calendar.get("description", ""),
|
||||
"primary": calendar.get("primary", False),
|
||||
"accessRole": calendar.get("accessRole"),
|
||||
"timeZone": calendar.get("timeZone"),
|
||||
}
|
||||
)
|
||||
|
||||
return formatted_calendars, None
|
||||
|
||||
except Exception as e:
|
||||
return [], f"Error fetching calendars: {e!s}"
|
||||
|
||||
def get_all_primary_calendar_events(
|
||||
self,
|
||||
max_results: int = 2500,
|
||||
) -> tuple[list[dict[str, Any]], str | None]:
|
||||
"""
|
||||
Fetch events from the primary calendar using Google OAuth credentials.
|
||||
|
||||
Args:
|
||||
max_results: Maximum number of events to fetch (default: 2500)
|
||||
|
||||
Returns:
|
||||
Tuple containing (events list, error message or None)
|
||||
"""
|
||||
try:
|
||||
service = self._get_service()
|
||||
|
||||
# Fetch events
|
||||
events_result = (
|
||||
service.events()
|
||||
.list(
|
||||
calendarId="primary",
|
||||
maxResults=max_results,
|
||||
singleEvents=True,
|
||||
orderBy="startTime",
|
||||
)
|
||||
.execute()
|
||||
)
|
||||
|
||||
events = events_result.get("items", [])
|
||||
|
||||
if not events:
|
||||
return [], "No events found in the specified date range."
|
||||
|
||||
return events, None
|
||||
|
||||
except Exception as e:
|
||||
return [], f"Error fetching events: {e!s}"
|
||||
|
||||
def format_event_to_markdown(self, event: dict[str, Any]) -> str:
|
||||
"""
|
||||
Format a Google Calendar event to markdown.
|
||||
|
||||
Args:
|
||||
event: Event object from Google Calendar API
|
||||
|
||||
Returns:
|
||||
Formatted markdown string
|
||||
"""
|
||||
# Extract basic event information
|
||||
summary = event.get("summary", "No Title")
|
||||
description = event.get("description", "")
|
||||
location = event.get("location", "")
|
||||
calendar_id = event.get("calendarId", "")
|
||||
|
||||
# Extract start and end times
|
||||
start = event.get("start", {})
|
||||
end = event.get("end", {})
|
||||
|
||||
start_time = start.get("dateTime") or start.get("date", "")
|
||||
end_time = end.get("dateTime") or end.get("date", "")
|
||||
|
||||
# Format times for display
|
||||
if start_time:
|
||||
try:
|
||||
if "T" in start_time: # DateTime format
|
||||
start_dt = datetime.fromisoformat(start_time.replace("Z", "+00:00"))
|
||||
start_formatted = start_dt.strftime("%Y-%m-%d %H:%M")
|
||||
else: # Date format (all-day event)
|
||||
start_formatted = start_time
|
||||
except Exception:
|
||||
start_formatted = start_time
|
||||
else:
|
||||
start_formatted = "Unknown"
|
||||
|
||||
if end_time:
|
||||
try:
|
||||
if "T" in end_time: # DateTime format
|
||||
end_dt = datetime.fromisoformat(end_time.replace("Z", "+00:00"))
|
||||
end_formatted = end_dt.strftime("%Y-%m-%d %H:%M")
|
||||
else: # Date format (all-day event)
|
||||
end_formatted = end_time
|
||||
except Exception:
|
||||
end_formatted = end_time
|
||||
else:
|
||||
end_formatted = "Unknown"
|
||||
|
||||
# Extract attendees
|
||||
attendees = event.get("attendees", [])
|
||||
attendee_list = []
|
||||
for attendee in attendees:
|
||||
email = attendee.get("email", "")
|
||||
display_name = attendee.get("displayName", email)
|
||||
response_status = attendee.get("responseStatus", "")
|
||||
attendee_list.append(f"- {display_name} ({response_status})")
|
||||
|
||||
# Build markdown content
|
||||
markdown_content = f"# {summary}\n\n"
|
||||
|
||||
# Add event details
|
||||
markdown_content += f"**Start:** {start_formatted}\n"
|
||||
markdown_content += f"**End:** {end_formatted}\n"
|
||||
|
||||
if location:
|
||||
markdown_content += f"**Location:** {location}\n"
|
||||
|
||||
if calendar_id:
|
||||
markdown_content += f"**Calendar:** {calendar_id}\n"
|
||||
|
||||
markdown_content += "\n"
|
||||
|
||||
# Add description if available
|
||||
if description:
|
||||
markdown_content += f"## Description\n\n{description}\n\n"
|
||||
|
||||
# Add attendees if available
|
||||
if attendee_list:
|
||||
markdown_content += "## Attendees\n\n"
|
||||
markdown_content += "\n".join(attendee_list)
|
||||
markdown_content += "\n\n"
|
||||
|
||||
# Add event metadata
|
||||
markdown_content += "## Event Details\n\n"
|
||||
markdown_content += f"- **Event ID:** {event.get('id', 'Unknown')}\n"
|
||||
markdown_content += f"- **Created:** {event.get('created', 'Unknown')}\n"
|
||||
markdown_content += f"- **Updated:** {event.get('updated', 'Unknown')}\n"
|
||||
|
||||
if event.get("recurringEventId"):
|
||||
markdown_content += (
|
||||
f"- **Recurring Event ID:** {event.get('recurringEventId')}\n"
|
||||
)
|
||||
|
||||
return markdown_content
|
Loading…
Add table
Reference in a new issue