GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 303568...b20752 )
by Anton
03:54
created

wallhavenapi.WallhavenApiV1.settings()   A

Complexity

Conditions 2

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
import logging
2
import requests
3
import os
4
from enum import Enum
5
6
7
class Purity(Enum):
8
    sfw = "sfw"
9
    sketchy = "sketchy"
10
    nsfw = "nsfw"
11
12
13
class Category(Enum):
14
    general = "general"
15
    anime = "anime"
16
    people = "people"
17
18
19
class Sorting(Enum):
20
    date_added = "date_added"
21
    relevance = "relevance"
22
    random = "random"
23
    views = "views"
24
    favorites = "favorites"
25
    toplist = "toplist"
26
27
28
class Order(Enum):
29
    # desc used by default
30
    desc = "desc"
31
    asc = "asc"
32
33
34
class TopRange(Enum):
35
    one_day = "1d"
36
    three_days = "3d"
37
    one_week = "1w"
38
    one_month = "1M"
39
    three_months = "3M"
40
    six_months = "6M"
41
    one_year = "1y"
42
43
44
class Color(Enum):
45
    # Color names from http://chir.ag/projects/name-that-color
46
    lonestar = "660000"
47
    red_berry = "990000"
48
    guardsman_red = "cc0000"
49
    persian_red = "cc3333"
50
    french_rose = "ea4c88"
51
    plum = "993399"
52
    royal_purple = "663399"
53
    sapphire = "333399"
54
    science_blue = "0066cc"
55
    pacific_blue = "0099cc"
56
    downy = "66cccc"
57
    atlantis = "77cc33"
58
    limeade = "669900"
59
    verdun_green = "336600"
60
    verdun_green_2 = "666600"
61
    olive = "999900"
62
    earls_green = "cccc33"
63
    yellow = "ffff00"
64
    sunglow = "ffcc33"
65
    orange_peel = "ff9900"
66
    blaze_orange = "ff6600"
67
    tuscany = "cc6633"
68
    potters_clay = "996633"
69
    nutmeg_wood_finish = "663300"
70
    black = "000000"
71
    dusty_gray = "999999"
72
    silver = "cccccc"
73
    white = "ffffff"
74
    gun_powder = "424153"
75
76
77
class Type(Enum):
78
    jpeg = "jpeg"
79
    jpg = "jpg" # the same as jpeg
80
    png = "png"
81
82
83
class RequestsLimitError(Exception):
84
    def __init__(self):
85
        super().__init__("You have exceeded requests limit. Please try later.")
86
87
88
class ApiKeyError(Exception):
89
    def __init__(self):
90
        super().__init__("Bad api key. Check it please.")
91
92
93
class UnhandledException(Exception):
94
    def __init__(self):
95
        super().__init__("Somthing went wrong. Please submit this issue to "
96
                         "https://github.com/Goblenus/WallhavenApi/issues.")
97
98
99
class NoWallpaperError(Exception):
100
    def __init__(self, wallpaper_id):
101
        super().__init__("No wallpaper with id {}".format(wallpaper_id))
102
103
104
class WallhavenApiV1:
105
    def __init__(self, api_key=None, verify_connection=True, base_url="https://wallhaven.cc/api/v1", 
106
                 timeout=(2,5)):
107
        self.verify_connection = verify_connection
108
        self.api_key = api_key
109
        self.base_url = base_url
110
        self.timeout = timeout
111
112
    def _request(self, to_json, **kwargs):
113
        if self.api_key is not None:
114
            if "params" in kwargs:
115
                kwargs["params"]["apikey"] = self.api_key
116
            else:
117
                kwargs["params"] = {"apikey": self.api_key}
118
119
        if "timeout" not in kwargs:
120
            kwargs["timeout"] = self.timeout
121
122
        if "verify" not in kwargs:
123
            kwargs["verify"] = self.verify_connection
124
125
        response = requests.request(**kwargs)
126
127
        if response.status_code == 429:
128
            raise RequestsLimitError
129
130
        if response.status_code == 401:
131
            raise ApiKeyError
132
133
        if response.status_code != 200:
134
            raise UnhandledException
135
136
        if to_json:
137
            try:
138
                return response.json()
139
            except:
140
                raise UnhandledException
141
142
        return response
143
144
    def _url_format(self, *args):
145
        url = self.base_url
146
        url += "/" if not url.endswith("/") else ""
147
148
        return url + "/".join((str(x) for x in args))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable x does not seem to be defined.
Loading history...
149
150
    @staticmethod
151
    def _category(general=True, anime=True, people=False):
152
        return "{}{}{}".format(int(general), int(anime), int(people))
153
154
    @staticmethod
155
    def _purity(sfw=True, sketchy=True, nsfw=False):
156
        return "{}{}{}".format(int(sfw), int(sketchy), int(nsfw))
157
158
    def search(self, q=None, categories=None, purities=None, sorting=None, order=None, top_range=None, atleast=None, 
159
               resolutions=None, ratios=None, colors=None, page=None):
160
        params = {}
161
        if q is not None:
162
            params["q"] = q
163
164
        if categories is not None:
165
            categories = categories if type(categories) is list else [categories]
166
            params["categories"] = self._category(Category.general in categories, Category.anime in categories, 
167
                                                  Category.people in categories)
168
169
        if purities is not None:
170
            purities = purities if type(purities) is list else [purities]
171
            params["purity"] = self._purity(Purity.sfw in purities, Purity.sketchy in purities, 
172
                Purity.nsfw in purities)
173
174
        if sorting is not None:
175
            params["sorting"] = sorting.value
176
177
        if order is not None:
178
            params["order"] = order.value
179
180
        if top_range is not None:
181
            params["topRange"] = top_range.value
182
183
        if atleast is not None:
184
            params["atleast"] = "{}x{}".format(atleast[0], atleast[1])
185
186
        if resolutions is not None:
187
            params["resolutions"] = ",".join(["{}x{}".format(x[0], x[1]) \
188
                for x in (resolutions if type(resolutions) is list else [resolutions])])
189
190
        if ratios is not None:
191
            params["ratios"] = ",".join(["{}x{}".format(x[0], x[1]) \
192
                for x in (ratios if type(ratios) is list else [ratios])])
193
        
194
        if colors is not None:
195
            params["colors"] = colors.value
196
197
        if page is not None:
198
            params["page"] = str(page)
199
200
        return self._request(True, method="get", url=self._url_format("search"), params=params)
201
202
    def wallpaper(self, wallpaper_id):
203
        return self._request(True, method="get", url=self._url_format("w", wallpaper_id))
204
205
    def is_walpaper_exists(self, wallpaper_id):
206
        return "error" not in self.wallpaper(wallpaper_id)
207
208
    def download_walpaper(self, wallpaper_id, file_path, chunk_size=4096):
209
        wallpaper_data = self.wallpaper(wallpaper_id)
210
211
        if "error" in wallpaper_data:
212
            raise NoWallpaperError(wallpaper_id)
213
214
        wallpaper = requests.get(wallpaper_data["data"]["path"], stream=True, timeout=self.timeout, 
215
                                 verify=self.verify_connection)
216
217
        if wallpaper.status_code != 200:
218
            raise UnhandledException
219
220
        save_path = os.path.abspath(file_path)
221
        save_directory_path = os.path.dirname(save_path)
222
223
        if not os.path.exists(save_directory_path):
224
            os.makedirs(save_directory_path)
225
226
        with open(save_path, "wb") as image_file:
227
            for chunk in wallpaper.iter_content(chunk_size):
228
                image_file.write(chunk)
229
230
        return save_path
231
232
    def tag(self, tag_id):
233
        return self._request(True, method="get", url=self._url_format("tag", tag_id))
234
235
    def settings(self):
236
        return None if self.api_key is None else self._request(True, method="get", url=self._url_format("settings"))
237