def read_free_busy(self, calendar_ids=(), from_date=None, to_date=None, last_modified=None, tzid=settings.DEFAULT_TIMEZONE_ID, include_managed=True, localized_times=False, automatic_pagination=True): """Read free/busy blocks for linked account (optionally for the specified calendars). :param tuple calendar_ids: Tuple or list of calendar ids to pass to cronofy. (Optional). :param datetime.date from_date: Start datetime (or ISO8601 string) for query. (Optional). :param datetime.date to_date: End datetime (or ISO8601 string) for query. (Optional). :param string tzid: Timezone ID for query. (Optional, default settings.DEFAULT_TIMEZONE_ID). Should match tzinfo on datetime objects. :param bool include_managed: Include pages created through the API. (Optional, default True) :param bool localized_times: Return time values for event start/end with localization information. This varies across providers. (Optional, default False). :param bool automatic_pagination: Autonatically fetch next page when iterating through results (Optional, default True) :return: Wrapped results (Containing first page of free/busy blocks). :rtype: ``Pages`` """ results = self.request_handler.get(endpoint='free_busy', params={ 'tzid': tzid, 'calendar_ids[]':calendar_ids, 'from': get_iso8601_string(from_date), 'to': get_iso8601_string(to_date), 'include_managed': include_managed, 'localized_times': localized_times, }).json() return Pages(self.request_handler, results, 'free_busy', automatic_pagination)
def upsert_event(self, calendar_id, event): """Inserts or updates an event for the specified calendar. :param string calendar_id: ID of calendar to insert/update event into. :param dict event: Dictionary of event data to send to cronofy. """ event['start'] = get_iso8601_string(event['start']) event['end'] = get_iso8601_string(event['end']) self.request_handler.post(endpoint='calendars/%s/events' % calendar_id, data=event)
def get_authorization_from_code(self, code, redirect_uri=''): """Updates the authorization tokens from the user provided code. :param string code: Authorization code to pass to Cronofy. :param string redirect_uri: Optionally override redirect uri obtained from user_auth_link. (They must match however). :return: Dictionary containing auth tokens, expiration info, and response status. :rtype: ``dict`` """ response = self.request_handler.post( url='%s/oauth/token' % settings.API_BASE_URL, data={ 'grant_type': 'authorization_code', 'client_id': self.auth.client_id, 'client_secret': self.auth.client_secret, 'code': code, 'redirect_uri': redirect_uri if redirect_uri else self.auth.redirect_uri, }) data = response.json() token_expiration = (datetime.datetime.utcnow() + datetime.timedelta(seconds=data['expires_in'])) self.auth.update( token_expiration=token_expiration, access_token=data['access_token'], refresh_token=data['refresh_token'], ) return { 'access_token': self.auth.access_token, 'refresh_token': self.auth.refresh_token, 'token_expiration': get_iso8601_string(self.auth.token_expiration), }
def refresh_authorization(self): """Refreshes the authorization tokens. :return: Dictionary containing auth tokens, expiration info, and response status. :rtype: ``dict`` """ response = self.request_handler.post( url='%s/oauth/token' % settings.API_BASE_URL, data={ 'grant_type': 'refresh_token', 'client_id': self.auth.client_id, 'client_secret': self.auth.client_secret, 'refresh_token': self.auth.refresh_token, } ) data = response.json() token_expiration = (datetime.datetime.utcnow() + datetime.timedelta(seconds=data['expires_in'])) self.auth.update( token_expiration=token_expiration, access_token=data['access_token'], refresh_token=data['refresh_token'], ) return { 'access_token': self.auth.access_token, 'refresh_token': self.auth.refresh_token, 'token_expiration': get_iso8601_string(self.auth.token_expiration), }
def test_datetime(): """Test get_iso8601_string returns an ISO8601 formatted datetime string when passed a datetime.date object, and throws an exception when tzinfo is not set.""" target_datetime = '2016-01-15T09:08:00' d = datetime.datetime.strptime(target_datetime, '%Y-%m-%dT%H:%M:%S') assert get_iso8601_string(d) == ('%sZ' % target_datetime)
def test_date(): """Test get_iso8601_string returns an ISO8601 formatted date string when passed a datetime.date object""" assert get_iso8601_string(datetime.date(2016, 1, 15)) == '2016-01-15'
def test_unsupported(): """Test get_iso8601_string throws an exception when passed an unsupported type""" with pytest.raises(Exception) as exception_info: get_iso8601_string(1) assert exception_info.value.message == 'Unsupported type: ``%s``.\nSupported types: ``<datetime.datetime>``, ``<datetime.date>``, or ``<str>``.' % repr(type(1)) assert exception_info.value.argument == 1
def test_tz_aware_datetime(): """Test get_iso8601_string returns an ISO8601 formatted datetime string with UTC timezone when passed a datetime.date object that's set to another timezone.""" d = datetime.datetime(2016, 1, 15, 14, 20, 15, tzinfo=pytz.timezone('EST')) assert get_iso8601_string(d) == '2016-01-15T19:20:15Z'
def test_none(): """Test get_iso8601_string returns None when passed None""" assert get_iso8601_string(None) == None
def test_iso8601_string(): """Test get_iso8601_string returns a string when passed a string""" assert get_iso8601_string('2016-01-15') == '2016-01-15'