Example #1
0
 def __init__(self, consumer_key, consumer_secret):
     """
     :param consumer_key: The application's API consumer key.
     :type consumer_key: str.
     :param consumer_secret: The application's API consumer secret.
     """
     self.oauth = OAuth(consumer_key, consumer_secret)
Example #2
0
 def __init__(self, consumer_key, consumer_secret):
     """
     :param consumer_key: The application's API consumer key.
     :type consumer_key: str.
     :param consumer_secret: The application's API consumer secret.
     """
     self.oauth = OAuth(consumer_key, consumer_secret)
Example #3
0
class ScoopItAPI(object):
    """
    Main class to access the Scoop.it API.
    """
    #XXX: take care not to duplicate objets actions in ScoopItAPI and objects methods

    def __init__(self, consumer_key, consumer_secret):
        """
        :param consumer_key: The application's API consumer key.
        :type consumer_key: str.
        :param consumer_secret: The application's API consumer secret.
        """
        self.oauth = OAuth(consumer_key, consumer_secret)

    def get_oauth_request_token(self):
        """
        Ask the API server for an oauth request_token.

        :returns: None
        """
        self.oauth.get_request_token()

    def get_oauth_access_token_url(self, callback_url):
        """
        Generate an access authorization URL.

        :param callback_url: The url to which the user should be redirected.
        :type callback_url: str.
        :returns: str -- The url to authorize the application.
        """
        return self.oauth.get_access_token_url(callback_url)

    def get_oauth_access_token(self, token_verifier):
        """
        Ask the API server for an oauth access_token.

        :param token_verifier: The code returned by the access_token url.
        :type token_verifier: str.
        :returns: None.
        """
        self.oauth.get_access_token(token_verifier)

    def save_oauth_token(self, filepath):
        """
        Save the current OAuth token to a file.

        :param filepath: Path to the file where the token should be saved.
        :type filepath: str.
        :returns: None.
        """
        self.oauth.save_token(filepath)

    def load_oauth_token(self, filepath):
        """
        Load a previously saved OAuth token.

        :param filepath: Path to the file containing the token.
        :type filepath: str.
        :returns: None.
        """
        self.oauth.load_token(filepath)

    def request(self, url, params, method='GET'):
        """
        Make a request to an API end-point, request will be signed using
        the current OAuth token.

        :param url: The end-point url.
        :type url: str.
        :param params: Parameters to pass to the request.
        :type params: dict.
        :param method: The HTTP method used to perform the request.
        :type method: str.
        :returns: dict -- Data returned by the server.
        """
        status, data = self.oauth.request(url, params, method)
        data = json.loads(data)
        if not data['success']:
            raise ScoopItError(
                "%s %s: %s" % (
                    status['status'],
                    ERROR_MESSAGES[status['status']],
                    data['error']
                ))
        return data

    def profile(self, profile_id=None, curated=None, curable=None):
        """
        Access a user's profile.

        :param profile_id: Profile owner's ID (defaults to the current user).
        :type profile_id: int or None.
        :param curated: Numer of curated posts to retrieve for each
                        topic (defaults to 0).
        :type curated: int or None.
        :param curable: Number of curable posts to retrieve for each topic
                        where the user is curator (defaults to 0).
        :returns: An :class:`scoopy.datatypes.User` object.
        """
        if (profile_id is not None) and (curable is not None):
            raise ScoopItError('profile_id and curable options are exclusive')
        params = {}
        if profile_id is not None:
            params['id'] = profile_id
        if curated is not None:
            params['curated'] = curated
        if curable is not None:
            params['curable'] = curable
        response = self.request(PROFILE_URL, params)
        return User(self, response['user'])

    def topic(self, topic_id, curated=None, curable=None,
                  order=None, tag=None, since=None):
        """
        Access a topic data (list of posts, statistics).

        :param topic_id: The topic's ID.
        :type topic_id: int or None.
        :param curated: Number of curated posts to retrieve from the
                        topic (defaults to 30).
        :type curated: int or None.
        :param curable: Number of curable posts to retrieve from the
                        topic (defaults to 30).
        :type curable: int or None.
        :param order: Sort order of curated posts, can be 'tag', 'curationDate',
                      or 'user' (mandatory if 'since' parameter isn't specified).
        :type order: str.
        :param tag: Tag used to filter results (mandatory if 'order' is 'tag').
        :type tag: str.
        :param since: Only retrieve curated posts newer than this.
        :type since: :class:`scoopy.datatypes.Timestamp`.
        :return: tuple -- (:class:`scoopy.datatypes.Topic`, :class:`scoopy.datatypes.TopicStats`)
        """
        # check for mandatory options
        if (curated is not None) and (curable is not None):
            raise ScoopItError('curated and curable options are exclusive')
        if (since is None) and (order is None):
            raise ScoopItError('at least order or since must be specified')
        if (order is not None) and (order not in ('tag', 'curationDate', 'user')):
            raise ScoopItError("order can only be 'tag', 'curationDate', or 'user'")
        if (order == 'tag') and (tag is None):
            raise ScoopItError("tag must be specified if order is 'tag'")
        # populate params
        params = {
            'id': topic_id,
        }
        if curated is not None:
            params['curated'] = curated
        if curable is not None:
            params['curable'] = curable
        if order is not None:
            params['order'] = order
        if tag is not None:
            params['tag'] = tag
        if since is not None:
            params['since'] = since.value
        response = self.request(TOPIC_URL, params)
        return Topic(self, response['topic'], response['stats'])

    def topic_reorder(self, topic_id, post_ids, start):
        #TODO: write ScoopItAPI.topic_reorder() method
        raise NotImplementedError

    def topic_follow(self, topic_id):
        self._topic_fum('follow', topic_id)
    def topic_unfollow(self, topic_id):
        self._topic_fum('unfollow', topic_id)
    def topic_markread(self, topic_id):
        self._topic_fum('markread', topic_id)
    def _topic_fum(self, action, topic_id):
        #TODO: write ScoopItAPI._topic_fum() method
        raise NotImplementedError

    def post(self, post_id):
        """
        Access a post data.

        :param post_id: The ID of the post.
        :type post_id: int.
        :return: a :class:`scoopy.datatypes.Post` object.
        """
        params = {
            'id': post_id,
        }
        response = self.request(POST_URL, params)
        return Post(self, response)

    def post_prepare(self, url):
        #TODO: write ScoopItAPI.post_prepare() method
        raise NotImplementedError

    def post_create(self, title, url, content, image_url, topic_id, share_on):
        #TODO: write ScoopItAPI.post_create() method
        raise NotImplementedError

    def post_comment(self, post_id, comment):
        #TODO: write ScoopItAPI.post_comment() method
        raise NotImplementedError

    def post_thank(self, post_id):
        #TODO: write ScoopItAPI.post_thank() method
        raise NotImplementedError

    def post_accept(self, post_id, title, content, image_url, share_on, topic_id):
        #TODO: write ScoopItAPI.post_accept() method
        raise NotImplementedError

    def post_forward(self, post_id, title, content, image_url, share_on, topic_id):
        #TODO: write ScoopItAPI.post_forward() method
        raise NotImplementedError

    def post_refuse(self, post_id, reason):
        #TODO: write ScoopItAPI.post_refuse() method
        raise NotImplementedError

    def post_delete(self, post_id):
        #TODO: write ScoopItAPI.post_delete() method
        raise NotImplementedError

    def post_edit(self, post_id, tags, title, content, image_url):
        #TODO: write ScoopItAPI.post_edit() method
        raise NotImplementedError

    def post_pin(self, post_id):
        #TODO: write ScoopItAPI.post_pin() method
        raise NotImplementedError

    def post_rescoop(self, post_id, topic_id):
        #TODO: write ScoopItAPI.post_rescoop() method
        raise NotImplementedError

    def post_share(self, post_id):
        #TODO: write ScoopItAPI.post_share() method
        raise NotImplementedError

    def notifications(self, since=None):
        """
        Notifications for the current user.

        :param since: Only get notifications newer than this.
        :type since: :class:`scoopy.datatypes.Timestamp` or None.
        :return: iterator -- :class:`scoopy.datatypes.Notification` objects.
        """
        params = {}
        if since is not None:
            params['since'] = since.value
        response = self.request(NOTIFICATIONS_URL, params)
        return [Notification(self, n) for n in response['notifications']]

    def compilation(self, since, count):
        """
        Get a compilation of followed topics of the current user.
        Posts are ordered by date.

        :param since: Only retrieve posts newer than this.
        :type since: :class:`scoopy.datatypes.Timestamp`.
        :param count: Maximum amount of posts to retrieve.
        :type count: int.
        :return: iterator -- :class:`scoopy.datatypes.Post` objects.
        """
        params = {
            'since': since.value,
            'count': count,
        }
        response = self.request(COMPILATION_URL, params)
        return [Post(self, p) for p in response['posts']]

    def test(self):
        #TODO: write ScoopItAPI.test() method
        raise NotImplementedError

    def search(self, type, query, page, lang):
        #TODO: write ScoopItAPI.search() method
        raise NotImplementedError

    def resolve(self, entity, short_name):
        """
        Resolve an object (topic or user) given its short name.

        :param entity: The type of entity to resolve ('user' or 'topic').
        :type entity: str.
        :param short_name: The short name to resolve.
        :type short_name: str.
        :return: str -- The ID corresponding to the given short name.
        """
        if entity.lower() not in ('user', 'topic'):
            raise ScoopItError("entity value can only be 'User' or 'Topic'")
        params = {
            'type': entity,
            'shortName': short_name,
        }
        response = self.request(RESOLVER_URL, params)
        return response['id']
Example #4
0
class ScoopItAPI(object):
    """
    Main class to access the Scoop.it API.
    """

    #XXX: take care not to duplicate objets actions in ScoopItAPI and objects methods

    def __init__(self, consumer_key, consumer_secret):
        """
        :param consumer_key: The application's API consumer key.
        :type consumer_key: str.
        :param consumer_secret: The application's API consumer secret.
        """
        self.oauth = OAuth(consumer_key, consumer_secret)

    def get_oauth_request_token(self):
        """
        Ask the API server for an oauth request_token.

        :returns: None
        """
        self.oauth.get_request_token()

    def get_oauth_access_token_url(self, callback_url):
        """
        Generate an access authorization URL.

        :param callback_url: The url to which the user should be redirected.
        :type callback_url: str.
        :returns: str -- The url to authorize the application.
        """
        return self.oauth.get_access_token_url(callback_url)

    def get_oauth_access_token(self, token_verifier):
        """
        Ask the API server for an oauth access_token.

        :param token_verifier: The code returned by the access_token url.
        :type token_verifier: str.
        :returns: None.
        """
        self.oauth.get_access_token(token_verifier)

    def save_oauth_token(self, filepath):
        """
        Save the current OAuth token to a file.

        :param filepath: Path to the file where the token should be saved.
        :type filepath: str.
        :returns: None.
        """
        self.oauth.save_token(filepath)

    def load_oauth_token(self, filepath):
        """
        Load a previously saved OAuth token.

        :param filepath: Path to the file containing the token.
        :type filepath: str.
        :returns: None.
        """
        self.oauth.load_token(filepath)

    def request(self, url, params, method='GET'):
        """
        Make a request to an API end-point, request will be signed using
        the current OAuth token.

        :param url: The end-point url.
        :type url: str.
        :param params: Parameters to pass to the request.
        :type params: dict.
        :param method: The HTTP method used to perform the request.
        :type method: str.
        :returns: dict -- Data returned by the server.
        """
        status, data = self.oauth.request(url, params, method)
        data = json.loads(data)
        if not data['success']:
            raise ScoopItError(
                "%s %s: %s" %
                (status['status'], ERROR_MESSAGES[status['status']],
                 data['error']))
        return data

    def profile(self, profile_id=None, curated=None, curable=None):
        """
        Access a user's profile.

        :param profile_id: Profile owner's ID (defaults to the current user).
        :type profile_id: int or None.
        :param curated: Numer of curated posts to retrieve for each
                        topic (defaults to 0).
        :type curated: int or None.
        :param curable: Number of curable posts to retrieve for each topic
                        where the user is curator (defaults to 0).
        :returns: An :class:`scoopy.datatypes.User` object.
        """
        if (profile_id is not None) and (curable is not None):
            raise ScoopItError('profile_id and curable options are exclusive')
        params = {}
        if profile_id is not None:
            params['id'] = profile_id
        if curated is not None:
            params['curated'] = curated
        if curable is not None:
            params['curable'] = curable
        response = self.request(PROFILE_URL, params)
        return User(self, response['user'])

    def topic(self,
              topic_id,
              curated=None,
              curable=None,
              order=None,
              tag=None,
              since=None):
        """
        Access a topic data (list of posts, statistics).

        :param topic_id: The topic's ID.
        :type topic_id: int or None.
        :param curated: Number of curated posts to retrieve from the
                        topic (defaults to 30).
        :type curated: int or None.
        :param curable: Number of curable posts to retrieve from the
                        topic (defaults to 30).
        :type curable: int or None.
        :param order: Sort order of curated posts, can be 'tag', 'curationDate',
                      or 'user' (mandatory if 'since' parameter isn't specified).
        :type order: str.
        :param tag: Tag used to filter results (mandatory if 'order' is 'tag').
        :type tag: str.
        :param since: Only retrieve curated posts newer than this.
        :type since: :class:`scoopy.datatypes.Timestamp`.
        :return: tuple -- (:class:`scoopy.datatypes.Topic`, :class:`scoopy.datatypes.TopicStats`)
        """
        # check for mandatory options
        if (curated is not None) and (curable is not None):
            raise ScoopItError('curated and curable options are exclusive')
        if (since is None) and (order is None):
            raise ScoopItError('at least order or since must be specified')
        if (order is not None) and (order
                                    not in ('tag', 'curationDate', 'user')):
            raise ScoopItError(
                "order can only be 'tag', 'curationDate', or 'user'")
        if (order == 'tag') and (tag is None):
            raise ScoopItError("tag must be specified if order is 'tag'")
        # populate params
        params = {
            'id': topic_id,
        }
        if curated is not None:
            params['curated'] = curated
        if curable is not None:
            params['curable'] = curable
        if order is not None:
            params['order'] = order
        if tag is not None:
            params['tag'] = tag
        if since is not None:
            params['since'] = since.value
        response = self.request(TOPIC_URL, params)
        return Topic(self, response['topic'], response['stats'])

    def topic_reorder(self, topic_id, post_ids, start):
        #TODO: write ScoopItAPI.topic_reorder() method
        raise NotImplementedError

    def topic_follow(self, topic_id):
        self._topic_fum('follow', topic_id)

    def topic_unfollow(self, topic_id):
        self._topic_fum('unfollow', topic_id)

    def topic_markread(self, topic_id):
        self._topic_fum('markread', topic_id)

    def _topic_fum(self, action, topic_id):
        #TODO: write ScoopItAPI._topic_fum() method
        raise NotImplementedError

    def post(self, post_id):
        """
        Access a post data.

        :param post_id: The ID of the post.
        :type post_id: int.
        :return: a :class:`scoopy.datatypes.Post` object.
        """
        params = {
            'id': post_id,
        }
        response = self.request(POST_URL, params)
        return Post(self, response)

    def post_prepare(self, url):
        #TODO: write ScoopItAPI.post_prepare() method
        raise NotImplementedError

    def post_create(self, title, url, content, image_url, topic_id, share_on):
        #TODO: write ScoopItAPI.post_create() method
        raise NotImplementedError

    def post_comment(self, post_id, comment):
        #TODO: write ScoopItAPI.post_comment() method
        raise NotImplementedError

    def post_thank(self, post_id):
        #TODO: write ScoopItAPI.post_thank() method
        raise NotImplementedError

    def post_accept(self, post_id, title, content, image_url, share_on,
                    topic_id):
        #TODO: write ScoopItAPI.post_accept() method
        raise NotImplementedError

    def post_forward(self, post_id, title, content, image_url, share_on,
                     topic_id):
        #TODO: write ScoopItAPI.post_forward() method
        raise NotImplementedError

    def post_refuse(self, post_id, reason):
        #TODO: write ScoopItAPI.post_refuse() method
        raise NotImplementedError

    def post_delete(self, post_id):
        #TODO: write ScoopItAPI.post_delete() method
        raise NotImplementedError

    def post_edit(self, post_id, tags, title, content, image_url):
        #TODO: write ScoopItAPI.post_edit() method
        raise NotImplementedError

    def post_pin(self, post_id):
        #TODO: write ScoopItAPI.post_pin() method
        raise NotImplementedError

    def post_rescoop(self, post_id, topic_id):
        #TODO: write ScoopItAPI.post_rescoop() method
        raise NotImplementedError

    def post_share(self, post_id):
        #TODO: write ScoopItAPI.post_share() method
        raise NotImplementedError

    def notifications(self, since=None):
        """
        Notifications for the current user.

        :param since: Only get notifications newer than this.
        :type since: :class:`scoopy.datatypes.Timestamp` or None.
        :return: iterator -- :class:`scoopy.datatypes.Notification` objects.
        """
        params = {}
        if since is not None:
            params['since'] = since.value
        response = self.request(NOTIFICATIONS_URL, params)
        return [Notification(self, n) for n in response['notifications']]

    def compilation(self, since, count):
        """
        Get a compilation of followed topics of the current user.
        Posts are ordered by date.

        :param since: Only retrieve posts newer than this.
        :type since: :class:`scoopy.datatypes.Timestamp`.
        :param count: Maximum amount of posts to retrieve.
        :type count: int.
        :return: iterator -- :class:`scoopy.datatypes.Post` objects.
        """
        params = {
            'since': since.value,
            'count': count,
        }
        response = self.request(COMPILATION_URL, params)
        return [Post(self, p) for p in response['posts']]

    def test(self):
        #TODO: write ScoopItAPI.test() method
        raise NotImplementedError

    def search(self, type, query, page, lang):
        #TODO: write ScoopItAPI.search() method
        raise NotImplementedError

    def resolve(self, entity, short_name):
        """
        Resolve an object (topic or user) given its short name.

        :param entity: The type of entity to resolve ('user' or 'topic').
        :type entity: str.
        :param short_name: The short name to resolve.
        :type short_name: str.
        :return: str -- The ID corresponding to the given short name.
        """
        if entity.lower() not in ('user', 'topic'):
            raise ScoopItError("entity value can only be 'User' or 'Topic'")
        params = {
            'type': entity,
            'shortName': short_name,
        }
        response = self.request(RESOLVER_URL, params)
        return response['id']