@@ -72,45 +72,31 @@ async def get_calendar(self, calendar_id):
7272 resource = "calendars" , method = "get" , calendarId = calendar_id
7373 )
7474
75- async def list_events (self , calendar_id ):
76- """Fetch all events from a specific calendar.
75+ async def list_events (self , calendar_id , time_min = None , time_max = None ):
76+ """Fetch all events from a specific calendar within the specified time range .
7777
7878 Args:
7979 calendar_id (str): The calendar ID.
80+ time_min (str): Start time in ISO format. Optional.
81+ time_max (str): End time in ISO format. Optional.
8082
8183 Yields:
8284 dict: Events page.
8385 """
86+ params = {
87+ "calendarId" : calendar_id ,
88+ "maxResults" : 100 ,
89+ }
90+ if time_min :
91+ params ["timeMin" ] = time_min
92+ if time_max :
93+ params ["timeMax" ] = time_max
94+
8495 async for page in self .api_call_paged (
85- resource = "events" ,
86- method = "list" ,
87- calendarId = calendar_id ,
88- maxResults = 100 ,
96+ resource = "events" , method = "list" , ** params
8997 ):
9098 yield page
9199
92- async def get_free_busy (self , calendar_ids , time_min , time_max ):
93- """Get free/busy information for a list of calendars.
94-
95- Args:
96- calendar_ids (list): List of calendar IDs.
97- time_min (str): Start time in ISO format.
98- time_max (str): End time in ISO format.
99-
100- Returns:
101- dict: Free/busy information.
102- """
103- items = [{"id" : calendar_id } for calendar_id in calendar_ids ]
104- request_body = {
105- "timeMin" : time_min ,
106- "timeMax" : time_max ,
107- "items" : items ,
108- }
109-
110- return await self .api_call (
111- resource = "freebusy" , method = "query" , body = request_body
112- )
113-
114100
115101class GoogleCalendarDataSource (BaseDataSource ):
116102 """Google Calendar connector for Elastic Enterprise Search.
@@ -119,7 +105,6 @@ class GoogleCalendarDataSource(BaseDataSource):
119105 - CalendarList entries (the user's list of calendars)
120106 - Each underlying Calendar resource
121107 - Events belonging to each Calendar
122- - Free/Busy data for each Calendar
123108
124109 Reference:
125110 https://developers.google.com/calendar/api/v3/reference
@@ -136,7 +121,6 @@ def __init__(self, configuration):
136121 """
137122 super ().__init__ (configuration = configuration )
138123 self ._calendar_client = None
139- self .include_freebusy = self .configuration .get ("include_freebusy" , False )
140124
141125 @classmethod
142126 def get_default_configuration (cls ):
@@ -157,12 +141,19 @@ def get_default_configuration(cls):
157141 "required" : True ,
158142 "type" : "str" ,
159143 },
160- "include_freebusy " : {
161- "display" : "toggle " ,
162- "label" : "Include Free/Busy Data " ,
144+ "days_back " : {
145+ "display" : "numeric " ,
146+ "label" : "Days back to fetch events " ,
163147 "order" : 3 ,
164- "type" : "bool" ,
165- "value" : False ,
148+ "type" : "int" ,
149+ "value" : 30 ,
150+ },
151+ "days_forward" : {
152+ "display" : "numeric" ,
153+ "label" : "Days forward to fetch events" ,
154+ "order" : 4 ,
155+ "type" : "int" ,
156+ "value" : 30 ,
166157 },
167158 }
168159
@@ -244,15 +235,6 @@ async def get_docs(self, filtering=None):
244235 async for event_doc in self ._generate_event_docs (client , cal_list_doc ):
245236 yield event_doc , None
246237
247- # 4) (Optionally) yield free/busy data for each calendar
248- if self .include_freebusy :
249- calendar_ids = [cal ["calendar_id" ] for cal in calendar_list_entries ]
250- if calendar_ids :
251- async for freebusy_doc in self ._generate_freebusy_docs (
252- client , calendar_ids
253- ):
254- yield freebusy_doc , None
255-
256238 async def _generate_calendar_list_docs (self , client ):
257239 """Yield documents for each calendar in the user's CalendarList.
258240
@@ -319,6 +301,14 @@ async def _generate_event_docs(self, client, cal_list_doc):
319301 """
320302 calendar_id = cal_list_doc ["calendar_id" ]
321303
304+ # Calculate time range based on configuration
305+ now = datetime .utcnow ()
306+ days_back = self .configuration .get ("days_back" , 30 )
307+ days_forward = self .configuration .get ("days_forward" , 30 )
308+
309+ time_min = (now - timedelta (days = days_back )).isoformat () + "Z"
310+ time_max = (now + timedelta (days = days_forward )).isoformat () + "Z"
311+
322312 # Create calendar reference for events
323313 calendar_ref = {
324314 "id" : calendar_id ,
@@ -329,7 +319,7 @@ async def _generate_event_docs(self, client, cal_list_doc):
329319 }
330320
331321 try :
332- async for page in client .list_events (calendar_id ):
322+ async for page in client .list_events (calendar_id , time_min , time_max ):
333323 for event in page .get ("items" , []):
334324 event_id = event ["id" ]
335325 # Extract date/time fields
@@ -339,89 +329,69 @@ async def _generate_event_docs(self, client, cal_list_doc):
339329 start_date = start_info .get ("date" )
340330 end_datetime = end_info .get ("dateTime" )
341331 end_date = end_info .get ("date" )
342- created_at_str = event .get ("created" )
343- updated_at_str = event .get ("updated" )
344-
345- # Convert created/updated to datetime if present
346- created_at = (
347- datetime .fromisoformat (created_at_str .replace ("Z" , "+00:00" ))
348- if created_at_str
349- else None
350- )
351- updated_at = (
352- datetime .fromisoformat (updated_at_str .replace ("Z" , "+00:00" ))
353- if updated_at_str
354- else None
355- )
332+
333+ # Extract attendee names and emails
334+ attendees_info = []
335+ if event .get ("attendees" ):
336+ for attendee in event .get ("attendees" , []):
337+ attendee_info = {}
338+ if attendee .get ("displayName" ):
339+ attendee_info ["name" ] = attendee .get ("displayName" )
340+ if attendee .get ("email" ):
341+ attendee_info ["email" ] = attendee .get ("email" )
342+ if attendee_info :
343+ attendees_info .append (attendee_info )
344+
345+ # Extract meeting/zoom links from conferenceData or location
346+ meeting_link = None
347+ if event .get ("conferenceData" ):
348+ entry_points = event .get ("conferenceData" , {}).get (
349+ "entryPoints" , []
350+ )
351+ for entry_point in entry_points :
352+ if entry_point .get ("uri" ):
353+ meeting_link = entry_point .get ("uri" )
354+ break
355+
356+ # Extract attachments
357+ attachments_info = []
358+ if event .get ("attachments" ):
359+ for attachment in event .get ("attachments" , []):
360+ attachment_info = {}
361+ if attachment .get ("title" ):
362+ attachment_info ["title" ] = attachment .get ("title" )
363+ if attachment .get ("fileUrl" ):
364+ attachment_info ["url" ] = attachment .get ("fileUrl" )
365+ if attachment .get ("mimeType" ):
366+ attachment_info ["mime_type" ] = attachment .get (
367+ "mimeType"
368+ )
369+ if attachment_info :
370+ attachments_info .append (attachment_info )
356371
357372 doc = {
358373 "_id" : event_id ,
359374 "type" : "event" ,
360375 "event_id" : event_id ,
361376 "calendar_id" : calendar_id ,
362377 "calendar" : calendar_ref ,
363- "status" : event .get ("status" ),
364- "html_link" : event .get ("htmlLink" ),
365- "created_at" : created_at .isoformat () if created_at else None ,
366- "updated_at" : updated_at .isoformat () if updated_at else None ,
367378 "summary" : event .get ("summary" ),
368379 "description" : event .get ("description" ),
369380 "location" : event .get ("location" ),
370- "color_id " : event . get ( "colorId" ) ,
381+ "meeting_link " : meeting_link ,
371382 "start_datetime" : start_datetime ,
372383 "start_date" : start_date ,
373384 "end_datetime" : end_datetime ,
374385 "end_date" : end_date ,
375- "recurrence" : event .get ("recurrence" ),
376- "recurring_event_id" : event .get ("recurringEventId" ),
377- "organizer" : event .get ("organizer" ),
378- "creator" : event .get ("creator" ),
379- "attendees" : event .get ("attendees" ),
380- "transparency" : event .get ("transparency" ),
381- "visibility" : event .get ("visibility" ),
382- "conference_data" : event .get ("conferenceData" ),
383- "event_type" : event .get ("eventType" ),
386+ "attendees" : attendees_info ,
387+ "attachments" : attachments_info ,
384388 }
385389 yield doc
386390 except Exception as e :
387391 self ._logger .warning (
388392 f"Error fetching events for calendar { calendar_id } : { str (e )} "
389393 )
390394
391- async def _generate_freebusy_docs (self , client , calendar_ids ):
392- """Yield documents for free/busy data for the next 7 days for each calendar.
393-
394- Args:
395- client (GoogleCalendarClient): The Google Calendar client.
396- calendar_ids (list): List of calendar IDs.
397-
398- Yields:
399- dict: Free/busy document.
400- """
401- now = datetime .utcnow ()
402- in_7_days = now + timedelta (days = 7 )
403- time_min = now .isoformat () + "Z"
404- time_max = in_7_days .isoformat () + "Z"
405-
406- try :
407- data = await client .get_free_busy (calendar_ids , time_min , time_max )
408- calendars = data .get ("calendars" , {})
409-
410- for calendar_id , busy_info in calendars .items ():
411- busy_ranges = busy_info .get ("busy" , [])
412-
413- doc = {
414- "_id" : f"{ calendar_id } _freebusy" ,
415- "type" : "freebusy" ,
416- "calendar_id" : calendar_id ,
417- "busy" : busy_ranges ,
418- "time_min" : time_min ,
419- "time_max" : time_max ,
420- }
421- yield doc
422- except Exception as e :
423- self ._logger .warning (f"Error fetching free/busy data: { str (e )} " )
424-
425395 async def close (self ):
426396 """Close any resources."""
427397 pass
0 commit comments