diff options
Diffstat (limited to 'gallery_dl/extractor/redgifs.py')
| -rw-r--r-- | gallery_dl/extractor/redgifs.py | 123 |
1 files changed, 104 insertions, 19 deletions
diff --git a/gallery_dl/extractor/redgifs.py b/gallery_dl/extractor/redgifs.py index e078bef..df50f70 100644 --- a/gallery_dl/extractor/redgifs.py +++ b/gallery_dl/extractor/redgifs.py @@ -8,15 +8,60 @@ """Extractors for https://redgifs.com/""" -from .gfycat import GfycatExtractor, GfycatAPI +from .common import Extractor, Message from .. import text -class RedgifsExtractor(GfycatExtractor): +class RedgifsExtractor(Extractor): """Base class for redgifs extractors""" category = "redgifs" + filename_fmt = "{category}_{id}.{extension}" + archive_fmt = "{id}" root = "https://www.redgifs.com" + def __init__(self, match): + Extractor.__init__(self, match) + self.key = match.group(1) + + formats = self.config("format") + if formats is None: + formats = ("hd", "sd", "gif") + elif isinstance(formats, str): + formats = (formats, "hd", "sd", "gif") + self.formats = formats + + def items(self): + metadata = self.metadata() + for gif in self.gifs(): + url = self._process(gif) + if not url: + self.log.warning("Skipping '%s' (format not available)", + gif["id"]) + continue + + gif.update(metadata) + yield Message.Directory, gif + yield Message.Url, url, gif + + def _process(self, gif): + gif["_fallback"] = formats = self._formats(gif) + gif["date"] = text.parse_timestamp(gif.get("createDate")) + return next(formats, None) + + def _formats(self, gif): + urls = gif["urls"] + for fmt in self.formats: + url = urls.get(fmt) + if url: + text.nameext_from_url(url, gif) + yield url + + def metadata(self): + return {} + + def gifs(self): + return () + class RedgifsUserExtractor(RedgifsExtractor): """Extractor for redgifs user profiles""" @@ -24,11 +69,14 @@ class RedgifsUserExtractor(RedgifsExtractor): directory_fmt = ("{category}", "{userName}") pattern = r"(?:https?://)?(?:www\.)?redgifs\.com/users/([^/?#]+)" test = ("https://www.redgifs.com/users/Natalifiction", { - "pattern": r"https://\w+\.(redgifs|gfycat)\.com/[A-Za-z]+\.mp4", - "count": ">= 100", + "pattern": r"https://\w+\.redgifs\.com/[A-Za-z]+\.mp4", + "count": ">= 120", }) - def gfycats(self): + def metadata(self): + return {"userName": self.key} + + def gifs(self): return RedgifsAPI(self).user(self.key) @@ -36,19 +84,23 @@ class RedgifsSearchExtractor(RedgifsExtractor): """Extractor for redgifs search results""" subcategory = "search" directory_fmt = ("{category}", "Search", "{search}") - pattern = r"(?:https?://)?(?:www\.)?redgifs\.com/gifs/browse/([^/?#]+)" - test = ("https://www.redgifs.com/gifs/browse/jav", { - "pattern": r"https://\w+\.(redgifs|gfycat)\.com/[A-Za-z]+\.mp4", - "range": "1-10", - "count": 10, - }) + pattern = r"(?:https?://)?(?:www\.)?redgifs\.com/browse/?\?([^#]+)" + test = ( + ("https://www.redgifs.com/browse?tags=JAV", { + "pattern": r"https://\w+\.redgifs\.com/[A-Za-z]+\.mp4", + "range": "1-10", + "count": 10, + }), + ("https://www.redgifs.com/browse?type=i&verified=y&order=top7"), + ) def metadata(self): - self.key = text.unquote(self.key).replace("-", " ") - return {"search": self.key} + self.params = params = text.parse_query(self.key) + search = params.get("tags") or params.get("order") or "trending" + return {"search": search} - def gfycats(self): - return RedgifsAPI(self).search(self.key) + def gifs(self): + return RedgifsAPI(self).search(self.params) class RedgifsImageExtractor(RedgifsExtractor): @@ -58,7 +110,7 @@ class RedgifsImageExtractor(RedgifsExtractor): r"|gifdeliverynetwork.com)/([A-Za-z]+)") test = ( ("https://redgifs.com/watch/foolishforkedabyssiniancat", { - "pattern": r"https://\w+\.(redgifs|gfycat)\.com" + "pattern": r"https://\w+\.redgifs\.com" r"/FoolishForkedAbyssiniancat\.mp4", "content": "f6e03f1df9a2ff2a74092f53ee7580d2fb943533", }), @@ -66,9 +118,42 @@ class RedgifsImageExtractor(RedgifsExtractor): ("https://www.gifdeliverynetwork.com/foolishforkedabyssiniancat"), ) - def gfycats(self): - return (RedgifsAPI(self).gfycat(self.key),) + def gifs(self): + return (RedgifsAPI(self).gif(self.key),) -class RedgifsAPI(GfycatAPI): +class RedgifsAPI(): API_ROOT = "https://api.redgifs.com" + + def __init__(self, extractor): + self.extractor = extractor + + def gif(self, gif_id): + endpoint = "/v2/gifs/" + gif_id.lower() + return self._call(endpoint)["gif"] + + def user(self, user, order="best"): + endpoint = "/v2/users/{}/search".format(user.lower()) + params = {"order": order} + return self._pagination(endpoint, params) + + def search(self, params): + endpoint = "/v2/gifs/search" + params["search_text"] = params.pop("tags", None) + params.pop("needSendGtm", None) + return self._pagination(endpoint, params) + + def _call(self, endpoint, params=None): + url = self.API_ROOT + endpoint + return self.extractor.request(url, params=params).json() + + def _pagination(self, endpoint, params): + params["page"] = 1 + + while True: + data = self._call(endpoint, params) + yield from data["gifs"] + + if params["page"] >= data["pages"]: + return + params["page"] += 1 |
