Skip to content

Commit f13fef7

Browse files
author
Patrick Vos
committed
Merge branch 'add_cleanup_release_name_group' into development
* add_cleanup_release_name_group: Fix rescan overwriting existing release_name Add cleanup release name, group pep8 cleanup
2 parents d76d2d0 + 5f7627b commit f13fef7

File tree

4 files changed

+113
-97
lines changed

4 files changed

+113
-97
lines changed

sickbeard/helpers.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
from sickbeard.exceptions import MultipleShowObjectsException, ex
5151
from sickbeard import logger, classes
5252
from sickbeard.common import USER_AGENT, mediaExtensions, XML_NSMAP
53+
from sickbeard.common import mediaExtensions
5354

5455
from sickbeard import db
5556
from sickbeard import encodingKludge as ek
@@ -82,6 +83,32 @@ def indentXML(elem, level=0):
8283
elem.tail = i
8384

8485

86+
def remove_extension(name):
87+
"""
88+
Remove download or media extension from name (if any)
89+
"""
90+
91+
if name and "." in name:
92+
base_name, sep, extension = name.rpartition('.') # @UnusedVariable
93+
if base_name and extension.lower() in ['nzb', 'torrent'] + mediaExtensions:
94+
name = base_name
95+
96+
return name
97+
98+
99+
def remove_non_release_groups(name):
100+
"""
101+
Remove non release groups from name
102+
"""
103+
104+
if name and "-" in name:
105+
name_group = name.rsplit('-', 1)
106+
if name_group[-1].upper() in ["RP", "NZBGEEK"]:
107+
name = name_group[0]
108+
109+
return name
110+
111+
85112
def replaceExtension(filename, newExt):
86113
'''
87114
>>> replaceExtension('foo.avi', 'mkv')

sickbeard/name_parser/parser.py

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,34 @@
2525
import sickbeard
2626

2727
from sickbeard import logger
28+
from sickbeard import encodingKludge as ek
29+
from sickbeard import helpers
30+
2831

2932
class NameParser(object):
30-
def __init__(self, file_name=True):
33+
def __init__(self, is_file_name=True):
3134

32-
self.file_name = file_name
35+
self.is_file_name = is_file_name
3336
self.compiled_regexes = []
3437
self._compile_regexes()
3538

3639
def clean_series_name(self, series_name):
3740
"""Cleans up series name by removing any . and _
3841
characters, along with any trailing hyphens.
39-
42+
4043
Is basically equivalent to replacing all _ and . with a
4144
space, but handles decimal numbers in string, for example:
42-
45+
4346
>>> cleanRegexedSeriesName("an.example.1.0.test")
4447
'an example 1.0 test'
4548
>>> cleanRegexedSeriesName("an_example_1.0_test")
4649
'an example 1.0 test'
47-
50+
4851
Stolen from dbr's tvnamer
4952
"""
50-
53+
5154
series_name = re.sub("(\D)\.(?!\s)(\D)", "\\1 \\2", series_name)
52-
series_name = re.sub("(\d)\.(\d{4})", "\\1 \\2", series_name) # if it ends in a year then don't keep the dot
55+
series_name = re.sub("(\d)\.(\d{4})", "\\1 \\2", series_name) # if it ends in a year then don't keep the dot
5356
series_name = re.sub("(\D)\.(?!\s)", "\\1 ", series_name)
5457
series_name = re.sub("\.(?!\s)(\D)", " \\1", series_name)
5558
series_name = series_name.replace("_", " ")
@@ -66,44 +69,44 @@ def _compile_regexes(self):
6669
self.compiled_regexes.append((cur_pattern_name, cur_regex))
6770

6871
def _parse_string(self, name):
69-
72+
7073
if not name:
7174
return None
72-
75+
7376
for (cur_regex_name, cur_regex) in self.compiled_regexes:
7477
match = cur_regex.match(name)
7578

7679
if not match:
7780
continue
78-
81+
7982
result = ParseResult(name)
8083
result.which_regex = [cur_regex_name]
81-
84+
8285
named_groups = match.groupdict().keys()
8386

8487
if 'series_name' in named_groups:
8588
result.series_name = match.group('series_name')
8689
if result.series_name:
8790
result.series_name = self.clean_series_name(result.series_name)
88-
91+
8992
if 'season_num' in named_groups:
9093
tmp_season = int(match.group('season_num'))
91-
if cur_regex_name == 'bare' and tmp_season in (19,20):
94+
if cur_regex_name == 'bare' and tmp_season in (19, 20):
9295
continue
9396
result.season_number = tmp_season
94-
97+
9598
if 'ep_num' in named_groups:
9699
ep_num = self._convert_number(match.group('ep_num'))
97100
if 'extra_ep_num' in named_groups and match.group('extra_ep_num'):
98-
result.episode_numbers = range(ep_num, self._convert_number(match.group('extra_ep_num'))+1)
101+
result.episode_numbers = range(ep_num, self._convert_number(match.group('extra_ep_num')) + 1)
99102
else:
100103
result.episode_numbers = [ep_num]
101104

102105
if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups:
103106
year = int(match.group('air_year'))
104107
month = int(match.group('air_month'))
105108
day = int(match.group('air_day'))
106-
109+
107110
# make an attempt to detect YYYY-DD-MM formats
108111
if month > 12:
109112
tmp_month = month
@@ -148,18 +151,18 @@ def _combine_results(self, first, second, attr):
148151
# if the second doesn't exist then return the first
149152
if not second:
150153
return getattr(first, attr)
151-
154+
152155
a = getattr(first, attr)
153156
b = getattr(second, attr)
154-
157+
155158
# if a is good use it
156159
if a != None or (type(a) == list and len(a)):
157160
return a
158161
# if not use b (if b isn't set it'll just be default)
159162
else:
160163
return b
161164

162-
def _unicodify(self, obj, encoding = "utf-8"):
165+
def _unicodify(self, obj, encoding="utf-8"):
163166
if isinstance(obj, basestring):
164167
if not isinstance(obj, unicode):
165168
obj = unicode(obj, encoding)
@@ -203,30 +206,30 @@ def _convert_number(self, number):
203206
return int(number)
204207

205208
def parse(self, name):
206-
209+
207210
name = self._unicodify(name)
208-
211+
209212
cached = name_parser_cache.get(name)
210213
if cached:
211214
return cached
212215

213216
# break it into parts if there are any (dirname, file name, extension)
214-
dir_name, file_name = os.path.split(name)
215-
ext_match = re.match('(.*)\.\w{3,4}$', file_name)
216-
if ext_match and self.file_name:
217-
base_file_name = ext_match.group(1)
217+
dir_name, file_name = ek.ek(os.path.split, name)
218+
219+
if self.is_file_name:
220+
base_file_name = helpers.remove_extension(file_name)
218221
else:
219222
base_file_name = file_name
220-
223+
221224
# use only the direct parent dir
222-
dir_name = os.path.basename(dir_name)
223-
225+
dir_name = ek.ek(os.path.basename, dir_name)
226+
224227
# set up a result to use
225228
final_result = ParseResult(name)
226-
229+
227230
# try parsing the file name
228231
file_name_result = self._parse_string(base_file_name)
229-
232+
230233
# parse the dirname for extra info if needed
231234
dir_name_result = self._parse_string(dir_name)
232235

@@ -263,6 +266,7 @@ def parse(self, name):
263266
# return it
264267
return final_result
265268

269+
266270
class ParseResult(object):
267271
def __init__(self,
268272
original_name,
@@ -275,7 +279,7 @@ def __init__(self,
275279
):
276280

277281
self.original_name = original_name
278-
282+
279283
self.series_name = series_name
280284
self.season_number = season_number
281285
if not episode_numbers:
@@ -285,15 +289,15 @@ def __init__(self,
285289

286290
self.extra_info = extra_info
287291
self.release_group = release_group
288-
292+
289293
self.air_date = air_date
290-
294+
291295
self.which_regex = None
292-
296+
293297
def __eq__(self, other):
294298
if not other:
295299
return False
296-
300+
297301
if self.series_name != other.series_name:
298302
return False
299303
if self.season_number != other.season_number:
@@ -306,7 +310,7 @@ def __eq__(self, other):
306310
return False
307311
if self.air_date != other.air_date:
308312
return False
309-
313+
310314
return True
311315

312316
def __str__(self):
@@ -315,10 +319,10 @@ def __str__(self):
315319
else:
316320
to_return = u''
317321
if self.season_number != None:
318-
to_return += 'S'+str(self.season_number)
322+
to_return += 'S' + str(self.season_number)
319323
if self.episode_numbers and len(self.episode_numbers):
320324
for e in self.episode_numbers:
321-
to_return += 'E'+str(e)
325+
to_return += 'E' + str(e)
322326

323327
if self.air_by_date:
324328
to_return += str(self.air_date)
@@ -328,7 +332,7 @@ def __str__(self):
328332
if self.release_group:
329333
to_return += ' (' + self.release_group + ')'
330334

331-
to_return += ' [ABD: '+str(self.air_by_date)+']'
335+
to_return += ' [ABD: ' + str(self.air_by_date) + ']'
332336

333337
return to_return.encode('utf-8')
334338

@@ -338,19 +342,20 @@ def _is_air_by_date(self):
338342
return False
339343
air_by_date = property(_is_air_by_date)
340344

345+
341346
class NameParserCache(object):
342347
#TODO: check if the fifo list can beskiped and only use one dict
343-
_previous_parsed_list = [] # keep a fifo list of the cached items
348+
_previous_parsed_list = [] # keep a fifo list of the cached items
344349
_previous_parsed = {}
345350
_cache_size = 100
346-
351+
347352
def add(self, name, parse_result):
348353
self._previous_parsed[name] = parse_result
349354
self._previous_parsed_list.append(name)
350355
while len(self._previous_parsed_list) > self._cache_size:
351356
del_me = self._previous_parsed_list.pop(0)
352357
self._previous_parsed.pop(del_me)
353-
358+
354359
def get(self, name):
355360
if name in self._previous_parsed:
356361
logger.log("Using cached parse result for: " + name, logger.DEBUG)
@@ -360,5 +365,6 @@ def get(self, name):
360365

361366
name_parser_cache = NameParserCache()
362367

368+
363369
class InvalidNameException(Exception):
364370
"The given name is not valid"

sickbeard/postProcessor.py

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,12 @@ def __init__(self, file_path, nzb_name=None, pp_options={}):
8383
self.force_replace = pp_options.get('force_replace', False)
8484

8585
self.in_history = False
86+
8687
self.release_group = None
87-
self.is_proper = False
8888

89-
self.good_results = {self.NZB_NAME: False,
90-
self.FOLDER_NAME: False,
91-
self.FILE_NAME: False}
89+
self.release_name = None
90+
91+
self.is_proper = False
9292

9393
self.log = ''
9494

@@ -359,8 +359,10 @@ def _analyze_name(self, name, file_name=True):
359359
if not name:
360360
return to_return
361361

362+
name = helpers.remove_non_release_groups(helpers.remove_extension(name))
363+
362364
# parse the name to break it into show name, season, and episode
363-
np = NameParser(file_name)
365+
np = NameParser(False)
364366
parse_result = np.parse(name)
365367
self._log(u"Parsed " + name + " into " + str(parse_result).decode('utf-8', 'xmlcharrefreplace'), logger.DEBUG)
366368

@@ -437,16 +439,10 @@ def _finalize(self, parse_result):
437439
self.is_proper = parse_result.is_proper
438440

439441
# if the result is complete then remember that for later
440-
if parse_result.series_name and parse_result.season_number != None and parse_result.episode_numbers and parse_result.release_group:
441-
test_name = ek.ek(os.path.basename, parse_result.original_name)
442-
if test_name == self.nzb_name:
443-
self.good_results[self.NZB_NAME] = True
444-
elif test_name == self.folder_name:
445-
self.good_results[self.FOLDER_NAME] = True
446-
elif test_name == self.file_name:
447-
self.good_results[self.FILE_NAME] = True
448-
else:
449-
logger.log(u"Nothing was good, found " + repr(test_name) + " and wanted either " + repr(self.nzb_name) + ", " + repr(self.folder_name) + ", or " + repr(self.file_name))
442+
if parse_result.series_name and parse_result.season_number is not None and parse_result.episode_numbers and parse_result.release_group:
443+
if not self.release_name:
444+
self.release_name = helpers.remove_extension(ek.ek(os.path.basename, parse_result.original_name))
445+
450446
else:
451447
logger.log(u"Parse result not sufficient (all following have to be set). will not save release name", logger.DEBUG)
452448
logger.log(u"Parse result(series_name): " + str(parse_result.series_name), logger.DEBUG)
@@ -813,28 +809,11 @@ def process(self):
813809

814810
# update the ep info before we rename so the quality & release name go into the name properly
815811
for cur_ep in [ep_obj] + ep_obj.relatedEps:
816-
cur_release_name = None
817-
818-
# use the best possible representation of the release name
819-
if self.good_results[self.NZB_NAME]:
820-
cur_release_name = self.nzb_name
821-
if cur_release_name.lower().endswith('.nzb'):
822-
cur_release_name = cur_release_name.rpartition('.')[0]
823-
824-
elif self.good_results[self.FILE_NAME]:
825-
cur_release_name = self.file_name
826-
# take the extension off the filename, it's not needed
827-
if '.' in self.file_name:
828-
cur_release_name = self.file_name.rpartition('.')[0]
829-
830-
elif self.good_results[self.FOLDER_NAME]:
831-
cur_release_name = self.folder_name
832-
833-
if cur_release_name:
834-
self._log("Found release name " + cur_release_name, logger.DEBUG)
835-
cur_ep.release_name = cur_release_name
812+
813+
if self.release_name:
814+
self._log("Found release name " + self.release_name, logger.DEBUG)
815+
cur_ep.release_name = self.release_name
836816
else:
837-
logger.log(u"good results: " + repr(self.good_results), logger.DEBUG)
838817
cur_ep.release_name = ""
839818

840819
cur_ep.status = common.Quality.compositeStatus(common.DOWNLOADED, new_ep_quality)

0 commit comments

Comments
 (0)