Fixed scene_numbering issues for shows that use scene numbers instead of TVDB numbering.

Fixed issues with local SB cache.

Fixed issues with sports naming patterns, we no longer treat sports as a airdate show and have created custom regex's to aid in finding sports related shows.
This commit is contained in:
echel0n 2014-04-30 05:10:13 -07:00
parent d14581b8cc
commit 319ac2602f
24 changed files with 176 additions and 293 deletions

View File

@ -776,7 +776,7 @@
<tr>
<td class="align-right"><i class="icon-info-sign" title="Multi-EP style is ignored"></i> <b>Release Name:</b></td>
<td>%RN</td>
<td>Show.Name.9.Mar.2011.HDTV.XviD-RLSGROUP</td>
<td>Show.Name.9th.Mar.2011.HDTV.XviD-RLSGROUP</td>
</tr>
<tr class="even">
<td class="align-right"><i class="icon-info-sign" title="'SiCKBEARD' is used in place of RLSGROUP if it could not be properly detected"></i> <b>Release Group:</b></td>

View File

@ -19,18 +19,11 @@
import datetime
import os.path
import re
import copy
import regexes
import sickbeard
import calendar
from sickbeard import logger, classes
from sickbeard import scene_numbering, scene_exceptions
from lib.dateutil.parser import parse
from time import strptime
from sickbeard import logger, helpers, scene_numbering
class NameParser(object):
ALL_REGEX = 0
@ -114,6 +107,11 @@ class NameParser(object):
if result.series_name:
result.series_name = self.clean_series_name(result.series_name)
if 'sports_event_title' in named_groups:
result.sports_event_title = match.group('sports_event_title')
if result.sports_event_title:
result.sports_event_title = self.clean_series_name(result.sports_event_title)
if 'season_num' in named_groups:
tmp_season = int(match.group('season_num'))
if cur_regex_name == 'bare' and tmp_season in (19, 20):
@ -129,16 +127,12 @@ class NameParser(object):
if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups:
year = int(match.group('air_year'))
month = match.group('air_month')
month = int(match.group('air_month'))
day = int(match.group('air_day'))
try:
try:
dtStr = '%s-%s-%s' % (year, month, day)
result.air_date = datetime.datetime.strptime(dtStr, "%Y-%m-%d").date()
except:
dtStr = '%s-%s-%s' % (day, month, year)
result.air_date = datetime.datetime.strptime(dtStr, "%d-%b-%Y").date()
dtStr = '%s-%s-%s' % (year, month, day)
result.air_date = datetime.datetime.strptime(dtStr, "%Y-%m-%d").date()
except ValueError, e:
raise InvalidNameException(e.message)
@ -235,7 +229,9 @@ class NameParser(object):
# build the ParseResult object
final_result.air_date = self._combine_results(file_name_result, dir_name_result, 'air_date')
final_result.sports_date = self._combine_results(file_name_result, dir_name_result, 'sports_date')
# sports event title
final_result.sports_event_title = self._combine_results(file_name_result, dir_name_result, 'sports_event_title')
if not final_result.air_date:
final_result.season_number = self._combine_results(file_name_result, dir_name_result, 'season_number')
@ -268,12 +264,12 @@ class ParseResult(object):
def __init__(self,
original_name,
series_name=None,
sports_event_title=None,
season_number=None,
episode_numbers=None,
extra_info=None,
release_group=None,
air_date=None,
sports_date=None
):
self.original_name = original_name
@ -289,7 +285,8 @@ class ParseResult(object):
self.release_group = release_group
self.air_date = air_date
self.sports_date = sports_date
self.sports_event_title = sports_event_title
self.which_regex = None
@ -309,7 +306,7 @@ class ParseResult(object):
return False
if self.air_date != other.air_date:
return False
if self.sports_date != other.sports_date:
if self.sports_event_title != other.sports_event_title:
return False
return True
@ -328,7 +325,7 @@ class ParseResult(object):
if self.air_by_date:
to_return += str(self.air_date)
if self.sports:
to_return += str(self.sports_date)
to_return += str(self.sports_event_title)
if self.extra_info:
to_return += ' - ' + self.extra_info
@ -341,14 +338,47 @@ class ParseResult(object):
return to_return.encode('utf-8')
def convert(self):
if self.air_by_date: return # scene numbering does not apply to air-by-date
if self.season_number == None: return self # can't work without a season
if len(self.episode_numbers) == 0: return self # need at least one episode
# convert scene numbered releases before storing to cache
indexer_id = helpers.searchDBForShow(self.series_name)
if indexer_id:
new_episode_numbers = []
new_season_numbers = []
for epNo in self.episode_numbers:
(s, e) = scene_numbering.get_indexer_numbering(indexer_id, self.season_number, epNo)
new_episode_numbers.append(e)
new_season_numbers.append(s)
# need to do a quick sanity check here. It's possible that we now have episodes
# from more than one season (by tvdb numbering), and this is just too much
# for sickbeard, so we'd need to flag it.
new_season_numbers = list(set(new_season_numbers)) # remove duplicates
if len(new_season_numbers) > 1:
raise InvalidNameException("Scene numbering results episodes from "
"seasons %s, (i.e. more than one) and "
"sickbeard does not support this. "
"Sorry." % (str(new_season_numbers)))
# I guess it's possible that we'd have duplicate episodes too, so lets
# eliminate them
new_episode_numbers = list(set(new_episode_numbers))
new_episode_numbers.sort()
self.episode_numbers = new_episode_numbers
self.season_number = new_season_numbers[0]
def _is_air_by_date(self):
if self.season_number == None and len(self.episode_numbers) == 0 and self.air_date and not self.sports_date:
if self.season_number == None and len(self.episode_numbers) == 0 and self.air_date:
return True
return False
air_by_date = property(_is_air_by_date)
def _is_sports(self):
if self.season_number == None and len(self.episode_numbers) == 0 and self.sports_date:
if self.sports_event_title:
return True
return False
sports = property(_is_sports)
@ -359,14 +389,14 @@ class NameParserCache(object):
_previous_parsed = {}
_cache_size = 100
def add(self, name, parse_result):
def add(self, name, parse_result, convert=False):
self._previous_parsed[name] = parse_result
self._previous_parsed_list.append(name)
while len(self._previous_parsed_list) > self._cache_size:
del_me = self._previous_parsed_list.pop(0)
self._previous_parsed.pop(del_me)
def get(self, name):
def get(self, name, convert=False):
if name in self._previous_parsed:
logger.log("Using cached parse result for: " + name, logger.DEBUG)
return self._previous_parsed[name]

View File

@ -187,16 +187,13 @@ ep_regexes = [
]
sports_regexs = [
('sports_event',
# Show.Name.123.Event.Nov.23rd.2010.Source.Quality.Etc-Group
'''
^((?P<series_name>.+?)[. _-]+)?
^((?P<event>.+?)[. _-]+)?
((?P<air_day>\d{1,2}))[. _-]+
(?P<air_month>\w{3,})[. _-]+
(?P<air_year>\d{4})
[. _-]*((?P<extra_info>.+?)
((?<![. _-])(?<!WEB)
-(?P<release_group>[^- ]+))?)?$
'''),
('sports_event_mma',
# Show.Name.123.Event.23rd.Nov.2010.Source.Quality.Etc-Group
'''
^(?P<series_name>.+?)[. _-]+
(?P<sports_event_title>\d{3}[. _-]+\w+[. _-]vs[. _-]\w+)
([. _-]*(?P<extra_info>.+?)((?<![. _-])(?<!WEB)
-(?P<release_group>[^- ]+))?)?$
'''
),
]

View File

@ -40,9 +40,11 @@ name_abd_presets = ('%SN - %A-D - %EN',
'%Y/%0M/%S.N.%A.D.%E.N-%RG'
)
name_sports_presets = ('%SN - %A-D - %EN',
'%S.N.%A.D.%E.N.%Q.N',
'%Y/%0M/%S.N.%A.D.%E.N-%RG'
name_sports_presets = ('%SN - %Sx%0E - %EN',
'%S.N.S%0SE%0E.%E.N',
'%Sx%0E - %EN',
'S%0SE%0E - %EN',
'Season %0S/%S.N.S%0SE%0E.%Q.N-%RG'
)
class TVShow():
@ -135,11 +137,7 @@ def check_valid_sports_naming(pattern=None):
def validate_name(pattern, multi=None, file_only=False, abd=False, sports=False):
ep = _generate_sample_ep(multi, abd, sports)
regexMode = 0
if sports:
regexMode = 2
parser = NameParser(True, regexMode)
parser = NameParser(True)
new_name = ep.formatted_filename(pattern, multi) + '.ext'
new_path = ep.formatted_dir(pattern, multi)
@ -164,10 +162,6 @@ def validate_name(pattern, multi=None, file_only=False, abd=False, sports=False)
if result.air_date != ep.airdate:
logger.log(u"Air date incorrect in parsed episode, pattern isn't valid", logger.DEBUG)
return False
elif sports:
if result.air_date != ep.airdate:
logger.log(u"Sports air date incorrect in parsed episode, pattern isn't valid", logger.DEBUG)
return False
else:
if result.season_number != ep.season:
logger.log(u"Season incorrect in parsed episode, pattern isn't valid", logger.DEBUG)
@ -182,6 +176,7 @@ def validate_name(pattern, multi=None, file_only=False, abd=False, sports=False)
def _generate_sample_ep(multi=None, abd=False, sports=False):
# make a fake episode object
ep = TVEpisode(2, 3, "Ep Name")
ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV)
ep._airdate = datetime.date(2011, 3, 9)
@ -189,7 +184,7 @@ def _generate_sample_ep(multi=None, abd=False, sports=False):
ep._release_name = 'Show.Name.2011.03.09.HDTV.XviD-RLSGROUP'
ep.show.air_by_date = 1
elif sports:
ep._release_name = 'Show.Name.09.Mar.2011.HDTV.XviD-RLSGROUP'
ep._release_name = 'Show.Name.100.Fighter.vs.Fighter.HDTV.XviD-RLSGROUP'
ep.show.sports = 1
else:
ep._release_name = 'Show.Name.S02E03.HDTV.XviD-RLSGROUP'

View File

@ -457,16 +457,13 @@ class PostProcessor(object):
# parse the name to break it into show name, season, and episode
np = NameParser(file)
parse_result = np.parse(name)
parse_result = np.parse(name).convert()
self._log("Parsed " + name + " into " + str(parse_result).decode('utf-8'), logger.DEBUG)
if parse_result.air_by_date:
season = -1
episodes = [parse_result.air_date]
elif parse_result.sports:
season = -1
episodes = [parse_result.sports_date]
else:
season = parse_result.season_number
episodes = parse_result.episode_numbers
@ -698,7 +695,7 @@ class PostProcessor(object):
# now that we've figured out which episode this file is just load it manually
try:
# convert scene numbered release and load episode from database
curEp = show_obj.getEpisode(season, cur_episode, sceneConvert=True)
curEp = show_obj.getEpisode(season, cur_episode)
except exceptions.EpisodeNotFoundException, e:
self._log(u"Unable to create episode: " + ex(e), logger.DEBUG)
raise exceptions.PostProcessingFailed()

View File

@ -100,7 +100,7 @@ class ProperFinder():
# parse the file name
try:
myParser = NameParser(False)
parse_result = myParser.parse(curProper.name)
parse_result = myParser.parse(curProper.name).convert()
except InvalidNameException:
logger.log(u"Unable to parse the filename " + curProper.name + " into a valid episode", logger.DEBUG)
continue
@ -115,9 +115,6 @@ class ProperFinder():
if parse_result.air_by_date:
curProper.season = -1
curProper.episode = parse_result.air_date
elif parse_result.sports:
curProper.season = -1
curProper.episode = parse_result.sports_date
else:
curProper.season = parse_result.season_number if parse_result.season_number != None else 1
curProper.episode = parse_result.episode_numbers[0]
@ -200,7 +197,7 @@ class ProperFinder():
continue
else:
# items stored in cache are scene numbered, convert before lookups
epObj = showObj.getEpisode(curProper.season, curProper.episode, sceneConvert=True)
epObj = showObj.getEpisode(curProper.season, curProper.episode)
curProper.season = epObj.season
curProper.episode = epObj.episode

View File

@ -61,7 +61,7 @@ class EZRSSProvider(generic.TorrentProvider):
results = {}
if self.show.air_by_date or show.sports:
if self.show.air_by_date or self.show.sports:
logger.log(self.name + u" doesn't support air-by-date or sports backloging because of limitations on their RSS search.",
logger.WARNING)
return results

View File

@ -257,18 +257,14 @@ class GenericProvider:
regexMode = 2
for ep_obj in ep_objs:
if show.sports:
logger.log(
u'Searching "%s" for "%s" as "%s"' % (self.name, ep_obj.prettyName(), ep_obj.sports_prettyName()))
else:
logger.log(u'Searching "%s" for "%s" as "%s"' % (self.name, ep_obj.prettyName(), ep_obj.scene_prettyName()))
logger.log(u'Searching "%s" for "%s" as "%s"' % (self.name, ep_obj.prettyName(), ep_obj.scene_prettyName()))
if seasonSearch:
for curString in self._get_season_search_strings(ep_obj.scene_season, ep_obj.airdate if show.air_by_date or show.sports else ep_obj.scene_episode):
itemList += self._doSearch(curString, show=show)
for curString in self._get_season_search_strings(ep_obj.scene_season, ep_obj.airdate if show.air_by_date else ep_obj.scene_episode):
itemList += self._doSearch(curString)
else:
for curString in self._get_episode_search_strings(ep_obj.scene_season, ep_obj.airdate if show.air_by_date or show.sports else ep_obj.scene_episode):
itemList += self._doSearch(curString, show=show)
for curString in self._get_episode_search_strings(ep_obj.scene_season, ep_obj.airdate if show.air_by_date else ep_obj.scene_episode):
itemList += self._doSearch(curString)
for item in itemList:
@ -279,12 +275,12 @@ class GenericProvider:
# parse the file name
try:
myParser = NameParser(False, regexMode=regexMode)
parse_result = myParser.parse(title)
parse_result = myParser.parse(title).convert()
except InvalidNameException:
logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING)
continue
if not show.air_by_date and not show.sports:
if not show.air_by_date:
# this check is meaningless for non-season searches
if (parse_result.season_number != None and parse_result.season_number != season) or (
parse_result.season_number == None and season != 1):
@ -303,19 +299,10 @@ class GenericProvider:
logger.DEBUG)
continue
if show.sports and not parse_result.sports:
logger.log(
u"This is supposed to be an sports search but the result " + title + " didn't parse as one, skipping it",
logger.DEBUG)
continue
myDB = db.DBConnection()
if parse_result.air_by_date:
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
[show.indexerid, parse_result.air_date.toordinal()])
elif parse_result.sports:
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
[show.indexerid, parse_result.sports_date.toordinal()])
if len(sql_results) != 1:
logger.log(

View File

@ -309,7 +309,7 @@ class HDTorrentsProvider(generic.TorrentProvider):
self.show = self.show = curshow = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"]))
curEp = curshow.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"]))
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date or curshow.sports else curEp.scene_episode, add_string='PROPER|REPACK')
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date else curEp.scene_episode, add_string='PROPER|REPACK')
for item in self._doSearch(searchString[0], show=curshow):
title, url = self._get_title_and_url(item)

View File

@ -257,7 +257,9 @@ class IPTorrentsProvider(generic.TorrentProvider):
for sqlshow in sqlResults:
self.show = curshow = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"]))
curEp = curshow.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"]))
searchString = self._get_episode_search_strings(curshow, curEp.scene_season, curEp.scene_episode, curshow.air_by_date or curshow.sports, add_string='PROPER|REPACK')
searchString = self._get_episode_search_strings(curEp.scene_season,
curEp.airdate if curshow.air_by_date else curEp.scene_episode,
add_string='PROPER|REPACK')
for item in self._doSearch(searchString[0], show=curshow):
title, url = self._get_title_and_url(item)

View File

@ -383,7 +383,7 @@ class KATProvider(generic.TorrentProvider):
self.show = curshow = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"]))
curEp = curshow.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"]))
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date or curshow.sports else curEp.scene_episode, add_string='PROPER|REPACK')
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date else curEp.scene_episode, add_string='PROPER|REPACK')
for item in self._doSearch(searchString[0], show=curshow):
title, url = self._get_title_and_url(item)

View File

@ -118,11 +118,9 @@ class NewznabProvider(generic.NZBProvider):
params['season'] = date_str.partition('-')[0]
params['ep'] = date_str.partition('-')[2].replace('-', '/')
elif self.show.sports:
date_str = str(episode)
params['season'] = date_str.partition('-')[0]
params['ep'] = date_str.partition('-')[2].replace('-', '/')
# elif self.show.sports:
# params['season']
# params['ep']
else:
params['season'] = season
params['ep'] = episode

View File

@ -305,7 +305,7 @@ class NextGenProvider(generic.TorrentProvider):
for sqlshow in sqlResults:
self.show = curshow = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"]))
curEp = curshow.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"]))
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date or curshow.sports else curEp.scene_episode, add_string='PROPER|REPACK')
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date else curEp.scene_episode, add_string='PROPER|REPACK')
for item in self._doSearch(searchString[0], show=curshow):
title, url = self._get_title_and_url(item)

View File

@ -278,12 +278,7 @@ class PublicHDProvider(generic.TorrentProvider):
self.show = curshow = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"]))
curEp = curshow.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"]))
season = curEp.scene_season
episode = curEp.scene_episode
if curshow.air_by_date or curshow.sports:
episode = curEp.airdate
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date or curshow.sports else curEp.scene_episode, add_string='PROPER|REPACK')
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date else curEp.scene_episode, add_string='PROPER|REPACK')
for item in self._doSearch(searchString[0], show=curshow):
title, url = self._get_title_and_url(item)

View File

@ -283,12 +283,7 @@ class SCCProvider(generic.TorrentProvider):
self.show = curshow = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"]))
curEp = curshow.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"]))
season = curEp.scene_season
episode = curEp.scene_episode
if curshow.air_by_date or curshow.sports:
episode = curEp.airdate
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date or curshow.sports else curEp.scene_episode, add_string='PROPER|REPACK')
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date else curEp.scene_episode, add_string='PROPER|REPACK')
for item in self._doSearch(searchString[0], show=curshow):
title, url = self._get_title_and_url(item)

View File

@ -236,12 +236,7 @@ class SpeedCDProvider(generic.TorrentProvider):
self.show = curshow = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"]))
curEp = curshow.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"]))
season = curEp.scene_season
episode = curEp.scene_episode
if curshow.air_by_date or curshow.sports:
episode = curEp.airdate
searchString = self._get_episode_search_strings(curshow, season, episode,add_string='PROPER|REPACK')
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date else curEp.scene_episode, add_string='PROPER|REPACK')
for item in self._doSearch(searchString[0], show=curshow):
title, url = self._get_title_and_url(item)

View File

@ -376,7 +376,7 @@ class ThePirateBayProvider(generic.TorrentProvider):
self.show = curshow = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"]))
curEp = curshow.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"]))
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date or curshow.sports else curEp.scene_episode, add_string='PROPER|REPACK')
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date else curEp.scene_episode, add_string='PROPER|REPACK')
for item in self._doSearch(searchString[0], show=curshow):
title, url = self._get_title_and_url(item)

View File

@ -255,12 +255,7 @@ class TorrentDayProvider(generic.TorrentProvider):
self.show = curshow = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"]))
curEp = curshow.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"]))
season = curEp.scene_season
episode = curEp.scene_episode
if curshow.air_by_date or curshow.sports:
episode = curEp.airdate
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date or curshow.sports else curEp.scene_episode, add_string='PROPER|REPACK')
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date else curEp.scene_episode, add_string='PROPER|REPACK')
for item in self._doSearch(searchString[0], show=curshow):
title, url = self._get_title_and_url(item)

View File

@ -256,7 +256,7 @@ class TorrentLeechProvider(generic.TorrentProvider):
self.show = curshow = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"]))
curEp = curshow.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"]))
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date or curshow.sports else curEp.scene_episode, add_string='PROPER|REPACK')
searchString = self._get_episode_search_strings(curEp.scene_season, curEp.airdate if curshow.air_by_date else curEp.scene_episode, add_string='PROPER|REPACK')
for item in self._doSearch(searchString[0], show=curshow):
title, url = self._get_title_and_url(item)

View File

@ -378,7 +378,9 @@ def searchProviders(show, season, episode=None, manualSearch=False):
# search cache first for wanted episodes
for ep_obj in wantedEps:
curResults.update(curProvider.cache.searchCache(ep_obj, manualSearch))
results = curProvider.cache.searchCache(ep_obj, manualSearch)
if results:
curResults.update(results)
# did we find our results ?
if curResults:

View File

@ -192,7 +192,7 @@ class BacklogQueueItem(generic_queue.QueueItem):
myDB = db.DBConnection()
# see if there is anything in this season worth searching for
if not self.show.air_by_date and not self.show.sports:
if not self.show.air_by_date:
statusResults = myDB.select("SELECT status FROM tv_episodes WHERE showid = ? AND season = ?",
[self.show.indexerid, self.segment])
else:

View File

@ -182,24 +182,7 @@ class TVShow(object):
return ep_list
def getEpisode(self, season, episode, file=None, noCreate=False, sceneConvert=False):
#return TVEpisode(self, season, episode)
if sceneConvert:
for curSeason in self.episodes:
for curEp in self.episodes[curSeason]:
myEp = self.episodes[curSeason][curEp]
try:
scene_season = myEp.scene_season
scene_episode = myEp.scene_episode
except:continue
if season != scene_season or episode != scene_episode:
continue
# found correct ep info
season = int(myEp.season)
episode = int(myEp.episode)
def getEpisode(self, season, episode, file=None, noCreate=False):
if not season in self.episodes:
self.episodes[season] = {}
@ -594,8 +577,6 @@ class TVShow(object):
epObj = None
if parse_result.air_by_date:
epObj = t[self.indexerid].airedOn(parse_result.air_date)[0]
elif parse_result.sports:
epObj = t[self.indexerid].airedOn(parse_result.sports_date)[0]
season = int(epObj["seasonnumber"])
episodes = [int(epObj["episodenumber"])]
@ -1910,70 +1891,37 @@ class TVEpisode(object):
else:
show_name = self.show.name
if self.show.sports:
return {
'%SN': show_name,
'%S.N': dot(show_name),
'%S_N': us(show_name),
'%EN': ep_name,
'%E.N': dot(ep_name),
'%E_N': us(ep_name),
'%QN': Quality.qualityStrings[epQual],
'%Q.N': dot(Quality.qualityStrings[epQual]),
'%Q_N': us(Quality.qualityStrings[epQual]),
'%S': str(self.season),
'%0S': '%02d' % self.season,
'%E': str(self.episode),
'%0E': '%02d' % self.episode,
'%XMS': str(self.scene_season),
'%0XMS': '%02d' % self.scene_season,
'%XME': str(self.scene_episode),
'%0XME': '%02d' % self.scene_episode,
'%RN': release_name(self.release_name),
'%RG': release_group(self.release_name),
'%AD': self.airdate.strftime('%d %b %Y'),
'%A.D': self.airdate.strftime('%d.%b.%Y'),
'%A_D': us(self.airdate.strftime('%d-%b-%Y')),
'%A-D': self.airdate.strftime('%d-%b-%Y'),
'%Y': str(self.airdate.year),
'%M': self.airdate.strftime('%b'),
'%D': str(self.airdate.day),
'%0M': '%02d' % self.airdate.month,
'%0D': '%02d' % self.airdate.day,
'%RT': "PROPER" if self.is_proper else "",
}
else:
return {
'%SN': show_name,
'%S.N': dot(show_name),
'%S_N': us(show_name),
'%EN': ep_name,
'%E.N': dot(ep_name),
'%E_N': us(ep_name),
'%QN': Quality.qualityStrings[epQual],
'%Q.N': dot(Quality.qualityStrings[epQual]),
'%Q_N': us(Quality.qualityStrings[epQual]),
'%S': str(self.season),
'%0S': '%02d' % self.season,
'%E': str(self.episode),
'%0E': '%02d' % self.episode,
'%XMS': str(self.scene_season),
'%0XMS': '%02d' % self.scene_season,
'%XME': str(self.scene_episode),
'%0XME': '%02d' % self.scene_episode,
'%RN': release_name(self.release_name),
'%RG': release_group(self.release_name),
'%AD': str(self.airdate).replace('-', ' '),
'%A.D': str(self.airdate).replace('-', '.'),
'%A_D': us(str(self.airdate)),
'%A-D': str(self.airdate),
'%Y': str(self.airdate.year),
'%M': str(self.airdate.month),
'%D': str(self.airdate.day),
'%0M': '%02d' % self.airdate.month,
'%0D': '%02d' % self.airdate.day,
'%RT': "PROPER" if self.is_proper else "",
}
return {
'%SN': show_name,
'%S.N': dot(show_name),
'%S_N': us(show_name),
'%EN': ep_name,
'%E.N': dot(ep_name),
'%E_N': us(ep_name),
'%QN': Quality.qualityStrings[epQual],
'%Q.N': dot(Quality.qualityStrings[epQual]),
'%Q_N': us(Quality.qualityStrings[epQual]),
'%S': str(self.season),
'%0S': '%02d' % self.season,
'%E': str(self.episode),
'%0E': '%02d' % self.episode,
'%XMS': str(self.scene_season),
'%0XMS': '%02d' % self.scene_season,
'%XME': str(self.scene_episode),
'%0XME': '%02d' % self.scene_episode,
'%RN': release_name(self.release_name),
'%RG': release_group(self.release_name),
'%AD': str(self.airdate).replace('-', ' '),
'%A.D': str(self.airdate).replace('-', '.'),
'%A_D': us(str(self.airdate)),
'%A-D': str(self.airdate),
'%Y': str(self.airdate.year),
'%M': str(self.airdate.month),
'%D': str(self.airdate.day),
'%0M': '%02d' % self.airdate.month,
'%0D': '%02d' % self.airdate.day,
'%RT': "PROPER" if self.is_proper else "",
}
def _format_string(self, pattern, replace_map):
"""

View File

@ -194,14 +194,16 @@ class TVCache():
cacheDB = self._getDB()
parse_result = None
from_cache = False
indexer_id = None
season = None
episodes = None
from_cache = False
# if we don't have complete info then parse the filename to get it
while(True):
try:
myParser = NameParser()
parse_result = myParser.parse(name)
parse_result = myParser.parse(name).convert()
except InvalidNameException:
logger.log(u"Unable to parse the filename " + name + " into a valid episode", logger.DEBUG)
return None
@ -239,64 +241,39 @@ class TVCache():
break
# if we didn't find a Indexer ID return None
if not indexer_id:
return None
if indexer_id:
# if the show isn't in out database then return None
try:
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
myDB = db.DBConnection()
if parse_result.air_by_date:
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
[showObj.indexerid, parse_result.air_date.toordinal()])
if sql_results > 0:
season = int(sql_results[0]["season"])
episodes = [int(sql_results[0]["episode"])]
else:
season = parse_result.season_number
episodes = parse_result.episode_numbers
# if the show isn't in out database then return None
try:showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
except:return None
if season and episodes:
# store episodes as a seperated string
episodeText = "|" + "|".join(map(str, episodes)) + "|"
if not showObj:
return None
# get the current timestamp
curTimestamp = int(time.mktime(datetime.datetime.today().timetuple()))
# if we weren't provided with season/episode information then get it from the name that we parsed
season = None
episodes = None
myDB = db.DBConnection()
if parse_result.air_by_date:
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
[showObj.indexerid, parse_result.air_date.toordinal()])
if sql_results > 0:
season = int(sql_results[0]["season"])
episodes = [int(sql_results[0]["episode"])]
elif parse_result.sports:
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
[showObj.indexerid, parse_result.sports_date.toordinal()])
if sql_results > 0:
season = int(sql_results[0]["season"])
episodes = [int(sql_results[0]["episode"])]
else:
season = parse_result.season_number
episodes = parse_result.episode_numbers
# get quality of release
quality = Quality.sceneQuality(name)
if not (season and episodes):
return None
# convert scene numbered releases before storing to cache
convertedEps = {}
for curEp in episodes:
epObj = showObj.getEpisode(season, curEp, sceneConvert=True)
if not epObj:
return None
if not epObj.season in convertedEps:
convertedEps[epObj.season] = []
convertedEps[epObj.season].append(epObj.episode)
# get the current timestamp
curTimestamp = int(time.mktime(datetime.datetime.today().timetuple()))
# get quality of release
quality = Quality.sceneQuality(name)
if not isinstance(name, unicode):
name = unicode(name, 'utf-8')
for season, episodes in convertedEps.items():
episodeText = "|" + "|".join(map(str, episodes)) + "|"
cacheDB.action(
"INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)",
[name, season, episodeText, indexer_id, url, curTimestamp, quality])
if not isinstance(name, unicode):
name = unicode(name, 'utf-8')
cacheDB.action(
"INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)",
[name, season, episodeText, indexer_id, url, curTimestamp, quality])
except:
return
def searchCache(self, episode, manualSearch=False):
neededEps = self.findNeededEpisodes(episode, manualSearch)

View File

@ -48,49 +48,22 @@ class XEMBasicTests(test.SickbeardTestDBCase):
except Exception, e:
print "There was an error creating the show"
def test_formating(self):
def test_parsing_scene_release(self):
self.loadFromDB()
show = sickbeard.helpers.findCertainShow(sickbeard.showList, 111051)
show.loadEpisodesFromDB()
ep = show.getEpisode(8, 56, sceneConvert=True)
ep.airdate = datetime.date.today()
# parse the file name
pattern = u'%SN - %A-D - %EN'
title = 'UFC.166.Velasquez.v.Dos Santos.III.19th.Oct.2013.HDTV.x264-Sir.Paul'
scene_parsse_results1 = ''
scene_parsse_results2 = ''
scene_release = 'Pawn Stars S08E41 Field Trip HDTV x264-tNe'
try:
myParser = NameParser(False, 1)
parse_result = myParser.parse(title)
scene_parsse_results1 = myParser.parse(scene_release)
scene_parsse_results2 = myParser.parse(scene_release).convert()
except InvalidNameException:
print(u"Unable to parse the filename " + ep.name + " into a valid episode")
print(u"Unable to parse the filename " + scene_release + " into a valid episode")
print parse_result
search_string = {'Episode':[]}
episode = ep.airdate
str(episode).replace('-', '|')
ep_string = sanitizeSceneName(show.name) + ' ' + \
str(episode).replace('-', '|') + '|' + \
episode.strftime('%b')
search_string['Episode'].append(ep_string)
scene_ep_string = sanitizeSceneName(show.name) + ' ' + \
sickbeard.config.naming_ep_type[2] % {'seasonnumber': ep.scene_season,
'episodenumber': ep.scene_episode} + '|' + \
sickbeard.config.naming_ep_type[0] % {'seasonnumber': ep.scene_season,
'episodenumber': ep.scene_episode} + '|' + \
sickbeard.config.naming_ep_type[3] % {'seasonnumber': ep.scene_season,
'episodenumber': ep.scene_episode} + ' %s category:tv' % ''
scene_season_string = show.name + ' S%02d' % int(ep.scene_season) + ' -S%02d' % int(ep.scene_season) + 'E' + ' category:tv' #1) ShowName SXX -SXXE
print(
u'Searching "%s" for "%s" as "%s"' % (show.name, ep.prettyName(), ep.scene_prettyName()))
print('Scene episode search strings: %s' % (scene_ep_string))
print('Scene season search strings: %s' % (scene_season_string))
print scene_parsse_results1
print scene_parsse_results2
if __name__ == "__main__":
print "=================="