From 7444fc125bacef8ce4db2e7e99aa80d3ee562f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20F=C3=A4hrmann?= Date: Thu, 6 Jul 2023 18:56:34 +0200 Subject: [PATCH] [gfycat] implement login support (#3770, #4271) For the record: '/webtoken' and '/weblogin' are not the same ... --- docs/configuration.rst | 1 + docs/supportedsites.md | 2 +- gallery_dl/extractor/gfycat.py | 41 +++++++++++++++++++++++++++++++++- scripts/supportedsites.py | 1 + test/test_results.py | 2 +- 5 files changed, 44 insertions(+), 3 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 193f35cf..75033307 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -382,6 +382,7 @@ Description * ``e621`` (*) * ``e926`` (*) * ``exhentai`` + * ``gfycat`` * ``idolcomplex`` * ``imgbb`` * ``inkbunny`` diff --git a/docs/supportedsites.md b/docs/supportedsites.md index 444e4db5..a3c0ee10 100644 --- a/docs/supportedsites.md +++ b/docs/supportedsites.md @@ -251,7 +251,7 @@ Consider all sites to be NSFW unless otherwise known. Gfycat https://gfycat.com/ Collections, individual Images, Search Results, User Profiles - + Supported Gofile diff --git a/gallery_dl/extractor/gfycat.py b/gallery_dl/extractor/gfycat.py index 2d057f48..ccebdf98 100644 --- a/gallery_dl/extractor/gfycat.py +++ b/gallery_dl/extractor/gfycat.py @@ -10,6 +10,7 @@ from .common import Extractor, Message from .. import text, exception +from ..cache import cache class GfycatExtractor(Extractor): @@ -221,6 +222,8 @@ class GfycatAPI(): def __init__(self, extractor): self.extractor = extractor + self.headers = {} + self.username, self.password = extractor._get_auth_info() def collection(self, user, collection): endpoint = "/v1/users/{}/collections/{}/gfycats".format( @@ -252,9 +255,45 @@ class GfycatAPI(): params = {"count": 100} return self._pagination(endpoint, params) + def authenticate(self): + self.headers["Authorization"] = \ + self._authenticate_impl(self.username, self.password) + + @cache(maxage=3600, keyarg=1) + def _authenticate_impl(self, username, password): + self.extractor.log.info("Logging in as %s", username) + + url = "https://weblogin.gfycat.com/oauth/webtoken" + headers = {"Origin": "https://gfycat.com"} + data = { + "access_key": "Anr96uuqt9EdamSCwK4txKPjMsf2" + "M95Rfa5FLLhPFucu8H5HTzeutyAa", + } + response = self.extractor.request( + url, method="POST", headers=headers, json=data).json() + + url = "https://weblogin.gfycat.com/oauth/weblogin" + headers["authorization"] = "Bearer " + response["access_token"] + data = { + "grant_type": "password", + "username" : username, + "password" : password, + } + response = self.extractor.request( + url, method="POST", headers=headers, json=data, fatal=None).json() + + if "errorMessage" in response: + raise exception.AuthenticationError( + response["errorMessage"]["description"]) + return "Bearer " + response["access_token"] + def _call(self, endpoint, params=None): + if self.username: + self.authenticate() + url = self.API_ROOT + endpoint - return self.extractor.request(url, params=params).json() + return self.extractor.request( + url, params=params, headers=self.headers).json() def _pagination(self, endpoint, params, key="gfycats"): while True: diff --git a/scripts/supportedsites.py b/scripts/supportedsites.py index 78e6843e..fb6ffa7b 100755 --- a/scripts/supportedsites.py +++ b/scripts/supportedsites.py @@ -312,6 +312,7 @@ AUTH_MAP = { "fanbox" : _COOKIES, "fantia" : _COOKIES, "flickr" : _OAUTH, + "gfycat" : "Supported", "furaffinity" : _COOKIES, "horne" : "Required", "idolcomplex" : "Supported", diff --git a/test/test_results.py b/test/test_results.py index 03a17c40..3c7d2844 100644 --- a/test/test_results.py +++ b/test/test_results.py @@ -325,7 +325,7 @@ def setup_test_config(): for category in ("danbooru", "atfbooru", "aibooru", "e621", "e926", "instagram", "twitter", "subscribestar", "deviantart", "inkbunny", "tapas", "pillowfort", "mangadex", - "vipergirls"): + "vipergirls", "gfycat"): config.set(("extractor", category), "username", None) config.set(("extractor", "mastodon.social"), "access-token",