def fetch_next(self, count=1): """ Fetch the next n messages after the previous fetch, where n is the specified count :param count: no.of messages to fetch """ skip_count = self.fetched_count if self._search: params = { '$filter': self._filter, '$top': count, '$search': '"{}"'.format(self._search) } else: params = { '$filter': self._filter, '$top': count, '$skip': skip_count } response = Connection.get_response(self.url, verify=self.verify, params=params) self.fetched_count += count messages = [] for message in response: messages.append(Message(message, Connection().auth)) return messages
def _get_url(key): """ Fetches the url for specified key as per the connection version configured :param key: the key for which url is required :return: URL to use for requests """ return FluentInbox.url_dict[key][Connection().api_version]
def __init__(self, credentials, *, protocol=None, main_resource=ME_RESOURCE, **kwargs): """ Creates an object which is used to access resources related to the specified credentials :param tuple credentials: a tuple containing the client_id and client_secret :param Protocol protocol: the protocol to be used in this account :param str main_resource: the resource to be used by this account ('me' or 'users') :param kwargs: any extra args to be passed to the Connection instance :raises ValueError: if an invalid protocol is passed """ protocol = protocol or MSGraphProtocol # Defaults to Graph protocol self.protocol = protocol( default_resource=main_resource, **kwargs) if isinstance( protocol, type) else protocol if not isinstance(self.protocol, Protocol): raise ValueError("'protocol' must be a subclass of Protocol") self.con = Connection(credentials, **kwargs) self.main_resource = main_resource
def getEvents(self, start=None, end=None, eventCount=10): ''' Pulls events in for this calendar. default range is today to a year now. Keyword Arguments: start -- The starting date from where you want to begin requesting events. The expected type is a struct_time. Default is today. end -- The ending date to where you want to end requesting events. The expected type is a struct_time. Default is a year from start. ''' # If no start time has been supplied, it is assumed you want to start as of now. if not start: start = time.strftime(self.time_string) # If no end time has been supplied, it is assumed you want the end time to be a year # from what ever the start date was. if not end: end = time.time() end += 3600 * 24 * 365 end = time.gmtime(end) end = time.strftime(self.time_string, end) connection = Connection() # Change URL if we use Oauth if connection.is_valid() and connection.oauth != None: self.events_url = self.events_url.replace( "outlook.office365.com/api", "graph.microsoft.com") # This is where the actual call to Office365 happens. response = connection.get_response(self.events_url.format( self.json['Id'], start, end, eventCount), auth=self.auth, verify=self.verify) log.info('Response from O365: %s', str(response)) #This takes that response and then parses it into individual calendar events. for event in response: try: duplicate = False # checks to see if the event is a duplicate. if it is local changes are clobbered. for i, e in enumerate(self.events): if e.json['Id'] == event['id']: self.events[i] = Event(event, self.auth, self) duplicate = True break if not duplicate: self.events.append(Event(event, self.auth, self)) log.debug('appended event: %s', event['subject']) except Exception as e: log.info('failed to append calendar: %', str(e)) log.debug('all events retrieved and put in to the list.') return True
def creds() -> Account: """Load or obtain credentials for user.""" credentials = "8da780f3-5ea0-4d97-ab13-9e7976370624" protocol = MSGraphProtocol(timezone="Europe/Stockholm") scopes = protocol.get_scopes_for(SCOPES) token_backend = FileSystemTokenBackend( token_path=os.path.dirname(__file__), token_filename="o365_token.txt") connection = Connection(credentials, auth_flow_type="public", token_backend=token_backend) account = Account( credentials, auth_flow_type="public", protocol=protocol, token_backend=token_backend, ) if (not os.path.exists("kronoxToGCalendar/logic/o365_token.txt") and not account.is_authenticated): print("AUTH TRIGGERED") auth_url = connection.get_authorization_url( requested_scopes=scopes, redirect_uri= "https://kronox-client-api.herokuapp.com/return_token_url", ) webbrowser.open_new(auth_url[0]) token_req = lambda: requests.get( "https://kronox-client-api.herokuapp.com/get_token_url") while token_req().text == "None": continue token_res_arr = token_req().text.split("&") print(token_res_arr) token_code = token_res_arr[0].split("?")[1][5:] token_state = token_res_arr[1][6:] token_url = ( "https://login.microsoftonline.com/common/oauth2/nativeclient?code=" + token_code + "&state=" + token_state) connection.request_token(token_url) print("AUTH PASSED") account.is_authenticated return account
def update(self): '''Updates an event that already exists in a calendar.''' connection = Connection() # Change URL if we use Oauth if connection.is_valid() and connection.oauth != None: self.update_url = self.update_url.replace( "outlook.office365.com/api", "graph.microsoft.com") elif not self.auth: return False if self.calendar: calId = self.calendar.calendarId else: return False headers = { 'Content-type': 'application/json', 'Accept': 'application/json' } data = json.dumps(self.json) response = None print(data) try: response = connection.patch_data(self.update_url.format( self.json['id']), data, headers=headers, auth=self.auth, verify=self.verify) log.debug('sending patch request now') except Exception as e: if response: log.debug('response to event creation: %s', str(response)) else: log.error( 'No response, something is very wrong with update: %s', str(e)) return False log.debug('response to event creation: %s', str(response)) return Event(json.dumps(response), self.auth)
def getCalendars(self): '''Begin the process of downloading calendar metadata.''' connection = Connection() # Change URL if we use Oauth if connection.is_valid() and connection.oauth != None: self.cal_url = self.cal_url.replace("outlook.office365.com/api", "graph.microsoft.com") log.debug('fetching calendars.') response = connection.get_response(self.cal_url, auth=self.auth, verify=self.verify) log.info('response from O365 for retriving message attachments: %s', str(response)) for calendar in response: try: duplicate = False log.debug('Got a calendar with name: {0} and id: {1}'.format( calendar['Name'], calendar['Id'])) for i, c in enumerate(self.calendars): if c.json['id'] == calendar['Id']: c.json = calendar c.name = calendar['Name'] c.calendarid = calendar['Id'] duplicate = True log.debug('Calendar: {0} is a duplicate', calendar['Name']) break if not duplicate: self.calendars.append(Calendar(calendar, self.auth)) log.debug('appended calendar: %s', calendar['Name']) log.debug('Finished with calendar {0} moving on.'.format( calendar['Name'])) except Exception as e: log.info('failed to append calendar: {0}'.format(str(e))) log.debug('all calendars retrieved and put in to the list.') return True
def __init__(self, credentials, *, auth_method=AUTH_METHOD.OAUTH, scopes=None, protocol=None, main_resource=ME_RESOURCE, **kwargs): if isinstance(auth_method, str): try: auth_method = AUTH_METHOD(auth_method) except ValueError as e: raise e if auth_method is AUTH_METHOD.BASIC: protocol = protocol or BasicAuthProtocol # using basic auth defaults to Office 365 protocol self.protocol = protocol( default_resource=main_resource, **kwargs) if isinstance( protocol, type) else protocol if self.protocol.api_version != 'v1.0' or not isinstance( self.protocol, BasicAuthProtocol): raise RuntimeError( 'Basic Authentication only works with Office 365 Api version v1.0 and until November 1 2018.' ) elif auth_method is AUTH_METHOD.OAUTH: protocol = protocol or MSGraphProtocol # using oauth auth defaults to Graph protocol self.protocol = protocol( default_resource=main_resource, **kwargs) if isinstance( protocol, type) else protocol if not isinstance(self.protocol, Protocol): raise ValueError("'protocol' must be a subclass of Protocol") self.con = kwargs.get('connection') or Connection( credentials, auth_method=auth_method, scopes=self.protocol.get_scopes_for(scopes)) self.main_resource = main_resource
def delete(self): ''' Delete's an event from the calendar it is in. But leaves you this handle. You could then change the calendar and transfer the event to that new calendar. You know, if that's your thing. ''' connection = Connection() # Change URL if we use Oauth if connection.is_valid() and connection.oauth != None: self.delete_url = self.delete_url.replace( "outlook.office365.com/api", "graph.microsoft.com") elif not self.auth: return False headers = {'Content-type': 'application/json', 'Accept': 'text/plain'} response = None try: log.debug('sending delete request') response = connection.delete_data(self.delete_url.format( self.json['id']), headers=headers, auth=self.auth, verify=self.verify) except Exception as e: if response: log.debug('response to deletion: %s', str(response)) else: log.error( 'No response, something is very wrong with delete: %s', str(e)) return False return response
def test_blank_connection(self): with pytest.raises(TypeError): c1 = Connection()
def create(self, calendar=None): ''' This method creates an event on the calender passed. IMPORTANT: It returns that event now created in the calendar, if you wish to make any changes to this event after you make it, use the returned value and not this particular event any further. calendar -- a calendar class onto which you want this event to be created. If this is left empty then the event's default calendar, specified at instancing, will be used. If no default is specified, then the event cannot be created. ''' connection = Connection() # Change URL if we use Oauth if connection.is_valid() and connection.oauth != None: self.create_url = self.create_url.replace( "outlook.office365.com/api", "graph.microsoft.com") elif not self.auth: log.debug('failed authentication check when creating event.') return False if calendar: calId = calendar.calendarId self.calendar = calendar log.debug('sent to passed calendar.') elif self.calendar: calId = self.calendar.calendarId log.debug('sent to default calendar.') else: log.debug('no valid calendar to upload to.') return False headers = { 'Content-type': 'application/json', 'Accept': 'application/json' } log.debug('creating json for request.') data = json.dumps(self.json) response = None try: log.debug('sending post request now') response = connection.post_data(self.create_url.format(calId), data, headers=headers, auth=self.auth, verify=self.verify) log.debug('sent post request.') if response.status_code > 399: log.error( "Invalid response code [{}], response text: \n{}".format( response.status_code, response.text)) return False except Exception as e: if response: log.debug('response to event creation: %s', str(response)) else: log.error( 'No response, something is very wrong with create: %s', str(e)) return False log.debug('response to event creation: %s', str(response)) return Event(response.json(), self.auth, calendar)