mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-05 17:43:37 +00:00
Change reduce aggressive use of scene numbering that was overriding user preference where not needed.
Change set "Scene numbering" checkbox and add text to the label tip in third step of add "New Show" if scene numbers are found for the selected show in the search results of the first step. Change label text on edit show page to highlight when manual numbering and scene numbers are available. Fix disabling "Scene numbering" of step three in add "New Show" was ignored when scene episode number mappings exist. Fix don't use scene episode number mappings everywhere when "Scene numbering" is disabled for a show. Fix width of legend underlining on the third step used to bring other display elements into alignment. Change when downloading magnet or nzb files, verify the file in cache dir and then move to blackhole. Change to consistent use of properties is_anime and is_sports in providers. Change name_parser pep8 and code conventions.
This commit is contained in:
parent
8b42315bde
commit
7b3f4356c7
19 changed files with 222 additions and 205 deletions
|
@ -1,6 +1,14 @@
|
|||
### 0.11.0 (2015-xx-xx xx:xx:xx UTC)
|
||||
|
||||
* Change to only refresh scene exception data for shows that need it
|
||||
* Change reduce aggressive use of scene numbering that was overriding user preference where not needed
|
||||
* Change set "Scene numbering" checkbox and add text to the label tip in third step of add "New Show" if scene numbers
|
||||
are found for the selected show in the search results of the first step
|
||||
* Change label text on edit show page to highlight when manual numbering and scene numbers are available
|
||||
* Fix disabling "Scene numbering" of step three in add "New Show" was ignored when scene episode number mappings exist
|
||||
* Fix don't use scene episode number mappings everywhere when "Scene numbering" is disabled for a show
|
||||
* Fix width of legend underlining on the third step used to bring other display elements into alignment
|
||||
* Change when downloading magnet or nzb files, verify the file in cache dir and then move to blackhole
|
||||
* Fix small cosmetic issue to correctly display "full backlog" date
|
||||
* Add search crawler exclusions
|
||||
* Fix saving default show list group on add new show options page
|
||||
|
|
|
@ -921,7 +921,7 @@ home_newShow.tmpl
|
|||
#newShowPortal,
|
||||
fieldset.sectionwrap,
|
||||
div.formpaginate{
|
||||
width:801px
|
||||
width:831px
|
||||
}
|
||||
|
||||
#addShowForm{
|
||||
|
@ -1666,6 +1666,10 @@ td.col-search{
|
|||
padding:15px 0 0
|
||||
}
|
||||
|
||||
#addShowForm #editShow.stepDiv span.component-desc{
|
||||
width:639px
|
||||
}
|
||||
|
||||
/* =======================================================================
|
||||
episodeView.tmpl
|
||||
========================================================================== */
|
||||
|
@ -3486,7 +3490,7 @@ div.stepsguide{
|
|||
|
||||
div.stepsguide .step{
|
||||
float:left;
|
||||
width:267px;
|
||||
width:277px;
|
||||
font:bold 24px Arial
|
||||
}
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@
|
|||
<span class="component-title">Scene numbering</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="scene" id="scene"#if $show.scene == 1 then $html_checked else ''#>
|
||||
<p>search for episodes that are numbered by scene groups instead of by the TV network</p>
|
||||
<p>search for episodes numbered by scene groups instead of by the TV network <em class="grey-text">(#if $show_has_scene_map then 'scene/manual numbers' else 'manual numbers only '# available)</em></p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#import os.path
|
||||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl')
|
||||
|
||||
<script>
|
||||
var show_scene_maps = ${show_scene_maps}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="$sbRoot/js/formwizard.js?$sbPID"></script>
|
||||
<script type="text/javascript" src="$sbRoot/js/qualityChooser.js?$sbPID"></script>
|
||||
<script type="text/javascript" src="$sbRoot/js/newShow.js?$sbPID"></script>
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
<span class="component-title">Scene numbering</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="scene" id="scene" #if $sickbeard.SCENE_DEFAULT then "checked=\"checked\"" else ""# />
|
||||
<p>search for episodes that are numbered by scene groups instead of by the TV network</p>
|
||||
<p>search for episodes numbered by scene groups instead of by the TV network<span id="scene-maps-found" style="display:none" class="grey-text"> (scene numbers found)</span></p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
$('#SubMenu a:contains("Backlog Overview")').addClass('btn').html('<i class="sgicon-backlog"></i>Backlog Overview');
|
||||
$('#SubMenu a[href$="/home/updatePLEX/"]').addClass('btn').html('<i class="sgicon-plex"></i>Update PLEX');
|
||||
$('#SubMenu a:contains("Force")').addClass('btn').html('<i class="sgicon-fullupdate"></i>Force Full Update');
|
||||
$('#SubMenu a:contains("Rename")').addClass('btn').html('<i class="sgicon-rename"></i>Preview Rename');
|
||||
$('#SubMenu a:contains("Rename")').addClass('btn').html('<i class="sgicon-rename"></i>Media Renamer');
|
||||
$('#SubMenu a[href$="/config/subtitles/"]').addClass('btn').html('<i class="sgicon-subtitles"></i>Search Subtitles');
|
||||
$('#SubMenu a[href*="/home/subtitleShow"]').addClass('btn').html('<i class="sgicon-subtitles"></i>Download Subtitles');
|
||||
$('#SubMenu a:contains("Anime")').addClass('btn').html('<i class="sgicon-anime"></i>Anime');
|
||||
|
|
|
@ -189,22 +189,23 @@ $(document).ready(function () {
|
|||
function updateSampleText() {
|
||||
// if something's selected then we have some behavior to figure out
|
||||
|
||||
var show_name,
|
||||
var show_name = '',
|
||||
sep_char,
|
||||
elRadio = $('input:radio[name="whichSeries"]:checked'),
|
||||
elInput = $('input:hidden[name="whichSeries"]'),
|
||||
elScene = $('#scene'),
|
||||
elRootDirs = $('#rootDirs'),
|
||||
elFullShowPath = $('#fullShowPath');
|
||||
|
||||
// if they've picked a radio button then use that
|
||||
if (elRadio.length) {
|
||||
show_name = elRadio.val().split('|')[4];
|
||||
elScene[0].checked = 0 <= show_scene_maps.indexOf(parseInt(elRadio.val().split('|')[3], 10));
|
||||
$('#scene-maps-found').css('display', elScene.is(':checked') ? 'inline' : 'None');
|
||||
}
|
||||
// if we provided a show in the hidden field, use that
|
||||
else if (elInput.length && elInput.val().length) {
|
||||
show_name = $('#providedName').val();
|
||||
} else {
|
||||
show_name = '';
|
||||
}
|
||||
update_bwlist(show_name);
|
||||
var sample_text = '<p>Adding show <span class="show-name">' + cleanseText(show_name, !0) + '</span>'
|
||||
|
|
|
@ -27,7 +27,6 @@ import regexes
|
|||
import sickbeard
|
||||
|
||||
from sickbeard import logger, helpers, scene_numbering, common, scene_exceptions, encodingKludge as ek, db
|
||||
from dateutil import parser
|
||||
from sickbeard.exceptions import ex
|
||||
from sickbeard.common import cpu_presets
|
||||
|
||||
|
@ -55,39 +54,40 @@ class NameParser(object):
|
|||
else:
|
||||
self._compile_regexes(self.ALL_REGEX)
|
||||
|
||||
def clean_series_name(self, series_name):
|
||||
@staticmethod
|
||||
def clean_series_name(series_name):
|
||||
"""Cleans up series name by removing any . and _
|
||||
characters, along with any trailing hyphens.
|
||||
|
||||
Is basically equivalent to replacing all _ and . with a
|
||||
space, but handles decimal numbers in string, for example:
|
||||
|
||||
>>> cleanRegexedSeriesName("an.example.1.0.test")
|
||||
>>> clean_series_name('an.example.1.0.test')
|
||||
'an example 1.0 test'
|
||||
>>> cleanRegexedSeriesName("an_example_1.0_test")
|
||||
>>> clean_series_name('an_example_1.0_test')
|
||||
'an example 1.0 test'
|
||||
|
||||
Stolen from dbr's tvnamer
|
||||
"""
|
||||
|
||||
series_name = re.sub("(\D)\.(?!\s)(\D)", "\\1 \\2", series_name)
|
||||
series_name = re.sub("(\d)\.(\d{4})", "\\1 \\2", series_name) # if it ends in a year then don't keep the dot
|
||||
series_name = re.sub("(\D)\.(?!\s)", "\\1 ", series_name)
|
||||
series_name = re.sub("\.(?!\s)(\D)", " \\1", series_name)
|
||||
series_name = series_name.replace("_", " ")
|
||||
series_name = re.sub("-$", "", series_name)
|
||||
series_name = re.sub("^\[.*\]", "", series_name)
|
||||
series_name = re.sub('(\D)\.(?!\s)(\D)', '\\1 \\2', series_name)
|
||||
series_name = re.sub('(\d)\.(\d{4})', '\\1 \\2', series_name) # if it ends in a year then don't keep the dot
|
||||
series_name = re.sub('(\D)\.(?!\s)', '\\1 ', series_name)
|
||||
series_name = re.sub('\.(?!\s)(\D)', ' \\1', series_name)
|
||||
series_name = series_name.replace('_', ' ')
|
||||
series_name = re.sub('-$', '', series_name)
|
||||
series_name = re.sub('^\[.*\]', '', series_name)
|
||||
return series_name.strip()
|
||||
|
||||
def _compile_regexes(self, regexMode):
|
||||
if regexMode == self.ANIME_REGEX:
|
||||
logger.log(u"Using ANIME regexs", logger.DEBUG)
|
||||
if self.ANIME_REGEX == regexMode:
|
||||
logger.log(u'Using ANIME regexs', logger.DEBUG)
|
||||
uncompiled_regex = [regexes.anime_regexes]
|
||||
elif regexMode == self.NORMAL_REGEX:
|
||||
logger.log(u"Using NORMAL regexs", logger.DEBUG)
|
||||
elif self.NORMAL_REGEX == regexMode:
|
||||
logger.log(u'Using NORMAL regexs', logger.DEBUG)
|
||||
uncompiled_regex = [regexes.normal_regexes]
|
||||
else:
|
||||
logger.log(u"Using ALL regexes", logger.DEBUG)
|
||||
logger.log(u'Using ALL regexes', logger.DEBUG)
|
||||
uncompiled_regex = [regexes.normal_regexes, regexes.anime_regexes]
|
||||
|
||||
self.compiled_regexes = {0: [], 1: []}
|
||||
|
@ -97,7 +97,7 @@ class NameParser(object):
|
|||
try:
|
||||
cur_regex = re.compile(cur_pattern, re.VERBOSE | re.IGNORECASE)
|
||||
except re.error as errormsg:
|
||||
logger.log(u"WARNING: Invalid episode_pattern, %s. %s" % (errormsg, cur_pattern))
|
||||
logger.log(u'WARNING: Invalid episode_pattern, %s. %s' % (errormsg, cur_pattern))
|
||||
else:
|
||||
self.compiled_regexes[index].append([cur_pattern_num, cur_pattern_name, cur_regex])
|
||||
index += 1
|
||||
|
@ -107,7 +107,7 @@ class NameParser(object):
|
|||
return
|
||||
|
||||
matches = []
|
||||
bestResult = None
|
||||
|
||||
for regex in self.compiled_regexes:
|
||||
for (cur_regex_num, cur_regex_name, cur_regex) in self.compiled_regexes[regex]:
|
||||
match = cur_regex.match(name)
|
||||
|
@ -132,7 +132,7 @@ class NameParser(object):
|
|||
|
||||
if 'season_num' in named_groups:
|
||||
tmp_season = int(match.group('season_num'))
|
||||
if cur_regex_name == 'bare' and tmp_season in (19, 20):
|
||||
if 'bare' == cur_regex_name and tmp_season in (19, 20):
|
||||
continue
|
||||
result.season_number = tmp_season
|
||||
result.score += 1
|
||||
|
@ -161,7 +161,7 @@ class NameParser(object):
|
|||
month = int(match.group('air_month'))
|
||||
day = int(match.group('air_day'))
|
||||
# make an attempt to detect YYYY-DD-MM formats
|
||||
if month > 12:
|
||||
if 12 < month:
|
||||
tmp_month = month
|
||||
month = day
|
||||
day = tmp_month
|
||||
|
@ -174,7 +174,7 @@ class NameParser(object):
|
|||
tmp_extra_info = match.group('extra_info')
|
||||
|
||||
# Show.S04.Special or Show.S05.Part.2.Extras is almost certainly not every episode in the season
|
||||
if tmp_extra_info and cur_regex_name == 'season_only' and re.search(
|
||||
if tmp_extra_info and 'season_only' == cur_regex_name and re.search(
|
||||
r'([. _-]|^)(special|extra)s?\w*([. _-]|$)', tmp_extra_info, re.I):
|
||||
continue
|
||||
result.extra_info = tmp_extra_info
|
||||
|
@ -198,42 +198,42 @@ class NameParser(object):
|
|||
|
||||
if len(matches):
|
||||
# pick best match with highest score based on placement
|
||||
bestResult = max(sorted(matches, reverse=True, key=lambda x: x.which_regex), key=lambda x: x.score)
|
||||
best_result = max(sorted(matches, reverse=True, key=lambda x: x.which_regex), key=lambda x: x.score)
|
||||
|
||||
show = None
|
||||
if not self.naming_pattern:
|
||||
# try and create a show object for this result
|
||||
show = helpers.get_show(bestResult.series_name, self.try_indexers, self.try_scene_exceptions)
|
||||
show = helpers.get_show(best_result.series_name, self.try_indexers, self.try_scene_exceptions)
|
||||
|
||||
# confirm passed in show object indexer id matches result show object indexer id
|
||||
if show and not self.testing:
|
||||
if self.showObj and show.indexerid != self.showObj.indexerid:
|
||||
show = None
|
||||
bestResult.show = show
|
||||
elif not show and self.showObj:
|
||||
bestResult.show = self.showObj
|
||||
show = self.showObj
|
||||
best_result.show = show
|
||||
|
||||
if bestResult.show and bestResult.show.is_anime and len(self.compiled_regexes[1]) > 1 and regex != 1:
|
||||
if show and show.is_anime and 1 < len(self.compiled_regexes[1]) and 1 != regex:
|
||||
continue
|
||||
|
||||
# if this is a naming pattern test then return best result
|
||||
if not bestResult.show or self.naming_pattern:
|
||||
return bestResult
|
||||
if not show or self.naming_pattern:
|
||||
return best_result
|
||||
|
||||
# get quality
|
||||
bestResult.quality = common.Quality.nameQuality(name, bestResult.show.is_anime)
|
||||
best_result.quality = common.Quality.nameQuality(name, show.is_anime)
|
||||
|
||||
new_episode_numbers = []
|
||||
new_season_numbers = []
|
||||
new_absolute_numbers = []
|
||||
|
||||
# if we have an air-by-date show then get the real season/episode numbers
|
||||
if bestResult.is_air_by_date:
|
||||
airdate = bestResult.air_date.toordinal()
|
||||
myDB = db.DBConnection()
|
||||
sql_result = myDB.select(
|
||||
"SELECT season, episode FROM tv_episodes WHERE showid = ? and indexer = ? and airdate = ?",
|
||||
[bestResult.show.indexerid, bestResult.show.indexer, airdate])
|
||||
if best_result.is_air_by_date:
|
||||
airdate = best_result.air_date.toordinal()
|
||||
my_db = db.DBConnection()
|
||||
sql_result = my_db.select(
|
||||
'SELECT season, episode FROM tv_episodes WHERE showid = ? and indexer = ? and airdate = ?',
|
||||
[show.indexerid, show.indexer, airdate])
|
||||
|
||||
season_number = None
|
||||
episode_numbers = []
|
||||
|
@ -244,64 +244,64 @@ class NameParser(object):
|
|||
|
||||
if not season_number or not len(episode_numbers):
|
||||
try:
|
||||
lINDEXER_API_PARMS = sickbeard.indexerApi(bestResult.show.indexer).api_params.copy()
|
||||
lindexer_api_parms = sickbeard.indexerApi(show.indexer).api_params.copy()
|
||||
|
||||
if bestResult.show.lang:
|
||||
lINDEXER_API_PARMS['language'] = bestResult.show.lang
|
||||
if show.lang:
|
||||
lindexer_api_parms['language'] = show.lang
|
||||
|
||||
t = sickbeard.indexerApi(bestResult.show.indexer).indexer(**lINDEXER_API_PARMS)
|
||||
t = sickbeard.indexerApi(show.indexer).indexer(**lindexer_api_parms)
|
||||
|
||||
epObj = t[bestResult.show.indexerid].airedOn(bestResult.air_date)[0]
|
||||
ep_obj = t[show.indexerid].airedOn(best_result.air_date)[0]
|
||||
|
||||
season_number = int(epObj["seasonnumber"])
|
||||
episode_numbers = [int(epObj["episodenumber"])]
|
||||
season_number = int(ep_obj['seasonnumber'])
|
||||
episode_numbers = [int(ep_obj['episodenumber'])]
|
||||
except sickbeard.indexer_episodenotfound:
|
||||
logger.log(u"Unable to find episode with date " + str(bestResult.air_date) + " for show " + bestResult.show.name + ", skipping", logger.WARNING)
|
||||
logger.log(u'Unable to find episode with date ' + str(best_result.air_date) + ' for show ' + show.name + ', skipping', logger.WARNING)
|
||||
episode_numbers = []
|
||||
except sickbeard.indexer_error as e:
|
||||
logger.log(u"Unable to contact " + sickbeard.indexerApi(bestResult.show.indexer).name + ": " + ex(e), logger.WARNING)
|
||||
logger.log(u'Unable to contact ' + sickbeard.indexerApi(show.indexer).name + ': ' + ex(e), logger.WARNING)
|
||||
episode_numbers = []
|
||||
|
||||
for epNo in episode_numbers:
|
||||
s = season_number
|
||||
e = epNo
|
||||
|
||||
if self.convert:
|
||||
(s, e) = scene_numbering.get_indexer_numbering(bestResult.show.indexerid,
|
||||
bestResult.show.indexer,
|
||||
if self.convert and show.is_scene:
|
||||
(s, e) = scene_numbering.get_indexer_numbering(show.indexerid,
|
||||
show.indexer,
|
||||
season_number,
|
||||
epNo)
|
||||
new_episode_numbers.append(e)
|
||||
new_season_numbers.append(s)
|
||||
|
||||
elif bestResult.show.is_anime and len(bestResult.ab_episode_numbers) and not self.testing:
|
||||
scene_season = scene_exceptions.get_scene_exception_by_name(bestResult.series_name)[1]
|
||||
for epAbsNo in bestResult.ab_episode_numbers:
|
||||
elif show.is_anime and len(best_result.ab_episode_numbers) and not self.testing:
|
||||
scene_season = scene_exceptions.get_scene_exception_by_name(best_result.series_name)[1]
|
||||
for epAbsNo in best_result.ab_episode_numbers:
|
||||
a = epAbsNo
|
||||
|
||||
if self.convert:
|
||||
a = scene_numbering.get_indexer_absolute_numbering(bestResult.show.indexerid,
|
||||
bestResult.show.indexer, epAbsNo,
|
||||
if self.convert and show.is_scene:
|
||||
a = scene_numbering.get_indexer_absolute_numbering(show.indexerid,
|
||||
show.indexer, epAbsNo,
|
||||
True, scene_season)
|
||||
|
||||
(s, e) = helpers.get_all_episodes_from_absolute_number(bestResult.show, [a])
|
||||
(s, e) = helpers.get_all_episodes_from_absolute_number(show, [a])
|
||||
|
||||
new_absolute_numbers.append(a)
|
||||
new_episode_numbers.extend(e)
|
||||
new_season_numbers.append(s)
|
||||
|
||||
elif bestResult.season_number and len(bestResult.episode_numbers) and not self.testing:
|
||||
for epNo in bestResult.episode_numbers:
|
||||
s = bestResult.season_number
|
||||
elif best_result.season_number and len(best_result.episode_numbers) and not self.testing:
|
||||
for epNo in best_result.episode_numbers:
|
||||
s = best_result.season_number
|
||||
e = epNo
|
||||
|
||||
if self.convert:
|
||||
(s, e) = scene_numbering.get_indexer_numbering(bestResult.show.indexerid,
|
||||
bestResult.show.indexer,
|
||||
bestResult.season_number,
|
||||
if self.convert and show.is_scene:
|
||||
(s, e) = scene_numbering.get_indexer_numbering(show.indexerid,
|
||||
show.indexer,
|
||||
best_result.season_number,
|
||||
epNo)
|
||||
if bestResult.show.is_anime:
|
||||
a = helpers.get_absolute_number_from_season_and_episode(bestResult.show, s, e)
|
||||
if show.is_anime:
|
||||
a = helpers.get_absolute_number_from_season_and_episode(show, s, e)
|
||||
if a:
|
||||
new_absolute_numbers.append(a)
|
||||
|
||||
|
@ -312,11 +312,11 @@ class NameParser(object):
|
|||
# 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 "
|
||||
"SickGear does not support this. "
|
||||
"Sorry." % (str(new_season_numbers)))
|
||||
if 1 < len(new_season_numbers):
|
||||
raise InvalidNameException('Scene numbering results episodes from '
|
||||
'seasons %s, (i.e. more than one) and '
|
||||
'SickGear 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
|
||||
|
@ -328,24 +328,24 @@ class NameParser(object):
|
|||
new_absolute_numbers.sort()
|
||||
|
||||
if len(new_absolute_numbers):
|
||||
bestResult.ab_episode_numbers = new_absolute_numbers
|
||||
best_result.ab_episode_numbers = new_absolute_numbers
|
||||
|
||||
if len(new_season_numbers) and len(new_episode_numbers):
|
||||
bestResult.episode_numbers = new_episode_numbers
|
||||
bestResult.season_number = new_season_numbers[0]
|
||||
best_result.episode_numbers = new_episode_numbers
|
||||
best_result.season_number = new_season_numbers[0]
|
||||
|
||||
if self.convert:
|
||||
logger.log(
|
||||
u"Converted parsed result " + bestResult.original_name + " into " + str(bestResult).decode('utf-8',
|
||||
'xmlcharrefreplace'),
|
||||
logger.DEBUG)
|
||||
if self.convert and show.is_scene:
|
||||
logger.log(u'Converted parsed result %s into %s'
|
||||
% (best_result.original_name, str(best_result).decode('utf-8', 'xmlcharrefreplace')),
|
||||
logger.DEBUG)
|
||||
|
||||
# CPU sleep
|
||||
time.sleep(cpu_presets[sickbeard.CPU_PRESET])
|
||||
|
||||
return bestResult
|
||||
return best_result
|
||||
|
||||
def _combine_results(self, first, second, attr):
|
||||
@staticmethod
|
||||
def _combine_results(first, second, attr):
|
||||
# if the first doesn't exist then return the second or nothing
|
||||
if not first:
|
||||
if not second:
|
||||
|
@ -361,19 +361,21 @@ class NameParser(object):
|
|||
b = getattr(second, attr)
|
||||
|
||||
# if a is good use it
|
||||
if a != None or (type(a) == list and len(a)):
|
||||
if None is not a or (list == type(a) and len(a)):
|
||||
return a
|
||||
# if not use b (if b isn't set it'll just be default)
|
||||
else:
|
||||
return b
|
||||
|
||||
def _unicodify(self, obj, encoding="utf-8"):
|
||||
@staticmethod
|
||||
def _unicodify(obj, encoding='utf-8'):
|
||||
if isinstance(obj, basestring):
|
||||
if not isinstance(obj, unicode):
|
||||
obj = unicode(obj, encoding, 'replace')
|
||||
return obj
|
||||
|
||||
def _convert_number(self, org_number):
|
||||
@staticmethod
|
||||
def _convert_number(org_number):
|
||||
"""
|
||||
Convert org_number into an integer
|
||||
org_number: integer or representation of a number: string or unicode
|
||||
|
@ -392,8 +394,7 @@ class NameParser(object):
|
|||
# on error try converting from Roman numerals
|
||||
roman_to_int_map = (('M', 1000), ('CM', 900), ('D', 500), ('CD', 400), ('C', 100),
|
||||
('XC', 90), ('L', 50), ('XL', 40), ('X', 10),
|
||||
('IX', 9), ('V', 5), ('IV', 4), ('I', 1)
|
||||
)
|
||||
('IX', 9), ('V', 5), ('IV', 4), ('I', 1))
|
||||
|
||||
roman_numeral = str(org_number).upper()
|
||||
number = 0
|
||||
|
@ -469,19 +470,18 @@ class NameParser(object):
|
|||
if not final_result.show:
|
||||
if self.testing:
|
||||
pass
|
||||
#final_result.which_regex = []
|
||||
else:
|
||||
raise InvalidShowException(
|
||||
"Unable to parse " + name.encode(sickbeard.SYS_ENCODING, 'xmlcharrefreplace'))
|
||||
raise InvalidShowException('Unable to parse %s'
|
||||
% name.encode(sickbeard.SYS_ENCODING, 'xmlcharrefreplace'))
|
||||
|
||||
# if there's no useful info in it then raise an exception
|
||||
if final_result.season_number == None and not final_result.episode_numbers and final_result.air_date == None and not final_result.ab_episode_numbers and not final_result.series_name:
|
||||
raise InvalidNameException("Unable to parse " + name.encode(sickbeard.SYS_ENCODING, 'xmlcharrefreplace'))
|
||||
if None is final_result.season_number and not final_result.episode_numbers and None is final_result.air_date and not final_result.ab_episode_numbers and not final_result.series_name:
|
||||
raise InvalidNameException('Unable to parse %s' % name.encode(sickbeard.SYS_ENCODING, 'xmlcharrefreplace'))
|
||||
|
||||
if cache_result:
|
||||
name_parser_cache.add(name, final_result)
|
||||
|
||||
logger.log(u"Parsed " + name + " into " + str(final_result).decode('utf-8', 'xmlcharrefreplace'), logger.DEBUG)
|
||||
logger.log(u'Parsed %s into %s' % (name, str(final_result).decode('utf-8', 'xmlcharrefreplace')), logger.DEBUG)
|
||||
return final_result
|
||||
|
||||
|
||||
|
@ -498,8 +498,7 @@ class ParseResult(object):
|
|||
show=None,
|
||||
score=None,
|
||||
quality=None,
|
||||
version=None
|
||||
):
|
||||
version=None):
|
||||
|
||||
self.original_name = original_name
|
||||
|
||||
|
@ -549,23 +548,15 @@ class ParseResult(object):
|
|||
return False
|
||||
if self.ab_episode_numbers != other.ab_episode_numbers:
|
||||
return False
|
||||
#if self.show != other.show:
|
||||
# return False
|
||||
#if self.score != other.score:
|
||||
# return False
|
||||
#if self.quality != other.quality:
|
||||
# return False
|
||||
#if self.version != other.version:
|
||||
# return False
|
||||
|
||||
return True
|
||||
|
||||
def __str__(self):
|
||||
if self.series_name != None:
|
||||
if None is not self.series_name:
|
||||
to_return = self.series_name + u' - '
|
||||
else:
|
||||
to_return = u''
|
||||
if self.season_number != None:
|
||||
if None is not self.season_number:
|
||||
to_return += 'S' + str(self.season_number)
|
||||
if self.episode_numbers and len(self.episode_numbers):
|
||||
for e in self.episode_numbers:
|
||||
|
@ -574,17 +565,17 @@ class ParseResult(object):
|
|||
if self.is_air_by_date:
|
||||
to_return += str(self.air_date)
|
||||
if self.ab_episode_numbers:
|
||||
to_return += ' [ABS: ' + str(self.ab_episode_numbers) + ']'
|
||||
to_return += ' [ABS: %s]' % str(self.ab_episode_numbers)
|
||||
if self.is_anime:
|
||||
if self.version:
|
||||
to_return += ' [ANIME VER: ' + str(self.version) + ']'
|
||||
to_return += ' [ANIME VER: %s]' % str(self.version)
|
||||
|
||||
if self.release_group:
|
||||
to_return += ' [GROUP: ' + self.release_group + ']'
|
||||
to_return += ' [GROUP: %s]' % self.release_group
|
||||
|
||||
to_return += ' [ABD: ' + str(self.is_air_by_date) + ']'
|
||||
to_return += ' [ANIME: ' + str(self.is_anime) + ']'
|
||||
to_return += ' [whichReg: ' + str(self.which_regex) + ']'
|
||||
to_return += ' [ABD: %s]' % str(self.is_air_by_date)
|
||||
to_return += ' [ANIME: %s]' % str(self.is_anime)
|
||||
to_return += ' [whichReg: %s]' % str(self.which_regex)
|
||||
|
||||
return to_return.encode('utf-8')
|
||||
|
||||
|
@ -614,7 +605,7 @@ class NameParserCache(object):
|
|||
|
||||
def get(self, name):
|
||||
if name in self._previous_parsed:
|
||||
logger.log("Using cached parse result for: " + name, logger.DEBUG)
|
||||
logger.log('Using cached parse result for: ' + name, logger.DEBUG)
|
||||
return self._previous_parsed[name]
|
||||
|
||||
|
||||
|
@ -622,8 +613,8 @@ name_parser_cache = NameParserCache()
|
|||
|
||||
|
||||
class InvalidNameException(Exception):
|
||||
"The given release name is not valid"
|
||||
"""The given release name is not valid"""
|
||||
|
||||
|
||||
class InvalidShowException(Exception):
|
||||
"The given show name is not valid"
|
||||
"""The given show name is not valid"""
|
||||
|
|
|
@ -62,7 +62,7 @@ class BeyondHDProvider(generic.TorrentProvider):
|
|||
for mode in search_params.keys():
|
||||
if 'Cache' != mode:
|
||||
show_type = self.show.air_by_date and 'Air By Date' \
|
||||
or self.show.sports and 'Sports' or self.show.anime and 'Anime' or None
|
||||
or self.show.is_sports and 'Sports' or self.show.is_anime and 'Anime' or None
|
||||
if show_type:
|
||||
logger.log(u'Provider does not carry shows of type: [%s], skipping' % show_type, logger.DEBUG)
|
||||
return results
|
||||
|
|
|
@ -171,13 +171,13 @@ class BTNProvider(generic.TorrentProvider):
|
|||
current_params = {'category': 'Season'}
|
||||
|
||||
# Search for entire seasons: no need to do special things for air by date or sports shows
|
||||
if ep_obj.show.air_by_date or ep_obj.show.sports:
|
||||
if ep_obj.show.air_by_date or ep_obj.show.is_sports:
|
||||
# Search for the year of the air by date show
|
||||
current_params['name'] = str(ep_obj.airdate).split('-')[0]
|
||||
elif ep_obj.show.is_anime:
|
||||
current_params['name'] = '%s' % ep_obj.scene_absolute_number
|
||||
else:
|
||||
current_params['name'] = 'Season ' + str(ep_obj.scene_season)
|
||||
current_params['name'] = 'Season %s' % (ep_obj.season, ep_obj.scene_season)[bool(ep_obj.show.is_scene)]
|
||||
|
||||
# search
|
||||
if 1 == ep_obj.show.indexer:
|
||||
|
@ -206,17 +206,19 @@ class BTNProvider(generic.TorrentProvider):
|
|||
search_params = {'category': 'Episode'}
|
||||
|
||||
# episode
|
||||
if ep_obj.show.air_by_date or ep_obj.show.sports:
|
||||
if ep_obj.show.air_by_date or ep_obj.show.is_sports:
|
||||
date_str = str(ep_obj.airdate)
|
||||
|
||||
# BTN uses dots in dates, we just search for the date since that
|
||||
# combined with the series identifier should result in just one episode
|
||||
search_params['name'] = date_str.replace('-', '.')
|
||||
elif ep_obj.show.anime:
|
||||
elif ep_obj.show.is_anime:
|
||||
search_params['name'] = '%s' % ep_obj.scene_absolute_number
|
||||
else:
|
||||
# Do a general name search for the episode, formatted like SXXEYY
|
||||
search_params['name'] = 'S%02dE%02d' % (ep_obj.scene_season, ep_obj.scene_episode)
|
||||
season, episode = ((ep_obj.season, ep_obj.episode),
|
||||
(ep_obj.scene_season, ep_obj.scene_episode))[bool(ep_obj.show.is_scene)]
|
||||
search_params['name'] = 'S%02dE%02d' % (season, episode)
|
||||
|
||||
# search
|
||||
if 1 == ep_obj.show.indexer:
|
||||
|
|
|
@ -149,7 +149,7 @@ class GenericProvider:
|
|||
|
||||
if GenericProvider.TORRENT == self.providerType:
|
||||
try:
|
||||
torrent_hash = re.findall('urn:btih:([0-9a-f]{32,40})', result.url)[0].upper()
|
||||
torrent_hash = re.findall('(?i)urn:btih:([0-9a-f]{32,40})', result.url)[0].upper()
|
||||
|
||||
if 32 == len(torrent_hash):
|
||||
torrent_hash = b16encode(b32decode(torrent_hash)).lower()
|
||||
|
@ -158,34 +158,40 @@ class GenericProvider:
|
|||
logger.log('Unable to extract torrent hash from link: ' + ex(result.url), logger.ERROR)
|
||||
return False
|
||||
|
||||
urls = ['https://%s/%s.torrent' % (u, torrent_hash)
|
||||
for u in ('torcache.net/torrent', 'torrage.com/torrent', 'getstrike.net/torrents/api/download')]
|
||||
urls = ['http%s://%s/%s.torrent' % (u + (torrent_hash,))
|
||||
for u in (('s', 'torcache.net/torrent'), ('s', 'getstrike.net/torrents/api/download'),
|
||||
('', 'thetorrent.org'))]
|
||||
except:
|
||||
urls = [result.url]
|
||||
|
||||
filename = ek.ek(os.path.join, sickbeard.TORRENT_DIR,
|
||||
helpers.sanitizeFileName(result.name) + '.' + self.providerType)
|
||||
elif GenericProvider.NZB == self.providerType:
|
||||
urls = [result.url]
|
||||
|
||||
filename = ek.ek(os.path.join, sickbeard.NZB_DIR,
|
||||
helpers.sanitizeFileName(result.name) + '.' + self.providerType)
|
||||
else:
|
||||
return
|
||||
|
||||
for url in urls:
|
||||
if helpers.download_file(url, filename, session=self.session):
|
||||
logger.log(u'Downloading a result from ' + self.name + ' at ' + url)
|
||||
cache_dir = sickbeard.CACHE_DIR or helpers._getTempDir()
|
||||
base_name = '%s.%s' % (helpers.sanitizeFileName(result.name), self.providerType)
|
||||
cache_file = ek.ek(os.path.join, cache_dir, base_name)
|
||||
|
||||
if GenericProvider.TORRENT == self.providerType:
|
||||
logger.log(u'Saved magnet link to ' + filename, logger.MESSAGE)
|
||||
else:
|
||||
logger.log(u'Saved result to ' + filename, logger.MESSAGE)
|
||||
if helpers.download_file(url, cache_file, session=self.session):
|
||||
logger.log(u'Downloaded a result from %s at %s' % (self.name, url))
|
||||
|
||||
if self._verify_download(filename):
|
||||
return True
|
||||
elif ek.ek(os.path.isfile, filename):
|
||||
ek.ek(os.remove, filename)
|
||||
if self._verify_download(cache_file):
|
||||
if GenericProvider.TORRENT == self.providerType:
|
||||
final_dir, link_type = (sickbeard.TORRENT_DIR, 'magnet')
|
||||
else:
|
||||
final_dir, link_type = (sickbeard.NZB_DIR, 'nzb')
|
||||
final_file = ek.ek(os.path.join, final_dir, base_name)
|
||||
|
||||
helpers.moveFile(cache_file, final_file)
|
||||
if not ek.ek(os.path.isfile, cache_file) and ek.ek(os.path.isfile, final_file):
|
||||
logger.log(u'Saved %s link to %s' % (link_type, final_file), logger.MESSAGE)
|
||||
return True
|
||||
|
||||
if ek.ek(os.path.isfile, cache_file):
|
||||
ek.ek(os.remove, cache_file)
|
||||
|
||||
logger.log(u'Failed to download result', logger.ERROR)
|
||||
return False
|
||||
|
@ -348,7 +354,7 @@ class GenericProvider:
|
|||
version = parse_result.version
|
||||
|
||||
add_cache_entry = False
|
||||
if not (show_obj.air_by_date or show_obj.sports):
|
||||
if not (show_obj.air_by_date or show_obj.is_sports):
|
||||
if 'sponly' == search_mode:
|
||||
if len(parse_result.episode_numbers):
|
||||
logger.log(u'This is supposed to be a season pack search but the result ' + title
|
||||
|
@ -644,14 +650,14 @@ class TorrentProvider(GenericProvider):
|
|||
|
||||
def _get_season_search_strings(self, ep_obj, detail_only=False, scene=True):
|
||||
|
||||
if ep_obj.show.air_by_date or ep_obj.show.sports:
|
||||
if ep_obj.show.air_by_date or ep_obj.show.is_sports:
|
||||
ep_detail = str(ep_obj.airdate).split('-')[0]
|
||||
elif ep_obj.show.anime:
|
||||
elif ep_obj.show.is_anime:
|
||||
ep_detail = ep_obj.scene_absolute_number
|
||||
else:
|
||||
ep_detail = 'S%02d' % int(ep_obj.scene_season)
|
||||
ep_detail = 'S%02d' % int((ep_obj.season, ep_obj.scene_season)[bool(ep_obj.show.is_scene)])
|
||||
|
||||
detail = ({}, {'Season_only': [ep_detail]})[detail_only and not self.show.sports and not self.show.anime]
|
||||
detail = ({}, {'Season_only': [ep_detail]})[detail_only and not self.show.is_sports and not self.show.is_anime]
|
||||
return [dict({'Season': self._build_search_strings(ep_detail, scene)}.items() + detail.items())]
|
||||
|
||||
def _get_episode_search_strings(self, ep_obj, add_string='', detail_only=False, scene=True, sep_date=' ', use_or=True):
|
||||
|
@ -659,18 +665,20 @@ class TorrentProvider(GenericProvider):
|
|||
if not ep_obj:
|
||||
return []
|
||||
|
||||
if self.show.air_by_date or self.show.sports:
|
||||
if self.show.air_by_date or self.show.is_sports:
|
||||
ep_detail = str(ep_obj.airdate).replace('-', sep_date)
|
||||
if self.show.sports:
|
||||
if self.show.is_sports:
|
||||
month = ep_obj.airdate.strftime('%b')
|
||||
ep_detail = ([ep_detail] + [month], '%s|%s' % (ep_detail, month))[use_or]
|
||||
elif self.show.anime:
|
||||
elif self.show.is_anime:
|
||||
ep_detail = ep_obj.scene_absolute_number
|
||||
else:
|
||||
ep_detail = sickbeard.config.naming_ep_type[2] % {'seasonnumber': ep_obj.scene_season,
|
||||
'episodenumber': ep_obj.scene_episode}
|
||||
append = (add_string, '')[self.show.anime]
|
||||
detail = ({}, {'Episode_only': [ep_detail]})[detail_only and not self.show.sports and not self.show.anime]
|
||||
season, episode = ((ep_obj.season, ep_obj.episode),
|
||||
(ep_obj.scene_season, ep_obj.scene_episode))[bool(ep_obj.show.is_scene)]
|
||||
ep_dict = {'seasonnumber': season, 'episodenumber': episode}
|
||||
ep_detail = sickbeard.config.naming_ep_type[2] % ep_dict
|
||||
append = (add_string, '')[self.show.is_anime]
|
||||
detail = ({}, {'Episode_only': [ep_detail]})[detail_only and not self.show.is_sports and not self.show.is_anime]
|
||||
return [dict({'Episode': self._build_search_strings(ep_detail, scene, append)}.items() + detail.items())]
|
||||
|
||||
def _build_search_strings(self, ep_detail, process_name=True, append=''):
|
||||
|
|
|
@ -117,18 +117,18 @@ class HDBitsProvider(generic.TorrentProvider):
|
|||
if episode:
|
||||
if show.air_by_date:
|
||||
param['episode'] = str(episode.airdate).replace('-', '|')
|
||||
elif show.sports:
|
||||
elif show.is_sports:
|
||||
param['episode'] = episode.airdate.strftime('%b')
|
||||
elif show.anime:
|
||||
elif show.is_anime:
|
||||
param['episode'] = '%i' % int(episode.scene_absolute_number)
|
||||
else:
|
||||
param['season'] = episode.scene_season
|
||||
param['episode'] = episode.scene_episode
|
||||
|
||||
if season:
|
||||
if show.air_by_date or show.sports:
|
||||
if show.air_by_date or show.is_sports:
|
||||
param['season'] = str(season.airdate)[:7]
|
||||
elif show.anime:
|
||||
elif show.is_anime:
|
||||
param['season'] = '%d' % season.scene_absolute_number
|
||||
else:
|
||||
param['season'] = season.scene_season
|
||||
|
|
|
@ -110,39 +110,39 @@ class KATProvider(generic.TorrentProvider):
|
|||
|
||||
def _get_season_search_strings(self, ep_obj, **kwargs):
|
||||
|
||||
if ep_obj.show.air_by_date or ep_obj.show.sports:
|
||||
if ep_obj.show.air_by_date or ep_obj.show.is_sports:
|
||||
airdate = str(ep_obj.airdate).split('-')[0]
|
||||
ep_detail = [airdate, 'Season ' + airdate]
|
||||
elif ep_obj.show.anime:
|
||||
elif ep_obj.show.is_anime:
|
||||
ep_detail = '%02i' % ep_obj.scene_absolute_number
|
||||
else:
|
||||
ep_detail = ['S%(s)02i -S%(s)02iE' % {'s': ep_obj.scene_season},
|
||||
'Season %s -Ep*' % ep_obj.scene_season]
|
||||
season = (ep_obj.season, ep_obj.scene_season)[bool(ep_obj.show.is_scene)]
|
||||
ep_detail = ['S%(s)02i -S%(s)02iE' % {'s': season}, 'Season %s -Ep*' % season]
|
||||
|
||||
return [{'Season': self._build_search_strings(ep_detail, append=(' category:tv', '')[self.show.anime])}]
|
||||
return [{'Season': self._build_search_strings(ep_detail, append=(' category:tv', '')[self.show.is_anime])}]
|
||||
|
||||
def _get_episode_search_strings(self, ep_obj, add_string='', **kwargs):
|
||||
|
||||
if not ep_obj:
|
||||
return []
|
||||
|
||||
if self.show.air_by_date or self.show.sports:
|
||||
if self.show.air_by_date or self.show.is_sports:
|
||||
ep_detail = str(ep_obj.airdate).replace('-', ' ')
|
||||
if self.show.sports:
|
||||
if self.show.is_sports:
|
||||
ep_detail += '|' + ep_obj.airdate.strftime('%b')
|
||||
elif self.show.anime:
|
||||
elif self.show.is_anime:
|
||||
ep_detail = '%02i' % ep_obj.scene_absolute_number
|
||||
else:
|
||||
ep_detail = '%s|%s' % (config.naming_ep_type[2] % {'seasonnumber': ep_obj.scene_season,
|
||||
'episodenumber': ep_obj.scene_episode},
|
||||
config.naming_ep_type[0] % {'seasonnumber': ep_obj.scene_season,
|
||||
'episodenumber': ep_obj.scene_episode})
|
||||
season, episode = ((ep_obj.season, ep_obj.episode),
|
||||
(ep_obj.scene_season, ep_obj.scene_episode))[bool(ep_obj.show.is_scene)]
|
||||
ep_dict = {'seasonnumber': season, 'episodenumber': episode}
|
||||
ep_detail = '%s|%s' % (config.naming_ep_type[2] % ep_dict, config.naming_ep_type[0] % ep_dict)
|
||||
# include provider specific appends
|
||||
if not isinstance(add_string, list):
|
||||
add_string = [add_string]
|
||||
add_string = [x + ' category:tv' for x in add_string]
|
||||
|
||||
return [{'Episode': self._build_search_strings(ep_detail, append=(add_string, '')[self.show.anime])}]
|
||||
return [{'Episode': self._build_search_strings(ep_detail, append=(add_string, '')[self.show.is_anime])}]
|
||||
|
||||
def _do_search(self, search_params, search_mode='eponly', epcount=0, age=0):
|
||||
|
||||
|
|
|
@ -116,14 +116,14 @@ class NewznabProvider(generic.NZBProvider):
|
|||
cur_params = {}
|
||||
|
||||
# season
|
||||
if ep_obj.show.air_by_date or ep_obj.show.sports:
|
||||
if ep_obj.show.air_by_date or ep_obj.show.is_sports:
|
||||
date_str = str(ep_obj.airdate).split('-')[0]
|
||||
cur_params['season'] = date_str
|
||||
cur_params['q'] = date_str.replace('-', '.')
|
||||
elif ep_obj.show.is_anime:
|
||||
cur_params['season'] = '%d' % ep_obj.scene_absolute_number
|
||||
else:
|
||||
cur_params['season'] = str(ep_obj.scene_season)
|
||||
cur_params['season'] = str((ep_obj.season, ep_obj.scene_season)[bool(ep_obj.show.is_scene)])
|
||||
|
||||
# search
|
||||
rid = helpers.mapIndexersToShow(ep_obj.show)[2]
|
||||
|
@ -151,15 +151,16 @@ class NewznabProvider(generic.NZBProvider):
|
|||
if not ep_obj:
|
||||
return [params]
|
||||
|
||||
if ep_obj.show.air_by_date or ep_obj.show.sports:
|
||||
if ep_obj.show.air_by_date or ep_obj.show.is_sports:
|
||||
date_str = str(ep_obj.airdate)
|
||||
params['season'] = date_str.partition('-')[0]
|
||||
params['ep'] = date_str.partition('-')[2].replace('-', '/')
|
||||
elif ep_obj.show.anime:
|
||||
elif ep_obj.show.is_anime:
|
||||
params['ep'] = '%i' % int(
|
||||
ep_obj.scene_absolute_number if int(ep_obj.scene_absolute_number) > 0 else ep_obj.scene_episode)
|
||||
else:
|
||||
params['season'], params['ep'] = ep_obj.scene_season, ep_obj.scene_episode
|
||||
params['season'], params['ep'] = ((ep_obj.season, ep_obj.episode),
|
||||
(ep_obj.scene_season, ep_obj.scene_episode))[bool(ep_obj.show.is_scene)]
|
||||
|
||||
# search
|
||||
rid = helpers.mapIndexersToShow(ep_obj.show)[2]
|
||||
|
@ -177,7 +178,7 @@ class NewznabProvider(generic.NZBProvider):
|
|||
cur_return['q'] = cur_exception
|
||||
to_return.append(cur_return)
|
||||
|
||||
if ep_obj.show.anime:
|
||||
if ep_obj.show.is_anime:
|
||||
# Experimental, add a searchstring without search explicitly for the episode!
|
||||
# Remove the ?ep=e46 paramater and use add the episode number to the query paramater.
|
||||
# Can be usefull for newznab indexers that do not have the episodes 100% parsed.
|
||||
|
|
|
@ -171,7 +171,7 @@ class RarbgProvider(generic.TorrentProvider):
|
|||
def _get_episode_search_strings(self, ep_obj, add_string='', **kwargs):
|
||||
|
||||
search_params = generic.TorrentProvider._get_episode_search_strings(self, ep_obj, detail_only=True)
|
||||
if self.show.air_by_date and self.show.sports:
|
||||
if self.show.air_by_date and self.show.is_sports:
|
||||
for x, types in enumerate(search_params):
|
||||
for y, ep_type in enumerate(types):
|
||||
search_params[x][ep_type][y] = '{{%s}}' % search_params[x][ep_type][y]
|
||||
|
|
|
@ -123,26 +123,26 @@ class ThePirateBayProvider(generic.TorrentProvider):
|
|||
elif ep_obj.show.anime:
|
||||
ep_detail = '%02i' % ep_obj.scene_absolute_number
|
||||
else:
|
||||
ep_detail = ['S%02d' % int(ep_obj.scene_season),
|
||||
'Season %s -Ep*' % ep_obj.scene_season]
|
||||
season = (ep_obj.season, ep_obj.scene_season)[bool(ep_obj.show.is_scene)]
|
||||
ep_detail = ['S%02d' % int(season), 'Season %s -Ep*' % season]
|
||||
|
||||
return [{'Season': self._build_search_strings(ep_detail)}]
|
||||
|
||||
def _get_episode_search_strings(self, ep_obj, add_string='', **kwargs):
|
||||
|
||||
if self.show.air_by_date or self.show.sports:
|
||||
if self.show.air_by_date or self.show.is_sports:
|
||||
ep_detail = str(ep_obj.airdate).replace('-', ' ')
|
||||
if self.show.sports:
|
||||
if self.show.is_sports:
|
||||
ep_detail += '|' + ep_obj.airdate.strftime('%b')
|
||||
elif self.show.anime:
|
||||
elif self.show.is_anime:
|
||||
ep_detail = '%02i' % ep_obj.scene_absolute_number
|
||||
else:
|
||||
ep_detail = '%s|%s' % (config.naming_ep_type[2] % {'seasonnumber': ep_obj.scene_season,
|
||||
'episodenumber': ep_obj.scene_episode},
|
||||
config.naming_ep_type[0] % {'seasonnumber': ep_obj.scene_season,
|
||||
'episodenumber': ep_obj.scene_episode})
|
||||
season, episode = ((ep_obj.season, ep_obj.episode),
|
||||
(ep_obj.scene_season, ep_obj.scene_episode))[bool(ep_obj.show.is_scene)]
|
||||
ep_dict = {'seasonnumber': season, 'episodenumber': episode}
|
||||
ep_detail = '%s|%s' % (config.naming_ep_type[2] % ep_dict, config.naming_ep_type[0] % ep_dict)
|
||||
|
||||
return [{'Episode': self._build_search_strings(ep_detail, append=(add_string, '')[self.show.anime])}]
|
||||
return [{'Episode': self._build_search_strings(ep_detail, append=(add_string, '')[self.show.is_anime])}]
|
||||
|
||||
def _do_search(self, search_params, search_mode='eponly', epcount=0, age=0):
|
||||
|
||||
|
|
|
@ -88,7 +88,8 @@ class ToTVProvider(generic.TorrentProvider):
|
|||
|
||||
def _get_season_search_strings(self, ep_obj, **kwargs):
|
||||
|
||||
return self._build_search_str(ep_obj, {'season': 'Season %02d' % ep_obj.scene_season})
|
||||
return self._build_search_str(ep_obj, {'season': 'Season %02d' %
|
||||
int((ep_obj.season, ep_obj.scene_season)[bool(ep_obj.show.is_scene)])})
|
||||
|
||||
def _get_episode_search_strings(self, ep_obj, add_string='', **kwargs):
|
||||
|
||||
|
@ -96,8 +97,9 @@ class ToTVProvider(generic.TorrentProvider):
|
|||
return [{}]
|
||||
|
||||
# Do a general name search for the episode, formatted like SXXEYY
|
||||
return self._build_search_str(ep_obj, {'episode': 'S%02dE%02d %s'
|
||||
% (ep_obj.scene_season, ep_obj.scene_episode, add_string)})
|
||||
season, episode = ((ep_obj.season, ep_obj.episode),
|
||||
(ep_obj.scene_season, ep_obj.scene_episode))[bool(ep_obj.show.is_scene)]
|
||||
return self._build_search_str(ep_obj, {'episode': 'S%02dE%02d %s' % (season, episode, add_string)})
|
||||
|
||||
@staticmethod
|
||||
def _build_search_str(ep_obj, search_params):
|
||||
|
|
|
@ -471,15 +471,14 @@ class QueueItemAdd(ShowQueueItem):
|
|||
|
||||
# Load XEM data to DB for show
|
||||
sickbeard.scene_numbering.xem_refresh(self.show.indexerid, self.show.indexer, force=True)
|
||||
# check if show has XEM mapping and if user disabled scene numbering during add show, output availability to log
|
||||
if not self.scene and self.show.indexerid in sickbeard.scene_exceptions.xem_tvdb_ids_list\
|
||||
+ sickbeard.scene_exceptions.xem_rage_ids_list:
|
||||
logger.log(u'Alternative scene episode numbers were disabled during add show. Edit show to enable them for searching.')
|
||||
|
||||
# update internal name cache
|
||||
name_cache.buildNameCache(self.show)
|
||||
|
||||
# check if show has XEM mapping so we can determine if searches should go by scene numbering or indexer numbering.
|
||||
if not self.scene and sickbeard.scene_numbering.get_xem_numbering_for_show(self.show.indexerid,
|
||||
self.show.indexer):
|
||||
self.show.scene = 1
|
||||
|
||||
self.finish()
|
||||
|
||||
def _finishEarly(self):
|
||||
|
|
|
@ -1091,7 +1091,7 @@ class Home(MainHandler):
|
|||
t.submenu.append({'title': 'Update show in Kodi',
|
||||
'path': 'home/updateKODI?showName=%s' % urllib.quote_plus(
|
||||
showObj.name.encode('utf-8')), 'requires': self.haveKODI})
|
||||
t.submenu.append({'title': 'Preview Rename', 'path': 'home/testRename?show=%d' % showObj.indexerid})
|
||||
t.submenu.append({'title': 'Media Renamer', 'path': 'home/testRename?show=%d' % showObj.indexerid})
|
||||
if sickbeard.USE_SUBTITLES and not sickbeard.showQueueScheduler.action.isBeingSubtitled(
|
||||
showObj) and showObj.subtitles:
|
||||
t.submenu.append(
|
||||
|
@ -1271,6 +1271,7 @@ class Home(MainHandler):
|
|||
with showObj.lock:
|
||||
t.show = showObj
|
||||
t.scene_exceptions = get_scene_exceptions(showObj.indexerid)
|
||||
t.show_has_scene_map = showObj.indexerid in sickbeard.scene_exceptions.xem_tvdb_ids_list + sickbeard.scene_exceptions.xem_rage_ids_list
|
||||
|
||||
return t.respond()
|
||||
|
||||
|
@ -2172,14 +2173,6 @@ class NewHomeAddShows(Home):
|
|||
|
||||
indexer, show_dir, indexer_id, show_name = self.split_extra_show(show_to_add)
|
||||
|
||||
if indexer_id and indexer and show_name:
|
||||
use_provided_info = True
|
||||
else:
|
||||
use_provided_info = False
|
||||
|
||||
# tell the template whether we're giving it show name & Indexer ID
|
||||
t.use_provided_info = use_provided_info
|
||||
|
||||
# use the given show_dir for the indexer search if available
|
||||
if use_show_name:
|
||||
t.default_show_name = show_name
|
||||
|
@ -2196,7 +2189,9 @@ class NewHomeAddShows(Home):
|
|||
elif type(other_shows) != list:
|
||||
other_shows = [other_shows]
|
||||
|
||||
if use_provided_info:
|
||||
# tell the template whether we're giving it show name & Indexer ID
|
||||
t.use_provided_info = bool(indexer_id and indexer and show_name)
|
||||
if t.use_provided_info:
|
||||
t.provided_indexer_id = int(indexer_id or 0)
|
||||
t.provided_indexer_name = show_name
|
||||
|
||||
|
@ -2208,6 +2203,8 @@ class NewHomeAddShows(Home):
|
|||
t.blacklist = []
|
||||
t.groups = []
|
||||
|
||||
t.show_scene_maps = sickbeard.scene_exceptions.xem_tvdb_ids_list + sickbeard.scene_exceptions.xem_rage_ids_list
|
||||
|
||||
return t.respond()
|
||||
|
||||
def recommendedShows(self, *args, **kwargs):
|
||||
|
|
Loading…
Reference in a new issue