__init__.py 2.85 KB
Newer Older
1
2
from __future__ import unicode_literals

3
4
import json
import os
echel0n's avatar
echel0n committed
5
import time
6
7
from urlparse import urljoin

echel0n's avatar
echel0n committed
8
from oauthlib.oauth2 import MissingTokenError, InvalidClientIdError, TokenExpiredError
echel0n's avatar
echel0n committed
9
10
from requests_oauthlib import OAuth2Session

11
12
13
14
15
import sickrage
from sickrage.core.api.exceptions import unauthorized, error


class API(object):
echel0n's avatar
echel0n committed
16
17
    def __init__(self):
        self.api_url = 'https://api.sickrage.ca/api/v1/'
echel0n's avatar
echel0n committed
18
19
20
        self.client_id = sickrage.app.oidc_client._client_id
        self.client_secret = sickrage.app.oidc_client._client_secret
        self.token_url = sickrage.app.oidc_client.well_known['token_endpoint']
21
        self.token_file = os.path.join(sickrage.app.data_dir, 'sr_token.json')
echel0n's avatar
echel0n committed
22
        self._session = None
23
        self._token = {}
24
25
26

    @property
    def session(self):
echel0n's avatar
echel0n committed
27
28
29
30
31
32
33
34
        if self._session is None:
            self._session = OAuth2Session(self.client_id,
                                          token=self.token,
                                          auto_refresh_url=self.token_url,
                                          auto_refresh_kwargs={'client_id': self.client_id,
                                                               'client_secret': self.client_secret},
                                          token_updater=self.token)
        return self._session
35
36
37

    @property
    def token(self):
echel0n's avatar
echel0n committed
38
39
40
        if os.path.exists(self.token_file):
            with open(self.token_file) as infile:
                self._token = json.load(infile)
41
        return self._token
echel0n's avatar
echel0n committed
42

echel0n's avatar
echel0n committed
43
44
    @token.setter
    def token(self, value):
45
        with open(self.token_file, 'w') as outfile:
echel0n's avatar
echel0n committed
46
            json.dump(value, outfile)
47

48
49
50
51
52
53
54
55
    @property
    def userinfo(self):
        if self.token:
            return sickrage.app.oidc_client.userinfo(self.token['access_token'])

    def register_appid(self, appid):
        self._request('POST', 'register-appid', json={'appid': appid})

56
    def _request(self, method, url, **kwargs):
echel0n's avatar
echel0n committed
57
        try:
echel0n's avatar
echel0n committed
58
59
60
            resp = self.session.request(method, urljoin(self.api_url, url), timeout=30,
                                        hooks={'response': self.throttle_hook}, **kwargs)

echel0n's avatar
echel0n committed
61
            if resp.status_code == 401:
echel0n's avatar
echel0n committed
62
                raise unauthorized(resp.json()['message'])
echel0n's avatar
echel0n committed
63
            elif resp.status_code >= 400:
echel0n's avatar
echel0n committed
64
                raise error(resp.json()['message'])
echel0n's avatar
echel0n committed
65
66

            return resp.json()
echel0n's avatar
echel0n committed
67
        except (InvalidClientIdError, MissingTokenError) as e:
68
            sickrage.app.log.warning("SiCKRAGE username or password is incorrect, please try again")
69

echel0n's avatar
echel0n committed
70
71
72
73
74
75
76
77
78
    @staticmethod
    def throttle_hook(response, **kwargs):
        ratelimited = "X-RateLimit-Remaining" in response.headers

        if ratelimited:
            remaining = int(response.headers["X-RateLimit-Remaining"])
            if remaining == 1:
                sickrage.app.log.debug("Throttling SiCKRAGE API Calls... Sleeping for 60 secs...\n")
                time.sleep(60)