Example #1
0
    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: Automatically 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': format_event_time(from_date),
            'to': format_event_time(to_date),
            'include_managed': include_managed,
            'localized_times': localized_times,
        }).json()

        return Pages(self.request_handler, results, 'free_busy', automatic_pagination)
Example #2
0
def test_unsupported():
    """Test format_event_time throws an exception when passed an unsupported type"""
    with pytest.raises(Exception) as exception_info:
        format_event_time(1)
    assert exception_info.value.message == 'Unsupported type: ``%s``.\nSupported types: ``<datetime.datetime>``, ``<datetime.date>``, ``<dict>``, or ``<str>``.' % repr(
        type(1))
    assert exception_info.value.argument == 1
Example #3
0
    def upsert_event(self, calendar_id, event):
        data = event.copy()

        data['start'] = format_event_time(event['start'])
        data['end'] = format_event_time(event['end'])

        self.post("/v1/calendars/%s/events" % calendar_id, data)
        return self
Example #4
0
    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'] = format_event_time(event['start'])
        event['end'] = format_event_time(event['end'])
        self.request_handler.post(
            endpoint='calendars/%s/events' % calendar_id, data=event)
Example #5
0
    def read_events(self,
                    calendar_ids=(),
                    from_date=None,
                    to_date=None,
                    last_modified=None,
                    tzid=settings.DEFAULT_TIMEZONE_ID,
                    only_managed=False,
                    include_managed=True,
                    include_deleted=False,
                    include_moved=False,
                    include_geo=False,
                    localized_times=False,
                    automatic_pagination=True):
        """Read events 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 datetime.datetime last_modified: Return items modified on or after last_modified. Datetime or ISO8601 string. (Optional).
        :param string tzid: Timezone ID for query. (Optional, default settings.DEFAULT_TIMEZONE_ID). Should match tzinfo on datetime objects.
        :param bool only_managed: Only include events created through the API. (Optional, default False)
        :param bool include_managed: Include events created through the API. (Optional, default True)
        :param bool include_deleted: Include deleted events. (Optional, default False)
        :param bool include_moved: Include events that ever existed within the from_date/to_date time window. (Optional, default False)
        :param bool include_geo: Include any geo location information for events when available (Optional, default False)
        :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 events).
        :rtype: ``Pages``
        """
        results = self.request_handler.get(
            endpoint='events',
            params={
                'tzid': tzid,
                'calendar_ids[]': calendar_ids,
                'from': format_event_time(from_date),
                'to': format_event_time(to_date),
                'last_modified': format_event_time(last_modified),
                'only_managed': only_managed,
                'include_managed': include_managed,
                'include_deleted': include_deleted,
                'include_moved': include_moved,
                'include_geo': include_geo,
                'localized_times': localized_times,
            }).json()

        return Pages(self.request_handler, results, 'events',
                     automatic_pagination)
Example #6
0
    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(
            endpoint='oauth/token',
            omit_api_version=True,
            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': format_event_time(self.auth.token_expiration),
        }
Example #7
0
    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(
            endpoint='oauth/token',
            omit_api_version=True,
            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': format_event_time(self.auth.token_expiration),
        }
Example #8
0
    def application_calendar(self, application_calendar_id):
        """Creates and Retrieves authorization for an application calendar

        :param string application_calendar_id: The Id for this application calendar
        :return: Dictionary containing auth tokens, expiration info, and response status.
        :rtype: ``dict``
        """
        response = self.request_handler.post(
            endpoint='application_calendar',
            data={
                'client_id': self.auth.client_id,
                'client_secret': self.auth.client_secret,
                'application_calendar_id': application_calendar_id,
            })
        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': format_event_time(self.auth.token_expiration),
            'sub': data.get('sub'),
            'application_calendar_id': data.get('application_calendar_id')
        }
Example #9
0
def test_iso8601_string_in_dict():
    """Test format_event_time returns an ISO8601 formatted date string in a dict when passed a iso8601 string"""
    date = '2016-01-15'
    params = {
        'time': date,
        'tzid': 'Etc/UTC',
    }
    assert format_event_time(params) == {
        'time': '2016-01-15',
        'tzid': 'Etc/UTC'
    }
Example #10
0
def test_date_nested_in_dict():
    """Test format_event_time returns an ISO8601 formatted date string in a dict when passed a datetime.date object"""
    date = datetime.date(2016, 1, 15)
    params = {
        'time': date,
        'tzid': 'Etc/UTC',
    }
    assert format_event_time(params) == {
        'time': '2016-01-15',
        'tzid': 'Etc/UTC'
    }
Example #11
0
def test_tz_aware_datetime_in_dict():
    """Test format_event_time returns an ISO8601 formatted date string in a dict when passed a datetimee object"""
    date = datetime.datetime(2016,
                             1,
                             15,
                             14,
                             20,
                             15,
                             tzinfo=pytz.timezone('EST'))
    params = {
        'time': date,
        'tzid': 'Etc/UTC',
    }
    assert format_event_time(params) == {
        'time': '2016-01-15T19:20:15Z',
        'tzid': 'Etc/UTC'
    }
Example #12
0
 def translate_available_periods(self, periods):
     for params in periods:
         for tp in ['start', 'end']:
             if params[tp]:
                 params[tp] = format_event_time(params[tp])
Example #13
0
    def upsert_smart_invite(self, smart_invite_id, recipient, event, callback_url=None, organizer=None):
        """ Creates or updates smart invite.
        :param string smart_invite_id - A String uniquely identifying the event for your
              application (note: this is NOT an ID generated
              by Cronofy).
        :param string callback_url - The URL within your application you want Cronofy to
             send notifications to about user interactions with
             the Smart Invite.
        :param dict recipient - A Dict containing the intended recipient of the invite
             :email      - A String for the email address you are
                           going to send the Smart Invite to.
        :param dict event - A Dict describing the event with symbolized keys:
             :summary      - A String to use as the summary, sometimes
                             referred to as the name or title, of the
                             event.
             :description  - A String to use as the description, sometimes
                             referred to as the notes or body, of the
                             event.
             :start        - The Time or Date the event starts.
             :end          - The Time or Date the event ends.
             :url          - The URL associated with the event.
             :location     - A Dict describing the location of the event
                             with keys (optional):
                             :description - A String describing the
                                            location.
                             :lat - A String of the location's latitude.
                             :long - A String of the location's longitude.
             :reminders    - An Array of Dicts describing the desired
                             reminders for the event. Reminders should be
                             specified in priority order as, for example,
                             when the underlying provider only supports a
                             single reminder then the first reminder will
                             be used.
                             :minutes - An Integer specifying the number
                                        of minutes before the start of the
                                        event that the reminder should
                                        occur.
             :transparency - The transparency state for the event (optional).
                             Accepted values are "transparent" and "opaque".
             :color        - The color of the event (optional).
        :param dict organizer - A Dict containing the organzier of the invite
             :name      - A String for the name of the organizer.
        """
        event['start'] = format_event_time(event['start'])
        event['end'] = format_event_time(event['end'])

        body = {
            'smart_invite_id': smart_invite_id,
            'event': event
        }
        if type(recipient) == dict:
            body['recipient'] = recipient
        elif type(recipient) == list:
            body['recipients'] = recipient

        if callback_url:
            body['callback_url'] = callback_url

        if organizer:
            body['organizer'] = organizer

        return self.request_handler.post('smart_invites', data=body, use_api_key=True).json()
Example #14
0
def test_datetime():
    """Test format_event_time 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 format_event_time(d) == ('%sZ' % target_datetime)
Example #15
0
def test_tz_aware_datetime():
    """Test format_event_time 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 format_event_time(d) == '2016-01-15T19:20:15Z'
Example #16
0
def test_none():
    """Test format_event_time returns None when passed None"""
    assert format_event_time(None) is None
Example #17
0
def test_iso8601_string():
    """Test format_event_time returns a string when passed a string"""
    assert format_event_time('2016-01-15') == '2016-01-15'
Example #18
0
def test_date():
    """Test format_event_time returns an ISO8601 formatted date string when passed a datetime.date object"""
    assert format_event_time(datetime.date(2016, 1, 15)) == '2016-01-15'