ees_microsoft_outlook/microsoft_outlook_calendar.py (203 lines of code) (raw):

# # Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one # or more contributor license agreements. Licensed under the Elastic License 2.0; # you may not use this file except in compliance with the Elastic License 2.0. # """This module allows to fetch calendar events from Microsoft Outlook. """ import requests from . import constant from .utils import (change_datetime_format, convert_datetime_to_ews_format, extract, get_schema_fields, html_to_text, insert_document_into_doc_id_storage, retry) class MicrosoftOutlookCalendar: """This class fetches Calendar Events for all users from Microsoft Outlook""" def __init__(self, logger, config): self.logger = logger self.config = config self.time_zone = constant.DEFAULT_TIME_ZONE self.retry_count = self.config.get_value("retry_count") def get_calendar_attachments( self, ids_list_calendars, calendar_obj, user_email_address, start_time, end_time ): """Method is used to fetches attachments from calendar object :param ids_list_calendars: Documents ids of calendar :param calendar_obj: Object of account :param user_email_address: Email address of user :param start_time: Start time for fetching the calendar events :param end_time: End time for fetching the calendar events Returns: calendar_attachments: Dictionary of calendar attachments """ calendar_attachments = [] for attachment in calendar_obj.attachments: # Logic for calendar last modified time attachment_created = "" if attachment.last_modified_time: attachment_created = change_datetime_format( attachment.last_modified_time, self.time_zone ) # Logic to fetch calendar events attachments if attachment.last_modified_time >= start_time and attachment.last_modified_time < end_time: attachments = { "type": constant.CALENDAR_ATTACHMENTS_OBJECT, "id": attachment.attachment_id.id, "title": attachment.name, "created": attachment_created, } attachments["_allow_permissions"] = [] if self.config.get_value("enable_document_permission"): attachments["_allow_permissions"] = [user_email_address] # Logic to insert calendar attachment into global_keys object insert_document_into_doc_id_storage( ids_list_calendars, attachment.attachment_id.id, calendar_obj.id, constant.CALENDAR_ATTACHMENTS_OBJECT.lower(), self.config.get_value("connector_platform_type"), ) if hasattr(attachment, "content"): attachments["body"] = extract(attachment.content) calendar_attachments.append(attachments) return calendar_attachments def calendar_to_docs( self, ids_list_calendars, calendar_obj, user_email_address, start_time, end_time, child_calendar, ): """Fetches data from outlook and store in dictionary :param ids_list_calendars: Documents ids of calendar :param calendar_obj: Object of account :param user_email_address: Email address of user :param start_time: Start time for fetching the calendar events :param end_time: End time for fetching the calendar events :param child_calendar: Type of child calendar Returns: calendar_document: Dictionary of calendar events calendar_attachments_documents: Dictionary of calendar attachments """ # Logic for attendees list if calendar_obj.required_attendees: attendees_list = [] for attendee in calendar_obj.required_attendees: if attendee.mailbox.email_address: attendees_list.append(attendee.mailbox.email_address) attendees = ", ".join(attendees_list) else: attendees = "" # Logic for meeting type if calendar_obj.type == "Single": event_type = "Normal" else: event_type = f"Recurring {calendar_obj.recurrence.pattern}" # Logic for calendar last modified time if calendar_obj.last_modified_time: calendar_created = change_datetime_format( calendar_obj.last_modified_time, self.time_zone ) else: calendar_created = "" # Logic to create document body calendar_document = { "type": constant.CALENDARS_OBJECT, "Id": calendar_obj.id, "DisplayName": calendar_obj.subject, "Created": calendar_created, } # Logic for Birthday Calendar Events if child_calendar in ["Folder (Birthdays)", "Birthdays (Birthdays)"]: calendar_document[ "Description" ] = f""" Date: {(change_datetime_format(calendar_obj.start, self.time_zone)).split('T', 1)[0]} Organizer: {calendar_obj.organizer.email_address}\n Meeting Type: {event_type}\n""" # Logic for Other Calendar Events else: calendar_document[ "Description" ] = f""" Start Date: {change_datetime_format(calendar_obj.start, self.time_zone)} End Date: {change_datetime_format(calendar_obj.end, self.time_zone)} Location: {calendar_obj.location} Organizer: {calendar_obj.organizer.email_address} Meeting Type: {event_type} Attendee List: {attendees} Description: {html_to_text(calendar_obj.body)}""" # Logic to fetches attachments calendar_attachments_documents = [] if calendar_obj.has_attachments: calendar_attachments_documents = self.get_calendar_attachments( ids_list_calendars, calendar_obj, user_email_address, start_time, end_time, ) return calendar_document, calendar_attachments_documents @retry(exception_list=(requests.exceptions.RequestException,)) def get_calendar(self, ids_list_calendars, accounts, start_time, end_time): """This method is used to get documents of calendar and mapped with Workplace Search fields :param ids_list_calendars: List of ids of documents param accounts: List of user accounts :param start_time: Start time for fetching the calendar events :param end_time: End time for fetching the calendar events Returns: documents: Documents with all calendar events """ documents = [] start_time = convert_datetime_to_ews_format(start_time) end_time = convert_datetime_to_ews_format(end_time) calendar_schema = get_schema_fields( constant.CALENDARS_OBJECT.lower(), self.config.get_value("objects") ) for account in accounts: # Logic to set time zone according to user account self.time_zone = account.default_timezone try: # Logic to fetch Calendar Events for calendar in account.calendar.filter( last_modified_time__gt=start_time, last_modified_time__lt=end_time, ).only( "required_attendees", "type", "recurrence", "last_modified_time", "subject", "start", "end", "location", "organizer", "body", "has_attachments", "attachments", ): # Logic to insert calendar into global_keys object insert_document_into_doc_id_storage( ids_list_calendars, calendar.id, "", constant.CALENDARS_OBJECT.lower(), self.config.get_value("connector_platform_type"), ) (calendar_obj, calendar_attachment,) = self.calendar_to_docs( ids_list_calendars, calendar, account.primary_smtp_address, start_time, end_time, str(calendar), ) calendar_map = {} calendar_map["_allow_permissions"] = [] if self.config.get_value("enable_document_permission"): calendar_map["_allow_permissions"] = [ account.primary_smtp_address ] calendar_map["type"] = calendar_obj["type"] for ws_field, ms_fields in calendar_schema.items(): calendar_map[ws_field] = calendar_obj[ms_fields] documents.append(calendar_map) if calendar_attachment: documents.extend(calendar_attachment) # Logic to fetch Custom Calendar Events for child_calendar in account.calendar.children: for calendar in child_calendar.filter( last_modified_time__gt=start_time, last_modified_time__lt=end_time, ).only( "required_attendees", "type", "recurrence", "last_modified_time", "subject", "start", "end", "location", "organizer", "body", "has_attachments", "attachments", ): # Logic to insert calendar into global_keys object insert_document_into_doc_id_storage( ids_list_calendars, calendar.id, "", constant.CALENDARS_OBJECT.lower(), self.config.get_value("connector_platform_type"), ) (calendar_obj, calendar_attachment,) = self.calendar_to_docs( ids_list_calendars, calendar, account.primary_smtp_address, start_time, end_time, str(child_calendar), ) calendar_map = {} calendar_map["_allow_permissions"] = [] if self.config.get_value("enable_document_permission"): calendar_map["_allow_permissions"] = [ account.primary_smtp_address ] calendar_map["type"] = calendar_obj["type"] for ws_field, ms_fields in calendar_schema.items(): calendar_map[ws_field] = calendar_obj[ms_fields] documents.append(calendar_map) if calendar_attachment: documents.extend(calendar_attachment) except requests.exceptions.RequestException as request_error: raise requests.exceptions.RequestException( f"Error while fetching calendar data for {account.primary_smtp_address}. Error: {request_error}" ) except Exception as exception: self.logger.info( f"Error while fetching calendar data for {account.primary_smtp_address}. Error: {exception}" ) pass return documents