diff --git a/gallery_dl/extractor/ao3.py b/gallery_dl/extractor/ao3.py index 72a69432..172d479b 100644 --- a/gallery_dl/extractor/ao3.py +++ b/gallery_dl/extractor/ao3.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright 2024-2025 Mike Fährmann +# Copyright 2024-2026 Mike Fährmann # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as @@ -9,7 +9,7 @@ """Extractors for https://archiveofourown.org/""" from .common import Extractor, Message, Dispatch -from .. import text, util, exception +from .. import text, util from ..cache import cache BASE_PATTERN = (r"(?:https?://)?(?:www\.)?" @@ -88,11 +88,11 @@ class Ao3Extractor(Extractor): response = self.request(url, method="POST", data=data) if not response.history: - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() remember = response.history[0].cookies.get("remember_user_token") if not remember: - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() return { "remember_user_token": remember, @@ -142,12 +142,12 @@ class Ao3WorkExtractor(Ao3Extractor): response = self.request(url, notfound=True) if response.url.endswith("/users/login?restricted=true"): - raise exception.AuthorizationError( + raise self.exc.AuthorizationError( "Login required to access member-only works") page = response.text if len(page) < 20000 and \ '

Adult Content Warning", pos-100)[0] self.kwdict["thread"] = self._parse_thread(page) diff --git a/gallery_dl/extractor/bilibili.py b/gallery_dl/extractor/bilibili.py index 2fc86bb7..9cad0525 100644 --- a/gallery_dl/extractor/bilibili.py +++ b/gallery_dl/extractor/bilibili.py @@ -7,7 +7,7 @@ """Extractors for https://www.bilibili.com/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util class BilibiliExtractor(Extractor): @@ -123,7 +123,7 @@ class BilibiliAPI(): if data["code"]: self.extractor.log.debug("Server response: %s", data) - raise exception.AbortExtraction("API request failed") + raise self.exc.AbortExtraction("API request failed") return data @@ -151,7 +151,7 @@ class BilibiliAPI(): page, "window.__INITIAL_STATE__=", "};") + "}") except Exception: if "window._riskdata_" not in page: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( article_id + ": Unable to extract INITIAL_STATE data") self.extractor.wait(seconds=300) @@ -174,9 +174,9 @@ class BilibiliAPI(): if data["code"] != 0: self.extractor.log.debug("Server response: %s", data) - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( "API request failed. Are you logges in?") try: return data["data"]["profile"]["mid"] except Exception: - raise exception.AbortExtraction("API request failed") + raise self.exc.AbortExtraction("API request failed") diff --git a/gallery_dl/extractor/bluesky.py b/gallery_dl/extractor/bluesky.py index 6e7b3442..a0c2eec2 100644 --- a/gallery_dl/extractor/bluesky.py +++ b/gallery_dl/extractor/bluesky.py @@ -9,7 +9,7 @@ """Extractors for https://bsky.app/""" from .common import Extractor, Message, Dispatch -from .. import text, util, exception +from .. import text, util from ..cache import cache, memcache BASE_PATTERN = (r"(?:https?://)?" @@ -96,7 +96,7 @@ class BlueskyExtractor(Extractor): uri = record["value"]["subject"]["uri"] if "/app.bsky.feed.post/" in uri: yield from self.api.get_post_thread_uri(uri, depth) - except exception.ControlException: + except self.exc.ControlException: pass # deleted post except Exception as exc: self.log.debug(record, exc_info=exc) @@ -569,7 +569,7 @@ class BlueskyAPI(): if response.status_code != 200: self.log.debug("Server response: %s", data) - raise exception.AuthenticationError( + raise self.exc.AuthenticationError( f"\"{data.get('error')}: {data.get('message')}\"") _refresh_token_cache.update(self.username, data["refreshJwt"]) @@ -600,7 +600,7 @@ class BlueskyAPI(): msg = f"{msg} ({response.status_code} {response.reason})" self.extractor.log.debug("Server response: %s", response.text) - raise exception.AbortExtraction(msg) + raise self.exc.AbortExtraction(msg) def _pagination(self, endpoint, params, key="feed", root=None, check_empty=False): diff --git a/gallery_dl/extractor/boosty.py b/gallery_dl/extractor/boosty.py index 01ecf59f..b3566296 100644 --- a/gallery_dl/extractor/boosty.py +++ b/gallery_dl/extractor/boosty.py @@ -7,7 +7,7 @@ """Extractors for https://www.boosty.to/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util import itertools BASE_PATTERN = r"(?:https?://)?boosty\.to" @@ -380,14 +380,14 @@ class BoostyAPI(): return response.json() elif response.status_code < 400: - raise exception.AuthenticationError("Invalid API access token") + raise self.exc.AuthenticationError("Invalid API access token") elif response.status_code == 429: self.extractor.wait(seconds=600) else: self.extractor.log.debug(response.text) - raise exception.AbortExtraction("API request failed") + raise self.exc.AbortExtraction("API request failed") def _pagination(self, endpoint, params, transform=None, key=None): if "is_only_allowed" not in params and self.extractor.only_allowed: diff --git a/gallery_dl/extractor/bunkr.py b/gallery_dl/extractor/bunkr.py index 93df6455..72e83af6 100644 --- a/gallery_dl/extractor/bunkr.py +++ b/gallery_dl/extractor/bunkr.py @@ -10,7 +10,7 @@ from .common import Extractor from .lolisafe import LolisafeAlbumExtractor -from .. import text, util, config, exception +from .. import text, util, config from ..cache import memcache import random @@ -110,7 +110,7 @@ class BunkrAlbumExtractor(LolisafeAlbumExtractor): self.log.debug("Redirect to known CF challenge domain '%s'", root) - except exception.HttpError as exc: + except self.exc.HttpError as exc: if exc.status != 403: raise @@ -125,7 +125,7 @@ class BunkrAlbumExtractor(LolisafeAlbumExtractor): pass else: if not DOMAINS: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( "All Bunkr domains require solving a CF challenge") # select alternative domain @@ -172,15 +172,15 @@ class BunkrAlbumExtractor(LolisafeAlbumExtractor): item, 'timestamp: "', '"'), "%H:%M:%S %d/%m/%Y") yield file - except exception.ControlException: + except self.exc.ControlException: raise except Exception as exc: self.log.error("%s: %s", exc.__class__.__name__, exc) self.log.debug("%s", item, exc_info=exc) - if isinstance(exc, exception.HttpError) and \ + if isinstance(exc, self.exc.HttpError) and \ exc.status == 400 and \ exc.response.url.startswith(self.root_api): - raise exception.AbortExtraction("Album deleted") + raise self.exc.AbortExtraction("Album deleted") def _extract_file(self, data_id): referer = f"{self.root_dl}/file/{data_id}" diff --git a/gallery_dl/extractor/civitai.py b/gallery_dl/extractor/civitai.py index e65ff950..ee2a1c6a 100644 --- a/gallery_dl/extractor/civitai.py +++ b/gallery_dl/extractor/civitai.py @@ -9,7 +9,7 @@ """Extractors for https://www.civitai.com/""" from .common import Extractor, Message, Dispatch -from .. import text, util, exception +from .. import text, util from ..cache import memcache import itertools import time @@ -201,7 +201,7 @@ class CivitaiExtractor(Extractor): if "Authorization" not in self.api.headers and \ not self.cookies.get( "__Secure-civitai-token", domain=".civitai.com"): - raise exception.AuthRequired(("api-key", "authenticated cookies")) + raise self.exc.AuthRequired(("api-key", "authenticated cookies")) def _parse_query(self, value): return text.parse_query_list( diff --git a/gallery_dl/extractor/comick.py b/gallery_dl/extractor/comick.py index c119b2e3..85434955 100644 --- a/gallery_dl/extractor/comick.py +++ b/gallery_dl/extractor/comick.py @@ -9,7 +9,7 @@ """Extractors for https://comick.io/""" from .common import GalleryExtractor, ChapterExtractor, MangaExtractor, Message -from .. import text, exception +from .. import text from ..cache import memcache BASE_PATTERN = r"(?:https?://)?(?:www\.)?comick\.io" @@ -71,7 +71,7 @@ class ComickChapterExtractor(ComickBase, ChapterExtractor): while True: try: props = _chapter_info(self, manga, chstr) - except exception.HttpError as exc: + except self.exc.HttpError as exc: if exc.response.status_code != 404: raise if exc.response.headers.get( @@ -84,7 +84,7 @@ class ComickChapterExtractor(ComickBase, ChapterExtractor): manga = _manga_info(self, slug) continue if b'"notFound":true' in exc.response.content: - raise exception.NotFoundError("chapter") + raise self.exc.NotFoundError("chapter") raise if "__N_REDIRECT" in props: diff --git a/gallery_dl/extractor/common.py b/gallery_dl/extractor/common.py index c96658ec..de9fad24 100644 --- a/gallery_dl/extractor/common.py +++ b/gallery_dl/extractor/common.py @@ -54,6 +54,7 @@ class Extractor(): request_interval_429 = 60.0 request_timestamp = 0.0 finalize = skip = None + exc = exception def __init__(self, match): self.log = logging.getLogger(self.category) diff --git a/gallery_dl/extractor/cyberfile.py b/gallery_dl/extractor/cyberfile.py index 49cc6db1..d98e17ad 100644 --- a/gallery_dl/extractor/cyberfile.py +++ b/gallery_dl/extractor/cyberfile.py @@ -9,7 +9,7 @@ """Extractors for https://cyberfile.me/""" from .common import Extractor, Message -from .. import text, exception +from .. import text BASE_PATTERN = r"(?:https?://)?(?:www\.)?cyberfile\.me" @@ -39,7 +39,7 @@ class CyberfileExtractor(Extractor): resp = self.request_json( url_pw, method="POST", headers=headers, data=data_pw) if not resp.get("success"): - raise exception.AuthorizationError(f"'{resp.get('msg')}'") + raise self.exc.AuthorizationError(f"'{resp.get('msg')}'") resp = self.request_json( url, method="POST", headers=headers, data=data) diff --git a/gallery_dl/extractor/deviantart.py b/gallery_dl/extractor/deviantart.py index 01153116..fd8a76b9 100644 --- a/gallery_dl/extractor/deviantart.py +++ b/gallery_dl/extractor/deviantart.py @@ -9,7 +9,7 @@ """Extractors for https://www.deviantart.com/""" from .common import Extractor, Message, Dispatch -from .. import text, util, dt, exception +from .. import text, util, dt from ..cache import cache, memcache import collections import mimetypes @@ -123,7 +123,7 @@ class DeviantartExtractor(Extractor): self.group = False elif group == "skip": self.log.info("Skipping group '%s'", self.user) - raise exception.AbortExtraction() + raise self.exc.AbortExtraction() else: self.subcategory = "group-" + self.subcategory self.group = True @@ -457,7 +457,7 @@ class DeviantartExtractor(Extractor): for subfolder in folder["subfolders"]: if subfolder["folderid"] == uuid: return subfolder - raise exception.NotFoundError("folder") + raise self.exc.NotFoundError("folder") def _folder_urls(self, folders, category, extractor): base = f"{self.root}/{self.user}/{category}/" @@ -1027,7 +1027,7 @@ class DeviantartDeviationExtractor(DeviantartExtractor): page = self._limited_request(url, notfound=True).text uuid = text.extr(page, '"deviationUuid\\":\\"', '\\') if not uuid: - raise exception.NotFoundError("deviation") + raise self.exc.NotFoundError("deviation") deviation = self.api.deviation(uuid) deviation["_page"] = page @@ -1111,7 +1111,7 @@ class DeviantartSearchExtractor(DeviantartExtractor): response = self.request(url, params=params) if response.history and "/users/login" in response.url: - raise exception.AbortExtraction("HTTP redirect to login page") + raise self.exc.AbortExtraction("HTTP redirect to login page") page = response.text for user, type, did in find(page)[:-3:3]: @@ -1476,7 +1476,7 @@ class DeviantartOAuthAPI(): if response.status_code != 200: self.log.debug("Server response: %s", data) - raise exception.AuthenticationError( + raise self.exc.AuthenticationError( f"\"{data.get('error_description')}\" ({data.get('error')})") if refresh_token_key: _refresh_token_cache.update( @@ -1515,9 +1515,9 @@ class DeviantartOAuthAPI(): error = data.get("error_description") if error == "User not found.": - raise exception.NotFoundError("user or group") + raise self.exc.NotFoundError("user or group") if error == "Deviation not downloadable.": - raise exception.AuthorizationError() + raise self.exc.AuthorizationError() self.log.debug(response.text) msg = f"API responded with {status} {response.reason}" @@ -1808,7 +1808,7 @@ class DeviantartEclipseAPI(): pos = page.find('\\"name\\":\\"watching\\"') if pos < 0: - raise exception.NotFoundError("'watching' module ID") + raise self.exc.NotFoundError("'watching' module ID") module_id = text.rextr(page, '\\"id\\":', ',', pos).strip('" ') self._fetch_csrf_token(page) @@ -1863,7 +1863,7 @@ def _login_impl(extr, username, password): response = extr.request(url, method="POST", data=data) if not response.history: - raise exception.AuthenticationError() + raise extr.exc.AuthenticationError() return { cookie.name: cookie.value diff --git a/gallery_dl/extractor/discord.py b/gallery_dl/extractor/discord.py index ef2943ec..84737ab7 100644 --- a/gallery_dl/extractor/discord.py +++ b/gallery_dl/extractor/discord.py @@ -7,7 +7,7 @@ """Extractors for https://discord.com/""" from .common import Extractor, Message -from .. import text, exception +from .. import text BASE_PATTERN = r"(?:https?://)?discord\.com" @@ -167,10 +167,10 @@ class DiscordExtractor(Extractor): yield from self.extract_channel( channel["channel_id"], safe=True) elif not safe: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( "This channel type is not supported." ) - except exception.HttpError as exc: + except self.exc.HttpError as exc: if not (exc.status == 403 and safe): raise @@ -474,7 +474,7 @@ class DiscordAPI(): try: response = self.extractor.request( url, params=params, headers=self.headers) - except exception.HttpError as exc: + except self.exc.HttpError as exc: if exc.status == 401: self._raise_invalid_token() raise @@ -490,7 +490,7 @@ class DiscordAPI(): offset += len(data) def _raise_invalid_token(self): - raise exception.AuthenticationError("""Invalid or missing token. + raise self.exc.AuthenticationError("""Invalid or missing token. Please provide a valid token following these instructions: 1) Open Discord in your browser (https://discord.com/app); diff --git a/gallery_dl/extractor/erome.py b/gallery_dl/extractor/erome.py index c82e4c7e..941ddeab 100644 --- a/gallery_dl/extractor/erome.py +++ b/gallery_dl/extractor/erome.py @@ -9,7 +9,7 @@ """Extractors for https://www.erome.com/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util from ..cache import cache import itertools @@ -74,12 +74,12 @@ class EromeAlbumExtractor(EromeExtractor): try: page = self.request(url).text - except exception.HttpError as exc: + except self.exc.HttpError as exc: if exc.status == 410: msg = text.extr(exc.response.text, "

", "<") else: msg = "Unable to fetch album page" - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"{album_id}: {msg} ({exc})") title, pos = text.extract( diff --git a/gallery_dl/extractor/exhentai.py b/gallery_dl/extractor/exhentai.py index eba82a85..92f7c4a1 100644 --- a/gallery_dl/extractor/exhentai.py +++ b/gallery_dl/extractor/exhentai.py @@ -9,7 +9,7 @@ """Extractors for https://e-hentai.org/ and https://exhentai.org/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util from ..cache import cache import collections import itertools @@ -53,13 +53,13 @@ class ExhentaiExtractor(Extractor): response = Extractor.request(self, url, **kwargs) if "Cache-Control" not in response.headers and not response.content: self.log.info("blank page") - raise exception.AuthorizationError() + raise self.exc.AuthorizationError() return response def login(self): """Login and set necessary cookies""" if self.LIMIT: - raise exception.AbortExtraction("Image limit reached!") + raise self.exc.AbortExtraction("Image limit reached!") if self.cookies_check(self.cookies_names): return @@ -99,9 +99,9 @@ class ExhentaiExtractor(Extractor): content = response.content if b"You are now logged in as:" not in content: if b"The captcha was not entered correctly" in content: - raise exception.AuthenticationError( + raise self.exc.AuthenticationError( "CAPTCHA required. Use cookies instead.") - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() # collect more cookies url = self.root + "/favorites.php" @@ -187,7 +187,7 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor): self.image_token = text.extr(gpage, 'hentai.org/s/', '"') if not self.image_token: self.log.debug("Page content:\n%s", gpage) - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( "Failed to extract initial image token") ipage = self._image_page() else: @@ -195,7 +195,7 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor): part = text.extr(ipage, 'hentai.org/g/', '"') if not part: self.log.debug("Page content:\n%s", ipage) - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( "Failed to extract gallery token") self.gallery_token = part.split("/")[1] gpage = self._gallery_page() @@ -313,7 +313,7 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor): data = self.request_json(self.api_url, method="POST", json=data) if "error" in data: - raise exception.AbortExtraction(data["error"]) + raise self.exc.AbortExtraction(data["error"]) return data["gmetadata"][0] @@ -338,7 +338,7 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor): data["_fallback"] = self._fallback_1280(nl, self.image_num) except IndexError: self.log.debug("Page content:\n%s", page) - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"Unable to parse image info for '{url}'") data["num"] = self.image_num @@ -389,7 +389,7 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor): nl, request["page"], imgkey) except IndexError: self.log.debug("Page content:\n%s", page) - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"Unable to parse image info for '{url}'") data["num"] = request["page"] @@ -438,7 +438,7 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor): data["_fallback"] = self._fallback_mpv_1280(info, request) except IndexError: self.log.debug("Page content:\n%s", info) - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"Unable to parse image info for '{url}'") data["num"] = pnum @@ -465,7 +465,7 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor): if " requires GP" in page: gp = self.config("gp") if gp == "stop": - raise exception.AbortExtraction("Not enough GP") + raise self.exc.AbortExtraction("Not enough GP") elif gp == "wait": self.input("Press ENTER to continue.") return response.url @@ -475,7 +475,7 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor): return self.data["_url_1280"] if " temporarily banned " in page: - raise exception.AuthorizationError("Temporarily Banned") + raise self.exc.AuthorizationError("Temporarily Banned") self._limits_exceeded() return response.url @@ -526,7 +526,7 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor): if not action or action == "stop": ExhentaiExtractor.LIMIT = True - raise exception.AbortExtraction(msg) + raise self.exc.AbortExtraction(msg) self.log.warning(msg) if action == "wait": @@ -559,12 +559,12 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor): page = response.text if response.status_code == 404 and "Gallery Not Available" in page: - raise exception.AuthorizationError() + raise self.exc.AuthorizationError() if page.startswith(("Key missing", "Gallery not found")): - raise exception.NotFoundError("gallery") + raise self.exc.NotFoundError("gallery") if page.count("hentai.org/mpv/") > 1: if self.gallery_token is None: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( "'/s/' URLs in MPV mode are not supported") self.mpv = True return page @@ -575,7 +575,7 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor): page = self.request(url, fatal=False).text if page.startswith(("Invalid page", "Keep trying")): - raise exception.NotFoundError("image page") + raise self.exc.NotFoundError("image page") return page def _fallback_original(self, nl, fullimg): diff --git a/gallery_dl/extractor/facebook.py b/gallery_dl/extractor/facebook.py index 7f03f846..0381e62a 100644 --- a/gallery_dl/extractor/facebook.py +++ b/gallery_dl/extractor/facebook.py @@ -7,7 +7,7 @@ """Extractors for https://www.facebook.com/""" from .common import Extractor, Message, Dispatch -from .. import text, util, exception +from .. import text, util from ..cache import memcache BASE_PATTERN = r"(?:https?://)?(?:[\w-]+\.)?facebook\.com" @@ -236,12 +236,12 @@ class FacebookExtractor(Extractor): res = self.request(url, **kwargs) if res.url.startswith(self.root + "/login"): - raise exception.AuthRequired( + raise self.exc.AuthRequired( message=("You must be logged in to continue viewing images." + LEFT_OFF_TXT)) if b'{"__dr":"CometErrorRoot.react"}' in res.content: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( "You've been temporarily blocked from viewing images.\n" "Please try using a different account, " "using a VPN or waiting before you retry." + LEFT_OFF_TXT) @@ -331,7 +331,7 @@ class FacebookExtractor(Extractor): break if ('"props":{"title":"This content isn\'t available right now"' in page): - raise exception.AuthRequired( + raise self.exc.AuthRequired( "authenticated cookies", "profile", "This content isn't available right now") diff --git a/gallery_dl/extractor/fansly.py b/gallery_dl/extractor/fansly.py index 8848501d..abdde463 100644 --- a/gallery_dl/extractor/fansly.py +++ b/gallery_dl/extractor/fansly.py @@ -9,7 +9,7 @@ """Extractors for https://fansly.com/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util import time BASE_PATTERN = r"(?:https?://)?(?:www\.)?fansly\.com" @@ -54,7 +54,7 @@ class FanslyExtractor(Extractor): if wall["id"] == wall_id: break else: - raise exception.NotFoundError("wall") + raise self.exc.NotFoundError("wall") walls = (wall,) for wall in walls: diff --git a/gallery_dl/extractor/fapello.py b/gallery_dl/extractor/fapello.py index 4cd97a69..7c41e457 100644 --- a/gallery_dl/extractor/fapello.py +++ b/gallery_dl/extractor/fapello.py @@ -7,7 +7,7 @@ """Extractors for https://fapello.com/""" from .common import Extractor, Message -from .. import text, exception +from .. import text BASE_PATTERN = r"(?:https?://)?(?:www\.)?fapello\.(?:com|su)" @@ -34,7 +34,7 @@ class FapelloPostExtractor(Extractor): self.request(url, allow_redirects=False).text, 'class="uk-align-center"', "", None) if page is None: - raise exception.NotFoundError("post") + raise self.exc.NotFoundError("post") data = { "model": self.model, diff --git a/gallery_dl/extractor/fikfap.py b/gallery_dl/extractor/fikfap.py index ccf6f6a0..76f785cf 100644 --- a/gallery_dl/extractor/fikfap.py +++ b/gallery_dl/extractor/fikfap.py @@ -9,7 +9,7 @@ """Extractors for https://fikfap.com/""" from .common import Extractor, Message -from .. import text, exception +from .. import text BASE_PATTERN = r"(?:https?://)?(?:www\.)?fikfap\.com" @@ -78,7 +78,7 @@ class FikfapPostExtractor(FikfapExtractor): if post["postId"] == int(pid): return (post,) - raise exception.NotFoundError("post") + raise self.exc.NotFoundError("post") class FikfapUserExtractor(FikfapExtractor): diff --git a/gallery_dl/extractor/flickr.py b/gallery_dl/extractor/flickr.py index 5071de7e..b2860634 100644 --- a/gallery_dl/extractor/flickr.py +++ b/gallery_dl/extractor/flickr.py @@ -9,7 +9,7 @@ """Extractors for https://www.flickr.com/""" from .common import Extractor, Message -from .. import text, oauth, util, exception +from .. import text, oauth, util from ..cache import memcache BASE_PATTERN = r"(?:https?://)?(?:www\.|secure\.|m\.)?flickr\.com" @@ -459,14 +459,14 @@ class FlickrAPI(oauth.OAuth1API): msg = data.get("message", "") self.log.debug("Server response: %s", data) if data["code"] == 1: - raise exception.NotFoundError(self.extractor.subcategory) + raise self.exc.NotFoundError(self.extractor.subcategory) elif data["code"] == 2: - raise exception.AuthorizationError(msg) + raise self.exc.AuthorizationError(msg) elif data["code"] == 98: - raise exception.AuthenticationError(msg) + raise self.exc.AuthenticationError(msg) elif data["code"] == 99: - raise exception.AuthorizationError(msg) - raise exception.AbortExtraction("API request failed: " + msg) + raise self.exc.AuthorizationError(msg) + raise self.exc.AbortExtraction("API request failed: " + msg) return data def _pagination(self, method, params, key="photos"): diff --git a/gallery_dl/extractor/gelbooru.py b/gallery_dl/extractor/gelbooru.py index 30e32f8c..0cd23c50 100644 --- a/gallery_dl/extractor/gelbooru.py +++ b/gallery_dl/extractor/gelbooru.py @@ -10,7 +10,7 @@ from .common import Extractor, Message from . import gelbooru_v02 -from .. import text, exception +from .. import text import binascii BASE_PATTERN = r"(?:https?://)?(?:www\.)?gelbooru\.com/(?:index\.php)?\?" @@ -33,9 +33,9 @@ class GelbooruBase(): url = self.root + "/index.php?page=dapi&q=index&json=1" try: data = self.request_json(url, params=params) - except exception.HttpError as exc: + except self.exc.HttpError as exc: if exc.status == 401: - raise exception.AuthRequired( + raise self.exc.AuthRequired( "'api-key' & 'user-id'", "the API") raise @@ -172,7 +172,7 @@ class GelbooruPoolExtractor(GelbooruBase, name, pos = text.extract(page, "

Now Viewing: ", "

") if not name: - raise exception.NotFoundError("pool") + raise self.exc.NotFoundError("pool") return { "pool": text.parse_int(self.pool_id), diff --git a/gallery_dl/extractor/gelbooru_v02.py b/gallery_dl/extractor/gelbooru_v02.py index 3a4b9208..dc1c1bff 100644 --- a/gallery_dl/extractor/gelbooru_v02.py +++ b/gallery_dl/extractor/gelbooru_v02.py @@ -9,7 +9,7 @@ """Extractors for Gelbooru Beta 0.2 sites""" from . import booru -from .. import text, util, exception +from .. import text, util import collections @@ -38,9 +38,9 @@ class GelbooruV02Extractor(booru.BooruExtractor): if root.tag == "error": msg = root.text if msg.lower().startswith("missing authentication"): - raise exception.AuthRequired( + raise self.exc.AuthRequired( "'api-key' & 'user-id'", "the API", msg) - raise exception.AbortExtraction(f"'{msg}'") + raise self.exc.AbortExtraction(f"'{msg}'") return root @@ -229,7 +229,7 @@ class GelbooruV02PoolExtractor(GelbooruV02Extractor): name, pos = text.extract(page, "

Pool: ", "

") if not name: - raise exception.NotFoundError("pool") + raise self.exc.NotFoundError("pool") self.post_ids = text.extract_iter( page, 'class="thumb" id="p', '"', pos) diff --git a/gallery_dl/extractor/girlswithmuscle.py b/gallery_dl/extractor/girlswithmuscle.py index 420b2ac8..50165fe5 100644 --- a/gallery_dl/extractor/girlswithmuscle.py +++ b/gallery_dl/extractor/girlswithmuscle.py @@ -5,7 +5,7 @@ # published by the Free Software Foundation. from .common import Extractor, Message -from .. import text, exception +from .. import text from ..cache import cache BASE_PATTERN = r"(?:https?://)?(?:www\.)?girlswithmuscle\.com" @@ -46,13 +46,13 @@ class GirlswithmuscleExtractor(Extractor): url, method="POST", headers=headers, data=data) if not response.history: - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() page = response.text if ">Wrong username or password" in page: - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() if ">Log in<" in page: - raise exception.AuthenticationError("Account data is missing") + raise self.exc.AuthenticationError("Account data is missing") return {c.name: c.value for c in response.history[0].cookies} @@ -69,7 +69,7 @@ class GirlswithmusclePostExtractor(GirlswithmuscleExtractor): url = f"{self.root}/{self.groups[0]}/" page = self.request(url).text if not page: - raise exception.NotFoundError("post") + raise self.exc.NotFoundError("post") metadata = self.metadata(page) @@ -152,7 +152,7 @@ class GirlswithmuscleSearchExtractor(GirlswithmuscleExtractor): response = self.request(url) if response.history: msg = f'Request was redirected to "{response.url}", try logging in' - raise exception.AuthorizationError(msg) + raise self.exc.AuthorizationError(msg) page = response.text match = text.re(r"Page (\d+) of (\d+)").search(page) diff --git a/gallery_dl/extractor/gofile.py b/gallery_dl/extractor/gofile.py index 83e58308..5a2b42bf 100644 --- a/gallery_dl/extractor/gofile.py +++ b/gallery_dl/extractor/gofile.py @@ -7,7 +7,7 @@ """Extractors for https://gofile.io/""" from .common import Extractor, Message -from .. import text, exception +from .. import text from ..cache import cache, memcache import hashlib @@ -44,7 +44,7 @@ class GofileFolderExtractor(Extractor): try: contents = folder.pop("children") except KeyError: - raise exception.AuthorizationError("Password required") + raise self.exc.AuthorizationError("Password required") num = 0 for content in contents.values(): @@ -94,10 +94,10 @@ class GofileFolderExtractor(Extractor): if response["status"] != "ok": if response["status"] == "error-notFound": - raise exception.NotFoundError("content") + raise self.exc.NotFoundError("content") if response["status"] == "error-passwordRequired": - raise exception.AuthorizationError("Password required") - raise exception.AbortExtraction( + raise self.exc.AuthorizationError("Password required") + raise self.exc.AbortExtraction( f"{endpoint} failed (Status: {response['status']})") return response["data"] diff --git a/gallery_dl/extractor/hotleak.py b/gallery_dl/extractor/hotleak.py index 0cc6cd62..a29e0e54 100644 --- a/gallery_dl/extractor/hotleak.py +++ b/gallery_dl/extractor/hotleak.py @@ -7,7 +7,7 @@ """Extractors for https://hotleak.vip/""" from .common import Extractor, Message -from .. import text, exception +from .. import text import binascii BASE_PATTERN = r"(?:https?://)?(?:www\.)?hotleak\.vip" @@ -116,7 +116,7 @@ class HotleakCreatorExtractor(HotleakExtractor): try: response = self.request( url, headers=headers, params=params, notfound=True) - except exception.HttpError as exc: + except self.exc.HttpError as exc: if exc.response.status_code == 429: self.wait( until=exc.response.headers.get("X-RateLimit-Reset")) diff --git a/gallery_dl/extractor/imagebam.py b/gallery_dl/extractor/imagebam.py index 7067c7d4..c46012a5 100644 --- a/gallery_dl/extractor/imagebam.py +++ b/gallery_dl/extractor/imagebam.py @@ -9,7 +9,7 @@ """Extractors for https://www.imagebam.com/""" from .common import Extractor, Message -from .. import text, exception +from .. import text class ImagebamExtractor(Extractor): @@ -29,7 +29,7 @@ class ImagebamExtractor(Extractor): page = self.request(self.root + path).text url, pos = text.extract(page, 'Not Found" in page: - raise exception.NotFoundError("gallery") + raise self.exc.NotFoundError("gallery") self.files = () return {} @@ -142,11 +142,11 @@ class ImagechestAPI(): return response.json()["data"] elif response.status_code < 400: - raise exception.AuthenticationError("Invalid API access token") + raise self.exc.AuthenticationError("Invalid API access token") elif response.status_code == 429: self.extractor.wait(seconds=600) else: self.extractor.log.debug(response.text) - raise exception.AbortExtraction("API request failed") + raise self.exc.AbortExtraction("API request failed") diff --git a/gallery_dl/extractor/imagefap.py b/gallery_dl/extractor/imagefap.py index f9cd8af4..1ea57195 100644 --- a/gallery_dl/extractor/imagefap.py +++ b/gallery_dl/extractor/imagefap.py @@ -9,7 +9,7 @@ """Extractors for https://www.imagefap.com/""" from .common import Extractor, Message -from .. import text, exception +from .. import text BASE_PATTERN = r"(?:https?://)?(?:www\.|beta\.)?imagefap\.com" @@ -31,7 +31,7 @@ class ImagefapExtractor(Extractor): self.log.warning("HTTP redirect to '%s'", response.url) if msg := text.extr(response.text, '
")[2].split()) - raise exception.AbortExtraction(f"'{msg}'") + raise self.exc.AbortExtraction(f"'{msg}'") return response diff --git a/gallery_dl/extractor/imagehosts.py b/gallery_dl/extractor/imagehosts.py index 344730df..60b5dea8 100644 --- a/gallery_dl/extractor/imagehosts.py +++ b/gallery_dl/extractor/imagehosts.py @@ -9,7 +9,7 @@ """Collection of extractors for various imagehosts""" from .common import Extractor, Message -from .. import text, exception +from .. import text from ..cache import memcache @@ -81,7 +81,7 @@ class ImagehostImageExtractor(Extractor): return () def not_found(self, resource=None): - raise exception.NotFoundError(resource or self.__class__.subcategory) + raise self.exc.NotFoundError(resource or self.__class__.subcategory) class ImxtoImageExtractor(ImagehostImageExtractor): diff --git a/gallery_dl/extractor/imgbb.py b/gallery_dl/extractor/imgbb.py index ed06c1ca..a6203f1b 100644 --- a/gallery_dl/extractor/imgbb.py +++ b/gallery_dl/extractor/imgbb.py @@ -9,7 +9,7 @@ """Extractors for https://imgbb.com/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util from ..cache import cache @@ -60,7 +60,7 @@ class ImgbbExtractor(Extractor): response = self.request(url, method="POST", headers=headers, data=data) if not response.history: - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() return self.cookies def _pagination(self, page, url, params): @@ -193,10 +193,10 @@ class ImgbbUserExtractor(ImgbbExtractor): return self._pagination(response.text, url + "json", params) if response.status_code == 301: - raise exception.NotFoundError("user") + raise self.exc.NotFoundError("user") redirect = "HTTP redirect to " + response.headers.get("Location", "") if response.status_code == 302: - raise exception.AuthRequired( + raise self.exc.AuthRequired( ("username & password", "authenticated cookies"), "profile", redirect) - raise exception.AbortExtraction(redirect) + raise self.exc.AbortExtraction(redirect) diff --git a/gallery_dl/extractor/imgbox.py b/gallery_dl/extractor/imgbox.py index 8ac66f4a..bfe5addd 100644 --- a/gallery_dl/extractor/imgbox.py +++ b/gallery_dl/extractor/imgbox.py @@ -9,7 +9,7 @@ """Extractors for https://imgbox.com/""" from .common import Extractor, Message, AsynchronousMixin -from .. import text, exception +from .. import text class ImgboxExtractor(Extractor): @@ -68,7 +68,7 @@ class ImgboxGalleryExtractor(AsynchronousMixin, ImgboxExtractor): def get_job_metadata(self): page = self.request(self.root + "/g/" + self.gallery_key).text if "The specified gallery could not be found." in page: - raise exception.NotFoundError("gallery") + raise self.exc.NotFoundError("gallery") self.image_keys = text.re( r'').findall(page)
 
@@ -104,5 +104,5 @@ class ImgboxImageExtractor(ImgboxExtractor):
     def get_image_metadata(self, page):
         data = ImgboxExtractor.get_image_metadata(self, page)
         if not data[= 400: self.log.debug("Server response: %s", response.text) - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"GraphQL query failed " f"('{response.status_code} {response.reason}')") @@ -82,7 +82,7 @@ class LusciousAlbumExtractor(LusciousExtractor): album = self._request_graphql("AlbumGet", variables)["album"]["get"] if "errors" in album: - raise exception.NotFoundError("album") + raise self.exc.NotFoundError("album") album["audiences"] = [item["title"] for item in album["audiences"]] album["genres"] = [item["title"] for item in album["genres"]] diff --git a/gallery_dl/extractor/madokami.py b/gallery_dl/extractor/madokami.py index 0b90e8ef..10c4d061 100644 --- a/gallery_dl/extractor/madokami.py +++ b/gallery_dl/extractor/madokami.py @@ -9,7 +9,7 @@ """Extractors for https://manga.madokami.al/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util BASE_PATTERN = r"(?:https?://)?manga\.madokami\.al" @@ -31,7 +31,7 @@ class MadokamiMangaExtractor(MadokamiExtractor): def items(self): username, password = self._get_auth_info() if not username: - raise exception.AuthRequired("username & password") + raise self.exc.AuthRequired("username & password") self.session.auth = util.HTTPBasicAuth(username, password) url = f"{self.root}/Manga/{self.groups[0]}" diff --git a/gallery_dl/extractor/mangadex.py b/gallery_dl/extractor/mangadex.py index 8a9bb844..16577b9b 100644 --- a/gallery_dl/extractor/mangadex.py +++ b/gallery_dl/extractor/mangadex.py @@ -9,7 +9,7 @@ """Extractors for https://mangadex.org/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util from ..cache import cache, memcache from collections import defaultdict @@ -129,7 +129,7 @@ class MangadexChapterExtractor(MangadexExtractor): data = self._transform(chapter) if data.get("_external_url") and not data["count"]: - raise exception.AbortExtraction( + raise self.exc.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']}.") @@ -333,7 +333,7 @@ class MangadexAPI(): try: access_token = data["access_token"] except Exception: - raise exception.AuthenticationError(data.get("error_description")) + raise self.exc.AuthenticationError(data.get("error_description")) if refresh_token != data.get("refresh_token"): _refresh_token_cache.update( @@ -356,7 +356,7 @@ class MangadexAPI(): data = self.extractor.request_json( url, method="POST", json=json, fatal=None) if data.get("result") != "ok": - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() if refresh_token != data["token"]["refresh"]: _refresh_token_cache.update(username, data["token"]["refresh"]) @@ -381,7 +381,7 @@ class MangadexAPI(): msg = ", ".join(f'{error["title"]}: "{error["detail"]}"' for error in response.json()["errors"]) - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"{response.status_code} {response.reason} ({msg})") def _pagination_chapters(self, endpoint, params=None, auth=False): diff --git a/gallery_dl/extractor/mangafire.py b/gallery_dl/extractor/mangafire.py index f5285444..a46b37ec 100644 --- a/gallery_dl/extractor/mangafire.py +++ b/gallery_dl/extractor/mangafire.py @@ -9,7 +9,7 @@ """Extractors for https://mangafire.to/""" from .common import ChapterExtractor, MangaExtractor -from .. import text, exception +from .. import text from ..cache import memcache BASE_PATTERN = r"(?:https?://)?(?:www\.)?mangafire\.to" @@ -42,7 +42,7 @@ class MangafireChapterExtractor(MangafireBase, ChapterExtractor): chapters = _manga_chapters(self, (manga_id, self.type, lang)) anchor = chapters[chapter_info] except KeyError: - raise exception.NotFoundError("chapter") + raise self.exc.NotFoundError("chapter") self.chapter_id = text.extr(anchor, 'data-id="', '"') return { diff --git a/gallery_dl/extractor/manganelo.py b/gallery_dl/extractor/manganelo.py index 3ff51bc0..71b0772d 100644 --- a/gallery_dl/extractor/manganelo.py +++ b/gallery_dl/extractor/manganelo.py @@ -10,7 +10,7 @@ """Extractors for https://www.mangakakalot.gg/ and mirror sites""" from .common import BaseExtractor, ChapterExtractor, MangaExtractor, Message -from .. import text, util, exception +from .. import text, util class ManganeloExtractor(BaseExtractor): @@ -144,7 +144,7 @@ class ManganeloBookmarkExtractor(ManganeloExtractor): response = self.request(url, params=params) if response.history: - raise exception.AuthRequired( + raise self.exc.AuthRequired( "authenticated cookies", "your bookmarks") page = response.text last = text.parse_int(text.extr(page, ">Last(", ")")) diff --git a/gallery_dl/extractor/mangapark.py b/gallery_dl/extractor/mangapark.py index 05899e99..44d61d3f 100644 --- a/gallery_dl/extractor/mangapark.py +++ b/gallery_dl/extractor/mangapark.py @@ -9,7 +9,7 @@ """Extractors for https://mangapark.net/""" from .common import ChapterExtractor, Extractor, Message -from .. import text, util, exception +from .. import text, util from ..cache import memcache BASE_PATTERN = (r"(?:https?://)?(?:www\.)?(?:" @@ -175,5 +175,5 @@ class MangaparkMangaExtractor(MangaparkBase, Extractor): not lang or data["lang"] == lang): return data["id"] - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"'{source}' does not match any available source") diff --git a/gallery_dl/extractor/mangaread.py b/gallery_dl/extractor/mangaread.py index 82fddde3..d74e7c8e 100644 --- a/gallery_dl/extractor/mangaread.py +++ b/gallery_dl/extractor/mangaread.py @@ -7,7 +7,7 @@ """Extractors for https://mangaread.org/""" from .common import ChapterExtractor, MangaExtractor -from .. import text, exception +from .. import text class MangareadBase(): @@ -40,7 +40,7 @@ class MangareadChapterExtractor(MangareadBase, ChapterExtractor): data = {"tags": list(text.split_html(tags)[::2])} info = text.extr(page, '

', "

") if not info: - raise exception.NotFoundError("chapter") + raise self.exc.NotFoundError("chapter") self.parse_chapter_string(info, data) return data @@ -61,7 +61,7 @@ class MangareadMangaExtractor(MangareadBase, MangaExtractor): def chapters(self, page): if 'class="error404' in page: - raise exception.NotFoundError("manga") + raise self.exc.NotFoundError("manga") data = self.metadata(page) results = [] for chapter in text.extract_iter( diff --git a/gallery_dl/extractor/mangoxo.py b/gallery_dl/extractor/mangoxo.py index 60f0de97..beffbee1 100644 --- a/gallery_dl/extractor/mangoxo.py +++ b/gallery_dl/extractor/mangoxo.py @@ -9,7 +9,7 @@ """Extractors for https://www.mangoxo.com/""" from .common import Extractor, Message -from .. import text, exception +from .. import text from ..cache import cache import hashlib import time @@ -50,7 +50,7 @@ class MangoxoExtractor(Extractor): data = response.json() if str(data.get("result")) != "1": - raise exception.AuthenticationError(data.get("msg")) + raise self.exc.AuthenticationError(data.get("msg")) return {"SESSION": self.cookies.get("SESSION")} def _sign_by_md5(self, username, password, token): diff --git a/gallery_dl/extractor/mastodon.py b/gallery_dl/extractor/mastodon.py index cca15307..70481cac 100644 --- a/gallery_dl/extractor/mastodon.py +++ b/gallery_dl/extractor/mastodon.py @@ -9,7 +9,7 @@ """Extractors for Mastodon instances""" from .common import BaseExtractor, Message -from .. import text, exception +from .. import text from ..cache import cache @@ -246,7 +246,7 @@ class MastodonAPI(): if account["acct"] == username: self.extractor._check_moved(account) return account["id"] - raise exception.NotFoundError("account") + raise self.exc.NotFoundError("account") def account_bookmarks(self): """Statuses the user has bookmarked""" @@ -312,16 +312,16 @@ class MastodonAPI(): if code < 400: return response if code == 401: - raise exception.AbortExtraction( + raise self.exc.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() + raise self.exc.NotFoundError() if code == 429: self.extractor.wait(until=self.extractor.parse_datetime_iso( response.headers["x-ratelimit-reset"])) continue - raise exception.AbortExtraction(response.json().get("error")) + raise self.exc.AbortExtraction(response.json().get("error")) def _pagination(self, endpoint, params): url = endpoint diff --git a/gallery_dl/extractor/misskey.py b/gallery_dl/extractor/misskey.py index f9459dab..a44d3e37 100644 --- a/gallery_dl/extractor/misskey.py +++ b/gallery_dl/extractor/misskey.py @@ -7,7 +7,7 @@ """Extractors for Misskey instances""" from .common import BaseExtractor, Message, Dispatch -from .. import text, dt, exception +from .. import text, dt from ..cache import memcache @@ -239,7 +239,7 @@ class MisskeyAPI(): def i_favorites(self): endpoint = "/i/favorites" if not self.access_token: - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() data = {"i": self.access_token} return self._pagination(endpoint, data) diff --git a/gallery_dl/extractor/motherless.py b/gallery_dl/extractor/motherless.py index 6c96c10c..7e748ab5 100644 --- a/gallery_dl/extractor/motherless.py +++ b/gallery_dl/extractor/motherless.py @@ -9,7 +9,7 @@ """Extractors for https://motherless.com/""" from .common import Extractor, Message -from .. import text, dt, exception +from .. import text, dt from ..cache import memcache BASE_PATTERN = r"(?:https?://)?motherless\.com" @@ -28,7 +28,7 @@ class MotherlessExtractor(Extractor): content = response.content if (b'
The page you're looking for cannot be found.<" in content): - raise exception.NotFoundError("page") + raise self.exc.NotFoundError("page") self.request = Extractor.request.__get__(self) return response diff --git a/gallery_dl/extractor/myhentaigallery.py b/gallery_dl/extractor/myhentaigallery.py index b94a73f4..adf13845 100644 --- a/gallery_dl/extractor/myhentaigallery.py +++ b/gallery_dl/extractor/myhentaigallery.py @@ -7,7 +7,7 @@ """Extractors for https://myhentaigallery.com/""" from .common import Extractor, GalleryExtractor, Message -from .. import text, exception +from .. import text BASE_PATTERN = r"(?:https?://)?myhentaigallery\.com" @@ -40,7 +40,7 @@ class MyhentaigalleryGalleryExtractor(MyhentaigalleryBase, GalleryExtractor): title = title[4:] if not title: - raise exception.NotFoundError("gallery") + raise self.exc.NotFoundError("gallery") return { "title" : text.unescape(title), diff --git a/gallery_dl/extractor/myportfolio.py b/gallery_dl/extractor/myportfolio.py index 3a211228..faff4a37 100644 --- a/gallery_dl/extractor/myportfolio.py +++ b/gallery_dl/extractor/myportfolio.py @@ -9,7 +9,7 @@ """Extractors for https://www.myportfolio.com/""" from .common import Extractor, Message -from .. import text, exception +from .. import text class MyportfolioGalleryExtractor(Extractor): @@ -34,7 +34,7 @@ class MyportfolioGalleryExtractor(Extractor): url = "https://" + self.domain + (self.path or "") response = self.request(url) if response.history and response.url.endswith(".adobe.com/missing"): - raise exception.NotFoundError() + raise self.exc.NotFoundError() page = response.text projects = text.extr( @@ -72,7 +72,7 @@ class MyportfolioGalleryExtractor(Extractor): elif user: user, _, title = user.partition(" - ") else: - raise exception.NotFoundError() + raise self.exc.NotFoundError() return { "user": text.unescape(user), diff --git a/gallery_dl/extractor/newgrounds.py b/gallery_dl/extractor/newgrounds.py index 9a8be8ab..1aac4e33 100644 --- a/gallery_dl/extractor/newgrounds.py +++ b/gallery_dl/extractor/newgrounds.py @@ -9,7 +9,7 @@ """Extractors for https://www.newgrounds.com/""" from .common import Extractor, Message, Dispatch -from .. import text, util, dt, exception +from .. import text, util, dt from ..cache import cache import itertools @@ -143,7 +143,7 @@ class NewgroundsExtractor(Extractor): if result.get("success"): break if "errors" in result: - raise exception.AuthenticationError( + raise self.exc.AuthenticationError( '"' + '", "'.join(result["errors"]) + '"') if result.get("requiresMfa"): @@ -370,7 +370,7 @@ class NewgroundsExtractor(Extractor): return if "errors" in data: msg = ", ".join(text.unescape(e) for e in data["errors"]) - raise exception.AbortExtraction(msg) + raise self.exc.AbortExtraction(msg) items = data.get("items") if not items: diff --git a/gallery_dl/extractor/nijie.py b/gallery_dl/extractor/nijie.py index 181d54d6..70b4f48f 100644 --- a/gallery_dl/extractor/nijie.py +++ b/gallery_dl/extractor/nijie.py @@ -9,7 +9,7 @@ """Extractors for nijie instances""" from .common import BaseExtractor, Message, Dispatch, AsynchronousMixin -from .. import text, dt, exception +from .. import text, dt from ..cache import cache @@ -134,7 +134,7 @@ class NijieExtractor(AsynchronousMixin, BaseExtractor): if username: return self.cookies_update(self._login_impl(username, password)) - raise exception.AuthenticationError("Username and password required") + raise self.exc.AuthenticationError("Username and password required") @cache(maxage=90*86400, keyarg=1) def _login_impl(self, username, password): @@ -145,7 +145,7 @@ class NijieExtractor(AsynchronousMixin, BaseExtractor): response = self.request(url, method="POST", data=data) if "/login.php" in response.text: - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() return self.cookies def _pagination(self, path): diff --git a/gallery_dl/extractor/oauth.py b/gallery_dl/extractor/oauth.py index 38bb5eeb..c7592d2b 100644 --- a/gallery_dl/extractor/oauth.py +++ b/gallery_dl/extractor/oauth.py @@ -9,7 +9,7 @@ """Utility classes to setup OAuth and link accounts to gallery-dl""" from .common import Extractor -from .. import text, oauth, util, config, exception +from .. import text, oauth, util, config from ..output import stdout_write from ..cache import cache, memcache @@ -74,7 +74,7 @@ class OAuthBase(Extractor): msg = "Received invalid" if exc: exc = f" ({exc.__class__.__name__}: {exc})" - raise exception.AbortExtraction(f"{msg} OAuth response{exc}") + raise self.exc.AbortExtraction(f"{msg} OAuth response{exc}") def send(self, msg): """Send 'msg' to the socket opened in 'recv()'""" @@ -396,7 +396,7 @@ 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.AbortExtraction( + raise self.exc.AbortExtraction( f"Failed to register new application: '{data}'") data["client-id"] = data.pop("client_id") diff --git a/gallery_dl/extractor/paheal.py b/gallery_dl/extractor/paheal.py index be22dea5..d533e76a 100644 --- a/gallery_dl/extractor/paheal.py +++ b/gallery_dl/extractor/paheal.py @@ -9,7 +9,7 @@ """Extractors for https://rule34.paheal.net/""" from .common import Extractor, Message -from .. import text, exception +from .. import text class PahealExtractor(Extractor): @@ -98,7 +98,7 @@ class PahealTagExtractor(PahealExtractor): while True: try: page = self.request(base + str(pnum)).text - except exception.HttpError as exc: + except self.exc.HttpError as exc: if exc.status == 404: return raise @@ -152,7 +152,7 @@ class PahealPostExtractor(PahealExtractor): def get_posts(self): try: return (self._extract_post(self.groups[0]),) - except exception.HttpError as exc: + except self.exc.HttpError as exc: if exc.status == 404: return () raise diff --git a/gallery_dl/extractor/patreon.py b/gallery_dl/extractor/patreon.py index 2635c4b3..cc58c6c9 100644 --- a/gallery_dl/extractor/patreon.py +++ b/gallery_dl/extractor/patreon.py @@ -9,7 +9,7 @@ """Extractors for https://www.patreon.com/""" from .common import Extractor, Message -from .. import text, util, dt, exception +from .. import text, util, dt from ..cache import memcache import collections import itertools @@ -347,7 +347,7 @@ class PatreonExtractor(Extractor): except Exception: pass - raise exception.AbortExtraction("Unable to extract bootstrap data") + raise self.exc.AbortExtraction("Unable to extract bootstrap data") class PatreonCollectionExtractor(PatreonExtractor): @@ -428,12 +428,12 @@ class PatreonCreatorExtractor(PatreonExtractor): data = None data = self._extract_bootstrap(page) return data["campaign"]["data"]["id"] - except exception.ControlException: + except self.exc.ControlException: pass except Exception as exc: if data: self.log.debug(data) - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"Unable to extract campaign ID " f"({exc.__class__.__name__}: {exc})") @@ -442,7 +442,7 @@ class PatreonCreatorExtractor(PatreonExtractor): page, r'{\"value\":{\"campaign\":{\"data\":{\"id\":\"', '\\"'): return cid - raise exception.AbortExtraction("Failed to extract campaign ID") + raise self.exc.AbortExtraction("Failed to extract campaign ID") def _get_filters(self, params): return "".join( diff --git a/gallery_dl/extractor/pexels.py b/gallery_dl/extractor/pexels.py index 5f4ebc72..68537528 100644 --- a/gallery_dl/extractor/pexels.py +++ b/gallery_dl/extractor/pexels.py @@ -9,7 +9,7 @@ """Extractors for https://pexels.com/""" from .common import Extractor, Message -from .. import text, exception +from .. import text BASE_PATTERN = r"(?:https?://)?(?:www\.)?pexels\.com" @@ -174,7 +174,7 @@ class PexelsAPI(): else: self.extractor.log.debug(response.text) - raise exception.AbortExtraction("API request failed") + raise self.exc.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 2f52b9ab..74330c44 100644 --- a/gallery_dl/extractor/philomena.py +++ b/gallery_dl/extractor/philomena.py @@ -9,7 +9,7 @@ """Extractors for Philomena sites""" from .booru import BooruExtractor -from .. import text, exception +from .. import text class PhilomenaExtractor(BooruExtractor): @@ -113,7 +113,7 @@ class PhilomenaGalleryExtractor(PhilomenaExtractor): try: return {"gallery": self.api.gallery(self.groups[-1])} except IndexError: - raise exception.NotFoundError("gallery") + raise self.exc.NotFoundError("gallery") def posts(self): gallery_id = "gallery_id:" + self.groups[-1] @@ -159,7 +159,7 @@ class PhilomenaAPI(): # error self.extractor.log.debug(response.content) - raise exception.HttpError("", response) + raise self.exc.HttpError("", response) def _pagination(self, endpoint, params): extr = self.extractor diff --git a/gallery_dl/extractor/pholder.py b/gallery_dl/extractor/pholder.py index 12e150d4..03ed9e0d 100644 --- a/gallery_dl/extractor/pholder.py +++ b/gallery_dl/extractor/pholder.py @@ -7,7 +7,7 @@ """Extractors for https://pholder.com/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util BASE_PATTERN = r"(?:https?://)?(?:www\.)?pholder\.com" @@ -50,7 +50,7 @@ class PholderExtractor(Extractor): except ValueError: pass - raise exception.AbortExtraction("Could not locate window.data JSON.") + raise self.exc.AbortExtraction("Could not locate window.data JSON.") def _posts(self, page_url): params = {"page": 1} diff --git a/gallery_dl/extractor/pillowfort.py b/gallery_dl/extractor/pillowfort.py index 570ed85a..f99d3d61 100644 --- a/gallery_dl/extractor/pillowfort.py +++ b/gallery_dl/extractor/pillowfort.py @@ -10,7 +10,7 @@ from .common import Extractor, Message from ..cache import cache -from .. import text, exception +from .. import text BASE_PATTERN = r"(?:https?://)?www\.pillowfort\.social" @@ -108,7 +108,7 @@ class PillowfortExtractor(Extractor): response = self.request(url, method="POST", headers=headers, data=data) if not response.history: - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() return { cookie.name: cookie.value diff --git a/gallery_dl/extractor/pinterest.py b/gallery_dl/extractor/pinterest.py index cd3d077c..652f04cf 100644 --- a/gallery_dl/extractor/pinterest.py +++ b/gallery_dl/extractor/pinterest.py @@ -9,7 +9,7 @@ """Extractors for https://www.pinterest.com/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util import itertools BASE_PATTERN = r"(?:https?://)?(?:\w+\.)?pinterest\.[\w.]+" @@ -394,7 +394,7 @@ class PinterestPinitExtractor(PinterestExtractor): f"/{self.groups[0]}/redirect/") location = self.request_location(url) if not location: - raise exception.NotFoundError("pin") + raise self.exc.NotFoundError("pin") elif PinterestPinExtractor.pattern.match(location): yield Message.Queue, location, { "_extractor": PinterestPinExtractor} @@ -402,7 +402,7 @@ class PinterestPinitExtractor(PinterestExtractor): yield Message.Queue, location, { "_extractor": PinterestBoardExtractor} else: - raise exception.NotFoundError("pin") + raise self.exc.NotFoundError("pin") class PinterestAPI(): @@ -545,9 +545,9 @@ class PinterestAPI(): return data if response.status_code == 404: resource = self.extractor.subcategory.rpartition("-")[2] - raise exception.NotFoundError(resource) + raise self.exc.NotFoundError(resource) self.extractor.log.debug("Server response: %s", response.text) - raise exception.AbortExtraction("API request failed") + raise self.exc.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 0a4f6b34..1deb7cc9 100644 --- a/gallery_dl/extractor/pixiv.py +++ b/gallery_dl/extractor/pixiv.py @@ -9,7 +9,7 @@ """Extractors for https://www.pixiv.net/""" from .common import Extractor, Message, Dispatch -from .. import text, util, dt, exception +from .. import text, util, dt from ..cache import cache, memcache import itertools import hashlib @@ -205,7 +205,7 @@ class PixivExtractor(Extractor): url = f"{base}0.{ext}" self.request(url, method="HEAD") break - except exception.HttpError: + except self.exc.HttpError: pass else: self.log.warning( @@ -329,7 +329,7 @@ class PixivExtractor(Extractor): url = f"{base}_p0.{ext}" self.request(url, method="HEAD") return url - except exception.HttpError: + except self.exc.HttpError: pass def _sanitize_ajax_caption(self, caption): @@ -721,7 +721,7 @@ class PixivRankingExtractor(PixivExtractor): try: self.mode = mode = mode_map[mode] except KeyError: - raise exception.AbortExtraction(f"Invalid mode '{mode}'") + raise self.exc.AbortExtraction(f"Invalid mode '{mode}'") if date := query.get("date"): if len(date) == 8 and date.isdecimal(): @@ -772,7 +772,7 @@ class PixivSearchExtractor(PixivExtractor): try: self.word = query["word"] except KeyError: - raise exception.AbortExtraction("Missing search term") + raise self.exc.AbortExtraction("Missing search term") sort = query.get("order", "date_d") sort_map = { @@ -785,7 +785,7 @@ class PixivSearchExtractor(PixivExtractor): try: self.sort = sort = sort_map[sort] except KeyError: - raise exception.AbortExtraction(f"Invalid search order '{sort}'") + raise self.exc.AbortExtraction(f"Invalid search order '{sort}'") target = query.get("s_mode", "s_tag_full") target_map = { @@ -796,7 +796,7 @@ class PixivSearchExtractor(PixivExtractor): try: self.target = target = target_map[target] except KeyError: - raise exception.AbortExtraction(f"Invalid search mode '{target}'") + raise self.exc.AbortExtraction(f"Invalid search mode '{target}'") self.date_start = query.get("scd") self.date_end = query.get("ecd") @@ -1153,7 +1153,7 @@ class PixivAppAPI(): @cache(maxage=3600, keyarg=1) def _login_impl(self, username): if not self.refresh_token: - raise exception.AuthenticationError( + raise self.exc.AuthenticationError( "'refresh-token' required.\n" "Run `gallery-dl oauth:pixiv` to get one.") @@ -1178,7 +1178,7 @@ class PixivAppAPI(): url, method="POST", headers=headers, data=data, fatal=False) if response.status_code >= 400: self.log.debug(response.text) - raise exception.AuthenticationError("Invalid refresh token") + raise self.exc.AuthenticationError("Invalid refresh token") data = response.json()["response"] return data["user"], "Bearer " + data["access_token"] @@ -1305,7 +1305,7 @@ class PixivAppAPI(): self.log.debug(data) if response.status_code == 404: - raise exception.NotFoundError() + raise self.exc.NotFoundError() error = data["error"] if "rate limit" in (error.get("message") or "").lower(): @@ -1315,7 +1315,7 @@ class PixivAppAPI(): msg = (f"'{msg}'" if (msg := error.get("user_message")) else f"'{msg}'" if (msg := error.get("message")) else error) - raise exception.AbortExtraction("API request failed: " + msg) + raise self.exc.AbortExtraction("API request failed: " + msg) def _pagination(self, endpoint, params, key_items="illusts", key_data=None, key_user=None): @@ -1326,7 +1326,7 @@ class PixivAppAPI(): if key_user is not None and not data[key_user].get("id"): user = self.user_detail(self.extractor.user_id, fatal=False) if user.get("error"): - raise exception.NotFoundError("user") + raise self.exc.NotFoundError("user") return while True: diff --git a/gallery_dl/extractor/pixnet.py b/gallery_dl/extractor/pixnet.py index 68f546ba..974c3cbf 100644 --- a/gallery_dl/extractor/pixnet.py +++ b/gallery_dl/extractor/pixnet.py @@ -9,7 +9,7 @@ """Extractors for https://www.pixnet.net/""" from .common import Extractor, Message -from .. import text, exception +from .. import text BASE_PATTERN = r"(?:https?://)?(?!www\.)([\w-]+)\.pixnet.net" @@ -52,7 +52,7 @@ class PixnetExtractor(Extractor): pnext = text.extr(page, 'class="nextBtn"', '>') if pnext is None and 'name="albumpass">' in page: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"Album {self.item_id} is password-protected.") if "href" not in pnext: return diff --git a/gallery_dl/extractor/plurk.py b/gallery_dl/extractor/plurk.py index 76ca59f7..c0a04bc8 100644 --- a/gallery_dl/extractor/plurk.py +++ b/gallery_dl/extractor/plurk.py @@ -9,7 +9,7 @@ """Extractors for https://www.plurk.com/""" from .common import Extractor, Message -from .. import text, util, dt, exception +from .. import text, util, dt class PlurkExtractor(Extractor): @@ -59,7 +59,7 @@ class PlurkExtractor(Extractor): def _load(self, data): if not data: - raise exception.NotFoundError("user") + raise self.exc.NotFoundError("user") return util.json_loads( text.re(r"new Date\(([^)]+)\)").sub(r"\1", data)) diff --git a/gallery_dl/extractor/poringa.py b/gallery_dl/extractor/poringa.py index 94a493f2..02fa093b 100644 --- a/gallery_dl/extractor/poringa.py +++ b/gallery_dl/extractor/poringa.py @@ -7,7 +7,7 @@ """Extractors for http://www.poringa.net/""" from .common import Extractor, Message -from .. import text, exception +from .. import text from ..cache import cache import itertools @@ -32,7 +32,7 @@ class PoringaExtractor(Extractor): try: response = self.request(url) - except exception.HttpError as exc: + except self.exc.HttpError as exc: self.log.warning( "Unable to fetch posts for '%s' (%s)", post_id, exc) continue diff --git a/gallery_dl/extractor/pornhub.py b/gallery_dl/extractor/pornhub.py index 3dd8b2a6..c2b45498 100644 --- a/gallery_dl/extractor/pornhub.py +++ b/gallery_dl/extractor/pornhub.py @@ -9,7 +9,7 @@ """Extractors for https://www.pornhub.com/""" from .common import Extractor, Message, Dispatch -from .. import text, exception +from .. import text BASE_PATTERN = r"(?:https?://)?(?:[\w-]+\.)?pornhub\.com" @@ -109,7 +109,7 @@ class PornhubGalleryExtractor(PornhubExtractor): data = self.request_json(url, params=params) if not (images := data.get("photos")): - raise exception.AuthorizationError() + raise self.exc.AuthorizationError() key = end = self._first results = [] diff --git a/gallery_dl/extractor/postmill.py b/gallery_dl/extractor/postmill.py index 22d2bded..99f44317 100644 --- a/gallery_dl/extractor/postmill.py +++ b/gallery_dl/extractor/postmill.py @@ -7,7 +7,7 @@ """Extractors for Postmill instances""" from .common import BaseExtractor, Message -from .. import text, exception +from .. import text class PostmillExtractor(BaseExtractor): @@ -102,7 +102,7 @@ class PostmillSubmissionsExtractor(PostmillExtractor): if response.history: redirect_url = response.url if redirect_url == self.root + "/login": - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"HTTP redirect to login page ({redirect_url})") page = response.text diff --git a/gallery_dl/extractor/readcomiconline.py b/gallery_dl/extractor/readcomiconline.py index 24a01712..6add5724 100644 --- a/gallery_dl/extractor/readcomiconline.py +++ b/gallery_dl/extractor/readcomiconline.py @@ -9,7 +9,7 @@ """Extractors for https://readcomiconline.li/""" from .common import Extractor, ChapterExtractor, MangaExtractor -from .. import text, exception +from .. import text import binascii BASE_PATTERN = r"(?i)(?:https?://)?(?:www\.)?readcomiconline\.(?:li|to)" @@ -36,7 +36,7 @@ class ReadcomiconlineBase(): "the CAPTCHA, and press ENTER to continue", response.url) self.input() else: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"Redirect to \n{response.url}\nVisit this URL in your " f"browser and solve the CAPTCHA to continue") diff --git a/gallery_dl/extractor/reddit.py b/gallery_dl/extractor/reddit.py index e731c841..0cd7ef71 100644 --- a/gallery_dl/extractor/reddit.py +++ b/gallery_dl/extractor/reddit.py @@ -9,7 +9,7 @@ """Extractors for https://www.reddit.com/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util from ..cache import cache @@ -525,7 +525,7 @@ class RedditAPI(): if response.status_code != 200: self.log.debug("Server response: %s", data) - raise exception.AuthenticationError( + raise self.exc.AuthenticationError( f"\"{data.get('error')}: {data.get('message')}\"") return "Bearer " + data["access_token"] @@ -555,16 +555,16 @@ class RedditAPI(): try: data = response.json() except ValueError: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( text.remove_html(response.text)) if "error" in data: if data["error"] == 403: - raise exception.AuthorizationError() + raise self.exc.AuthorizationError() if data["error"] == 404: - raise exception.NotFoundError() + raise self.exc.NotFoundError() self.log.debug(data) - raise exception.AbortExtraction(data.get("message")) + raise self.exc.AbortExtraction(data.get("message")) return data def _pagination(self, endpoint, params): @@ -592,7 +592,7 @@ class RedditAPI(): if post["num_comments"] and self.comments: try: yield self.submission(post["id"]) - except exception.AuthorizationError: + except self.exc.AuthorizationError: pass else: yield post, () diff --git a/gallery_dl/extractor/rule34xyz.py b/gallery_dl/extractor/rule34xyz.py index 6b313d8a..8c5f3e4d 100644 --- a/gallery_dl/extractor/rule34xyz.py +++ b/gallery_dl/extractor/rule34xyz.py @@ -9,7 +9,7 @@ """Extractors for https://rule34.xyz/""" from .booru import BooruExtractor -from .. import text, exception +from .. import text from ..cache import cache import collections @@ -129,7 +129,7 @@ class Rule34xyzExtractor(BooruExtractor): if jwt := response.get("jwt"): return "Bearer " + jwt - raise exception.AuthenticationError( + raise self.exc.AuthenticationError( (msg := response.get("message")) and f'"{msg}"') diff --git a/gallery_dl/extractor/sankaku.py b/gallery_dl/extractor/sankaku.py index 6cb9f79d..b8595540 100644 --- a/gallery_dl/extractor/sankaku.py +++ b/gallery_dl/extractor/sankaku.py @@ -10,7 +10,7 @@ from .booru import BooruExtractor from .common import Message -from .. import text, util, exception +from .. import text, util from ..cache import cache import collections @@ -284,7 +284,7 @@ class SankakuAPI(): if response.status_code == 429: until = response.headers.get("X-RateLimit-Reset") if not until and b"_tags-explicit-limit" in response.content: - raise exception.AuthorizationError( + raise self.exc.AuthorizationError( "Search tag limit exceeded") seconds = None if until else 600 self.extractor.wait(until=until, seconds=seconds) @@ -305,7 +305,7 @@ class SankakuAPI(): code = f"'{code.rpartition('__')[2].replace('-', ' ')}'" except Exception: pass - raise exception.AbortExtraction(code) + raise self.exc.AbortExtraction(code) return data def _pagination(self, endpoint, params): @@ -365,5 +365,5 @@ def _authenticate_impl(extr, username, password): data = response.json() if response.status_code >= 400 or not data.get("success"): - raise exception.AuthenticationError(data.get("error")) + raise extr.exc.AuthenticationError(data.get("error")) return "Bearer " + data["access_token"] diff --git a/gallery_dl/extractor/schalenetwork.py b/gallery_dl/extractor/schalenetwork.py index 4a927b51..bb26d9fc 100644 --- a/gallery_dl/extractor/schalenetwork.py +++ b/gallery_dl/extractor/schalenetwork.py @@ -9,7 +9,7 @@ """Extractors for https://niyaniya.moe/""" from .common import GalleryExtractor, Extractor, Message -from .. import text, exception +from .. import text import collections BASE_PATTERN = ( @@ -66,7 +66,7 @@ class SchalenetworkExtractor(Extractor): if token := self.config("token"): return "Bearer " + token.rpartition(' ')[2] if required: - raise exception.AuthRequired("'token'", "your favorites") + raise self.exc.AuthRequired("'token'", "your favorites") def _crt(self): crt = self.config("crt") @@ -88,7 +88,7 @@ class SchalenetworkExtractor(Extractor): msg = None else: msg = f"{exc.status} {exc.response.reason}" - raise exception.AuthRequired( + raise self.exc.AuthRequired( "'crt' query parameter & matching 'user-agent'", None, msg) @@ -153,7 +153,7 @@ class SchalenetworkGalleryExtractor(SchalenetworkExtractor, GalleryExtractor): try: data_fmt = self.request_json( url, method="POST", headers=headers) - except exception.HttpError as exc: + except self.exc.HttpError as exc: self._require_auth(exc) self.fmt = self._select_format(data_fmt["data"]) @@ -217,7 +217,7 @@ class SchalenetworkGalleryExtractor(SchalenetworkExtractor, GalleryExtractor): self.log.debug("%s: Format %s is not available", self.groups[1], fmtid) else: - raise exception.NotFoundError("format") + raise self.exc.NotFoundError("format") self.log.debug("%s: Selected format %s", self.groups[1], fmtid) fmt["w"] = fmtid diff --git a/gallery_dl/extractor/scrolller.py b/gallery_dl/extractor/scrolller.py index b4693ae8..e9554756 100644 --- a/gallery_dl/extractor/scrolller.py +++ b/gallery_dl/extractor/scrolller.py @@ -9,7 +9,7 @@ """Extractors for https://scrolller.com/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util from ..cache import cache BASE_PATTERN = r"(?:https?://)?(?:www\.)?scrolller\.com" @@ -82,9 +82,9 @@ class ScrolllerExtractor(Extractor): try: data = self._request_graphql("LoginQuery", variables, False) - except exception.HttpError as exc: + except self.exc.HttpError as exc: if exc.status == 403: - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() raise return data["login"]["token"] @@ -206,7 +206,7 @@ class ScrolllerFollowingExtractor(ScrolllerExtractor): self.login() if not self.auth_token: - raise exception.AuthorizationError("Login required") + raise self.exc.AuthorizationError("Login required") variables = { "iterator": None, diff --git a/gallery_dl/extractor/seiga.py b/gallery_dl/extractor/seiga.py index 8ea4f24a..f221ed89 100644 --- a/gallery_dl/extractor/seiga.py +++ b/gallery_dl/extractor/seiga.py @@ -9,7 +9,7 @@ """Extractors for https://seiga.nicovideo.jp/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util from ..cache import cache @@ -45,7 +45,7 @@ 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.AbortExtraction( + raise self.exc.AbortExtraction( f"HTTP redirect to login page ({location.partition('?')[0]})") return location.replace("/o/", "/priv/", 1) @@ -57,7 +57,7 @@ class SeigaExtractor(Extractor): if username: return self.cookies_update(self._login_impl(username, password)) - raise exception.AuthorizationError( + raise self.exc.AuthorizationError( "username & password or 'user_session' cookie required") @cache(maxage=365*86400, keyarg=1) @@ -76,7 +76,7 @@ class SeigaExtractor(Extractor): response = self.request(url, method="POST", data=data) if "message=cant_login" in response.url: - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() if "/mfa" in response.url: page = response.text @@ -93,7 +93,7 @@ class SeigaExtractor(Extractor): if not response.history and \ b"Confirmation code is incorrect" in response.content: - raise exception.AuthenticationError( + raise self.exc.AuthenticationError( "Incorrect Confirmation Code") return { @@ -133,7 +133,7 @@ class SeigaUserExtractor(SeigaExtractor): ))[0] if not data["name"] and "ユーザー情報が取得出来ませんでした" in page: - raise exception.NotFoundError("user") + raise self.exc.NotFoundError("user") return { "user": { diff --git a/gallery_dl/extractor/simplyhentai.py b/gallery_dl/extractor/simplyhentai.py index 78d3daf9..01e45aa6 100644 --- a/gallery_dl/extractor/simplyhentai.py +++ b/gallery_dl/extractor/simplyhentai.py @@ -9,7 +9,7 @@ """Extract hentai-manga from https://www.simply-hentai.com/""" from .common import GalleryExtractor, Extractor, Message -from .. import text, util, exception +from .. import text, util class SimplyhentaiGalleryExtractor(GalleryExtractor): @@ -38,7 +38,7 @@ class SimplyhentaiGalleryExtractor(GalleryExtractor): title = extr('", " / "): model_name = text.unescape(model_name) @@ -86,7 +86,7 @@ class ThefapModelExtractor(ThefapExtractor): page = self.request(url).text if 'id="content"' not in page: - raise exception.NotFoundError("model") + raise self.exc.NotFoundError("model") if model_name := text.extr(page, ""): model_name = text.unescape(model_name[model_name.find(">")+1:]) diff --git a/gallery_dl/extractor/tiktok.py b/gallery_dl/extractor/tiktok.py index 3b4c19af..3a272a9e 100644 --- a/gallery_dl/extractor/tiktok.py +++ b/gallery_dl/extractor/tiktok.py @@ -7,7 +7,7 @@ """Extractors for https://www.tiktok.com/""" from .common import Extractor, Message, Dispatch -from .. import text, util, ytdl, exception +from .. import text, util, ytdl import functools import itertools import binascii @@ -166,7 +166,7 @@ class TiktokExtractor(Extractor): try: response = self.request(url) if response.history and "/login" in response.url: - raise exception.AuthorizationError( + raise self.exc.AuthorizationError( "HTTP redirect to login page " f"('{response.url.partition('?')[0]}')") html = response.text @@ -227,14 +227,14 @@ class TiktokExtractor(Extractor): data["webapp.app-context"] data = data["webapp.user-detail"] if not self._check_status_code(data, profile_url, "profile"): - raise exception.ExtractionError( + raise self.exc.ExtractionError( f"{profile_url}: could not extract rehydration data") try: for key in additional_keys: data = data[key] except KeyError as exc: self.log.traceback(exc) - raise exception.ExtractionError( + raise self.exc.ExtractionError( "%s: could not extract rehydration data (%s)", profile_url, ", ".join(additional_keys)) return data @@ -258,7 +258,7 @@ class TiktokExtractor(Extractor): if test.digest() == expected: break else: - raise exception.ExtractionError("failed to find matching digest") + raise self.exc.ExtractionError("failed to find matching digest") # extract cookie names wci = text.extr(text.extr(html, 'id="wci"', '>'), 'class="', '"') @@ -278,7 +278,7 @@ class TiktokExtractor(Extractor): sec_uid = self._extract_id( profile_url, user_name, r"MS4wLjABAAAA[\w-]{64}", "secUid") if sec_uid is None: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"{user_name}: unable to extract secondary user ID") return sec_uid @@ -286,7 +286,7 @@ class TiktokExtractor(Extractor): author_id = self._extract_id( profile_url, user_name, r"[0-9]+", "id") if author_id is None: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"{user_name}: unable to extract user ID") return author_id @@ -306,7 +306,7 @@ class TiktokExtractor(Extractor): video = post["video"] urls = self._extract_video_urls(video) if not urls: - raise exception.ExtractionError( + raise self.exc.ExtractionError( f"{post['id']}: Failed to extract video URLs. " f"You may need cookies to continue.") @@ -533,7 +533,7 @@ class TiktokVmpostExtractor(TiktokExtractor): url = self.request_location(url, headers=headers, notfound="post") if not url or len(url) <= 28: # https://www.tiktok.com/?_r=1 - raise exception.NotFoundError("post") + raise self.exc.NotFoundError("post") data = {"_extractor": TiktokPostExtractor} yield Message.Queue, url.partition("?")[0], data @@ -944,7 +944,7 @@ class TiktokTimeCursor(TiktokPaginationCursor): elif not self.reverse and (new_cursor < self.cursor or no_cursor): new_cursor = self.fallback_cursor(data) elif no_cursor: - raise exception.ExtractionError("Could not extract next cursor") + raise self.exc.ExtractionError("Could not extract next cursor") self.cursor = new_cursor return not data.get(self.has_more_key, False) @@ -1273,7 +1273,7 @@ class TiktokPaginationRequest: extractor.log.warning("%s: TikTok API keeps sending the same " "page. Taking measures to avoid an infinite " "loop", url) - raise exception.ExtractionError( + raise self.exc.ExtractionError( "TikTok API keeps sending the same page") diff --git a/gallery_dl/extractor/tumblr.py b/gallery_dl/extractor/tumblr.py index bd597807..3cae41aa 100644 --- a/gallery_dl/extractor/tumblr.py +++ b/gallery_dl/extractor/tumblr.py @@ -9,7 +9,7 @@ """Extractors for https://www.tumblr.com/""" from .common import Extractor, Message -from .. import text, util, dt, oauth, exception +from .. import text, util, dt, oauth BASE_PATTERN = ( @@ -473,7 +473,7 @@ class TumblrAPI(oauth.OAuth1API): self.log.debug(data) if status == 403: - raise exception.AuthorizationError() + raise self.exc.AuthorizationError() elif status == 404: try: @@ -492,8 +492,8 @@ class TumblrAPI(oauth.OAuth1API): else: self.log.info("Run 'gallery-dl oauth:tumblr' " "to access dashboard-only blogs") - raise exception.AuthorizationError(error) - raise exception.NotFoundError("user or post") + raise self.exc.AuthorizationError(error) + raise self.exc.NotFoundError("user or post") elif status == 429: # daily rate limit @@ -514,7 +514,7 @@ class TumblrAPI(oauth.OAuth1API): continue t = (dt.now() + dt.timedelta(0, float(reset))).time() - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"Aborting - Rate limit will reset at " f"{t.hour:02}:{t.minute:02}:{t.second:02}") @@ -524,7 +524,7 @@ class TumblrAPI(oauth.OAuth1API): self.extractor.wait(seconds=reset) continue - raise exception.AbortExtraction(data) + raise self.exc.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 4558e212..844ed302 100644 --- a/gallery_dl/extractor/twibooru.py +++ b/gallery_dl/extractor/twibooru.py @@ -9,7 +9,7 @@ """Extractors for https://twibooru.org/""" from .booru import BooruExtractor -from .. import text, exception +from .. import text import operator BASE_PATTERN = r"(?:https?://)?(?:www\.)?twibooru\.org" @@ -153,7 +153,7 @@ class TwibooruAPI(): # error self.extractor.log.debug(response.content) - raise exception.HttpError("", response) + raise self.exc.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 dc5cf11b..d89a7b68 100644 --- a/gallery_dl/extractor/twitter.py +++ b/gallery_dl/extractor/twitter.py @@ -9,7 +9,7 @@ """Extractors for https://x.com/""" from .common import Extractor, Message, Dispatch -from .. import text, util, dt, exception +from .. import text, util, dt from ..cache import cache, memcache import itertools import random @@ -906,7 +906,7 @@ class TwitterTimelineExtractor(TwitterExtractor): return self.api.user_media if strategy == "with_replies": return self.api.user_tweets_and_replies - raise exception.AbortExtraction(f"Invalid strategy '{strategy}'") + raise self.exc.AbortExtraction(f"Invalid strategy '{strategy}'") class TwitterTweetsExtractor(TwitterExtractor): @@ -1092,7 +1092,7 @@ class TwitterTweetExtractor(TwitterExtractor): try: self._assign_user(tweet["core"]["user_results"]["result"]) except KeyError: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"'{tweet.get('reason') or 'Unavailable'}'") yield tweet @@ -1403,10 +1403,10 @@ class TwitterAPI(): if tweet.get("__typename") == "TweetUnavailable": reason = tweet.get("reason") if reason in {"NsfwViewerHasNoStatedAge", "NsfwLoggedOut"}: - raise exception.AuthRequired(message="NSFW Tweet") + raise self.exc.AuthRequired(message="NSFW Tweet") if reason == "Protected": - raise exception.AuthRequired(message="Protected Tweet") - raise exception.AbortExtraction(f"Tweet unavailable ('{reason}')") + raise self.exc.AuthRequired(message="Protected Tweet") + raise self.exc.AbortExtraction(f"Tweet unavailable ('{reason}')") return tweet @@ -1754,9 +1754,9 @@ class TwitterAPI(): return user["rest_id"] except KeyError: if user and user.get("__typename") == "UserUnavailable": - raise exception.NotFoundError(user["message"], False) + raise self.exc.NotFoundError(user["message"], False) else: - raise exception.NotFoundError("user") + raise self.exc.NotFoundError("user") @cache(maxage=3600) def _guest_token(self): @@ -1835,13 +1835,13 @@ class TwitterAPI(): if "this account is temporarily locked" in msg: msg = "Account temporarily locked" if self.extractor.config("locked") != "wait": - raise exception.AuthorizationError(msg) + raise self.exc.AuthorizationError(msg) self.log.warning(msg) self.extractor.input("Press ENTER to retry.") retry = True elif "Could not authenticate you" in msg: - raise exception.AbortExtraction(f"'{msg}'") + raise self.exc.AbortExtraction(f"'{msg}'") elif msg.lower().startswith("timeout"): retry = True @@ -1858,7 +1858,7 @@ class TwitterAPI(): return data elif response.status_code in {403, 404} and \ not self.headers["x-twitter-auth-type"]: - raise exception.AuthRequired( + raise self.exc.AuthRequired( "authenticated cookies", "timeline") elif response.status_code == 429: self._handle_ratelimit(response) @@ -1870,7 +1870,7 @@ class TwitterAPI(): except Exception: pass - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"{response.status_code} {response.reason} ({errors})") def _pagination_rest(self, endpoint, params): @@ -2065,13 +2065,13 @@ class TwitterAPI(): self.headers["x-twitter-auth-type"] = None extr.log.info("Retrying API request as guest") continue - raise exception.AuthorizationError( + raise self.exc.AuthorizationError( user["screen_name"] + " blocked your account") elif user.get("protected"): - raise exception.AuthorizationError( + raise self.exc.AuthorizationError( user["screen_name"] + "'s Tweets are protected") - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( "Unable to retrieve Tweets from this timeline") tweets = [] @@ -2301,7 +2301,7 @@ class TwitterAPI(): def _handle_ratelimit(self, response): rl = self.extractor.config("ratelimit") if rl == "abort": - raise exception.AbortExtraction("Rate limit exceeded") + raise self.exc.AbortExtraction("Rate limit exceeded") until = response.headers.get("x-rate-limit-reset") seconds = None if until else 60.0 @@ -2313,7 +2313,7 @@ class TwitterAPI(): num = text.parse_int(num) msg = f"Rate limit exceeded ({amt}/{num})" if amt >= num: - raise exception.AbortExtraction(msg) + raise self.exc.AbortExtraction(msg) self.log.warning(msg) self._ratelimit_amt = amt + 1 elif rl == "wait": diff --git a/gallery_dl/extractor/urlgalleries.py b/gallery_dl/extractor/urlgalleries.py index 0d8b3d38..4e3660de 100644 --- a/gallery_dl/extractor/urlgalleries.py +++ b/gallery_dl/extractor/urlgalleries.py @@ -7,7 +7,7 @@ """Extractors for https://urlgalleries.net/""" from .common import GalleryExtractor, Message -from .. import text, exception +from .. import text class UrlgalleriesGalleryExtractor(GalleryExtractor): @@ -29,8 +29,8 @@ class UrlgalleriesGalleryExtractor(GalleryExtractor): if 300 <= response.status_code < 500: if response.headers.get("location", "").endswith( "/not_found_adult.php"): - raise exception.NotFoundError("gallery") - raise exception.HttpError(None, response) + raise self.exc.NotFoundError("gallery") + raise self.exc.HttpError(None, response) page = response.text imgs = self.images(page) diff --git a/gallery_dl/extractor/urlshortener.py b/gallery_dl/extractor/urlshortener.py index 7a9269d0..b8c9521e 100644 --- a/gallery_dl/extractor/urlshortener.py +++ b/gallery_dl/extractor/urlshortener.py @@ -7,7 +7,6 @@ """Extractors for general-purpose URL shorteners""" from .common import BaseExtractor, Message -from .. import exception class UrlshortenerExtractor(BaseExtractor): @@ -40,5 +39,5 @@ class UrlshortenerLinkExtractor(UrlshortenerExtractor): location = self.request_location( url, headers=self.config_instance("headers"), notfound="URL") if not location: - raise exception.AbortExtraction("Unable to resolve short URL") + raise self.exc.AbortExtraction("Unable to resolve short URL") yield Message.Queue, location, {} diff --git a/gallery_dl/extractor/vipergirls.py b/gallery_dl/extractor/vipergirls.py index 39817632..07f807dd 100644 --- a/gallery_dl/extractor/vipergirls.py +++ b/gallery_dl/extractor/vipergirls.py @@ -9,7 +9,7 @@ """Extractors for https://vipergirls.to/""" from .common import Extractor, Message -from .. import text, util, exception +from .. import text, util from ..cache import cache BASE_PATTERN = r"(?:https?://)?(?:www\.)?vipergirls\.to" @@ -104,7 +104,7 @@ class VipergirlsExtractor(Extractor): response = self.request(url, method="POST", data=data) if not response.cookies.get("vg_password"): - raise exception.AuthenticationError() + raise self.exc.AuthenticationError() return {cookie.name: cookie.value for cookie in response.cookies} diff --git a/gallery_dl/extractor/vk.py b/gallery_dl/extractor/vk.py index a9774e1c..95894e7a 100644 --- a/gallery_dl/extractor/vk.py +++ b/gallery_dl/extractor/vk.py @@ -9,7 +9,7 @@ """Extractors for https://vk.com/""" from .common import Extractor, Message -from .. import text, exception +from .. import text BASE_PATTERN = r"(?:https://)?(?:www\.|m\.)?vk\.com" @@ -100,13 +100,13 @@ class VkExtractor(Extractor): response = self.request( url, method="POST", headers=headers, data=data) if response.history and "/challenge.html" in response.url: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( "HTTP redirect to 'challenge' page:\n" + response.url) payload = response.json()["payload"][1] if len(payload) < 4: self.log.debug(payload) - raise exception.AuthorizationError( + raise self.exc.AuthorizationError( text.unescape(payload[0]) if payload[0] else None) total = payload[1] diff --git a/gallery_dl/extractor/wallhaven.py b/gallery_dl/extractor/wallhaven.py index 3025c566..041d4d2f 100644 --- a/gallery_dl/extractor/wallhaven.py +++ b/gallery_dl/extractor/wallhaven.py @@ -9,7 +9,7 @@ """Extractors for https://wallhaven.cc/""" from .common import Extractor, Message, Dispatch -from .. import text, exception +from .. import text class WallhavenExtractor(Extractor): @@ -199,7 +199,7 @@ class WallhavenAPI(): continue self.extractor.log.debug("Server response: %s", response.text) - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"API request failed " f"({response.status_code} {response.reason})") diff --git a/gallery_dl/extractor/webtoons.py b/gallery_dl/extractor/webtoons.py index b8fff9b3..d74fa0c9 100644 --- a/gallery_dl/extractor/webtoons.py +++ b/gallery_dl/extractor/webtoons.py @@ -10,7 +10,7 @@ """Extractors for https://www.webtoons.com/""" from .common import GalleryExtractor, Extractor, Message -from .. import exception, text, util +from .. import text, util BASE_PATTERN = r"(?:https?://)?(?:www\.)?webtoons\.com" LANG_PATTERN = BASE_PATTERN + r"/(([^/?#]+)" @@ -40,7 +40,7 @@ class WebtoonsBase(): def request(self, url, **kwargs): response = Extractor.request(self, url, **kwargs) if response.history and "/ageGate" in response.url: - raise exception.AbortExtraction( + raise self.exc.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 040d483f..076a6517 100644 --- a/gallery_dl/extractor/weibo.py +++ b/gallery_dl/extractor/weibo.py @@ -9,7 +9,7 @@ """Extractors for https://www.weibo.com/""" from .common import Extractor, Message, Dispatch -from .. import text, util, exception +from .. import text, util from ..cache import cache import random @@ -65,7 +65,7 @@ class WeiboExtractor(Extractor): if response.history: if "login.sina.com" in response.url: - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f"HTTP redirect to login page " f"({response.url.partition('?')[0]})") if "passport.weibo.com" in response.url: @@ -189,7 +189,7 @@ class WeiboExtractor(Extractor): not text.ext_from_url(video["url"]): try: video["url"] = self.request_location(video["url"]) - except exception.HttpError as exc: + except self.exc.HttpError as exc: self.log.warning("%s: %s", exc.__class__.__name__, exc) video["url"] = "" @@ -230,7 +230,7 @@ class WeiboExtractor(Extractor): if not data.get("ok"): self.log.debug(response.content) if "since_id" not in params: # first iteration - raise exception.AbortExtraction( + raise self.exc.AbortExtraction( f'"{data.get("msg") or "unknown error"}"') try: @@ -479,14 +479,14 @@ class WeiboAlbumExtractor(WeiboExtractor): try: sub = subalbums[int(subalbum)-1] except Exception: - raise exception.NotFoundError("subalbum") + raise self.exc.NotFoundError("subalbum") else: subalbum = text.unquote(subalbum) for sub in subalbums: if sub["pic_title"] == subalbum: break else: - raise exception.NotFoundError("subalbum") + raise self.exc.NotFoundError("subalbum") return ((sub, self._pagination_subalbum(uid, sub)),) def _pagination_subalbum(self, uid, sub): @@ -504,7 +504,7 @@ class WeiboStatusExtractor(WeiboExtractor): status = self._status_by_id(self.user) if status.get("ok") != 1: self.log.debug(status) - raise exception.NotFoundError("status") + raise self.exc.NotFoundError("status") return (status,) diff --git a/gallery_dl/extractor/wikimedia.py b/gallery_dl/extractor/wikimedia.py index 1be211c3..528ae95d 100644 --- a/gallery_dl/extractor/wikimedia.py +++ b/gallery_dl/extractor/wikimedia.py @@ -10,7 +10,7 @@ """Extractors for Wikimedia sites""" from .common import BaseExtractor, Message -from .. import text, util, exception +from .. import text, util from ..cache import cache @@ -71,7 +71,7 @@ class WikimediaExtractor(BaseExtractor): response = self.request(url, method="HEAD", fatal=None) if response.status_code < 400: return url - raise exception.AbortExtraction("Unable to find API endpoint") + raise self.exc.AbortExtraction("Unable to find API endpoint") def prepare_info(self, info): """Adjust the content of an image info object""" diff --git a/gallery_dl/extractor/xenforo.py b/gallery_dl/extractor/xenforo.py index a199ff82..bafee2d4 100644 --- a/gallery_dl/extractor/xenforo.py +++ b/gallery_dl/extractor/xenforo.py @@ -9,7 +9,7 @@ """Extractors for XenForo forums""" from .common import BaseExtractor, Message -from .. import text, util, exception +from .. import text, util from ..cache import cache import binascii @@ -165,7 +165,7 @@ class XenforoExtractor(BaseExtractor): def request_page(self, url): try: return self.request(url) - except exception.HttpError as exc: + except self.exc.HttpError as exc: if exc.status == 403 and b">Log in<" in exc.response.content: self._require_auth(exc.response) raise @@ -197,7 +197,7 @@ class XenforoExtractor(BaseExtractor): if not response.history: err = self._extract_error(response.text) err = f'"{err}"' if err else None - raise exception.AuthenticationError(err) + raise self.exc.AuthenticationError(err) return { cookie.name: cookie.value @@ -420,7 +420,7 @@ class XenforoExtractor(BaseExtractor): return main["contentUrl"], media def _require_auth(self, response=None): - raise exception.AuthRequired( + raise self.exc.AuthRequired( ("username & password", "authenticated cookies"), None, None if response is None else self._extract_error(response.text)) @@ -473,7 +473,7 @@ class XenforoPostExtractor(XenforoExtractor): pos = page.find(f'data-content="post-{post_id}"') if pos < 0: - raise exception.NotFoundError("post") + raise self.exc.NotFoundError("post") html = text.extract(page, "
", "<"): self.log.warning(f"'{msg}'")