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 ( 226fe6...caa6b4 )
by Anton
03:51
created

wallhavenapi.WallhavenApiV1.collections()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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