Browse Source

Merge branch 'master' into develop

tags/release_0.25.1
JackDandy 4 years ago
parent
commit
e31bbb6658
  1. 6
      CHANGES.md
  2. 16
      recommended.txt
  3. 9
      sickbeard/__init__.py
  4. 89
      sickbeard/providers/newznab.py

6
CHANGES.md

@ -106,6 +106,12 @@
* Fix glide cursor left and right key collisions with ctrl + alt/meta with left and right * Fix glide cursor left and right key collisions with ctrl + alt/meta with left and right
### 0.24.16 (2021-08-28 16:05:00 UTC)
* Update Windows recommended modules lxml, pip, regex, setuptools, and add cffi, python-Levenshtein
* Change newznab provider add handler for http response code 401
### 0.24.15 (2021-08-05 11:45:00 UTC) ### 0.24.15 (2021-08-05 11:45:00 UTC)
* Change media process move process method for *nix systems that don't support native move * Change media process move process method for *nix systems that don't support native move

16
recommended.txt

@ -1,25 +1,29 @@
cffi@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/cffi-1.14.6-cp310-cp310-win_amd64.whl ; '3.10' <= python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine)
cffi@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/cffi-1.14.6-cp310-cp310-win32.whl ; '3.10' <= python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine)
cryptography; '3.7' <= python_version cryptography; '3.7' <= python_version
cryptography <= 3.2.1; '3.0' > python_version cryptography <= 3.2.1; '3.0' > python_version
lxml >= 4.6.1 lxml >= 4.6.3
lxml@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/lxml-4.6.3-cp310-cp310-win_amd64.whl ; '3.10' <= python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine) lxml@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/lxml-4.6.3-cp310-cp310-win_amd64.whl ; '3.10' <= python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine)
lxml@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/lxml-4.6.3-cp310-cp310-win32.whl ; '3.10' <= python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine) lxml@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/lxml-4.6.3-cp310-cp310-win32.whl ; '3.10' <= python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine)
pip >= 20.0.0; '3.7' <= python_version pip >= 21.2.4; '3.7' <= python_version
pip <= 19.3.1; '3.0' > python_version pip <= 19.3.1; '3.0' > python_version
python-Levenshtein >= 0.12.2; '3.7' <= python_version and 'Windows' == platform_system python-Levenshtein >= 0.12.2; '3.7' <= python_version and 'Windows' == platform_system
python-Levenshtein >= 0.12.0, != 0.12.1; '3.7' <= python_version and 'Windows' != platform_system python-Levenshtein >= 0.12.0, != 0.12.1; '3.7' <= python_version and 'Windows' != platform_system
python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp310-cp310-win_amd64.whl ; '3.10' == python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine)
python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp39-cp39-win_amd64.whl ; '3.9' == python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine) python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp39-cp39-win_amd64.whl ; '3.9' == python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine)
python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp38-cp38-win_amd64.whl ; '3.8' == python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine) python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp38-cp38-win_amd64.whl ; '3.8' == python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine)
python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp37-cp37m-win_amd64.whl ; '3.7' == python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine) python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp37-cp37m-win_amd64.whl ; '3.7' == python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine)
python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp310-cp310-win32.whl ; '3.10' == python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine)
python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp39-cp39-win32.whl ; '3.9' == python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine) python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp39-cp39-win32.whl ; '3.9' == python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine)
python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp38-cp38-win32.whl ; '3.8' == python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine) python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp38-cp38-win32.whl ; '3.8' == python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine)
python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp37-cp37m-win32.whl ; '3.7' == python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine) python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.2-cp37-cp37m-win32.whl ; '3.7' == python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine)
python-Levenshtein == 0.12.0; '3.0' > python_version python-Levenshtein == 0.12.0; '3.0' > python_version
python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.0-cp27-cp27m-win_amd64.whl ; '2.7' == python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine) python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.0-cp27-cp27m-win_amd64.whl ; '2.7' == python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine)
python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.0-cp27-cp27m-win32.whl ; '2.7' == python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine) python-Levenshtein@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/python_Levenshtein-0.12.0-cp27-cp27m-win32.whl ; '2.7' == python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine)
regex >= 2020.11.1; '3.7' <= python_version regex >= 2021.8.28; '3.7' <= python_version
regex <= 2020.10.28; '3.0' > python_version regex <= 2020.10.28; '3.0' > python_version
regex@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/regex-2021.4.4-cp310-cp310-win_amd64.whl ; '3.10' <= python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine) regex@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/regex-2021.8.28-cp310-cp310-win_amd64.whl ; '3.10' <= python_version and 'Windows' == platform_system and ('AMD64' == platform_machine or 'x86_64' == platform_machine)
regex@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/regex-2021.4.4-cp310-cp310-win32.whl ; '3.10' <= python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine) regex@https://raw.githubusercontent.com/wiki/SickGear/SickGear/packages/regex-2021.8.28-cp310-cp310-win32.whl ; '3.10' <= python_version and 'Windows' == platform_system and ('AMD64' != platform_machine and 'x86_64' != platform_machine)
scandir >= 1.10.0; '3.0' > python_version scandir >= 1.10.0; '3.0' > python_version
setuptools >= 50.0.0; '3.7' <= python_version setuptools >= 57.4.0; '3.7' <= python_version
setuptools <= 44.1.1; '3.0' > python_version setuptools <= 44.1.1; '3.0' > python_version

9
sickbeard/__init__.py

@ -579,7 +579,7 @@ SG_EXTRA_SCRIPTS = []
GIT_PATH = None GIT_PATH = None
IGNORE_WORDS = { IGNORE_WORDS = {
'^(?=.*?\bspanish\b)((?!spanish.?princess).)*$', r'^(?=.*?\bspanish\b)((?!spanish.?princess).)*$',
'core2hd', 'hevc', 'MrLss', 'reenc', 'x265', 'danish', 'deutsch', 'dutch', 'flemish', 'french', 'core2hd', 'hevc', 'MrLss', 'reenc', 'x265', 'danish', 'deutsch', 'dutch', 'flemish', 'french',
'german', 'italian', 'nordic', 'norwegian', 'portuguese', 'spanish', 'swedish', 'turkish' 'german', 'italian', 'nordic', 'norwegian', 'portuguese', 'spanish', 'swedish', 'turkish'
} }
@ -608,7 +608,7 @@ if TRAKT_STAGING:
TRAKT_CLIENT_ID = '2aae3052f90b14235d184cc8f709b12b4fd8ae35f339a060a890c70db92be87a' TRAKT_CLIENT_ID = '2aae3052f90b14235d184cc8f709b12b4fd8ae35f339a060a890c70db92be87a'
TRAKT_CLIENT_SECRET = '900e03471220503843d4a856bfbef17080cddb630f2b7df6a825e96e3ff3c39e' TRAKT_CLIENT_SECRET = '900e03471220503843d4a856bfbef17080cddb630f2b7df6a825e96e3ff3c39e'
TRAKT_PIN_URL = 'https://staging.trakt.tv/pin/638' TRAKT_PIN_URL = 'https://staging.trakt.tv/pin/638'
TRAKT_BASE_URL = 'http://api.staging.trakt.tv/' TRAKT_BASE_URL = 'http' + '://api.staging.trakt.tv/'
else: else:
# production trakt values: # production trakt values:
TRAKT_CLIENT_ID = 'f1c453c67d81f1307f9118172c408a883eb186b094d5ea33080d59ddedb7fc7c' TRAKT_CLIENT_ID = 'f1c453c67d81f1307f9118172c408a883eb186b094d5ea33080d59ddedb7fc7c'
@ -1306,9 +1306,10 @@ def init_stage_1(console_logging):
GIT_PATH = check_setting_str(CFG, 'General', 'git_path', '') GIT_PATH = check_setting_str(CFG, 'General', 'git_path', '')
IGNORE_WORDS, IGNORE_WORDS_REGEX = helpers.split_word_str( IGNORE_WORDS, IGNORE_WORDS_REGEX = helpers.split_word_str(
check_setting_str(CFG, 'General', 'ignore_words', IGNORE_WORDS)) check_setting_str(CFG, 'General', 'ignore_words', helpers.generate_word_str(IGNORE_WORDS, IGNORE_WORDS_REGEX)))
REQUIRE_WORDS, REQUIRE_WORDS_REGEX = helpers.split_word_str( REQUIRE_WORDS, REQUIRE_WORDS_REGEX = helpers.split_word_str(
check_setting_str(CFG, 'General', 'require_words', REQUIRE_WORDS)) check_setting_str(CFG, 'General', 'require_words',
helpers.generate_word_str(REQUIRE_WORDS, REQUIRE_WORDS_REGEX)))
CALENDAR_UNPROTECTED = bool(check_setting_int(CFG, 'General', 'calendar_unprotected', 0)) CALENDAR_UNPROTECTED = bool(check_setting_int(CFG, 'General', 'calendar_unprotected', 0))

89
sickbeard/providers/newznab.py

@ -30,7 +30,7 @@ from . import generic
from .. import classes, db, helpers, logger, tvcache from .. import classes, db, helpers, logger, tvcache
from ..classes import SearchResult from ..classes import SearchResult
from ..common import NeededQualities, Quality from ..common import NeededQualities, Quality
from ..helpers import remove_non_release_groups, try_int from ..helpers import remove_non_release_groups
from ..indexers.indexer_config import * from ..indexers.indexer_config import *
from ..network_timezones import SG_TIMEZONE from ..network_timezones import SG_TIMEZONE
from ..sgdatetime import SGDatetime, timestamp_near from ..sgdatetime import SGDatetime, timestamp_near
@ -40,7 +40,7 @@ from ..scene_exceptions import has_season_exceptions
from ..tv import TVEpisode, TVShow from ..tv import TVEpisode, TVShow
from lib.dateutil import parser from lib.dateutil import parser
from lib.sg_helpers import md5_for_text from lib.sg_helpers import md5_for_text, try_int
from exceptions_helper import AuthException, ex, MultipleShowObjectsException from exceptions_helper import AuthException, ex, MultipleShowObjectsException
from lxml_etree import etree from lxml_etree import etree
@ -308,7 +308,7 @@ class NewznabProvider(generic.NZBProvider):
limit = xml_caps.find('.//limits') limit = xml_caps.find('.//limits')
if None is not limit: if None is not limit:
lim = helpers.try_int(limit.get('max'), 100) lim = try_int(limit.get('max'), 100)
self._limits = (100, lim)[100 <= lim] self._limits = (100, lim)[100 <= lim]
try: try:
@ -399,40 +399,38 @@ class NewznabProvider(generic.NZBProvider):
return False return False
if 'error' == data.tag: if 'error' == data.tag:
code = data.get('code', '') code = try_int(data.get('code'))
description = data.get('description', '') description = data.get('description') or ''
msg = ('', ': %s' % description)[bool(description)]
if '100' == code:
raise AuthException('Your API key for %s is incorrect, check your config.' % self.name) if code not in (100, 101, 102, 401, 429, 500, 910):
elif '101' == code: logger.warning('Unknown error given from %s%s' % (self.name, msg))
raise AuthException('Your account on %s has been suspended, contact the admin.' % self.name)
elif '102' == code:
try:
retry_time, unit = re.findall(r'Try again in (\d+)\W+([a-z]+)', description, flags=re.I)[0]
except IndexError:
retry_time, unit = None, None
if (description and 'limit' in description.lower()) or (retry_time and unit):
self.tmr_limit_update(retry_time, unit, description)
self.log_failure_url(url)
else:
raise AuthException('Your account isn\'t allowed to use the API on %s, contact the admin.%s' %
(self.name, ('', ' Provider message: %s' % description)[
description not in ('', None)]))
elif code in ['429', '500']:
try:
retry_time, unit = re.findall(r'Retry in (\d+)\W+([a-z]+)', description, flags=re.I)[0]
except IndexError:
retry_time, unit = None, None
self.tmr_limit_update(retry_time, unit, description)
self.log_failure_url(url)
elif '910' == code:
logger.log(
'%s %s, please check with provider.' %
(self.name, ('currently has their API disabled', description)[description not in (None, '')]),
logger.WARNING)
else: else:
logger.log('Unknown error given from %s: %s' % (self.name, data.get('description', '')), if 100 == code:
logger.WARNING) raise AuthException('API key for %s is incorrect, check your config' % self.name)
elif 101 == code:
raise AuthException('Account suspended on %s, contact the admin' % self.name)
elif 401 == code:
logger.warning('Error code 401 (Unauthorized) from provider%s' % msg)
raise AuthException('Account disabled on %s (code 401), contact the admin%s' % (self.name, msg))
elif code in (102, 429, 500):
try:
retry_time, unit = re.findall(r'(?i)(?:Try again|Retry) in (\d+)\W+([a-z]+)', description)[0]
except IndexError:
retry_time, unit = None, None
handle_fail = True
if 102 == code:
handle_fail = ('limit' in description.lower()) or (retry_time and unit)
if not handle_fail:
raise AuthException(
'Your account isn\'t allowed to use the %s API, contact the admin%s' %
(self.name, ('', '. Provider message: %s' % description)[bool(description)]))
if handle_fail:
self.tmr_limit_update(retry_time, unit, description)
self.log_failure_url(url)
elif 910 == code:
logger.warning('%s %s, please check with provider' %
(self.name, ('currently has their API disabled', description)[bool(description)]))
return False return False
self.tmr_limit_count = 0 self.tmr_limit_count = 0
@ -469,7 +467,7 @@ class NewznabProvider(generic.NZBProvider):
base_params['season'] = '%d' % ep_obj.scene_absolute_number base_params['season'] = '%d' % ep_obj.scene_absolute_number
else: else:
base_params['season'] = str((ep_obj.season, ep_obj.scene_season)[bool(ep_obj.show_obj.is_scene)]) base_params['season'] = str((ep_obj.season, ep_obj.scene_season)[bool(ep_obj.show_obj.is_scene)])
ep_detail = 'S%02d' % helpers.try_int(base_params['season'], 1) ep_detail = 'S%02d' % try_int(base_params['season'], 1)
# id search # id search
params = base_params.copy() params = base_params.copy()
@ -521,15 +519,13 @@ class NewznabProvider(generic.NZBProvider):
base_params['ep'] = '/'.join(airdate[1:]) base_params['ep'] = '/'.join(airdate[1:])
ep_detail = '+"%s.%s"' % (base_params['season'], '.'.join(airdate[1:])) ep_detail = '+"%s.%s"' % (base_params['season'], '.'.join(airdate[1:]))
elif ep_obj.show_obj.is_anime: elif ep_obj.show_obj.is_anime:
base_params['ep'] = '%i' % (helpers.try_int(ep_obj.scene_absolute_number) or base_params['ep'] = '%i' % (try_int(ep_obj.scene_absolute_number) or try_int(ep_obj.scene_episode))
helpers.try_int(ep_obj.scene_episode)) ep_detail = '%02d' % try_int(base_params['ep'])
ep_detail = '%02d' % helpers.try_int(base_params['ep'])
else: else:
base_params['season'], base_params['ep'] = ( base_params['season'], base_params['ep'] = (
(ep_obj.season, ep_obj.episode), (ep_obj.scene_season, ep_obj.scene_episode))[ep_obj.show_obj.is_scene] (ep_obj.season, ep_obj.episode), (ep_obj.scene_season, ep_obj.scene_episode))[ep_obj.show_obj.is_scene]
ep_detail = sickbeard.config.naming_ep_type[2] % { ep_detail = sickbeard.config.naming_ep_type[2] % {
'seasonnumber': helpers.try_int(base_params['season'], 1), 'seasonnumber': try_int(base_params['season'], 1), 'episodenumber': try_int(base_params['ep'], 1)}
'episodenumber': helpers.try_int(base_params['ep'], 1)}
# id search # id search
params = base_params.copy() params = base_params.copy()
@ -833,7 +829,7 @@ class NewznabProvider(generic.NZBProvider):
if ns and 'newznab' in ns: if ns and 'newznab' in ns:
for attr in item.findall('%sattr' % ns['newznab']): for attr in item.findall('%sattr' % ns['newznab']):
if 'size' == attr.get('name', ''): if 'size' == attr.get('name', ''):
parsed_size = helpers.try_int(attr.get('value'), -1) parsed_size = try_int(attr.get('value'), -1)
elif 'guid' == attr.get('name', ''): elif 'guid' == attr.get('name', ''):
uid = attr.get('value') uid = attr.get('value')
except (BaseException, Exception): except (BaseException, Exception):
@ -1013,12 +1009,11 @@ class NewznabProvider(generic.NZBProvider):
# get total and offset attributes # get total and offset attributes
try: try:
if 0 == total: if 0 == total:
total = (helpers.try_int(parsed_xml.find( total = (try_int(parsed_xml.find(
'.//%sresponse' % n_spaces['newznab']).get('total', 0)), 1000)['Cache' == mode] './/%sresponse' % n_spaces['newznab']).get('total', 0)), 1000)['Cache' == mode]
hits = (total // self.limits + int(0 < (total % self.limits))) hits = (total // self.limits + int(0 < (total % self.limits)))
hits += int(0 == hits) hits += int(0 == hits)
offset = helpers.try_int(parsed_xml.find('.//%sresponse' offset = try_int(parsed_xml.find('.//%sresponse' % n_spaces['newznab']).get('offset', 0))
% n_spaces['newznab']).get('offset', 0))
except (AttributeError, KeyError): except (AttributeError, KeyError):
if not use_rss: if not use_rss:
break break
@ -1246,7 +1241,7 @@ class NewznabCache(tvcache.TVCache):
if 'newznab' in ns: if 'newznab' in ns:
for attr in item.findall('%sattr' % ns['newznab']): for attr in item.findall('%sattr' % ns['newznab']):
if attr.get('name', '') in NewznabConstants.providerToIndexerMapping: if attr.get('name', '') in NewznabConstants.providerToIndexerMapping:
v = helpers.try_int(attr.get('value')) v = try_int(attr.get('value'))
if 0 < v: if 0 < v:
ids[NewznabConstants.providerToIndexerMapping[attr.get('name')]] = v ids[NewznabConstants.providerToIndexerMapping[attr.get('name')]] = v
return ids return ids

Loading…
Cancel
Save