xybu/onedrived-dev

View on GitHub
onedrived/od_api_helper.py

Summary

Maintainability
A
1 hr
Test Coverage
import json
import logging
import time

import onedrivesdk
import onedrivesdk.error
import requests

from . import od_dateutils

THROTTLE_PAUSE_SEC = 60


def get_drive_request_builder(repo):
    return onedrivesdk.DriveRequestBuilder(
        request_url=repo.authenticator.client.base_url + 'drives/' + repo.drive.id,
        client=repo.authenticator.client)


def create_subscription(folder_item_request, repo, webhook_url, expiration_time):
    """
    :param onedrivesdk.ItemRequestBuilder folder_item_request:
    :param onedrived.od_repo.OneDriveLocalRepository repo:
    :param str webhook_url:
    :param datetime.datetime.datetime expiration_time:
    :return onedrivesdk.Subscription:
    """
    subscriptions_collection_req = folder_item_request.subscriptions
    subscription_req_builder = onedrivesdk.SubscriptionRequestBuilder(subscriptions_collection_req._request_url,
                                                                      subscriptions_collection_req._client)
    subscription_req = item_request_call(repo, subscription_req_builder.request)
    subscription_req.content_type = "application/json"
    subscription_req.method = "POST"
    subscription = onedrivesdk.Subscription()
    subscription.notification_url = webhook_url
    subscription.expiration_date_time = expiration_time
    return onedrivesdk.Subscription(json.loads(subscription_req.send(subscription).content))


def update_subscription(self, subscription):
    """ A temp patch for bug https://github.com/OneDrive/onedrive-sdk-python/issues/95. """
    self.content_type = "application/json"
    self.method = "PATCH"
    entity = onedrivesdk.Subscription(json.loads(self.send(subscription).content))
    return entity


onedrivesdk.SubscriptionRequest.update = update_subscription


def get_item_modified_datetime(item):
    """
    :param onedrivesdk.Item item:
    :return [arrow.Arrow, True | False]: Return a 2-tuple (datetime, bool) in which the bool indicates modifiable.
    """
    # SDK Bug: the API can return some non-standard datetime string that SDK can't handle.
    # https://github.com/OneDrive/onedrive-sdk-python/issues/89
    # Until the bug is fixed I'll avoid the SDK calls and use the value directly.
    try:
        return od_dateutils.str_to_datetime(item.file_system_info._prop_dict['lastModifiedDateTime']), True
    except AttributeError:
        # OneDrive for Business does not have FileSystemInfo facet. Fall back to read-only mtime attribute.
        return od_dateutils.str_to_datetime(item._prop_dict['lastModifiedDateTime']), False


def get_item_created_datetime(item):
    return od_dateutils.str_to_datetime(item._prop_dict['createdDateTime'])


def item_request_call(repo, request_func, *args, **kwargs):
    while True:
        try:
            return request_func(*args, **kwargs)
        except onedrivesdk.error.OneDriveError as e:
            logging.error('Encountered API Error: %s.', e)
            if e.code == onedrivesdk.error.ErrorCode.ActivityLimitReached:
                time.sleep(THROTTLE_PAUSE_SEC)
            elif e.code == onedrivesdk.error.ErrorCode.Unauthenticated:
                repo.authenticator.refresh_session(repo.account_id)
            else:
                raise e
        except requests.ConnectionError as e:
            logging.error('Encountered connection error: %s. Retry in %d sec.', e, THROTTLE_PAUSE_SEC)
            time.sleep(THROTTLE_PAUSE_SEC)