From d8ef1d693f3dbe77e1fd7e9df5df1691269374ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20F=C3=A4hrmann?= Date: Wed, 9 Jul 2025 21:07:28 +0200 Subject: [PATCH] rename 'StopExtraction' to 'AbortExtraction' for cases where StopExtraction was used to report errors --- gallery_dl/__init__.py | 6 ++---- gallery_dl/exception.py | 6 +----- gallery_dl/extractor/ao3.py | 2 +- gallery_dl/extractor/arcalive.py | 5 ++--- gallery_dl/extractor/bilibili.py | 11 ++++++----- gallery_dl/extractor/bluesky.py | 4 ++-- gallery_dl/extractor/boosty.py | 2 +- gallery_dl/extractor/bunkr.py | 4 ++-- gallery_dl/extractor/common.py | 4 ++-- gallery_dl/extractor/deviantart.py | 4 ++-- gallery_dl/extractor/discord.py | 2 +- gallery_dl/extractor/exhentai.py | 20 ++++++++++---------- gallery_dl/extractor/facebook.py | 15 +++++++-------- gallery_dl/extractor/flickr.py | 2 +- gallery_dl/extractor/gofile.py | 4 ++-- gallery_dl/extractor/idolcomplex.py | 2 +- gallery_dl/extractor/imagechest.py | 2 +- gallery_dl/extractor/imagefap.py | 2 +- gallery_dl/extractor/inkbunny.py | 2 +- gallery_dl/extractor/instagram.py | 15 ++++++++------- gallery_dl/extractor/lofter.py | 2 +- gallery_dl/extractor/luscious.py | 6 +++--- gallery_dl/extractor/mangadex.py | 12 ++++++------ gallery_dl/extractor/mangapark.py | 4 ++-- gallery_dl/extractor/mastodon.py | 9 ++++----- gallery_dl/extractor/newgrounds.py | 2 +- gallery_dl/extractor/oauth.py | 4 ++-- gallery_dl/extractor/patreon.py | 12 ++++++------ gallery_dl/extractor/pexels.py | 2 +- gallery_dl/extractor/philomena.py | 3 +-- gallery_dl/extractor/pinterest.py | 2 +- gallery_dl/extractor/pixiv.py | 10 +++++----- gallery_dl/extractor/pixnet.py | 4 ++-- gallery_dl/extractor/postmill.py | 4 ++-- gallery_dl/extractor/readcomiconline.py | 6 +++--- gallery_dl/extractor/reddit.py | 5 +++-- gallery_dl/extractor/sankaku.py | 2 +- gallery_dl/extractor/seiga.py | 4 ++-- gallery_dl/extractor/smugmug.py | 4 ++-- gallery_dl/extractor/steamgriddb.py | 8 ++++---- gallery_dl/extractor/subscribestar.py | 4 ++-- gallery_dl/extractor/tsumino.py | 10 +++++----- gallery_dl/extractor/tumblr.py | 6 +++--- gallery_dl/extractor/twibooru.py | 3 +-- gallery_dl/extractor/twitter.py | 18 +++++++++--------- gallery_dl/extractor/urlshortener.py | 2 +- gallery_dl/extractor/vk.py | 4 ++-- gallery_dl/extractor/wallhaven.py | 6 +++--- gallery_dl/extractor/webtoons.py | 4 ++-- gallery_dl/extractor/weibo.py | 10 +++++----- gallery_dl/extractor/wikimedia.py | 2 +- gallery_dl/extractor/xfolio.py | 2 +- gallery_dl/extractor/ytdl.py | 2 +- gallery_dl/extractor/zerochan.py | 2 +- gallery_dl/job.py | 7 ++++--- gallery_dl/update.py | 2 +- gallery_dl/ytdl.py | 2 +- 57 files changed, 149 insertions(+), 156 deletions(-) diff --git a/gallery_dl/__init__.py b/gallery_dl/__init__.py index 9a6449c0..12c590be 100644 --- a/gallery_dl/__init__.py +++ b/gallery_dl/__init__.py @@ -351,13 +351,11 @@ def main(): else: input_manager.success() - except exception.StopExtraction: - pass - except exception.TerminateExtraction: - pass except exception.RestartExtraction: log.debug("Restarting '%s'", url) continue + except exception.ControlException: + pass except exception.NoExtractorError: log.error("Unsupported URL '%s'", url) retval |= 64 diff --git a/gallery_dl/exception.py b/gallery_dl/exception.py index 86e54f7f..79d663ce 100644 --- a/gallery_dl/exception.py +++ b/gallery_dl/exception.py @@ -47,6 +47,7 @@ class GalleryDLException(Exception): message = f"{message.__class__.__name__}: {message}" if fmt and self.msgfmt is not None: message = self.msgfmt.replace("{}", message) + self.message = message Exception.__init__(self, message) @@ -151,11 +152,6 @@ class ControlException(GalleryDLException): class StopExtraction(ControlException): """Stop data extraction""" - def __init__(self, message=None, *args): - ControlException.__init__(self) - self.message = message % args if args else message - self.code = 1 if message else 0 - class AbortExtraction(ExtractionError, ControlException): """Abort data extraction due to an error""" diff --git a/gallery_dl/extractor/ao3.py b/gallery_dl/extractor/ao3.py index 3f361fc4..805b081f 100644 --- a/gallery_dl/extractor/ao3.py +++ b/gallery_dl/extractor/ao3.py @@ -144,7 +144,7 @@ class Ao3WorkExtractor(Ao3Extractor): page = response.text if len(page) < 20000 and \ '

Adult Content Warning 4: - raise exception.StopExtraction( + raise exception.AbortExtraction( "Non-members can only search up to 4 tags at once") return {"search_tags": " ".join(tags)} diff --git a/gallery_dl/extractor/imagechest.py b/gallery_dl/extractor/imagechest.py index 3a94640e..f3ae2bcb 100644 --- a/gallery_dl/extractor/imagechest.py +++ b/gallery_dl/extractor/imagechest.py @@ -152,4 +152,4 @@ class ImagechestAPI(): else: self.extractor.log.debug(response.text) - raise exception.StopExtraction("API request failed") + raise exception.AbortExtraction("API request failed") diff --git a/gallery_dl/extractor/imagefap.py b/gallery_dl/extractor/imagefap.py index 1a235628..975add54 100644 --- a/gallery_dl/extractor/imagefap.py +++ b/gallery_dl/extractor/imagefap.py @@ -31,7 +31,7 @@ class ImagefapExtractor(Extractor): msg = text.extr(response.text, '
")[2].split()) - raise exception.StopExtraction("'%s'", msg) + raise exception.AbortExtraction(f"'{msg}'") self.log.warning("HTTP redirect to %s", response.url) return response diff --git a/gallery_dl/extractor/inkbunny.py b/gallery_dl/extractor/inkbunny.py index be562a43..1de2b441 100644 --- a/gallery_dl/extractor/inkbunny.py +++ b/gallery_dl/extractor/inkbunny.py @@ -350,7 +350,7 @@ class InkbunnyAPI(): self.authenticate(invalidate=True) continue - raise exception.StopExtraction(data.get("error_message")) + raise exception.AbortExtraction(data.get("error_message")) def _pagination_search(self, params): params["page"] = 1 diff --git a/gallery_dl/extractor/instagram.py b/gallery_dl/extractor/instagram.py index e7a495ee..c2f1224d 100644 --- a/gallery_dl/extractor/instagram.py +++ b/gallery_dl/extractor/instagram.py @@ -136,9 +136,9 @@ class InstagramExtractor(Extractor): else: page = None - if page: - raise exception.StopExtraction("HTTP redirect to %s page (%s)", - page, url.partition("?")[0]) + if page is not None: + raise exception.AbortExtraction( + f"HTTP redirect to {page} page ({url.partition('?')[0]})") www_claim = response.headers.get("x-ig-set-www-claim") if www_claim is not None: @@ -979,7 +979,7 @@ class InstagramGraphqlAPI(): self.user_id = api.user_id def _unsupported(self, _=None): - raise exception.StopExtraction("Unsupported with GraphQL API") + raise exception.AbortExtraction("Unsupported with GraphQL API") def highlights_tray(self, user_id): query_hash = "d4d88dc1500312af6f937f7b804c68c3" @@ -1065,9 +1065,10 @@ class InstagramGraphqlAPI(): if not info["has_next_page"]: return extr._update_cursor(None) elif not data["edges"]: - s = "" if self.extractor.item.endswith("s") else "s" - raise exception.StopExtraction( - "%s'%s posts are private", self.extractor.item, s) + user = self.extractor.item + s = "" if user.endswith("s") else "s" + raise exception.AbortExtraction( + f"{user}'{s} posts are private") variables["after"] = extr._update_cursor(info["end_cursor"]) diff --git a/gallery_dl/extractor/lofter.py b/gallery_dl/extractor/lofter.py index b92a6fff..c20d983d 100644 --- a/gallery_dl/extractor/lofter.py +++ b/gallery_dl/extractor/lofter.py @@ -136,7 +136,7 @@ class LofterAPI(): if info["meta"]["status"] != 200: self.extractor.log.debug("Server response: %s", info) - raise exception.StopExtraction("API request failed") + raise exception.AbortExtraction("API request failed") return info["response"] diff --git a/gallery_dl/extractor/luscious.py b/gallery_dl/extractor/luscious.py index 66f2b6ab..0cbc5231 100644 --- a/gallery_dl/extractor/luscious.py +++ b/gallery_dl/extractor/luscious.py @@ -32,9 +32,9 @@ class LusciousExtractor(Extractor): if response.status_code >= 400: self.log.debug("Server response: %s", response.text) - raise exception.StopExtraction( - "GraphQL query failed ('%s %s')", - response.status_code, response.reason) + raise exception.AbortExtraction( + f"GraphQL query failed " + f"('{response.status_code} {response.reason}')") return response.json()["data"] diff --git a/gallery_dl/extractor/mangadex.py b/gallery_dl/extractor/mangadex.py index 10616844..b1c008f4 100644 --- a/gallery_dl/extractor/mangadex.py +++ b/gallery_dl/extractor/mangadex.py @@ -112,10 +112,10 @@ class MangadexChapterExtractor(MangadexExtractor): data = self._transform(chapter) if data.get("_external_url") and not data["count"]: - raise exception.StopExtraction( - "Chapter %s%s is not available on MangaDex and can instead be " - "read on the official publisher's website at %s.", - data["chapter"], data["chapter_minor"], data["_external_url"]) + raise exception.AbortExtraction( + f"Chapter {data['chapter']}{data['chapter_minor']} is not " + f"available on MangaDex and can instead be read on the " + f"official publisher's website at {data['_external_url']}.") yield Message.Directory, data @@ -356,8 +356,8 @@ class MangadexAPI(): msg = ", ".join('{title}: "{detail}"'.format_map(error) for error in response.json()["errors"]) - raise exception.StopExtraction( - "%s %s (%s)", response.status_code, response.reason, msg) + raise exception.AbortExtraction( + f"{response.status_code} {response.reason} ({msg})") def _pagination_chapters(self, endpoint, params=None, auth=False): if params is None: diff --git a/gallery_dl/extractor/mangapark.py b/gallery_dl/extractor/mangapark.py index 76d59368..67e81bbc 100644 --- a/gallery_dl/extractor/mangapark.py +++ b/gallery_dl/extractor/mangapark.py @@ -176,8 +176,8 @@ class MangaparkMangaExtractor(MangaparkBase, Extractor): not lang or data["lang"] == lang): return data["id"] - raise exception.StopExtraction( - "'%s' does not match any available source", source) + raise exception.AbortExtraction( + f"'{source}' does not match any available source") QUERIES = { diff --git a/gallery_dl/extractor/mastodon.py b/gallery_dl/extractor/mastodon.py index 00e5296b..77ed8f71 100644 --- a/gallery_dl/extractor/mastodon.py +++ b/gallery_dl/extractor/mastodon.py @@ -315,10 +315,9 @@ class MastodonAPI(): if code < 400: return response if code == 401: - raise exception.StopExtraction( - "Invalid or missing access token.\n" - "Run 'gallery-dl oauth:mastodon:%s' to obtain one.", - self.extractor.instance) + raise exception.AbortExtraction( + f"Invalid or missing access token.\nRun 'gallery-dl oauth:" + f"mastodon:{self.extractor.instance}' to obtain one.") if code == 404: raise exception.NotFoundError() if code == 429: @@ -327,7 +326,7 @@ class MastodonAPI(): "%Y-%m-%dT%H:%M:%S.%fZ", )) continue - raise exception.StopExtraction(response.json().get("error")) + raise exception.AbortExtraction(response.json().get("error")) def _pagination(self, endpoint, params): url = endpoint diff --git a/gallery_dl/extractor/newgrounds.py b/gallery_dl/extractor/newgrounds.py index 63782c63..dac72889 100644 --- a/gallery_dl/extractor/newgrounds.py +++ b/gallery_dl/extractor/newgrounds.py @@ -366,7 +366,7 @@ class NewgroundsExtractor(Extractor): return if "errors" in data: msg = ", ".join(text.unescape(e) for e in data["errors"]) - raise exception.StopExtraction(msg) + raise exception.AbortExtraction(msg) items = data.get("items") if not items: diff --git a/gallery_dl/extractor/oauth.py b/gallery_dl/extractor/oauth.py index b7848dc2..9bafcfc3 100644 --- a/gallery_dl/extractor/oauth.py +++ b/gallery_dl/extractor/oauth.py @@ -386,8 +386,8 @@ class OAuthMastodon(OAuthBase): data = self.request_json(url, method="POST", data=data) if "client_id" not in data or "client_secret" not in data: - raise exception.StopExtraction( - "Failed to register new application: '%s'", data) + raise exception.AbortExtraction( + f"Failed to register new application: '{data}'") data["client-id"] = data.pop("client_id") data["client-secret"] = data.pop("client_secret") diff --git a/gallery_dl/extractor/patreon.py b/gallery_dl/extractor/patreon.py index bce5bda3..c019218b 100644 --- a/gallery_dl/extractor/patreon.py +++ b/gallery_dl/extractor/patreon.py @@ -306,7 +306,7 @@ class PatreonExtractor(Extractor): except Exception: pass - raise exception.StopExtraction("Unable to extract bootstrap data") + raise exception.AbortExtraction("Unable to extract bootstrap data") class PatreonCreatorExtractor(PatreonExtractor): @@ -354,21 +354,21 @@ class PatreonCreatorExtractor(PatreonExtractor): data = None data = self._extract_bootstrap(page) return data["campaign"]["data"]["id"] - except exception.StopExtraction: + except exception.ControlException: pass except Exception as exc: if data: self.log.debug(data) - raise exception.StopExtraction( - "Unable to extract campaign ID (%s: %s)", - exc.__class__.__name__, exc) + raise exception.AbortExtraction( + f"Unable to extract campaign ID " + f"({exc.__class__.__name__}: {exc})") # Next.js 13 if cid := text.extr( page, r'{\"value\":{\"campaign\":{\"data\":{\"id\":\"', '\\"'): return cid - raise exception.StopExtraction("Failed to extract campaign ID") + raise exception.AbortExtraction("Failed to extract campaign ID") def _get_filters(self, query): return "".join( diff --git a/gallery_dl/extractor/pexels.py b/gallery_dl/extractor/pexels.py index 49aba270..f95d4099 100644 --- a/gallery_dl/extractor/pexels.py +++ b/gallery_dl/extractor/pexels.py @@ -175,7 +175,7 @@ class PexelsAPI(): else: self.extractor.log.debug(response.text) - raise exception.StopExtraction("API request failed") + raise exception.AbortExtraction("API request failed") def _pagination(self, endpoint, params): while True: diff --git a/gallery_dl/extractor/philomena.py b/gallery_dl/extractor/philomena.py index 4bf8a93a..9cc099b8 100644 --- a/gallery_dl/extractor/philomena.py +++ b/gallery_dl/extractor/philomena.py @@ -160,8 +160,7 @@ class PhilomenaAPI(): # error self.extractor.log.debug(response.content) - raise exception.StopExtraction( - "%s %s", response.status_code, response.reason) + raise exception.HttpError("", response) def _pagination(self, endpoint, params): extr = self.extractor diff --git a/gallery_dl/extractor/pinterest.py b/gallery_dl/extractor/pinterest.py index af80f80a..2327d0a4 100644 --- a/gallery_dl/extractor/pinterest.py +++ b/gallery_dl/extractor/pinterest.py @@ -543,7 +543,7 @@ class PinterestAPI(): resource = self.extractor.subcategory.rpartition("-")[2] raise exception.NotFoundError(resource) self.extractor.log.debug("Server response: %s", response.text) - raise exception.StopExtraction("API request failed") + raise exception.AbortExtraction("API request failed") def _pagination(self, resource, options): while True: diff --git a/gallery_dl/extractor/pixiv.py b/gallery_dl/extractor/pixiv.py index 977ba005..bf0ba43f 100644 --- a/gallery_dl/extractor/pixiv.py +++ b/gallery_dl/extractor/pixiv.py @@ -694,7 +694,7 @@ class PixivRankingExtractor(PixivExtractor): try: self.mode = mode = mode_map[mode] except KeyError: - raise exception.StopExtraction("Invalid mode '%s'", mode) + raise exception.AbortExtraction(f"Invalid mode '{mode}'") date = query.get("date") if date: @@ -747,7 +747,7 @@ class PixivSearchExtractor(PixivExtractor): try: self.word = query["word"] except KeyError: - raise exception.StopExtraction("Missing search term") + raise exception.AbortExtraction("Missing search term") sort = query.get("order", "date_d") sort_map = { @@ -760,7 +760,7 @@ class PixivSearchExtractor(PixivExtractor): try: self.sort = sort = sort_map[sort] except KeyError: - raise exception.StopExtraction("Invalid search order '%s'", sort) + raise exception.AbortExtraction(f"Invalid search order '{sort}'") target = query.get("s_mode", "s_tag_full") target_map = { @@ -771,7 +771,7 @@ class PixivSearchExtractor(PixivExtractor): try: self.target = target = target_map[target] except KeyError: - raise exception.StopExtraction("Invalid search mode '%s'", target) + raise exception.AbortExtraction(f"Invalid search mode '{target}'") self.date_start = query.get("scd") self.date_end = query.get("ecd") @@ -1288,7 +1288,7 @@ class PixivAppAPI(): self.extractor.wait(seconds=300) continue - raise exception.StopExtraction("API request failed: %s", error) + raise exception.AbortExtraction(f"API request failed: {error}") def _pagination(self, endpoint, params, key_items="illusts", key_data=None): diff --git a/gallery_dl/extractor/pixnet.py b/gallery_dl/extractor/pixnet.py index 66b7e914..b85b3e18 100644 --- a/gallery_dl/extractor/pixnet.py +++ b/gallery_dl/extractor/pixnet.py @@ -53,8 +53,8 @@ class PixnetExtractor(Extractor): pnext = text.extr(page, 'class="nextBtn"', '>') if pnext is None and 'name="albumpass">' in page: - raise exception.StopExtraction( - "Album %s is password-protected.", self.item_id) + raise exception.AbortExtraction( + f"Album {self.item_id} is password-protected.") if "href" not in pnext: return url = self.root + text.extr(pnext, 'href="', '"') diff --git a/gallery_dl/extractor/postmill.py b/gallery_dl/extractor/postmill.py index 29f4c31c..af971ab5 100644 --- a/gallery_dl/extractor/postmill.py +++ b/gallery_dl/extractor/postmill.py @@ -102,8 +102,8 @@ class PostmillSubmissionsExtractor(PostmillExtractor): if response.history: redirect_url = response.url if redirect_url == self.root + "/login": - raise exception.StopExtraction( - "HTTP redirect to login page (%s)", redirect_url) + raise exception.AbortExtraction( + f"HTTP redirect to login page ({redirect_url})") page = response.text for nav in text.extract_iter(page, diff --git a/gallery_dl/extractor/readcomiconline.py b/gallery_dl/extractor/readcomiconline.py index 0bbf5419..e1c7df3b 100644 --- a/gallery_dl/extractor/readcomiconline.py +++ b/gallery_dl/extractor/readcomiconline.py @@ -37,9 +37,9 @@ class ReadcomiconlineBase(): "the CAPTCHA, and press ENTER to continue", response.url) self.input() else: - raise exception.StopExtraction( - "Redirect to \n%s\nVisit this URL in your browser and " - "solve the CAPTCHA to continue", response.url) + raise exception.AbortExtraction( + f"Redirect to \n{response.url}\nVisit this URL in your " + f"browser and solve the CAPTCHA to continue") class ReadcomiconlineIssueExtractor(ReadcomiconlineBase, ChapterExtractor): diff --git a/gallery_dl/extractor/reddit.py b/gallery_dl/extractor/reddit.py index aae4e836..3ea20c1b 100644 --- a/gallery_dl/extractor/reddit.py +++ b/gallery_dl/extractor/reddit.py @@ -507,7 +507,8 @@ class RedditAPI(): try: data = response.json() except ValueError: - raise exception.StopExtraction(text.remove_html(response.text)) + raise exception.AbortExtraction( + text.remove_html(response.text)) if "error" in data: if data["error"] == 403: @@ -515,7 +516,7 @@ class RedditAPI(): if data["error"] == 404: raise exception.NotFoundError() self.log.debug(data) - raise exception.StopExtraction(data.get("message")) + raise exception.AbortExtraction(data.get("message")) return data def _pagination(self, endpoint, params): diff --git a/gallery_dl/extractor/sankaku.py b/gallery_dl/extractor/sankaku.py index 2c242259..dc201e65 100644 --- a/gallery_dl/extractor/sankaku.py +++ b/gallery_dl/extractor/sankaku.py @@ -308,7 +308,7 @@ class SankakuAPI(): ("unauthorized", "invalid-token", "invalid_token")): _authenticate_impl.invalidate(self.username) continue - raise exception.StopExtraction(code) + raise exception.AbortExtraction(code) return data def _pagination(self, endpoint, params): diff --git a/gallery_dl/extractor/seiga.py b/gallery_dl/extractor/seiga.py index 2fda06e3..73197319 100644 --- a/gallery_dl/extractor/seiga.py +++ b/gallery_dl/extractor/seiga.py @@ -45,8 +45,8 @@ class SeigaExtractor(Extractor): url = f"{self.root}/image/source/{image_id}" location = self.request_location(url, notfound="image") if "nicovideo.jp/login" in location: - raise exception.StopExtraction( - "HTTP redirect to login page (%s)", location.partition("?")[0]) + raise exception.AbortExtraction( + f"HTTP redirect to login page ({location.partition('?')[0]})") return location.replace("/o/", "/priv/", 1) def login(self): diff --git a/gallery_dl/extractor/smugmug.py b/gallery_dl/extractor/smugmug.py index d5da3306..e9c89a10 100644 --- a/gallery_dl/extractor/smugmug.py +++ b/gallery_dl/extractor/smugmug.py @@ -211,9 +211,9 @@ class SmugmugAPI(oauth.OAuth1API): if data["Code"] == 404: raise exception.NotFoundError() if data["Code"] == 429: - raise exception.StopExtraction("Rate limit reached") + raise exception.AbortExtraction("Rate limit reached") self.log.debug(data) - raise exception.StopExtraction("API request failed") + raise exception.AbortExtraction("API request failed") def _expansion(self, endpoint, expands, params=None): endpoint = self._extend(endpoint, expands) diff --git a/gallery_dl/extractor/steamgriddb.py b/gallery_dl/extractor/steamgriddb.py index de8a872c..e17b9fd1 100644 --- a/gallery_dl/extractor/steamgriddb.py +++ b/gallery_dl/extractor/steamgriddb.py @@ -74,7 +74,7 @@ class SteamgriddbExtractor(Extractor): def _call(self, endpoint, **kwargs): data = self.request_json(self.root + endpoint, **kwargs) if not data["success"]: - raise exception.StopExtraction(data["error"]) + raise exception.AbortExtraction(data["error"]) return data["data"] @@ -87,7 +87,7 @@ class SteamgriddbAssetsExtractor(SteamgriddbExtractor): id = int(match[2]) self.game_id = id if list_type == "game" else None self.collection_id = id if list_type == "collection" else None - self.page = int(match[3] or 1) + self.page = int(p) if (p := match[3]) else 1 def assets(self): limit = 48 @@ -96,7 +96,7 @@ class SteamgriddbAssetsExtractor(SteamgriddbExtractor): sort = self.config("sort", "score_desc") if sort not in ("score_desc", "score_asc", "score_old_desc", "score_old_asc", "age_desc", "age_asc"): - raise exception.StopExtractor("Invalid sort '%s'", sort) + raise exception.AbortExtraction(f"Invalid sort '{sort}'") json = { "static" : self.config("static", True), @@ -149,7 +149,7 @@ class SteamgriddbAssetsExtractor(SteamgriddbExtractor): for i in value: if i not in valid_values: - raise exception.StopExtraction("Invalid %s '%s'", type_name, i) + raise exception.AbortExtraction(f"Invalid {type_name} '{i}'") return value diff --git a/gallery_dl/extractor/subscribestar.py b/gallery_dl/extractor/subscribestar.py index 504bbc36..874a015b 100644 --- a/gallery_dl/extractor/subscribestar.py +++ b/gallery_dl/extractor/subscribestar.py @@ -65,8 +65,8 @@ class SubscribestarExtractor(Extractor): if response.history and ( "/verify_subscriber" in response.url or "/age_confirmation_warning" in response.url): - raise exception.StopExtraction( - "HTTP redirect to %s", response.url) + raise exception.AbortExtraction( + f"HTTP redirect to {response.url}") content = response.content if len(content) < 250 and b">redirected<" in content: diff --git a/gallery_dl/extractor/tsumino.py b/gallery_dl/extractor/tsumino.py index 688f6d6b..8732c604 100644 --- a/gallery_dl/extractor/tsumino.py +++ b/gallery_dl/extractor/tsumino.py @@ -86,9 +86,9 @@ class TsuminoGalleryExtractor(TsuminoBase, GalleryExtractor): response = self.request(url, headers=headers, fatal=False) if "/Auth/" in response.url: - raise exception.StopExtraction( - "Failed to get gallery JSON data. Visit '%s' in a browser " - "and solve the CAPTCHA to continue.", response.url) + raise exception.AbortExtraction( + f"Failed to get gallery JSON data. Visit '{response.url}' " + f"in a browser and solve the CAPTCHA to continue.") page = response.text tpl, pos = text.extract(page, 'data-cdn="', '"') @@ -155,8 +155,8 @@ class TsuminoSearchExtractor(TsuminoBase, Extractor): return self._parse_simple(query) return self._parse_jsurl(query) except Exception as exc: - raise exception.StopExtraction( - "Invalid search query '%s' (%s)", query, exc) + raise exception.AbortExtraction( + f"Invalid search query '{query}' ({exc})") def _parse_simple(self, query): """Parse search query with format '?=value>'""" diff --git a/gallery_dl/extractor/tumblr.py b/gallery_dl/extractor/tumblr.py index 96eb71ae..ea579686 100644 --- a/gallery_dl/extractor/tumblr.py +++ b/gallery_dl/extractor/tumblr.py @@ -499,8 +499,8 @@ class TumblrAPI(oauth.OAuth1API): continue t = (datetime.now() + timedelta(0, float(reset))).time() - raise exception.StopExtraction( - "Aborting - Rate limit will reset at %s", + raise exception.AbortExtraction( + f"Aborting - Rate limit will reset at " f"{t.hour:02}:{t.minute:02}:{t.second:02}") # hourly rate limit @@ -510,7 +510,7 @@ class TumblrAPI(oauth.OAuth1API): self.extractor.wait(seconds=reset) continue - raise exception.StopExtraction(data) + raise exception.AbortExtraction(data) def _pagination(self, endpoint, params, blog=None, key="posts", cache=False): diff --git a/gallery_dl/extractor/twibooru.py b/gallery_dl/extractor/twibooru.py index 38d8bee8..cf67135b 100644 --- a/gallery_dl/extractor/twibooru.py +++ b/gallery_dl/extractor/twibooru.py @@ -154,8 +154,7 @@ class TwibooruAPI(): # error self.extractor.log.debug(response.content) - raise exception.StopExtraction( - "%s %s", response.status_code, response.reason) + raise exception.HttpError("", response) def _pagination(self, endpoint, params): extr = self.extractor diff --git a/gallery_dl/extractor/twitter.py b/gallery_dl/extractor/twitter.py index fb2fdf89..b8770724 100644 --- a/gallery_dl/extractor/twitter.py +++ b/gallery_dl/extractor/twitter.py @@ -725,7 +725,7 @@ class TwitterTimelineExtractor(TwitterExtractor): return self.api.user_media if strategy == "with_replies": return self.api.user_tweets_and_replies - raise exception.StopExtraction("Invalid strategy '%s'", strategy) + raise exception.AbortExtraction(f"Invalid strategy '{strategy}'") class TwitterTweetsExtractor(TwitterExtractor): @@ -940,8 +940,8 @@ class TwitterTweetExtractor(TwitterExtractor): try: self._assign_user(tweet["core"]["user_results"]["result"]) except KeyError: - raise exception.StopExtraction( - "'%s'", tweet.get("reason") or "Unavailable") + raise exception.AbortExtraction( + f"'{tweet.get('reason') or 'Unavailable'}'") yield tweet @@ -1253,7 +1253,7 @@ class TwitterAPI(): raise exception.AuthorizationError("NSFW Tweet") if reason == "Protected": raise exception.AuthorizationError("Protected Tweet") - raise exception.StopExtraction("Tweet unavailable ('%s')", reason) + raise exception.AbortExtraction(f"Tweet unavailable ('{reason}')") return tweet @@ -1634,8 +1634,8 @@ class TwitterAPI(): except Exception: pass - raise exception.StopExtraction( - "%s %s (%s)", response.status_code, response.reason, errors) + raise exception.AbortExtraction( + f"{response.status_code} {response.reason} ({errors})") def _pagination_legacy(self, endpoint, params): extr = self.extractor @@ -1809,7 +1809,7 @@ class TwitterAPI(): raise exception.AuthorizationError( f"{user['screen_name']}'s Tweets are protected") - raise exception.StopExtraction( + raise exception.AbortExtraction( "Unable to retrieve Tweets from this timeline") tweets = [] @@ -1988,7 +1988,7 @@ class TwitterAPI(): def _handle_ratelimit(self, response): rl = self.extractor.config("ratelimit") if rl == "abort": - raise exception.StopExtraction("Rate limit exceeded") + raise exception.AbortExtraction("Rate limit exceeded") elif rl and isinstance(rl, str) and rl.startswith("wait:"): until = None seconds = text.parse_float(rl.partition(":")[2]) or 60.0 @@ -2172,7 +2172,7 @@ def _login_impl(extr, username, password): raise exception.AuthenticationError( "No 'auth_token' cookie received") else: - raise exception.StopExtraction("Unrecognized subtask %s", subtask) + raise exception.AbortExtraction(f"Unrecognized subtask {subtask}") inputs = {"subtask_id": subtask} inputs.update(data) diff --git a/gallery_dl/extractor/urlshortener.py b/gallery_dl/extractor/urlshortener.py index 0478ef09..7a9269d0 100644 --- a/gallery_dl/extractor/urlshortener.py +++ b/gallery_dl/extractor/urlshortener.py @@ -40,5 +40,5 @@ class UrlshortenerLinkExtractor(UrlshortenerExtractor): location = self.request_location( url, headers=self.config_instance("headers"), notfound="URL") if not location: - raise exception.StopExtraction("Unable to resolve short URL") + raise exception.AbortExtraction("Unable to resolve short URL") yield Message.Queue, location, {} diff --git a/gallery_dl/extractor/vk.py b/gallery_dl/extractor/vk.py index 4a34e4f0..c618d041 100644 --- a/gallery_dl/extractor/vk.py +++ b/gallery_dl/extractor/vk.py @@ -96,8 +96,8 @@ class VkExtractor(Extractor): response = self.request( url, method="POST", headers=headers, data=data) if response.history and "/challenge.html" in response.url: - raise exception.StopExtraction( - "HTTP redirect to 'challenge' page<:\n%s", response.url) + raise exception.AbortExtraction( + f"HTTP redirect to 'challenge' page:\n{response.url}") payload = response.json()["payload"][1] if len(payload) < 4: diff --git a/gallery_dl/extractor/wallhaven.py b/gallery_dl/extractor/wallhaven.py index 2871043f..f0f27e0c 100644 --- a/gallery_dl/extractor/wallhaven.py +++ b/gallery_dl/extractor/wallhaven.py @@ -200,9 +200,9 @@ class WallhavenAPI(): continue self.extractor.log.debug("Server response: %s", response.text) - raise exception.StopExtraction( - "API request failed (%s %s)", - response.status_code, response.reason) + raise exception.AbortExtraction( + f"API request failed " + f"({response.status_code} {response.reason})") def _pagination(self, endpoint, params=None, metadata=None): if params is None: diff --git a/gallery_dl/extractor/webtoons.py b/gallery_dl/extractor/webtoons.py index f289e00c..49a94b5e 100644 --- a/gallery_dl/extractor/webtoons.py +++ b/gallery_dl/extractor/webtoons.py @@ -40,8 +40,8 @@ class WebtoonsBase(): def request(self, url, **kwargs): response = Extractor.request(self, url, **kwargs) if response.history and "/ageGate" in response.url: - raise exception.StopExtraction( - "HTTP redirect to age gate check ('%s')", response.url) + raise exception.AbortExtraction( + f"HTTP redirect to age gate check ('{response.url}')") return response diff --git a/gallery_dl/extractor/weibo.py b/gallery_dl/extractor/weibo.py index 25769e54..22144181 100644 --- a/gallery_dl/extractor/weibo.py +++ b/gallery_dl/extractor/weibo.py @@ -46,9 +46,9 @@ class WeiboExtractor(Extractor): if response.history: if "login.sina.com" in response.url: - raise exception.StopExtraction( - "HTTP redirect to login page (%s)", - response.url.partition("?")[0]) + raise exception.AbortExtraction( + f"HTTP redirect to login page " + f"({response.url.partition('?')[0]})") if "passport.weibo.com" in response.url: self._sina_visitor_system(response) response = Extractor.request(self, url, **kwargs) @@ -179,8 +179,8 @@ class WeiboExtractor(Extractor): if not data.get("ok"): self.log.debug(response.content) if "since_id" not in params: # first iteration - raise exception.StopExtraction( - '"%s"', data.get("msg") or "unknown error") + raise exception.AbortExtraction( + f'"{data.get("msg") or "unknown error"}"') data = data["data"] statuses = data["list"] diff --git a/gallery_dl/extractor/wikimedia.py b/gallery_dl/extractor/wikimedia.py index 6304a2f5..599a6338 100644 --- a/gallery_dl/extractor/wikimedia.py +++ b/gallery_dl/extractor/wikimedia.py @@ -51,7 +51,7 @@ class WikimediaExtractor(BaseExtractor): response = self.request(url, method="HEAD", fatal=None) if response.status_code < 400: return url - raise exception.StopExtraction("Unable to find API endpoint") + raise exception.AbortExtraction("Unable to find API endpoint") def prepare(self, image): """Adjust the content of an image object""" diff --git a/gallery_dl/extractor/xfolio.py b/gallery_dl/extractor/xfolio.py index 21d57ec3..b68b779c 100644 --- a/gallery_dl/extractor/xfolio.py +++ b/gallery_dl/extractor/xfolio.py @@ -38,7 +38,7 @@ class XfolioExtractor(Extractor): response = Extractor.request(self, url, **kwargs) if "/system/recaptcha" in response.url: - raise exception.StopExtraction("Bot check / CAPTCHA page") + raise exception.AbortExtraction("Bot check / CAPTCHA page") return response diff --git a/gallery_dl/extractor/ytdl.py b/gallery_dl/extractor/ytdl.py index 63f7eca0..34e0daf7 100644 --- a/gallery_dl/extractor/ytdl.py +++ b/gallery_dl/extractor/ytdl.py @@ -95,7 +95,7 @@ class YoutubeDLExtractor(Extractor): ytdl_instance.get_info_extractor(self.ytdl_ie_key), False, {}, True) except ytdl_module.utils.YoutubeDLError: - raise exception.StopExtraction("Failed to extract video data") + raise exception.AbortExtraction("Failed to extract video data") if not info_dict: return diff --git a/gallery_dl/extractor/zerochan.py b/gallery_dl/extractor/zerochan.py index 0b768f01..1f146236 100644 --- a/gallery_dl/extractor/zerochan.py +++ b/gallery_dl/extractor/zerochan.py @@ -238,7 +238,7 @@ class ZerochanTagExtractor(ZerochanExtractor): self.log.warning("HTTP redirect to %s", url) if self.config("redirects"): continue - raise exception.StopExtraction() + raise exception.AbortExtraction() data = response.json() try: diff --git a/gallery_dl/job.py b/gallery_dl/job.py index 8011b553..28ee4a6e 100644 --- a/gallery_dl/job.py +++ b/gallery_dl/job.py @@ -153,9 +153,10 @@ class Job(): try: for msg in extractor: self.dispatch(msg) - except exception.StopExtraction as exc: - if exc.message: - log.error(exc.message) + except exception.StopExtraction: + pass + except exception.AbortExtraction as exc: + log.error(exc.message) self.status |= exc.code except (exception.TerminateExtraction, exception.RestartExtraction): raise diff --git a/gallery_dl/update.py b/gallery_dl/update.py index 73da5265..273ca189 100644 --- a/gallery_dl/update.py +++ b/gallery_dl/update.py @@ -189,7 +189,7 @@ class UpdateExtractor(Extractor): try: path_repo = REPOS[repo or "stable"] except KeyError: - raise exception.StopExtraction("Invalid channel '%s'", repo) + raise exception.AbortExtraction(f"Invalid channel '{repo}'") path_tag = tag if tag == "latest" else "tags/" + tag url = f"{self.root_api}/repos/{path_repo}/releases/{path_tag}" diff --git a/gallery_dl/ytdl.py b/gallery_dl/ytdl.py index 14b09be4..dda72c00 100644 --- a/gallery_dl/ytdl.py +++ b/gallery_dl/ytdl.py @@ -41,7 +41,7 @@ def construct_YoutubeDL(module, obj, user_opts, system_opts=None): try: opts = parse_command_line(module, argv) if argv else user_opts except SystemExit: - raise exception.StopExtraction("Invalid command-line option") + raise exception.AbortExtraction("Invalid command-line option") if opts.get("format") is None: opts["format"] = config("format")