From e17bad6ec49421a315d463522ae40c5c9cd06dc9 Mon Sep 17 00:00:00 2001 From: morpheus65535 Date: Wed, 15 Jan 2025 22:32:00 -0500 Subject: [PATCH] Added some failsafe to RegieLive provider to try to prevent getting redirected to captcha validation or being completely blocked for a while. #2165 --- bazarr/app/get_providers.py | 7 ++- .../subliminal_patch/providers/regielive.py | 51 ++++++++++++++++--- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/bazarr/app/get_providers.py b/bazarr/app/get_providers.py index a4316a9d5..b73e91c11 100644 --- a/bazarr/app/get_providers.py +++ b/bazarr/app/get_providers.py @@ -15,7 +15,7 @@ import re from requests import ConnectionError from subzero.language import Language from subliminal_patch.exceptions import TooManyRequests, APIThrottled, ParseResponseError, IPAddressBlocked, \ - MustGetBlacklisted, SearchLimitReached + MustGetBlacklisted, SearchLimitReached, ProviderError from subliminal.providers.opensubtitles import DownloadLimitReached, PaymentRequired, Unauthorized from subliminal.exceptions import DownloadLimitExceeded, ServiceUnavailable, AuthenticationError, ConfigurationError from subliminal import region as subliminal_cache_region @@ -123,6 +123,11 @@ def provider_throttle_map(): "whisperai": { ConnectionError: (datetime.timedelta(hours=24), "24 hours"), }, + "regielive": { + APIThrottled: (datetime.timedelta(hours=1), "1 hour"), + TooManyRequests: (datetime.timedelta(minutes=5), "5 minutes"), + ProviderError: (datetime.timedelta(minutes=10), "10 minutes"), + }, } diff --git a/custom_libs/subliminal_patch/providers/regielive.py b/custom_libs/subliminal_patch/providers/regielive.py index 8c7363bf0..a65379f93 100644 --- a/custom_libs/subliminal_patch/providers/regielive.py +++ b/custom_libs/subliminal_patch/providers/regielive.py @@ -4,8 +4,9 @@ import logging import io import os -from requests import Session +from requests import Session, JSONDecodeError from guessit import guessit +from subliminal_patch.exceptions import TooManyRequests, APIThrottled, ProviderError from subliminal_patch.providers import Provider from subliminal_patch.subtitle import Subtitle, guess_matches from subliminal.subtitle import SUBTITLE_EXTENSIONS, fix_line_ending @@ -87,13 +88,18 @@ class RegieLiveProvider(Provider): payload['nume'] = video.title payload['an'] = video.year - response = self.session.get( - self.url + "?" + urllib.parse.urlencode(payload), - data=payload, headers=self.headers) + response = self.checked( + lambda: self.session.get( + self.url + "?" + urllib.parse.urlencode(payload), + data=payload, headers=self.headers) + ) subtitles = [] if response.status_code == 200: - results = response.json() + try: + results = response.json() + except JSONDecodeError: + raise ProviderError('Unable to parse JSON response') if len(results) > 0: results_subs = results['rezultate'] for film in results_subs: @@ -122,9 +128,13 @@ class RegieLiveProvider(Provider): 'Cache-Control': 'no-cache' } session.headers.update(_addheaders) - res = session.get('https://subtitrari.regielive.ro') + res = self.checked( + lambda: session.get('https://subtitrari.regielive.ro') + ) cookies = res.cookies - _zipped = session.get(subtitle.page_link, cookies=cookies) + _zipped = self.checked( + lambda: session.get(subtitle.page_link, cookies=cookies, allow_redirects=False) + ) if _zipped: if _zipped.text == '500': raise ValueError('Error 500 on server') @@ -135,7 +145,8 @@ class RegieLiveProvider(Provider): return subtitle raise ValueError('Problems conecting to the server') - def _get_subtitle_from_archive(self, archive): + @staticmethod + def _get_subtitle_from_archive(archive): # some files have a non subtitle with .txt extension _tmp = list(SUBTITLE_EXTENSIONS) _tmp.remove('.txt') @@ -153,3 +164,27 @@ class RegieLiveProvider(Provider): return archive.read(name) raise APIThrottled('Can not find the subtitle in the compressed file') + + @staticmethod + def checked(fn): + """Run :fn: and check the response status before returning it. + + :param fn: the function to make an API call to provider. + :return: the response. + + """ + response = None + try: + response = fn() + except Exception: + logger.exception('Unhandled exception raised.') + raise ProviderError('Unhandled exception raised. Check log.') + else: + status_code = response.status_code + + if status_code == 301: + raise APIThrottled() + elif status_code == 429: + raise TooManyRequests() + + return response