Browse Source

Merge branch 'hotfix/0.21.25'

tags/release_0.21.25^0 release_0.21.25
JackDandy 5 years ago
parent
commit
c3aa1f87b9
  1. 12
      CHANGES.md
  2. BIN
      gui/slick/images/providers/digitalhive.png
  3. 2
      sickbeard/anime.py
  4. 13
      sickbeard/metadata/generic.py
  5. 2
      sickbeard/providers/__init__.py
  6. 119
      sickbeard/providers/dh.py
  7. 8
      sickbeard/providers/generic.py
  8. 10
      sickbeard/webapi.py
  9. 2
      sickbeard/webserve.py

12
CHANGES.md

@ -1,4 +1,14 @@
### 0.21.24 (2020-04-04 00:30:00 UTC)
### 0.21.25 (2020-04-10 01:50:00 UTC)
* Fix Kodi uniqueid tag not validated during import
* Change slightly improve performance iterating metadata providers
* Fix AttributeError in anime manager while editing show
* Remove DigitalHive torrent provider
* Fix failure time reset of service URLs
* Change improve clarity of show update/refresh API failure message
### 0.21.24 (2020-04-04 00:30:00 UTC)
* Fix use release group for Propers check from history if status is snatched
* Change add provider filter fallbacks into Propers search flow

BIN
gui/slick/images/providers/digitalhive.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 532 B

2
sickbeard/anime.py

@ -174,7 +174,7 @@ def short_group_names(groups):
pass
if isinstance(adba_result, LoginFirstResponse):
break
if None is adba_result or not adba_result.hasattr('datalines'):
if None is adba_result or not adba_result.hasattr('datalines', None):
continue
for line in adba_result.datalines:
if line['shortname']:

13
sickbeard/metadata/generic.py

@ -1043,9 +1043,10 @@ class GenericMetadata(object):
showXML = etree.ElementTree(file=xmlFileObj)
if None is showXML.findtext('title') \
or (None is showXML.findtext('tvdbid')
and None is showXML.findtext('id')) \
and None is showXML.findtext('indexer'):
or (None is showXML.find('//uniqueid[@type="tvdb"]')
and (None is showXML.findtext('tvdbid')
and None is showXML.findtext('id'))
and None is showXML.findtext('indexer')):
logger.log(u"Invalid info in tvshow.nfo (missing name or id):"
+ str(showXML.findtext('title')) + ' '
+ str(showXML.findtext('indexer')) + ' '
@ -1060,7 +1061,11 @@ class GenericMetadata(object):
except (BaseException, Exception):
tvid = None
if None is not showXML.findtext('tvdbid'):
prodid = showXML.find('//uniqueid[@type="tvdb"]')
if None is not prodid:
prodid = int(prodid.text)
tvid = TVINFO_TVDB
elif None is not showXML.findtext('tvdbid'):
prodid = int(showXML.findtext('tvdbid'))
tvid = TVINFO_TVDB
elif None is not showXML.findtext('id'):

2
sickbeard/providers/__init__.py

@ -32,7 +32,7 @@ __all__ = [
'omgwtfnzbs',
# torrent
'alpharatio', 'bb', 'bithdtv', 'blutopia', 'btn',
'custom01', 'custom11', 'dh', 'ettv', 'eztv', 'fano', 'filelist', 'funfile', 'grabtheinfo',
'custom01', 'custom11', 'ettv', 'eztv', 'fano', 'filelist', 'funfile', 'grabtheinfo',
'hdbits', 'hdme', 'hdspace', 'hdtorrents', 'horriblesubs',
'immortalseed', 'iptorrents', 'limetorrents', 'magnetdl', 'milkie', 'morethan', 'nebulance', 'ncore', 'nyaa',
'pisexy', 'pretome', 'privatehd', 'ptf',

119
sickbeard/providers/dh.py

@ -1,119 +0,0 @@
# coding=utf-8
#
# This file is part of SickGear.
#
# SickGear is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# SickGear is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
import re
import traceback
from . import generic
from .. import logger
from ..helpers import try_int
from bs4_parser import BS4Parser
from _23 import unidecode
from six import iteritems
class DHProvider(generic.TorrentProvider):
def __init__(self):
generic.TorrentProvider.__init__(self, 'DigitalHive')
self.url_base = 'https://www.digitalhive.org/'
self.urls = {'config_provider_home_uri': self.url_base,
'login': self.url_base + 'getrss.php',
'search': self.url_base + 'browse.php?search=%s&%s&titleonly=1&incldead=%s'}
self.categories = {'Season': [34], 'Episode': [7, 32, 55, 57], 'anime': [2]}
self.categories['Cache'] = self.categories['Season'] + self.categories['Episode']
self.url = self.urls['config_provider_home_uri']
self.digest, self.freeleech, self.minseed, self.minleech = 4 * [None]
def _authorised(self, **kwargs):
return super(DHProvider, self)._authorised(
logged_in=(lambda y=None: (None is y or re.search(r'(?i)rss\slink', y)) and self.has_all_cookies() and
self.session.cookies['uid'] in self.digest and self.session.cookies['pass'] in self.digest),
failed_msg=(lambda y=None: u'Invalid cookie details for %s. Check settings'))
def _search_provider(self, search_params, **kwargs):
results = []
if not self._authorised():
return results
items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []}
rc = dict([(k, re.compile('(?i)' + v)) for (k, v) in iteritems({'info': 'details', 'get': 'download'})])
for mode in search_params:
rc['cats'] = re.compile('(?i)cat=(?:%s)' % self._categories_string(mode, template='', delimiter='|'))
for search_string in search_params[mode]:
search_string = unidecode(search_string)
html = self.get_url(self.urls['search'] % (
'+'.join(search_string.split()), self._categories_string(mode), ('3', '0')[not self.freeleech]))
if self.should_skip():
return results
cnt = len(items[mode])
try:
if not html or self._has_no_results(html):
raise generic.HaltParseException
with BS4Parser(html, parse_only=dict(table={'cellpadding': 0})) as tbl:
tbl_rows = [] if not tbl else tbl.find_all('tr')
if 2 > len(tbl_rows):
raise generic.HaltParseException
head = None
for tr in tbl_rows[1:]:
cells = tr.find_all('td')
if 6 > len(cells):
continue
try:
head = head if None is not head else self._header_row(tr)
seeders, leechers, size = [try_int(n, n) for n in [
cells[head[x]].get_text().strip() for x in ('seed', 'leech', 'size')]]
if not tr.find('a', href=rc['cats']) or self._reject_item(seeders, leechers):
continue
title = tr.find('a', href=rc['info']).get_text().strip()
download_url = self._link(tr.find('a', href=rc['get'])['href'])
except (AttributeError, TypeError, ValueError, IndexError):
continue
if title and download_url:
items[mode].append((title, download_url, seeders, self._bytesizer(size)))
except generic.HaltParseException:
pass
except (BaseException, Exception):
logger.log(u'Failed to parse. Traceback: %s' % traceback.format_exc(), logger.ERROR)
self._log_search(mode, len(items[mode]) - cnt, self.session.response.get('url'))
results = self._sort_seeding(mode, results + items[mode])
return results
def ui_string(self, key):
return ('%s_digest' % self.get_id()) == key and 'use... \'uid=xx; pass=yy\'' or ''
provider = DHProvider()

8
sickbeard/providers/generic.py

@ -335,8 +335,12 @@ class GenericProvider(object):
changed_val = self._failure_time != value
self._failure_time = value
if changed_val:
# noinspection PyCallByClass,PyTypeChecker
self._save_fail_value('failure_time', (SGDatetime.totimestamp(value), value)[None is value])
if isinstance(value, datetime.datetime):
# noinspection PyCallByClass,PyTypeChecker
save_value = SGDatetime.totimestamp(value)
else:
save_value = value
self._save_fail_value('failure_time', save_value)
@property
def tmr_limit_count(self):

10
sickbeard/webapi.py

@ -3915,10 +3915,10 @@ class CMD_SickGearShowRefresh(ApiCall):
try:
sickbeard.showQueueScheduler.action.refreshShow(show_obj)
return _responds(RESULT_SUCCESS, msg=str(show_obj.name) + " has queued to be refreshed")
except exceptions_helper.CantRefreshException:
return _responds(RESULT_SUCCESS, msg="%s has queued to be refreshed" % show_obj.name)
except exceptions_helper.CantRefreshException as e:
# TODO: log the exception
return _responds(RESULT_FAILURE, msg="Unable to refresh " + str(show_obj.name))
return _responds(RESULT_FAILURE, msg="Unable to refresh %s. %s" % (show_obj.name, ex(e)))
class CMD_ShowRefresh(CMD_SickGearShowRefresh):
@ -4336,10 +4336,10 @@ class CMD_SickGearShowUpdate(ApiCall):
try:
sickbeard.showQueueScheduler.action.updateShow(show_obj, True)
return _responds(RESULT_SUCCESS, msg=str(show_obj.name) + " has queued to be updated")
return _responds(RESULT_SUCCESS, msg="%s has queued to be updated" % show_obj.name)
except exceptions_helper.CantUpdateException as e:
self.log(u"Unable to update %s. %s" % (show_obj.name, ex(e)), logger.ERROR)
return _responds(RESULT_FAILURE, msg="Unable to update " + str(show_obj.name))
return _responds(RESULT_FAILURE, msg="Unable to update %s. %s" % (show_obj.name, ex(e)))
class CMD_ShowUpdate(CMD_SickGearShowUpdate):

2
sickbeard/webserve.py

@ -3630,7 +3630,7 @@ class AddShows(Home):
prodid = show_name = tvid = None
for cur_provider in itervalues(sickbeard.metadata_provider_dict):
if prodid and show_name:
continue
break
(tvid, prodid, show_name) = cur_provider.retrieveShowMetadata(cur_path)

Loading…
Cancel
Save