def test_no_show_required_ignored_words(self): self.show.rls_ignore_words = '' self.show.rls_require_words = '' self.assertFalse(filter_bad_releases('Release name that is IGNORED', False, show=self.show)) self.assertTrue(filter_bad_releases('Release name that is REQUIRED', False, show=self.show)) self.assertFalse(filter_bad_releases('Release name that is REQUIRED but contains IGNORED', False, show=self.show))
def test_filter_bad_releases(self): """ Test filtering of bad releases """ sickbeard.IGNORE_WORDS = 'GermaN' sickbeard.REQUIRE_WORDS = 'STUFF' self.assertFalse(show_name_helpers.filter_bad_releases('Show.S02.German.Stuff-Grp')) self.assertTrue(show_name_helpers.filter_bad_releases('Show.S02.Some.Stuff-Core2HD')) self.assertFalse(show_name_helpers.filter_bad_releases('Show.S02.Some.German.Stuff-Grp')) # self.assertTrue(show_name_helpers.filter_bad_releases('German.Show.S02.Some.Stuff-Grp')) self.assertFalse(show_name_helpers.filter_bad_releases('Show.S02.This.Is.German'))
def _test_filter_bad_releases(self, name, expected): """ Test filter of bad releases :param name: :param expected: :return: """ result = show_name_helpers.filter_bad_releases(name) self.assertEqual(result, expected)
def pickBestResult(results, show): # pylint: disable=too-many-branches """ Find the best result out of a list of search results for a show :param results: list of result objects :param show: Shows we check for :return: best result object """ results = results if isinstance(results, list) else [results] logger.log("Picking the best result out of " + str([x.name for x in results]), logger.DEBUG) bestResult = None # find the best result for the current episode for cur_result in results: if show and cur_result.show is not show: continue # build the black And white list if show.is_anime: if not show.release_groups.is_valid(cur_result): continue logger.log("Quality of " + cur_result.name + " is " + Quality.qualityStrings[cur_result.quality]) anyQualities, bestQualities = Quality.splitQuality(show.quality) if cur_result.quality not in anyQualities + bestQualities: logger.log(cur_result.name + " is a quality we know we don't want, rejecting it", logger.DEBUG) continue if not show_name_helpers.filter_bad_releases(cur_result.name, parse=False, show=show): continue if hasattr(cur_result, 'size'): if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(cur_result.name, cur_result.size, cur_result.provider.name): logger.log(cur_result.name + " has previously failed, rejecting it") continue if not bestResult: bestResult = cur_result elif cur_result.quality in bestQualities and (bestResult.quality < cur_result.quality or bestResult.quality not in bestQualities): bestResult = cur_result elif cur_result.quality in anyQualities and bestResult.quality not in bestQualities and bestResult.quality < cur_result.quality: bestResult = cur_result elif bestResult.quality == cur_result.quality: if "proper" in cur_result.name.lower() or "real" in cur_result.name.lower() or "repack" in cur_result.name.lower(): logger.log("Preferring " + cur_result.name + " (repack/proper/real over nuked)") bestResult = cur_result elif "internal" in bestResult.name.lower() and "internal" not in cur_result.name.lower(): logger.log("Preferring " + cur_result.name + " (normal instead of internal)") bestResult = cur_result elif "xvid" in bestResult.name.lower() and "x264" in cur_result.name.lower(): logger.log("Preferring " + cur_result.name + " (x264 over xvid)") bestResult = cur_result if bestResult: logger.log("Picked " + bestResult.name + " as the best", logger.DEBUG) else: logger.log("No result picked.", logger.DEBUG) return bestResult
def pickBestResult(results, show): # pylint: disable=too-many-branches """ Find the best result out of a list of search results for a show :param results: list of result objects :param show: Shows we check for :return: best result object """ results = results if isinstance(results, list) else [results] logger.log( "Picking the best result out of " + str([x.name for x in results]), logger.DEBUG) bestResult = None # find the best result for the current episode for cur_result in results: if show and cur_result.show is not show: continue # build the black And white list if show.is_anime: if not show.release_groups.is_valid(cur_result): continue logger.log("Quality of " + cur_result.name + " is " + Quality.qualityStrings[cur_result.quality]) anyQualities, bestQualities = Quality.splitQuality(show.quality) if cur_result.quality not in anyQualities + bestQualities: logger.log( cur_result.name + " is a quality we know we don't want, rejecting it", logger.DEBUG) continue if not show_name_helpers.filter_bad_releases( cur_result.name, parse=False, show=show): continue if hasattr(cur_result, 'size'): if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed( cur_result.name, cur_result.size, cur_result.provider.name): logger.log(cur_result.name + " has previously failed, rejecting it") continue if not bestResult: bestResult = cur_result elif cur_result.quality in bestQualities and ( bestResult.quality < cur_result.quality or bestResult.quality not in bestQualities): bestResult = cur_result elif cur_result.quality in anyQualities and bestResult.quality not in bestQualities and bestResult.quality < cur_result.quality: bestResult = cur_result elif bestResult.quality == cur_result.quality: if "proper" in cur_result.name.lower( ) or "real" in cur_result.name.lower( ) or "repack" in cur_result.name.lower(): logger.log("Preferring " + cur_result.name + " (repack/proper/real over nuked)") bestResult = cur_result elif "internal" in bestResult.name.lower( ) and "internal" not in cur_result.name.lower(): logger.log("Preferring " + cur_result.name + " (normal instead of internal)") bestResult = cur_result elif "xvid" in bestResult.name.lower( ) and "x264" in cur_result.name.lower(): logger.log("Preferring " + cur_result.name + " (x264 over xvid)") bestResult = cur_result if bestResult: logger.log("Picked " + bestResult.name + " as the best", logger.DEBUG) else: logger.log("No result picked.", logger.DEBUG) return bestResult
def find_needed_episodes(self, episode, manualSearch=False, downCurQuality=False): # pylint:disable=too-many-locals, too-many-branches needed_eps = {} cl = [] cache_db_con = self._get_db() if not episode: sql_results = cache_db_con.select("SELECT * FROM [" + self.provider_id + "]") elif not isinstance(episode, list): sql_results = cache_db_con.select( "SELECT * FROM [" + self.provider_id + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ?", [episode.show.indexerid, episode.season, "%|" + str(episode.episode) + "|%"]) else: for ep_obj in episode: cl.append([ "SELECT * FROM [" + self.provider_id + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ? AND quality IN (" + ",".join( [str(x) for x in ep_obj.wantedQuality]) + ")", [ep_obj.show.indexerid, ep_obj.season, "%|" + str(ep_obj.episode) + "|%"]]) sql_results = cache_db_con.mass_action(cl, fetchall=True) sql_results = list(itertools.chain(*sql_results)) # for each cache entry for cur_result in sql_results: # get the show object, or if it's not one of our shows then ignore it show_obj = Show.find(sickbeard.showList, int(cur_result[b"indexerid"])) if not show_obj: continue # ignored/required words, and non-tv junk if not show_name_helpers.filter_bad_releases(cur_result[b"name"], show=show_obj): continue # skip if provider is anime only and show is not anime if self.provider.anime_only and not show_obj.is_anime: logger.log("" + str(show_obj.name) + " is not an anime, skiping", logger.DEBUG) continue # get season and ep data (ignoring multi-eps for now) cur_season = int(cur_result[b"season"]) if cur_season == -1: continue cur_ep = cur_result[b"episodes"].split("|")[1] if not cur_ep: continue cur_ep = int(cur_ep) cur_quality = int(cur_result[b"quality"]) cur_release_group = cur_result[b"release_group"] cur_version = cur_result[b"version"] # if the show says we want that episode then add it to the list if not show_obj.wantEpisode(cur_season, cur_ep, cur_quality, manualSearch, downCurQuality): logger.log("Ignoring " + cur_result[b"name"], logger.DEBUG) continue ep_obj = show_obj.getEpisode(cur_season, cur_ep) # build a result object title = cur_result[b"name"] url = cur_result[b"url"] logger.log("Found result " + title + " at " + url) result = self.provider.get_result([ep_obj]) result.show = show_obj result.url = url result.name = title result.quality = cur_quality result.release_group = cur_release_group result.version = cur_version result.content = None # add it to the list if ep_obj not in needed_eps: needed_eps[ep_obj] = [result] else: needed_eps[ep_obj].append(result) # datetime stamp this search so cache gets cleared self.set_last_search() return needed_eps
def test_global_only(self): self.assertFalse(filter_bad_releases('Release name that is IGNORED', False)) self.assertTrue(filter_bad_releases('Release name that is REQUIRED', False)) self.assertFalse(filter_bad_releases('Release name that is REQUIRED but contains IGNORED', False))
def pickBestResult(results, show): # pylint: disable=too-many-branches """ Find the best result out of a list of search results for a show :param results: list of result objects :param show: Shows we check for :return: best result object """ results = results if isinstance(results, list) else [results] logger.log( "Picking the best result out of " + str([x.name for x in results]), logger.DEBUG) preferredWords = [i.strip() for i in sickbeard.PREFERRED_WORDS.split(',')] # find the best result for the current episode for cur_result in results: if show and cur_result.show is not show: continue cur_result.searcher_score = 0 nameLower = cur_result.name.lower() # build the black And white list if show.is_anime: if not show.release_groups.is_valid(cur_result): continue logger.log("Quality of " + cur_result.name + " is " + Quality.qualityStrings[cur_result.quality]) anyQualities, bestQualities = Quality.splitQuality(show.quality) if cur_result.quality not in anyQualities + bestQualities: logger.log( cur_result.name + " is a quality we know we don't want, rejecting it", logger.DEBUG) continue if not show_name_helpers.filter_bad_releases( cur_result.name, parse=False, show=show): continue cur_result.searcher_score += (cur_result.quality * 100) if hasattr(cur_result, 'size'): if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed( cur_result.name, cur_result.size, cur_result.provider.name): logger.log(cur_result.name + " has previously failed, rejecting it") cur_result.searcher_score = -1 continue for i in preferredWords: if i.lower() in nameLower: logger.log('Found preferred word {} in {}'.format( i, cur_result.name)) cur_result.searcher_score += 1 results.sort(key=lambda x: x.searcher_score, reverse=True) if len(results) == 0 or results[0].searcher_score == -1: logger.log("No result picked.", logger.DEBUG) return None else: acceptableResults = list( i for i in results if i.searcher_score == results[0].searcher_score) if len(acceptableResults) == 1: logger.log("Picked " + acceptableResults[0].name + " as the best", logger.DEBUG) return acceptableResults[0] else: logger.log('Found {} acceptable results.'.format( len(acceptableResults))) bestResult = None for result in acceptableResults: nameLower = result.name.lower() if any(i in nameLower for i in ('proper', 'real', 'repack')): logger.log("Preferring " + result.name + " (repack/proper/real over nuked)") bestResult = result break elif 'internal' in nameLower: logger.log('Lowering preferece for {} (internal)'.format( result.name)) result.searcher_score -= 10 elif "xvid" in nameLower: logger.log('Lowering preferece for {} (xvid)'.format( result.name)) result.searcher_score -= 1 if not bestResult: bestResult = sorted(acceptableResults, key=lambda x: x.searcher_score, reverse=True)[0] logger.log("Picked " + bestResult.name + " as the best", logger.DEBUG) return bestResult