__init__.py 2.66 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/'
18
        self.token_file = os.path.join(sickrage.app.data_dir, 'sr_token.json')
19
        self._token = {}
20
21
22

    @property
    def session(self):
echel0n's avatar
echel0n committed
23
        return OAuth2Session(token=self.token)
24
25
26

    @property
    def token(self):
echel0n's avatar
echel0n committed
27
28
29
        if os.path.exists(self.token_file):
            with open(self.token_file) as infile:
                self._token = json.load(infile)
30
        return self._token
echel0n's avatar
echel0n committed
31

echel0n's avatar
echel0n committed
32
33
    @token.setter
    def token(self, value):
34
        with open(self.token_file, 'w') as outfile:
echel0n's avatar
echel0n committed
35
            json.dump(value, outfile)
36

37
38
39
40
41
42
43
44
    @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})

45
    def _request(self, method, url, **kwargs):
echel0n's avatar
echel0n committed
46
        try:
echel0n's avatar
echel0n committed
47
48
49
            resp = self.session.request(method, urljoin(self.api_url, url), timeout=30,
                                        hooks={'response': self.throttle_hook}, **kwargs)

echel0n's avatar
echel0n committed
50
            if resp.status_code == 401:
echel0n's avatar
echel0n committed
51
52
                msg = resp.json()['message']
                raise unauthorized(msg)
echel0n's avatar
echel0n committed
53
            elif resp.status_code >= 400:
echel0n's avatar
echel0n committed
54
55
56
57
                msg = resp.json()['message']
                if resp.status_code == 500 and msg == 'Token is expired':
                    raise TokenExpiredError
                raise error(msg)
echel0n's avatar
echel0n committed
58
59

            return resp.json()
echel0n's avatar
echel0n committed
60
        except TokenExpiredError as e:
echel0n's avatar
echel0n committed
61
62
63
64
65
            try:
                self.token = sickrage.app.oidc_client.refresh_token(self.token['refresh_token'])
            except Exception:
                if os.path.exists(self.token_file):
                    os.remove(self.token_file)
echel0n's avatar
echel0n committed
66
            return self._request(method, url, **kwargs)
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)