diff --git a/docs/configuration.rst b/docs/configuration.rst index 49205791..d9feb440 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -896,6 +896,28 @@ Description See `Filters `_ for details. +extractor.deviantart.auto-watch +------------------------------- +Type + ``bool`` +Default + ``false`` +Description + Automatically watch users when encountering "Watchers-Only Deviations" + (requires a `refresh-token `_). + + +extractor.deviantart.auto-unwatch +--------------------------------- +Type + ``bool`` +Default + ``false`` +Description + After watching a user through `auto-watch `_, + unwatch that user at the end of the current extractor run. + + extractor.deviantart.comments ----------------------------- Type @@ -1053,17 +1075,6 @@ Description or whenever your `cache file `__ is deleted or cleared. -extractor.deviantart.auto-watch -------------------------------- -Type - ``bool`` -Default - ``false`` -Description - Automatically watch users when encountering "Watchers-Only Deviations" - (requires a `refresh-token `_). - - extractor.deviantart.wait-min ----------------------------- Type diff --git a/gallery_dl/extractor/deviantart.py b/gallery_dl/extractor/deviantart.py index b4ac742f..9bf898ca 100644 --- a/gallery_dl/extractor/deviantart.py +++ b/gallery_dl/extractor/deviantart.py @@ -46,6 +46,13 @@ class DeviantartExtractor(Extractor): self.group = False self.api = None + unwatch = self.config("auto-unwatch") + if unwatch: + self.unwatch = [] + self.finalize = self._unwatch_premium + else: + self.unwatch = None + if self.quality: self.quality = ",q_{}".format(self.quality) @@ -318,44 +325,48 @@ class DeviantartExtractor(Extractor): except KeyError: pass - # check accessibility - if self.api.refresh_token_key: - dev = self.api.deviation(deviation["deviationid"], False) - has_access = dev["premium_folder_data"]["has_access"] - username = dev["author"]["username"] - folder = dev["premium_folder_data"] - - if not has_access and folder["type"] == "watchers" and \ - self.config("auto-watch"): - if self.api.user_friends_watch(username): - has_access = True - self.log.info( - "Watching %s for premium folder access", username) - else: - self.log.warning( - "Error when trying to watch %s. " - "Try again with a new refresh-token", username) - else: + if not self.api.refresh_token_key: self.log.warning( "Unable to access premium content (no refresh-token)") self._fetch_premium = lambda _: None return None - if has_access: - self.log.info("Fetching premium folder data") - else: + dev = self.api.deviation(deviation["deviationid"], False) + folder = dev["premium_folder_data"] + username = dev["author"]["username"] + has_access = folder["has_access"] + + if not has_access and folder["type"] == "watchers" and \ + self.config("auto-watch"): + if self.unwatch is not None: + self.unwatch.append(username) + if self.api.user_friends_watch(username): + has_access = True + self.log.info( + "Watching %s for premium folder access", username) + else: + self.log.warning( + "Error when trying to watch %s. " + "Try again with a new refresh-token", username) + + if not has_access: self.log.warning("Unable to access premium content (type: %s)", folder["type"]) self._fetch_premium = lambda _: None return None - # fill cache + self.log.info("Fetching premium folder data") cache = self._premium_cache for dev in self.api.gallery( username, folder["gallery_id"], public=False): cache[dev["deviationid"]] = dev return cache[deviation["deviationid"]] + def _unwatch_premium(self): + for username in self.unwatch: + self.log.info("Unwatching %s", username) + self.api.user_friends_unwatch(username) + class DeviantartUserExtractor(DeviantartExtractor): """Extractor for an artist's user profile""" @@ -1153,13 +1164,15 @@ class DeviantartOAuthAPI(): "mature_content" : self.mature, } return self._call( - endpoint, method="POST", data=data, public=False, fatal=False) + endpoint, method="POST", data=data, public=False, fatal=False, + ).get("success") def user_friends_unwatch(self, username): """Unwatch a user""" endpoint = "user/friends/unwatch/" + username return self._call( - endpoint, method="POST", public=False, fatal=False) + endpoint, method="POST", public=False, fatal=False, + ).get("success") def authenticate(self, refresh_token_key): """Authenticate the application by requesting an access token"""