Private GIT

Skip to content
Snippets Groups Projects
Unverified Commit 88883c1d authored by miigotu's avatar miigotu
Browse files

Refactor FilterBadReleases to filter_bad_releases

**Show specific required/ignored words now totally override global settings if they are set**

If show ignored words are not set, global ignored words will be used
If show required words are not set, global required will be used

If the show has required words, they will be removed from the overall calculated ignored list when evaluating
If the show has ignored words, they will be removed from the overall calculated rquired words list when evaluating

If a show has required words which are also in the global ignored words they will override the global ignored and the release will be accepted
If a show has ignored words which are also in the global required words they will overrid the global required and the release will be discared

Release must not contain ANY of the final ignored words list, and at least ONE of the final calculated required words.

Added a unit test to make sure this behavior is as expected and remains that way

Fixes #1541
Fixes #1619
Fixes #1623
Fixes #1629
parent 7111172c
No related branches found
No related tags found
No related merge requests found
......@@ -228,7 +228,7 @@ def pickBestResult(results, show): # pylint: disable=too-many-branches
logger.log(cur_result.name + " is a quality we know we don't want, rejecting it", logger.DEBUG)
continue
if not show_name_helpers.filterBadReleases(cur_result.name, parse=False, show=show):
if not show_name_helpers.filter_bad_releases(cur_result.name, parse=False, show=show):
continue
if hasattr(cur_result, 'size'):
......
......@@ -60,22 +60,7 @@ def containsAtLeastOneWord(name, words):
return False
def containsAllWords(name, words):
"""
Filters out results based on filter_words
name: name to check
words : string of words separated by a ',' or list of words
Returns: False if the name doesn't contain any word of words list, or the found word from the list.
"""
if isinstance(words, basestring):
words = words.split(',')
return all(re.compile(r'(^|[\W_]){0}($|[\W_])'.format(re.escape(word.strip())), re.I).search(name) for word in words)
def filterBadReleases(name, parse=True, show=None):
def filter_bad_releases(name, parse=True, show=None):
"""
Filters out non-english and just all-around stupid releases by comparing them
to the resultFilters contents.
......@@ -99,14 +84,16 @@ def filterBadReleases(name, parse=True, show=None):
# if any of the bad strings are in the name then say no
ignore_words = list(resultFilters)
if sickbeard.IGNORE_WORDS:
ignore_words.extend(sickbeard.IGNORE_WORDS.split(','))
if show:
if show.rls_ignore_words:
if show and show.rls_ignore_words:
ignore_words.extend(show.rls_ignore_words.split(','))
if show.rls_require_words:
elif sickbeard.IGNORE_WORDS:
ignore_words.extend(sickbeard.IGNORE_WORDS.split(','))
if show and show.rls_require_words:
ignore_words = list(set(ignore_words).difference(x.strip() for x in show.rls_require_words.split(',') if x.strip()))
elif sickbeard.REQUIRE_WORDS and not (show and show.rls.ignore_words): # Only remove global require words from the list if we arent using show ignore words
ignore_words = list(set(ignore_words).difference(x.strip() for x in sickbeard.REQUIRE_WORDS.split(',') if x.strip()))
word = containsAtLeastOneWord(name, ignore_words)
if word:
......@@ -115,14 +102,18 @@ def filterBadReleases(name, parse=True, show=None):
# if any of the good strings aren't in the name then say no
require_words = sickbeard.REQUIRE_WORDS.split(',') if sickbeard.REQUIRE_WORDS else []
if show:
if show.rls_ignore_words:
require_words = list(set(require_words).difference(x.strip() for x in show.rls_ignore_words.split(',') if x.strip()))
if show.rls_require_words:
require_words = []
if show and show.rls_require_words:
require_words.extend(show.rls_require_words.split(','))
elif sickbeard.REQUIRE_WORDS:
require_words.extend(sickbeard.REQUIRE_WORDS.split(','))
if show and show.rls_ignore_words:
require_words = list(set(require_words).difference(x.strip() for x in show.rls_ignore_words.split(',') if x.strip()))
elif sickbeard.IGNORE_WORDS and not (show and show.rls_require_words): # Only remove global ignore words from the list if we arent using show require words
require_words = list(set(require_words).difference(x.strip() for x in sickbeard.IGNORE_WORDS.split(',') if x.strip()))
if require_words and not containsAllWords(name, require_words):
if require_words and not containsAtLeastOneWord(name, require_words):
logger.log(u"Release: " + name + " doesn't contain any of " + ', '.join(set(require_words)) +
", ignoring it", logger.INFO)
return False
......@@ -196,13 +187,13 @@ def determineReleaseName(dir_name=None, nzb_name=None):
if len(results) == 1:
found_file = ek(os.path.basename, results[0])
found_file = found_file.rpartition('.')[0]
if filterBadReleases(found_file):
if filter_bad_releases(found_file):
logger.log(u"Release name (" + found_file + ") found from file (" + results[0] + ")")
return found_file.rpartition('.')[0]
# If that fails, we try the folder
folder = ek(os.path.basename, dir_name)
if filterBadReleases(folder):
if filter_bad_releases(folder):
# NOTE: Multiple failed downloads will change the folder name.
# (e.g., appending #s)
# Should we handle that?
......
......@@ -319,7 +319,7 @@ class TVCache(object):
continue
# ignored/required words, and non-tv junk
if not show_name_helpers.filterBadReleases(curResult["name"], show=showObj):
if not show_name_helpers.filter_bad_releases(curResult["name"], show=showObj):
continue
# skip if provider is anime only and show is not anime
......
......@@ -5,16 +5,13 @@ Test scene helpers
# pylint: disable=line-too-long
import os.path
import sys
import unittest
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), '../lib')))
sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
import tests.test_lib as test
from sickbeard import show_name_helpers, scene_exceptions, common, name_cache, db
from sickbeard.tv import TVShow as Show
import tests.test_lib as test
class SceneTests(test.SickbeardTestDBCase):
......@@ -45,7 +42,7 @@ class SceneTests(test.SickbeardTestDBCase):
:param expected:
:return:
"""
result = show_name_helpers.filterBadReleases(name)
result = show_name_helpers.filter_bad_releases(name)
self.assertEqual(result, expected)
def test_all_possible_show_names(self):
......
#!/usr/bin/env python2.7
# coding=utf-8
from __future__ import unicode_literals, print_function
import unittest
import test_lib as test_ # pylint: disable=unused-import
import sickbeard
from sickbeard.show_name_helpers import filter_bad_releases
from sickbeard.tv import TVShow as Show
class ReleaseWordFilterTests(unittest.TestCase):
def setUp(self):
sickbeard.QUALITY_DEFAULT = 2
self.show = Show(1, 1)
sickbeard.REQUIRE_WORDS = 'REQUIRED'
sickbeard.IGNORE_WORDS = 'IGNORED'
# These are opposite of global, to prove they override
self.show.rls_ignore_words = 'REQUIRED'
self.show.rls_require_words = 'IGNORED'
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 test_show_required_ignored_words(self):
self.assertFalse(filter_bad_releases('Release name that is not REQUIRED', False, show=self.show))
self.assertTrue(filter_bad_releases('Release name that is not IGNORED', False, show=self.show))
self.assertFalse(filter_bad_releases('Release name that is not REQUIRED but contains IGNORED', False, show=self.show))
if __name__ == '__main__':
SUITE = unittest.TestLoader().loadTestsFromTestCase(ReleaseWordFilterTests)
unittest.TextTestRunner(verbosity=2).run(SUITE)
......@@ -14,5 +14,5 @@ deps =
pytz
commands =
nosetests -c nose.cfg
nosetests -c nose.cfg --nocapture
- coveralls
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment