mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-05 17:43:37 +00:00
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:
parent
d14581b8cc
commit
319ac2602f
24 changed files with 176 additions and 293 deletions
|
@ -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>
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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>[^- ]+))?)?$
|
||||
'''
|
||||
),
|
||||
]
|
|
@ -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'
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
116
sickbeard/tv.py
116
sickbeard/tv.py
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 "=================="
|
||||
|
|
Loading…
Reference in a new issue