diff --git a/couchpotato/core/plugins/renamer/main.py b/couchpotato/core/plugins/renamer/main.py index 6757bb8..d1daf18 100644 --- a/couchpotato/core/plugins/renamer/main.py +++ b/couchpotato/core/plugins/renamer/main.py @@ -148,6 +148,10 @@ class Renamer(Plugin): remove_releases = [] movie_title = getTitle(group['library']) + try: + destination = group['category']['path'] + except: + destination = self.conf('to') # Add _UNKNOWN_ if no library item is connected if not group['library'] or not movie_title: @@ -817,4 +821,4 @@ Remove it if you want it to be renamed (again, or at least let it try again) return item['id'] and item['downloader'] and item['folder'] def movieInFromFolder(self, movie_folder): - return movie_folder and self.conf('from') in movie_folder or not movie_folder \ No newline at end of file + return movie_folder and self.conf('from') in movie_folder or not movie_folder diff --git a/couchpotato/core/plugins/score/main.py b/couchpotato/core/plugins/score/main.py index 4f16539..28baae7 100644 --- a/couchpotato/core/plugins/score/main.py +++ b/couchpotato/core/plugins/score/main.py @@ -3,8 +3,8 @@ from couchpotato.core.helpers.encoding import toUnicode from couchpotato.core.helpers.variable import getTitle from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin -from couchpotato.core.plugins.score.scores import nameScore, nameRatioScore, \ - sizeScore, providerScore, duplicateScore, partialIgnoredScore, namePositionScore, \ +from couchpotato.core.plugins.score.scores import nameScore, CatnameScore, nameRatioScore, \ + sizeScore, providerScore, duplicateScore, partialIgnoredScore, CatpartialIgnoredScore, namePositionScore, \ halfMultipartScore log = CPLog(__name__) @@ -18,7 +18,10 @@ class Score(Plugin): def calculate(self, nzb, movie): ''' Calculate the score of a NZB, used for sorting later ''' - score = nameScore(toUnicode(nzb['name'] + ' ' + nzb.get('name_extra', '')), movie['library']['year']) + if movie and movie['category'] and movie['category']['preferred']: + score = CatnameScore(toUnicode(nzb['name']), movie['library']['year'], movie['category']['preferred']) + else: + score = nameScore(toUnicode(nzb['name']), movie['library']['year']) for movie_title in movie['library']['titles']: score += nameRatioScore(toUnicode(nzb['name']), toUnicode(movie_title['title'])) @@ -41,7 +44,10 @@ class Score(Plugin): score += duplicateScore(nzb['name'], getTitle(movie['library'])) # Partial ignored words - score += partialIgnoredScore(nzb['name'], getTitle(movie['library'])) + if movie and movie['category'] and movie['category']['ignored']: + score = CatpartialIgnoredScore(nzb['name'], getTitle(movie['library']), movie['category']['ignored']) + else: + score += partialIgnoredScore(nzb['name'], getTitle(movie['library'])) # Ignore single downloads from multipart score += halfMultipartScore(nzb['name']) diff --git a/couchpotato/core/plugins/score/scores.py b/couchpotato/core/plugins/score/scores.py index 95ef9b9..5af07fa 100644 --- a/couchpotato/core/plugins/score/scores.py +++ b/couchpotato/core/plugins/score/scores.py @@ -47,6 +47,32 @@ def nameScore(name, year): return score +def CatnameScore(name, year, preferred): + ''' Calculate score for words in the NZB name ''' + + score = 0 + name = name.lower() + + # give points for the cool stuff + for value in name_scores: + v = value.split(':') + add = int(v.pop()) + if v.pop() in name: + score = score + add + + # points if the year is correct + if str(year) in name: + score = score + 5 + + # Contains preferred word + nzb_words = re.split('\W+', simplifyString(name)) + preferred_words = [x.strip() for x in preferred.split(',')] + for word in preferred_words: + if word.strip() and word.strip().lower() in nzb_words: + score = score + 100 + + return score + def nameRatioScore(nzb_name, movie_name): nzb_words = re.split('\W+', fireEvent('scanner.create_file_identifier', nzb_name, single = True)) @@ -148,6 +174,20 @@ def partialIgnoredScore(nzb_name, movie_name): return score +def CatpartialIgnoredScore(nzb_name, movie_name, ignored): + + nzb_name = nzb_name.lower() + movie_name = movie_name.lower() + + ignored_words = [x.strip().lower() for x in ignored.split(',')] + + score = 0 + for ignored_word in ignored_words: + if ignored_word in nzb_name and ignored_word not in movie_name: + score -= 5 + + return score + def halfMultipartScore(nzb_name): wrong_found = 0 diff --git a/couchpotato/core/plugins/searcher/main.py b/couchpotato/core/plugins/searcher/main.py index cc2774a..759ac38 100644 --- a/couchpotato/core/plugins/searcher/main.py +++ b/couchpotato/core/plugins/searcher/main.py @@ -392,24 +392,30 @@ class Searcher(Plugin): nzb_words = re.split('\W+', nzb_name) # Make sure it has required words - required_words = splitString(self.conf('required_words').lower()) + try: + required_words = splitString(movie['category']['required'].lower()) + except: + required_words = splitString(self.conf('required_words').lower()) req_match = 0 for req_set in required_words: req = splitString(req_set, '&') req_match += len(list(set(nzb_words) & set(req))) == len(req) - if self.conf('required_words') and req_match == 0: + if len(required_words) > 0 and req_match == 0: log.info2('Wrong: Required word missing: %s', nzb['name']) return False # Ignore releases - ignored_words = splitString(self.conf('ignored_words').lower()) + try: + ignored_words = splitString(movie['category']['ignored'].lower()) + except: + ignored_words = splitString(self.conf('ignored_words').lower()) ignored_match = 0 for ignored_set in ignored_words: ignored = splitString(ignored_set, '&') ignored_match += len(list(set(nzb_words) & set(ignored))) == len(ignored) - if self.conf('ignored_words') and ignored_match: + if len(ignored_words) > 0 and ignored_match: log.info2("Wrong: '%s' contains 'ignored words'", (nzb['name'])) return False diff --git a/couchpotato/core/settings/model.py b/couchpotato/core/settings/model.py index 00ac34e..25e0883 100644 --- a/couchpotato/core/settings/model.py +++ b/couchpotato/core/settings/model.py @@ -82,6 +82,7 @@ class Movie(Entity): library = ManyToOne('Library', cascade = 'delete, delete-orphan', single_parent = True) status = ManyToOne('Status') profile = ManyToOne('Profile') + category = ManyToOne('Category') releases = OneToMany('Release', cascade = 'all, delete-orphan') files = ManyToMany('File', cascade = 'all, delete-orphan', single_parent = True) @@ -206,6 +207,22 @@ class Profile(Entity): return orig_dict +class Category(Entity): + """""" + using_options(order_by = 'order') + + label = Field(Unicode(50)) + order = Field(Integer, default = 0, index = True) + core = Field(Boolean, default = False) + hide = Field(Boolean, default = False) + + movie = OneToMany('Movie') + path = Field(Unicode(255)) + required = Field(Unicode(255)) + preferred = Field(Unicode(255)) + ignored = Field(Unicode(255)) + + class ProfileType(Entity): """""" using_options(order_by = 'order')