33# or more contributor license agreements. Licensed under the Elastic License 2.0;
44# you may not use this file except in compliance with the Elastic License 2.0.
55#
6- import urllib .parse
76from datetime import datetime , timedelta
8- from typing import Any , Dict , List , Optional
97
108from connectors .source import BaseDataSource , ConfigurableFieldValueError
119from connectors .sources .google import (
1513 validate_service_account_json ,
1614)
1715
18-
1916# Default timeout for Google Calendar API calls (in seconds)
2017DEFAULT_TIMEOUT = 60
2118
@@ -47,9 +44,7 @@ def __init__(self, json_credentials, subject=None):
4744
4845 async def ping (self ):
4946 """Verify connectivity to Google Calendar API."""
50- return await self .api_call (
51- resource = "calendarList" , method = "list" , maxResults = 1
52- )
47+ return await self .api_call (resource = "calendarList" , method = "list" , maxResults = 1 )
5348
5449 async def list_calendar_list (self ):
5550 """Fetch all calendar list entries from Google Calendar.
@@ -119,13 +114,13 @@ async def get_free_busy(self, calendar_ids, time_min, time_max):
119114
120115class GoogleCalendarDataSource (BaseDataSource ):
121116 """Google Calendar connector for Elastic Enterprise Search.
122-
117+
123118 This connector fetches data from a user's Google Calendar (read-only mode):
124119 - CalendarList entries (the user's list of calendars)
125120 - Each underlying Calendar resource
126121 - Events belonging to each Calendar
127122 - Free/Busy data for each Calendar
128-
123+
129124 Reference:
130125 https://developers.google.com/calendar/api/v3/reference
131126 """
@@ -184,9 +179,7 @@ def _service_account_credentials(self):
184179 dict: The loaded service account credentials.
185180 """
186181 service_account_credentials = self .configuration ["service_account_credentials" ]
187- return load_service_account_json (
188- service_account_credentials , "Google Calendar"
189- )
182+ return load_service_account_json (service_account_credentials , "Google Calendar" )
190183
191184 def calendar_client (self ):
192185 """Get or create a Google Calendar client.
@@ -226,31 +219,31 @@ async def ping(self):
226219
227220 async def get_docs (self , filtering = None ):
228221 """Yields documents from Google Calendar API.
229-
222+
230223 Each document is a tuple with:
231224 - a mapping with the data to index
232225 - an optional mapping with attachment data
233226 """
234227 client = self .calendar_client ()
235-
228+
236229 # 1) Get the user's calendarList
237230 calendar_list_entries = []
238231 async for cal_list_doc in self ._generate_calendar_list_docs (client ):
239232 yield cal_list_doc , None
240233 calendar_list_entries .append (cal_list_doc )
241-
234+
242235 # 2) For each calendar in the user's calendarList, yield its Calendar resource
243236 for cal_list_doc in calendar_list_entries :
244237 async for calendar_doc in self ._generate_calendar_docs (
245238 client , cal_list_doc ["calendar_id" ]
246239 ):
247240 yield calendar_doc , None
248-
241+
249242 # 3) For each calendar, yield event documents
250243 for cal_list_doc in calendar_list_entries :
251244 async for event_doc in self ._generate_event_docs (client , cal_list_doc ):
252245 yield event_doc , None
253-
246+
254247 # 4) (Optionally) yield free/busy data for each calendar
255248 if self .include_freebusy :
256249 calendar_ids = [cal ["calendar_id" ] for cal in calendar_list_entries ]
@@ -262,10 +255,10 @@ async def get_docs(self, filtering=None):
262255
263256 async def _generate_calendar_list_docs (self , client ):
264257 """Yield documents for each calendar in the user's CalendarList.
265-
258+
266259 Args:
267260 client (GoogleCalendarClient): The Google Calendar client.
268-
261+
269262 Yields:
270263 dict: Calendar list entry document.
271264 """
@@ -291,11 +284,11 @@ async def _generate_calendar_list_docs(self, client):
291284
292285 async def _generate_calendar_docs (self , client , calendar_id ):
293286 """Yield a document for the specified calendar_id.
294-
287+
295288 Args:
296289 client (GoogleCalendarClient): The Google Calendar client.
297290 calendar_id (str): The calendar ID.
298-
291+
299292 Yields:
300293 dict: Calendar document.
301294 """
@@ -316,23 +309,25 @@ async def _generate_calendar_docs(self, client, calendar_id):
316309
317310 async def _generate_event_docs (self , client , cal_list_doc ):
318311 """Yield documents for all events in the given calendar.
319-
312+
320313 Args:
321314 client (GoogleCalendarClient): The Google Calendar client.
322315 cal_list_doc (dict): Calendar list entry document.
323-
316+
324317 Yields:
325318 dict: Event document.
326319 """
327320 calendar_id = cal_list_doc ["calendar_id" ]
328-
321+
329322 # Create calendar reference for events
330323 calendar_ref = {
331324 "id" : calendar_id ,
332- "name" : cal_list_doc .get ("summary_override" ) or cal_list_doc .get ("summary" ) or "" ,
325+ "name" : cal_list_doc .get ("summary_override" )
326+ or cal_list_doc .get ("summary" )
327+ or "" ,
333328 "type" : "calendar" ,
334329 }
335-
330+
336331 try :
337332 async for page in client .list_events (calendar_id ):
338333 for event in page .get ("items" , []):
@@ -346,7 +341,7 @@ async def _generate_event_docs(self, client, cal_list_doc):
346341 end_date = end_info .get ("date" )
347342 created_at_str = event .get ("created" )
348343 updated_at_str = event .get ("updated" )
349-
344+
350345 # Convert created/updated to datetime if present
351346 created_at = (
352347 datetime .fromisoformat (created_at_str .replace ("Z" , "+00:00" ))
@@ -358,7 +353,7 @@ async def _generate_event_docs(self, client, cal_list_doc):
358353 if updated_at_str
359354 else None
360355 )
361-
356+
362357 doc = {
363358 "_id" : event_id ,
364359 "type" : "event" ,
@@ -389,30 +384,32 @@ async def _generate_event_docs(self, client, cal_list_doc):
389384 }
390385 yield doc
391386 except Exception as e :
392- self ._logger .warning (f"Error fetching events for calendar { calendar_id } : { str (e )} " )
387+ self ._logger .warning (
388+ f"Error fetching events for calendar { calendar_id } : { str (e )} "
389+ )
393390
394391 async def _generate_freebusy_docs (self , client , calendar_ids ):
395392 """Yield documents for free/busy data for the next 7 days for each calendar.
396-
393+
397394 Args:
398395 client (GoogleCalendarClient): The Google Calendar client.
399396 calendar_ids (list): List of calendar IDs.
400-
397+
401398 Yields:
402399 dict: Free/busy document.
403400 """
404401 now = datetime .utcnow ()
405402 in_7_days = now + timedelta (days = 7 )
406403 time_min = now .isoformat () + "Z"
407404 time_max = in_7_days .isoformat () + "Z"
408-
405+
409406 try :
410407 data = await client .get_free_busy (calendar_ids , time_min , time_max )
411408 calendars = data .get ("calendars" , {})
412-
409+
413410 for calendar_id , busy_info in calendars .items ():
414411 busy_ranges = busy_info .get ("busy" , [])
415-
412+
416413 doc = {
417414 "_id" : f"{ calendar_id } _freebusy" ,
418415 "type" : "freebusy" ,
@@ -427,4 +424,4 @@ async def _generate_freebusy_docs(self, client, calendar_ids):
427424
428425 async def close (self ):
429426 """Close any resources."""
430- pass
427+ pass
0 commit comments