mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-01 08:53:37 +00:00
Merge pull request #484 from JackDandy/feature/ChangeSceneNumbers
Change reduce aggressive use of scene numbering that was overriding u…
This commit is contained in:
commit
41e1119f69
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