Change increase show search capability when using plain text and also add TVDB id, IMDb id and IMDb url search.

Change improve existing show page and the handling when an attempt to add a show to an existing location
This commit is contained in:
JackDandy 2015-11-14 13:49:54 +00:00
parent f418c245fb
commit 670e30efda
8 changed files with 227 additions and 113 deletions

View file

@ -63,6 +63,8 @@
* Change replace trakt with libtrakt for API v2
* Change Trakt notification config to only handle PIN authentication with the service
* Remove all other Trakt deprecated API V1 service features pending reconsideration
* Change increase show search capability when using plain text and also add TVDB id, IMDb id and IMDb url search
* Change improve existing show page and the handling when an attempt to add a show to an existing location
[develop changelog]
Enable Alpha Ratio again now that the secure login page over https is fixed

View file

@ -526,7 +526,7 @@ h2.day, h2.network{
.carousel-indicators .active{
background:#8DBEEE;
border-color:#8DBEEE
}
}
/* =======================================================================
config*.tmpl
@ -655,6 +655,7 @@ span.path{
background-color:#333
}
#addRootDirTable td label .filepath.red-text,
.red-text{
color:#d33
}
@ -1444,4 +1445,4 @@ jquery.confirm.css
#confirmBox .red:hover{
background-color:#A13331
}
}

View file

@ -23,12 +23,12 @@ inc_top.tmpl
background:url("../css/lib/images/animated-overlay.gif")
}
.ui-dialog,
.ui-dialog,
.ui-dialog-buttonpane{
background:#eceadf url("../css/lib/images/ui-bg_fine-grain_10_eceadf_60x60.png") 50% 50% repeat !important
}
.ui-accordion-content,
.ui-accordion-content,
.ui-tabs-panel{
background:#ededed !important;
background-image:none !important
@ -50,41 +50,41 @@ inc_top.tmpl
background:#fff url("../css/lib/images/ui-bg_flat_0_ffffff_40x100.png") 50% 50% repeat-x
}
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default{
background:#fff;
border:1px solid #CCC
}
.ui-state-hover,
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-state-hover,
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-widget-header .ui-state-focus{
background:#fff
}
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-widget-header .ui-state-active{
background:#F7F7F7
}
.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight{
background:#fbf9ee url("../css/lib/images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x
}
.ui-state-error,
.ui-widget-content .ui-state-error,
.ui-state-error,
.ui-widget-content .ui-state-error,
.ui-widget-header .ui-state-error{
background:#fef1ec url("../css/lib/images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x
}
.ui-icon,
.ui-icon,
.ui-widget-content .ui-icon{
background-image:url("../css/lib/images/ui-icons_222222_256x240.png")
}
@ -97,7 +97,7 @@ inc_top.tmpl
background-image:url("../css/lib/images/ui-icons_8c291d_256x240.png")
}
.ui-state-hover .ui-icon,
.ui-state-hover .ui-icon,
.ui-state-focus .ui-icon{
background-image:url("../css/lib/images/ui-icons_222222_256x240.png")
}
@ -110,7 +110,7 @@ inc_top.tmpl
background-image:url("../css/lib/images/ui-icons_2e83ff_256x240.png")
}
.ui-state-error .ui-icon,
.ui-state-error .ui-icon,
.ui-state-error-text .ui-icon{
background-image:url("../css/lib/images/ui-icons_cd0a0a_256x240.png")
}
@ -345,7 +345,7 @@ home_postprocess.tmpl
/* =======================================================================
displayShow.tmpl
displayShow.tmpl
========================================================================== */
tr.seasonheader{
@ -508,7 +508,7 @@ h2.day, h2.network{
.carousel-indicators .active{
background:#C7DB40;
border-color:#C7DB40
}
}
/* =======================================================================
config*.tmpl
@ -630,6 +630,7 @@ span.path{
background-color:#f5f1e4
}
#addRootDirTable td label .filepath.red-text,
.red-text{
color:#d33
}

View file

@ -10,14 +10,11 @@
#import os.path
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl')
<script type="text/javascript" src="$sbRoot/js/qualityChooser.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/addExistingShow.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/rootDirs.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/addShowOptions.js?v=$sbPID"></script>
<script type="text/javascript" charset="utf-8">
<!--
\$(document).ready(function(){
\$.sgSid = '$kwargs.get('sid', '')';
\$.sgHashDir = '$kwargs.get('hash_dir', '')';
\$(document).ready(function(){
\$( '#tabs' ).tabs({
collapsible: true,
selected: #if $sickbeard.ROOT_DIRS then '-1' else '0'#
@ -25,6 +22,10 @@
});
//-->
</script>
<script type="text/javascript" src="$sbRoot/js/qualityChooser.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/addExistingShow.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/rootDirs.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/addShowOptions.js?v=$sbPID"></script>
#if $varExists('header')
<h1 class="header">$header</h1>
@ -36,48 +37,56 @@
<form id="addShowForm" method="post" action="$sbRoot/home/addShows/addNewShow" accept-charset="utf-8">
<p>Tip: shows are added quicker when usable show nfo and xml metadata is found</p>
<span#if $kwargs.get('hash_dir', None)# style="display:none"#end if>
<p>Tip: shows are added quicker when usable show nfo and xml metadata is found</p>
<p style="margin-top:15px">
<input type="checkbox" id="promptForSettings" name="promptForSettings" style="vertical-align: top;" />
<label for="promptForSettings">Enable to change the following options per show, otherwise use these options with all shows added below</label>
</p>
<p style="margin-top:15px">
<input type="checkbox" id="promptForSettings" name="promptForSettings" style="vertical-align: top;" />
<label for="promptForSettings">Enable to change the following options per show, otherwise use these options with all shows added below</label>
</p>
<div id="tabs">
<ul>
<li><a href="#tabs-1">Manage parent folders</a></li>
<li><a href="#tabs-2">Custom options</a></li>
</ul>
<div id="tabs-1" class="existingtabs">
<div style="width: 430px; margin: 0px auto">
<div id="tabs">
<ul>
<li><a href="#tabs-1">Manage parent folders</a></li>
<li><a href="#tabs-2">Custom options</a></li>
</ul>
<div id="tabs-1" class="existingtabs">
<div style="width: 430px; margin: 0px auto">
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_rootDirs.tmpl')
</div>
</div>
</div>
<div id="tabs-2">
<div class="stepDiv">
<div id="tabs-2">
<div class="stepDiv">
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_addShowOptions.tmpl')
</div>
</div>
</div>
</div>
<br />
<hr />
<br />
<hr />
</span>
<p>The following parent folder(s) are scanned for existing shows. Toggle a folder to display shows</p>
<p>The following parent folder$multi_parents scanned for
#if not $kwargs.get('hash_dir', None)#existing shows. Toggle a folder to display shows#else#the existing show...#end if#
</p>
<ul id="rootDirStaticList">
<li></li>
</ul>
#if not $kwargs.get('hash_dir', None)
<p>shows <span class="boldest">not known</span> to SickGear are listed below...</p>
#end if
<div id="tableDiv"></div>
<br />
#if not $kwargs.get('hash_dir', None)
<p>If you tried to add a show, arrived here and can't see the folder, then that show may already be in your show list.</p>
#end if
<input class="btn btn-primary" type="button" value="Submit" id="submitShowDirs" />
<input class="btn btn-primary" type="button" value="#if $kwargs.get('hash_dir', None)#Redo Search#else#Submit#end if#" id="submitShowDirs" />
</form>
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')

View file

@ -2,48 +2,67 @@
#from sickbeard.helpers import anon_url
<table id="addRootDirTable" class="sickbeardTable tablesorter">
<thead><tr><th class="col-checkbox"><input type="checkbox" id="checkAll" checked=checked></th><th>Parent\show folder</th><th width="20%">Show name<br />(tvshow.nfo)<th width="15%">TV database</td></tr></thead>
<tfoot>
<tr>
<th rowspan="1" colspan="4" align="left"><a href="#" class="showManage">Manage Directories</a></th>
</tr>
</tfoot>
<tbody>
#for $curDir in $dirList:
#if $curDir['added_already']:
#continue
#end if
#set $show_id = $curDir['dir']
#if $curDir['existing_info'][0]:
#set $show_id = $show_id + '|' + $str($curDir['existing_info'][0]) + '|' + $str($curDir['existing_info'][1])
#set $indexer = $curDir['existing_info'][2]
#end if
#set $indexer = 0
#if $curDir['existing_info'][0]:
#set $indexer = $curDir['existing_info'][2]
#elif $sickbeard.INDEXER_DEFAULT > 0:
#set $indexer = $sickbeard.INDEXER_DEFAULT
#end if
<tr>
<td class="col-checkbox"><input type="checkbox" id="$show_id" class="dirCheck" checked=checked></td>
<td><label for="$show_id">$curDir['display_dir']</label></td>
#if $curDir['existing_info'][1] and $indexer > 0:
<td><a href="<%= anon_url(sickbeard.indexerApi(indexer).config['show_url'], curDir['existing_info'][0]) %>" target="_new">$curDir['existing_info'][1]</a></td>
#else:
<td>?</td>
<thead>
<tr>
<th class="col-checkbox">
<input type="checkbox" id="checkAll" checked=checked>
</th>
<th>Parent\show folder</th>
<th width="20%">Show name<br />(tvshow.nfo)</th>
<th width="15%">TV info source</th>
</tr>
</thead>
<tfoot>
<tr>
<th rowspan="1" colspan="4" align="left">
<a href="#" class="showManage">Manage Directories</a>
</th>
</tr>
</tfoot>
<tbody>
#for $curDir in $dirList
#if $curDir['added_already'] and None is $curDir.get('highlight')
#continue
#end if
<td align="center">
<select name="indexer">
#for $curIndexer in $sickbeard.indexerApi().indexers.items():
<option value="$curIndexer[0]" #if $curIndexer[0] == $indexer then "selected=\"selected\"" else "UNKNOWN"#>$curIndexer[1]</option>
#end for
</select>
</td>
</tr>
#set $show_id = $curDir['dir']
#if $curDir['existing_info'][0]
#set $show_id = $show_id + '|' + $str($curDir['existing_info'][0]) + '|' + $str($curDir['existing_info'][1])
#set $indexer = $curDir['existing_info'][2]
#end if
#set $indexer = 0
#if $curDir['existing_info'][0]
#set $indexer = $curDir['existing_info'][2]
#elif 0 < $sickbeard.INDEXER_DEFAULT
#set $indexer = $sickbeard.INDEXER_DEFAULT
#end if
<tr>
<td class="col-checkbox">
<input type="checkbox" id="$show_id" class="dirCheck" checked=checked>
</td>
<td>
<label for="$show_id">
<span class="filepath#echo ('', ' red-text')[$curDir['highlight']]#">$curDir['path']</span>$curDir['name']
#echo ('', '<br />^ <span class="red-text">... (cannot add, this location is in use)</span>')[$curDir['highlight']]#
</label>
</td>
#if $curDir['existing_info'][1] and $indexer > 0
<td>
<a href="<%= anon_url(sickbeard.indexerApi(indexer).config['show_url'], curDir['existing_info'][0]) %>" target="_new">$curDir['existing_info'][1]</a>
</td>
#else
<td>?</td>
#end if
<td align="center">
<select name="indexer">
#for $curIndexer in $sickbeard.indexerApi().indexers.items()
<option value="$curIndexer[0]" #if $curIndexer[0] == $indexer then 'selected="selected"' else ''#>$curIndexer[1]</option>
#end for
</select>
</td>
</tr>
#end for
</tbody>
</tbody>
</table>
</tbody>
</table>

View file

@ -65,7 +65,7 @@
<input class="btn btn-inline" type="button" id="searchName" value="Search" />
</span>
<br />
<p style="margin:5px 0 15px"><b>*</b> SickGear supports english episodes. The language choice is used for fetching show data and episode filenames</p>
<p style="margin:5px 0 15px">Enter show name, TVDB ID, IMDb Url, or IMDb ID.&nbsp;&nbsp;<b>*</b>SickGear supports english, language is used for show/episode data</p>
<div id="searchResults" style="height: 100%"></div>
#end if
@ -116,4 +116,4 @@
</div></div>
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')

View file

@ -28,6 +28,7 @@ $(document).ready(function(){
window.location.href = sbRoot + '/home/addShows/addExistingShows'
+ '?promptForSettings=' + ($('#promptForSettings').prop('checked') ? 'on' : 'off')
+ (undefined !== $.sgSid && 0 < $.sgSid.length ? '&sid=' + $.sgSid : '')
+ '&shows_to_add=' + dirArr.join('&shows_to_add=');
});
@ -47,7 +48,7 @@ $(document).ready(function(){
+ ' height="32" width="32" />'
+ ' scanning parent folders...');
$.get(sbRoot + '/home/addShows/massAddTable',
$.get(sbRoot + '/home/addShows/massAddTable' + (undefined !== $.sgHashDir && 0 < $.sgHashDir.length ? '?hash_dir=' + $.sgHashDir : ''),
url,
function(data){
$('#tableDiv').html(data);
@ -90,4 +91,4 @@ $(document).ready(function(){
$('html,body').animate({scrollTop: 0}, 1000);
});
});
});

View file

@ -40,6 +40,7 @@ from sickbeard.common import SNATCHED, UNAIRED, IGNORED, ARCHIVED, WANTED, FAILE
from sickbeard.common import SD, HD720p, HD1080p
from sickbeard.exceptions import ex
from sickbeard.helpers import remove_article, starify
from sickbeard.indexers.indexer_config import INDEXER_TVDB, INDEXER_TVRAGE
from sickbeard.scene_exceptions import get_scene_exceptions
from sickbeard.scene_numbering import get_scene_numbering, set_scene_numbering, get_scene_numbering_for_show, \
get_xem_numbering_for_show, get_scene_absolute_numbering_for_show, get_xem_absolute_numbering_for_show, \
@ -2052,6 +2053,16 @@ class NewHomeAddShows(Home):
results = {}
final_results = []
search_id, indexer_id = '', None
search_id = ''
try:
search_id = re.search(r'(?m)((?:tt\d{4,})|^\d{4,}$)', search_term).group(1)
resp = self.getTrakt('/search?id_type=%s&id=%s' % (('tvdb', 'imdb')['tt' in search_id], search_id))[0]
search_term = resp['show']['title']
indexer_id = resp['show']['ids']['tvdb']
except:
search_term = (search_term, '')['tt' in search_id]
# Query Indexers for each search term and build the list of results
for indexer in sickbeard.indexerApi().indexers if not int(indexer) else [int(indexer)]:
lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
@ -2059,24 +2070,64 @@ class NewHomeAddShows(Home):
lINDEXER_API_PARMS['custom_ui'] = classes.AllShowsListUI
t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)
logger.log('Searching for Show with searchterm: %s on Indexer: %s' % (
search_term, sickbeard.indexerApi(indexer).name), logger.DEBUG)
try:
# add search results
results.setdefault(indexer, []).extend(t[search_term])
if bool(indexer_id):
logger.log('Fetching show using id: %s (%s) from tv datasource %s' % (
search_id, search_term, sickbeard.indexerApi(indexer).name), logger.DEBUG)
results.setdefault('tt' in search_id and 3 or indexer, []).extend(
[{'id': indexer_id, 'seriesname': t[indexer_id]['seriesname'], 'firstaired': t[indexer_id]['firstaired']}])
break
else:
logger.log('Searching for shows using search term: %s from tv datasource %s' % (
search_term, sickbeard.indexerApi(indexer).name), logger.DEBUG)
results.setdefault(indexer, []).extend(t[search_term])
except Exception as e:
continue
pass
# Query trakt for tvdb ids
try:
logger.log('Searching for show using search term: %s from tv datasource Trakt' % search_term, logger.DEBUG)
resp = self.getTrakt('/search?query=%s&type=show' % search_term)
tvdb_ids = []
for tvdb_item in results[INDEXER_TVDB]:
tvdb_ids.append(int(tvdb_item['id']))
results_trakt = []
for item in resp:
if 'tvdb' in item['show']['ids'] and item['show']['ids']['tvdb'] and \
item['show']['ids']['tvdb'] not in tvdb_ids:
results_trakt.append({'id': item['show']['ids']['tvdb'], 'seriesname': item['show']['title'],
'firstaired': item['show']['year']})
results.update({3: results_trakt})
except:
pass
id_names = [None, sickbeard.indexerApi(INDEXER_TVDB).name, sickbeard.indexerApi(INDEXER_TVRAGE).name,
'%s via Trakt' % sickbeard.indexerApi(INDEXER_TVDB).name]
map(final_results.extend,
([[sickbeard.indexerApi(id).name, id, sickbeard.indexerApi(id).config['show_url'], int(show['id']),
([['%s%s' % (id_names[id], helpers.findCertainShow(sickbeard.showList, int(show['id'])) and ' - exists in db' or ''),
(id, INDEXER_TVDB)[id == 3], sickbeard.indexerApi((id, INDEXER_TVDB)[id == 3]).config['show_url'], int(show['id']),
show['seriesname'], show['firstaired']] for show in shows] for id, shows in results.items()))
lang_id = sickbeard.indexerApi().config['langabbv_to_id'][lang]
return json.dumps({'results': final_results, 'langid': lang_id})
def massAddTable(self, rootDir=None):
def getTrakt(self, url, *args, **kwargs):
filtered = []
try:
resp = TraktAPI(ssl_verify=sickbeard.TRAKT_VERIFY, timeout=sickbeard.TRAKT_TIMEOUT).trakt_request(url)
if len(resp):
filtered = resp
except traktException as e:
logger.log(u'Could not connect to Trakt service: %s' % ex(e), logger.WARNING)
return filtered
def massAddTable(self, rootDir=None, **kwargs):
t = PageTemplate(headers=self.request.headers, file='home_massAddTable.tmpl')
t.submenu = self.HomeMenu()
t.kwargs = kwargs
if not rootDir:
return 'No folders selected.'
@ -2100,12 +2151,34 @@ class NewHomeAddShows(Home):
dir_list = []
display_one_dir = file_list = None
if kwargs.get('hash_dir'):
try:
for root_dir in sickbeard.ROOT_DIRS.split('|')[1:]:
try:
file_list = ek.ek(os.listdir, root_dir)
except:
continue
for cur_file in file_list:
cur_path = ek.ek(os.path.normpath, ek.ek(os.path.join, root_dir, cur_file))
if not ek.ek(os.path.isdir, cur_path):
continue
display_one_dir = kwargs.get('hash_dir') == str(abs(hash(cur_path)))
if display_one_dir:
raise ValueError('hash matched')
except ValueError:
pass
myDB = db.DBConnection()
for root_dir in root_dirs:
try:
file_list = ek.ek(os.listdir, root_dir)
except:
continue
if not file_list:
try:
file_list = ek.ek(os.listdir, root_dir)
except:
continue
for cur_file in file_list:
@ -2113,11 +2186,14 @@ class NewHomeAddShows(Home):
if not ek.ek(os.path.isdir, cur_path):
continue
highlight = kwargs.get('hash_dir') == str(abs(hash(cur_path)))
if display_one_dir and not highlight:
continue
cur_dir = {
'dir': cur_path,
'display_dir': '<span class="filepath">' + ek.ek(os.path.dirname, cur_path) + os.sep + '</span>' + ek.ek(
os.path.basename,
cur_path),
'highlight': highlight,
'name': ek.ek(os.path.basename, cur_path),
'path': '%s%s' % (ek.ek(os.path.dirname, cur_path), os.sep)
}
# see if the folder is in XBMC already
@ -2311,6 +2387,8 @@ class NewHomeAddShows(Home):
t = PageTemplate(headers=self.request.headers, file='home_addExistingShow.tmpl')
t.submenu = self.HomeMenu()
t.enable_anime_options = False
t.kwargs = kwargs
t.multi_parents = helpers.maybe_plural(len(sickbeard.ROOT_DIRS.split('|')[1:])) and 's are' or ' is'
return t.respond()
@ -2385,7 +2463,7 @@ class NewHomeAddShows(Home):
# blanket policy - if the dir exists you should have used 'add existing show' numbnuts
if ek.ek(os.path.isdir, show_dir) and not fullShowPath:
ui.notifications.error('Unable to add show', u'Found existing folder: ' + show_dir)
return self.redirect('/home/addShows/existingShows/')
return self.redirect('/home/addShows/existingShows?sid=%s&hash_dir=%s' % (indexer_id, abs(hash(show_dir))))
# don't create show dir if config says not to
if sickbeard.ADD_SHOWS_WO_DIR:
@ -2448,12 +2526,16 @@ class NewHomeAddShows(Home):
return (indexer, show_dir, indexer_id, show_name)
def addExistingShows(self, shows_to_add=None, promptForSettings=None):
def addExistingShows(self, shows_to_add=None, promptForSettings=None, **kwargs):
"""
Receives a dir list and add them. Adds the ones with given TVDB IDs first, then forwards
along to the newShow page.
"""
if kwargs.get('sid', None):
return self.redirect('/home/addShows/newShow?show_to_add=%s&use_show_name=True' %
'|'.join(['', '', '', kwargs.get('sid', '')]))
# grab a list of other shows to add, if provided
if not shows_to_add:
shows_to_add = []
@ -2470,7 +2552,7 @@ class NewHomeAddShows(Home):
split_vals = cur_dir.split('|')
if len(split_vals) < 3:
dirs_only.append(cur_dir)
if not '|' in cur_dir:
if '|' not in cur_dir:
dirs_only.append(cur_dir)
else:
indexer, show_dir, indexer_id, show_name = self.split_extra_show(cur_dir)
@ -2480,7 +2562,6 @@ class NewHomeAddShows(Home):
indexer_id_given.append((int(indexer), show_dir, int(indexer_id), show_name))
# if they want me to prompt for settings then I will just carry on to the newShow page
if promptForSettings and shows_to_add:
return self.newShow(shows_to_add[0], shows_to_add[1:])