diff --git a/CHANGES.md b/CHANGES.md index d34fefe..2918139 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ * Fix provider SCC handle null server responses * Change provider SCC remove 1 of 3 requests per search to save 30% time * Change provider Womble's use SSL +* Change refactor and code simplification for torrent providers * Fix getManualSearchStatus: object has no attribute 'segment' * Change handling of general HTTP error response codes to prevent issues * Add handling for CloudFlare custom HTTP response codes diff --git a/sickbeard/providers/generic.py b/sickbeard/providers/generic.py index 5a81c43..963e03a 100644 --- a/sickbeard/providers/generic.py +++ b/sickbeard/providers/generic.py @@ -40,11 +40,11 @@ class GenericProvider: NZB = "nzb" TORRENT = "torrent" - def __init__(self, name, supportsBacklog, anime_only): + def __init__(self, name, supports_backlog=False, anime_only=False): # these need to be set in the subclass self.providerType = None self.name = name - self.supportsBacklog = supportsBacklog + self.supportsBacklog = supports_backlog self.anime_only = anime_only self.url = '' @@ -226,9 +226,9 @@ class GenericProvider: def _get_title_and_url(self, item): """ - Retrieves the title and URL data from the item XML node + Retrieves the title and URL data from the item - item: An elementtree.ElementTree element representing the tag of the RSS feed + item: An elementtree.ElementTree element representing the tag of the RSS feed, or a two part tup Returns: A tuple containing two strings representing title and URL respectively """ @@ -236,14 +236,21 @@ class GenericProvider: title = None url = None - if 'title' in item: - title = item.title + try: + if isinstance(item, tuple): + title = item[0] + url = item[1] + else: + if 'title' in item: + title = item.title - if title: - title = title.replace(' ', '.') + if 'link' in item: + url = item.link + except Exception: + pass - if 'link' in item: - url = item.link + if title: + title = re.sub(r'\s+', '.', u'' + title) if url: url = url.replace('&', '&') @@ -464,12 +471,74 @@ class GenericProvider: class NZBProvider(GenericProvider): - def __init__(self, name, supportsBacklog, anime_only): - GenericProvider.__init__(self, name, supportsBacklog, anime_only) + def __init__(self, name, supports_backlog=True, anime_only=False): + GenericProvider.__init__(self, name, supports_backlog, anime_only) self.providerType = GenericProvider.NZB class TorrentProvider(GenericProvider): - def __init__(self, name, supportsBacklog, anime_only): - GenericProvider.__init__(self, name, supportsBacklog, anime_only) + + def __init__(self, name, supports_backlog=True, anime_only=False): + GenericProvider.__init__(self, name, supports_backlog, anime_only) self.providerType = GenericProvider.TORRENT + self._seed_ratio = None + + def get_cache_data(self): + search_params = {'RSS': ['']} + return self._doSearch(search_params) + + def seedRatio(self): + return self._seed_ratio + + def getQuality(self, item, anime=False): + if isinstance(item, tuple): + name = item[0] + else: + name = item.title + return Quality.sceneQuality(name, anime) + + def _find_propers(self, search_date=datetime.datetime.today(), method=None): + """ + Search for releases of type PROPER + :param search_date: Filter search on episodes since this date + :param method: String or list of strings that qualify PROPER release types + :return: list of Proper objects + """ + results = [] + + my_db = db.DBConnection() + sql_results = my_db.select( + 'SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.airdate FROM tv_episodes AS e' + + ' INNER JOIN tv_shows AS s ON (e.showid = s.indexer_id)' + + ' WHERE e.airdate >= ' + str(search_date.toordinal()) + + ' AND (e.status IN (%s)' % ','.join([str(x) for x in Quality.DOWNLOADED]) + + ' OR (e.status IN (%s)))' % ','.join([str(x) for x in Quality.SNATCHED]) + ) + + if not sql_results: + return results + + for sqlshow in sql_results: + showid, season, episode = (int(sqlshow['showid']), int(sqlshow['season']), int(sqlshow['episode'])) + + self.show = helpers.findCertainShow(sickbeard.showList, showid) + if not self.show: + continue + + cur_ep = self.show.getEpisode(season, episode) + + if not isinstance(method, list): + if None is method: + method = 'PROPER|REPACK' + method = [method] + + for proper_string in method: + search_string = self._get_episode_search_strings(cur_ep, add_string=proper_string) + + for item in self._doSearch(search_string[0]): + title, url = self._get_title_and_url(item) + if not re.search('(?i)(?:%s)' % '|'.join(method), title): + continue + results.append(classes.Proper(title, url, datetime.datetime.today(), self.show)) + + return results