diff --git a/CHANGES.md b/CHANGES.md index e04cbb26..859893ae 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -65,6 +65,10 @@ * 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 +* Change consolidate Trakt Trending and Recommended views into an "Add From Trakt" view which defaults to trending +* Change Trakt view drop down "Show" to reveal Brand-new Shows, Season Premieres, Recommendations and Trending views +* Change increase number of displayed Trakt shows to 100 +* Add genres and rating to all Trakt shows [develop changelog] Enable Alpha Ratio again now that the secure login page over https is fixed diff --git a/gui/slick/css/dark.css b/gui/slick/css/dark.css index 84c469bb..715cb0ec 100644 --- a/gui/slick/css/dark.css +++ b/gui/slick/css/dark.css @@ -326,15 +326,15 @@ ul#rootDirStaticList li{ } /* ======================================================================= -home_trendingShows.tmpl +home_browseShows.tmpl ========================================================================== */ -.traktContainer{ +.browse-container{ background-color:#333; border:1px solid #111 } -.trakt-image{ +.browse-image{ border-bottom:1px solid #111 } diff --git a/gui/slick/css/light.css b/gui/slick/css/light.css index f3906ddb..258ca6d3 100644 --- a/gui/slick/css/light.css +++ b/gui/slick/css/light.css @@ -327,15 +327,15 @@ ul#rootDirStaticList li{ } /* ======================================================================= -home_trendingShows.tmpl +home_browseShows.tmpl ========================================================================== */ -.traktContainer{ +.browse-container{ background-color:#DFDACF; border:1px solid #111 } -.trakt-image{ +.browse-image{ border-bottom:1px solid #111 } diff --git a/gui/slick/css/style.css b/gui/slick/css/style.css index 5e34c3f3..ae724e74 100644 --- a/gui/slick/css/style.css +++ b/gui/slick/css/style.css @@ -1054,25 +1054,25 @@ ul#rootDirStaticList li input[type="checkbox"]{ } /* ======================================================================= -home_trendingShows.tmpl +home_browseShows.tmpl ========================================================================== */ -.traktShowTitleIcons{ +.browse-add-show-holder{ float:right; padding-right:4px; padding-bottom:4px } -.traktContainer p{ +.browse-container p{ padding-top:2px } -.traktContainer p img{ +.browse-container p img{ position:relative; top:-2px } -.traktContainer p, .traktContainer i{ +.browse-container p, .browse-container i{ white-space:nowrap; font-size:12px; overflow:hidden; @@ -1080,15 +1080,16 @@ home_trendingShows.tmpl margin:0 } -.traktContainer{ - margin:12px; +.browse-container{ + margin:12px 12px 12px 0; width:188px; background-color:#DFDACF; border:1px solid #111; border-radius:6px } -.trakt-image{ +.browse-image{ + display:block; overflow:hidden; height:273px; width:186px; diff --git a/gui/slick/interfaces/default/home_addShows.tmpl b/gui/slick/interfaces/default/home_addShows.tmpl index a5269960..c4c553b2 100644 --- a/gui/slick/interfaces/default/home_addShows.tmpl +++ b/gui/slick/interfaces/default/home_addShows.tmpl @@ -10,55 +10,42 @@ #import os.path #include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl') -#if $varExists('header') +#if $varExists('header')

$header

-#else +#else

$title

#end if
-

Add New Show

-

Search a TV database for a show to add. A new folder will be created for episodes

+

Search a TV database for a show to add.

- -
+
+
-

Add From Trending

-

Browse a current trending show list to add from. A folder for episodes will be created

+

Add From Trakt

+

Browse trends, recommended and more.

+
 
+

Add Existing Shows

-

Scan parent folders for shows and episode metadata to import into SickGear

+

Scan parent folders to import into SickGear.

-#if True == $sickbeard.USE_TRAKT: - -
-
-

Add Recommended

-

Browse recommendations based on your Trakt.tv show library to add to SickGear

-
-
-#else -
-

There's more... unlock another button to browse
- recommended shows based on your Trakt.tv show
- library by enabling Trakt in Config/Notifications/Social

-
-#end if +
 
+
-
 
-#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl') \ No newline at end of file +#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl') diff --git a/gui/slick/interfaces/default/home_browseShows.tmpl b/gui/slick/interfaces/default/home_browseShows.tmpl new file mode 100644 index 00000000..6a6d819c --- /dev/null +++ b/gui/slick/interfaces/default/home_browseShows.tmpl @@ -0,0 +1,230 @@ +#import sickbeard +#import datetime +#import re +#import urllib +#from sickbeard.common import * +#from sickbeard import sbdatetime +#from sickbeard.helpers import anon_url +## +#set global $title='Browse Shows' +#set global $header='Browse Shows' +#set global $sbPath='..' +#set global $topmenu='home' +## +#import os.path +#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl') + + + + +#if $varExists('header') + #set $heading = ('header', $header) +#else + #set $heading = ('title', $title) +#end if +

%s' % $heading#

+ +#if $all_shows or ($kwargs and $kwargs.get('show_header', None)) +
+ Show: + + + Sort By: + + + Sort Order: + +
+

$browse_title

+ #if $kwargs and $kwargs.get('oldest', None): +
+ First aired from $kwargs['oldest'] until $kwargs['newest'] +
+ #end if +#end if + +
+#if $all_shows + #for $this_show in $all_shows: + #set $title_html = $this_show['title'].replace('"', '"').replace("'", ''') + +
+
+ + +
+ <%= (this_show['title'], ' ')['' == this_show['title']] %> +
+ +
+

$this_show['rating']% $this_show['votes'] votes

+ #if 'url_tvdb' in $this_show and $this_show['url_tvdb']: + + tvdb + #end if + +
+ #if ':' in $this_show['show_id']: +

In library

+ #else + Add Show + #end if +
+
+
+
+ #end for +
+ #if $kwargs and $kwargs.get('footnote', None): +
+ $kwargs['footnote'] +
+ #end if +#else +
+

+ #if $kwargs and $kwargs.get('error_msg', None): + $kwargs['error_msg'] + #else + $browse_type API did not return results, this can happen from time to time. +

This view should auto refresh every 10 mins. + #end if +

+
+ +#end if + + + +#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl') diff --git a/gui/slick/interfaces/default/home_newShow.tmpl b/gui/slick/interfaces/default/home_newShow.tmpl index b92008c4..f8eb5166 100644 --- a/gui/slick/interfaces/default/home_newShow.tmpl +++ b/gui/slick/interfaces/default/home_newShow.tmpl @@ -35,7 +35,7 @@
-

Find show at a TV database

+

#if $use_provided_info#Using known show information#else#Find show at TV info source#end if#

@@ -43,9 +43,9 @@ #if $use_provided_info #set $provided_indexer_local = $provided_indexer #set $provided_indexer_id_local = $provided_indexer_id - Show retrieved from existing metadata: $provided_indexer_name + Show: $provided_indexer_name - + #else diff --git a/gui/slick/interfaces/default/home_trendingShows.tmpl b/gui/slick/interfaces/default/home_trendingShows.tmpl deleted file mode 100644 index 1492882e..00000000 --- a/gui/slick/interfaces/default/home_trendingShows.tmpl +++ /dev/null @@ -1,169 +0,0 @@ -#import sickbeard -#import datetime -#import re -#import urllib -#from sickbeard.common import * -#from sickbeard import sbdatetime -#from sickbeard.helpers import anon_url -## -#set global $title='Trending Shows' -#set global $header='Trending Shows' -#set global $sbPath='..' -#set global $topmenu='episodeView' -## -#import os.path -#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl') - - - - - -#if $varExists('header') -

$header

-#else -

$title

-#end if - -#if $trending_shows -
- Show: - - - Sort By: - - - Sort Order: - -
-#end if - -
- -#if None is $trending_shows -
-

Trakt API did not return results, this can happen from time to time. -

This view should auto refresh every 10 mins.

-
-#else -#for $cur_show in $trending_shows: - -#set $image = re.sub(r'(.*)/original/(.+)$', r'\1/thumb/\2', $cur_show['images']['poster'], 0, re.IGNORECASE | re.MULTILINE) - -
-
-
- -
- -
- <%= (cur_show['title'], ' ')[ '' == cur_show['title']] %> -
- -
-

$cur_show['ratings']['percentage']%

- $cur_show['ratings']['votes'] votes - -
-#if ':' in $cur_show['show_id']: -

In library

-#else - #set $encoded_show_title = urllib.quote($cur_show['title'].encode("utf-8")) - Add Show -#end if -
-
-
-
- -#end for -#end if -
- - - -#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl') \ No newline at end of file diff --git a/gui/slick/js/newShow.js b/gui/slick/js/newShow.js index c4503961..1f6ab119 100644 --- a/gui/slick/js/newShow.js +++ b/gui/slick/js/newShow.js @@ -77,40 +77,38 @@ $(document).ready(function () { if (0 === data.results.length) { resultStr += 'Sorry, no results found. Try a different search.'; } else { + var idxSrcDB = 0, idxSrcDBId = 1, idxSrcUrl = 2, idxShowID = 3, idxTitle = 4, idxDate = 5; $.each(data.results, function (index, obj) { checked = (0 == row ? ' checked' : ''); rowType = (0 == row % 2 ? '' : ' class="alt"'); row++; - var whichSeries = cleanseText(obj.join('|'), !0), - display_show_name = cleanseText(obj[4], !0), - showstartdate = ''; + var display_show_name = cleanseText(obj[idxTitle], !0), showstartdate = ''; - if (null !== obj[5]) { - var startDate = new Date(obj[5]); + if (null !== obj[idxDate]) { + var startDate = new Date(obj[idxDate]); var today = new Date(); showstartdate = ' (' + (startDate > today ? 'will debut' : 'started') - + ' on ' + obj[5] + ')'; + + ': ' + obj[idxDate] + ')'; } - resultStr += '' + '' + '' + display_show_name + '' + showstartdate - + (null == obj[0] ? '' - : ' ' + '[' + obj[0] + ']' + '') + + (null == obj[idxSrcDB] ? '' + : ' ' + '[' + obj[idxSrcDB] + ']' + '') + '
' + "\n"; }); } @@ -195,12 +193,13 @@ $(document).ready(function () { elInput = $('input:hidden[name="whichSeries"]'), elScene = $('#scene'), elRootDirs = $('#rootDirs'), - elFullShowPath = $('#fullShowPath'); + elFullShowPath = $('#fullShowPath'), + idxWhichShowID = 2, idxWhichTitle = 3; // 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)); + show_name = elRadio.val().split('|')[idxWhichTitle]; + elScene[0].checked = 0 <= show_scene_maps.indexOf(parseInt(elRadio.val().split('|')[idxWhichShowID], 10)); $('#scene-maps-found').css('display', elScene.is(':checked') ? 'inline' : 'None'); } // if we provided a show in the hidden field, use that diff --git a/gui/slick/js/recommendedShows.js b/gui/slick/js/recommendedShows.js deleted file mode 100644 index 4f7dee00..00000000 --- a/gui/slick/js/recommendedShows.js +++ /dev/null @@ -1,211 +0,0 @@ -$(document).ready(function (){ - - function getRecommendedShows(){ - - $('#searchResults').empty().html('' - + ' fetching recommendations...'); - - $.getJSON(sbRoot + '/home/addShows/getRecommendedShows', - {}, - function (data){ - var resultStr = '', checked = '', rowType, row = 0; - - if (null === data || 0 === data.results.length){ - resultStr += '

Sorry, no recommended shows found, this can happen from time to time.

' - + '

However, if the issue persists, then try updating your watched shows list on trakt.tv

'; - } else { - - $.each(data.results, function (index, obj){ - checked = (0 == row ? ' checked' : ''); - rowType = (0 == row % 2 ? '' : ' class="alt"'); - row++; - - var whichSeries = obj[6] + '|' + obj[0] + '|' + obj[1] + '|' + obj[2] + '|' + obj[3], - showstartdate = ''; - - if (null !== obj[3]){ - var startDate = new Date(obj[3]); - var today = new Date(); - showstartdate = ' (' - + (startDate > today ? 'will debut' : 'started') - + ' on ' + obj[3] + ')'; - } - - resultStr += '' - + '' - + '
' - + '' + obj[1] + '' - + showstartdate - + (null == obj[6] ? '' - : ' ' - + '' - + '' - + '' + obj[4] + '' - + '' - + '' - + '' - ) - + (null == obj[10] ? '' - : ' ' - + '' - + '' - + '' + obj[8] + '' - + '' - + '' - + '' - ) - + (null == obj[2] ? '' - : ' 
' + obj[2] + '
') - + '
'; - }); - } - - $('#searchResults').html( - '
' + "\n" + '' - + (0 < row ? row : 'No') - + ' recommended result' + (1 == row ? '' : 's') + '...' + "\n" - + resultStr - + '
' - ); - updateSampleText(); - myform.loadsection(0); - $('.stepone-result-radio, .stepone-result-title, .service').each(addQTip); - } - ); - } - - $('#addShowButton').click(function () { - // if they haven't picked a show don't let them submit - if (!$('input:radio[name="whichSeries"]:checked').val() - && !$('input:hidden[name="whichSeries"]').val().length) { - alert('You must choose a show to continue'); - return false; - } - $('#addShowForm').submit(); - }); - - $('#qualityPreset').change(function (){ - myform.loadsection(2); - }); - - var myform = new FormToWizard({ - fieldsetborderwidth: 0, - formid: 'addShowForm', - revealfx: ['slide', 500], - oninit: function (){ - getRecommendedShows(); - updateSampleText(); - } - }); - - function goToStep(num){ - $('.step').each(function (){ - if ($.data(this, 'section') + 1 == num){ - $(this).click(); - } - }); - } - - function updateSampleText(){ - // if something's selected then we have some behavior to figure out - - var elRadio = $('input:radio[name="whichSeries"]:checked'), - elFullShowPath = $('#fullShowPath'), - sep_char = '', - root_dirs = $('#rootDirs'), - // if they've picked a radio button then use that - show_name = (elRadio.length ? elRadio.val().split('|')[2] : ''), - sample_text = '

Adding show ' + show_name + '' - + ('' == show_name ? 'into
' : '
into') - + ' '; - - // if we have a root dir selected, figure out the path - if (root_dirs.find('option:selected').length){ - var root_dir_text = root_dirs.find('option:selected').val(); - if (0 <= root_dir_text.indexOf('/')){ - sep_char = '/'; - } else if (0 <= root_dir_text.indexOf('\\')){ - sep_char = '\\'; - } - - root_dir_text += (sep_char != root_dir_text.substr(sample_text.length - 1) - ? sep_char : '') - + '||' + sep_char; - - sample_text += root_dir_text; - } else if (elFullShowPath.length && elFullShowPath.val().length){ - sample_text += elFullShowPath.val(); - } else { - sample_text += 'unknown dir.'; - } - - sample_text += '

'; - - // if we have a show name then sanitize and use it for the dir name - if (show_name.length){ - $.get(sbRoot + '/home/addShows/sanitizeFileName', {name: show_name}, function (data){ - $('#displayText').html(sample_text.replace('||', data)); - }); - // if not then it's unknown - } else { - $('#displayText').html(sample_text.replace('||', '??')); - } - - // also toggle the add show button - $('#addShowButton').attr('disabled', - ((root_dirs.find('option:selected').length - || (elFullShowPath.length && elFullShowPath.val().length)) - && elRadio.length - ? false : true)); - } - - var addQTip = (function(){ - $(this).css('cursor', 'help'); - $(this).qtip({ - show: { - solo: true - }, - position: { - viewport: $(window), - my: 'left center', - adjust: { - y: -10, - x: 2 - } - }, - style: { - tip: { - corner: true, - method: 'polygon' - }, - classes: 'qtip-rounded qtip-bootstrap qtip-shadow ui-tooltip-sb' - } - }); - }); - - $('#rootDirText').change(updateSampleText); - - $('#searchResults').on('click', '.stepone-result-radio', updateSampleText); - -}); diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 60a694f9..03fdaec3 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -23,6 +23,7 @@ import time import urllib import re import datetime +import dateutil.parser import random import traceback @@ -2283,100 +2284,129 @@ class NewHomeAddShows(Home): return t.respond() - def recommendedShows(self, *args, **kwargs): - """ - Display the new show page which collects a tvdb id, folder, and extra options and - posts them to addNewShow - """ - self.set_header('Cache-Control', 'no-cache, no-store, must-revalidate') - self.set_header('Pragma', 'no-cache') - self.set_header('Expires', '0') + def traktTrending(self, *args, **kwargs): - t = PageTemplate(headers=self.request.headers, file='home_recommendedShows.tmpl') - t.submenu = self.HomeMenu() - t.enable_anime_options = False + return self.browse_trakt('shows/trending?limit=%s&' % 100, 'Trending at Trakt', mode='trending') - return t.respond() + def traktRecommended(self, *args, **kwargs): - def getRecommendedShows(self, *args, **kwargs): - final_results = [] + return self.browse_trakt('recommendations/shows?limit=%s&' % 100, + 'Recommended for you by Trakt', mode='recommended') - logger.log(u'Getting recommended shows from Trakt.tv', logger.DEBUG) - recommendedlist = TraktCall('recommendations/shows.json/%API%', sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, - sickbeard.TRAKT_PASSWORD) + def traktNewShows(self, *args, **kwargs): - if recommendedlist == 'NULL': - logger.log(u'No shows found in your recommendedlist, aborting recommendedlist update', logger.DEBUG) - return + return self.browse_trakt('/calendars/all/shows/new/%s/%s?' % (sbdatetime.sbdatetime.sbfdate( + dt=datetime.datetime.now() + datetime.timedelta(days=-16), d_preset='%Y-%m-%d'), 32), 'Brand-new shows at Trakt', + mode='newshows', footnote='Note; Expect default placeholder images in this list') - if recommendedlist is None: - logger.log(u'Could not connect to trakt service, aborting recommended list update', logger.ERROR) - return + def traktNewSeasons(self, *args, **kwargs): - map(final_results.append, - ([show['url'], - show['title'], - show['overview'], - sbdatetime.sbdatetime.sbfdate(datetime.date.fromtimestamp(int(show['first_aired']))), - sickbeard.indexerApi(1).name, - sickbeard.indexerApi(1).config['icon'], - int(show['tvdb_id'] or 0), - '%s%s' % (sickbeard.indexerApi(1).config['show_url'], int(show['tvdb_id'] or 0)), - sickbeard.indexerApi(2).name, - sickbeard.indexerApi(2).config['icon'], - int(show['tvrage_id'] or 0), - '%s%s' % (sickbeard.indexerApi(2).config['show_url'], int(show['tvrage_id'] or 0)) - ] for show in recommendedlist if not helpers.findCertainShow(sickbeard.showList, indexerid=int(show['tvdb_id'])))) + return self.browse_trakt('/calendars/all/shows/premieres/%s/%s?' % (sbdatetime.sbdatetime.sbfdate( + dt=datetime.datetime.now() + datetime.timedelta(days=-16), d_preset='%Y-%m-%d'), 32), 'Season premieres at Trakt', + mode='newseasons', footnote='Note; Expect default placeholder images in this list') - self.set_header('Content-Type', 'application/json') - return json.dumps({'results': final_results}) + def browse_trakt(self, url, browse_title, *args, **kwargs): - def addRecommendedShow(self, whichSeries=None, indexerLang='en', rootDir=None, defaultStatus=None, - anyQualities=None, bestQualities=None, flatten_folders=None, subtitles=None, - fullShowPath=None, other_shows=None, skipShow=None, providedIndexer=None, anime=None, - scene=None): + browse_type = 'Trakt' + normalised, filtered = ([], []) - indexer = 1 - indexer_name = sickbeard.indexerApi(int(indexer)).name - show_url = whichSeries.split('|')[1] - indexer_id = whichSeries.split('|')[0] - show_name = whichSeries.split('|')[2] + if 'recommended' == kwargs.get('mode', None) and not sickbeard.USE_TRAKT: + error_msg = 'To browse personal recommendations, enable Trakt.tv in Config/Notifications/Social' + return self.browse_shows(browse_type, browse_title, filtered, error_msg=error_msg, show_header=1, **kwargs) - return self.addNewShow('|'.join([indexer_name, str(indexer), show_url, indexer_id, show_name, '']), - indexerLang, rootDir, - defaultStatus, - anyQualities, bestQualities, flatten_folders, subtitles, fullShowPath, other_shows, - skipShow, providedIndexer, anime, scene) - - def trendingShows(self, *args, **kwargs): - """ - Display the new show page which collects a tvdb id, folder, and extra options and - posts them to addNewShow - """ - t = PageTemplate(headers=self.request.headers, file='home_trendingShows.tmpl') - t.submenu = self.HomeMenu() - - trakt_api = TraktAPI() - limit_show = 50 + error_msg = None try: - t.trending_shows = trakt_api.trakt_request("shows/trending?limit=" + str(limit_show) + "&extended=full,images") or [] - t.trending_inlibrary = 0 - if None is not t.trending_shows: - for item in t.trending_shows: - tvdbs = ['tvdb_id', 'tvrage_id'] - for index, tvdb in enumerate(tvdbs): - try: - item[u'show_id'] = str(item[tvdb]) - tvshow = helpers.findCertainShow(sickbeard.showList, int(item[tvdb])) - except: - continue - # check tvshow indexer is not using the same id from another indexer - if tvshow and (index + 1) == tvshow.indexer: - item[u'show_id'] = u'%s:%s' % (tvshow.indexer, item[tvdb]) - t.trending_inlibrary += 1 - break + resp = TraktAPI(ssl_verify=sickbeard.TRAKT_VERIFY, timeout=sickbeard.TRAKT_TIMEOUT).trakt_request('%sextended=full,images' % url) + if resp: + if 'show' in resp[0]: + if 'first_aired' in resp[0]: + for item in resp: + item['show']['first_aired'] = item['first_aired'] + del item['first_aired'] + normalised = resp + else: + for item in resp: + normalised.append({u'show': item}) + del resp + except traktAuthException as e: + logger.log(u'Pin authorisation needed to connect to Trakt service: %s' % ex(e), logger.WARNING) + error_msg = 'Unauthorized: Get another pin in the Notifications Trakt settings' except traktException as e: - logger.log(u"Could not connect to Trakt service: %s" % ex(e), logger.WARNING) + logger.log(u'Could not connect to Trakt service: %s' % ex(e), logger.WARNING) + except (IndexError, KeyError): + pass + + oldest_dt = 9999999 + newest_dt = 0 + oldest = None + newest = None + for item in normalised: + try: + dt = dateutil.parser.parse(item['show']['first_aired']) + dt_ordinal = dt.toordinal() + dt_string = sbdatetime.sbdatetime.sbfdate(dt) + if dt_ordinal < oldest_dt: + oldest_dt = dt_ordinal + oldest = dt_string + if dt_ordinal > newest_dt: + newest_dt = dt_ordinal + newest = dt_string + filtered.append(dict( + premiered=dt_ordinal, + premiered_str=dt_string, + genres='' if 'genres' not in item['show'] else ', '.join(['%s' % v for v in item['show']['genres']]), + ids=item['show']['ids'], + images='' if 'images' not in item['show'] else item['show']['images'], + overview='' if 'overview' not in item['show'] or None is item['show']['overview'] else re.sub( + r'[\"\']+', '', item['show']['overview'][:250:].strip()), + rating='0' if 'rating' not in item['show'] else '%.2f' % (item['show']['rating'] * 10), + title=item['show']['title'].strip(), + url_src_db='https://trakt.tv/shows/%s' % item['show']['ids']['slug'], + url_tvdb=('', '%s%s' % (sickbeard.indexerApi(INDEXER_TVDB).config['show_url'], + item['show']['ids']['tvdb']))[isinstance(item['show']['ids']['tvdb'], (int, long)) + and 0 < item['show']['ids']['tvdb']], + votes='0' if 'votes' not in item['show'] else item['show']['votes'])) + except: + pass + + kwargs.update(dict(oldest=oldest, newest=newest, error_msg=error_msg)) + return self.browse_shows(browse_type, browse_title, filtered, **kwargs) + + def addTraktShow(self, indexer_id, showName): + + if not helpers.findCertainShow(sickbeard.showList, config.to_int(indexer_id, '')): + return self.newShow('|'.join(['', '', '', config.to_int(indexer_id, None) and indexer_id or showName]), + use_show_name=True) + + def browse_shows(self, browse_type, browse_title, shows, *args, **kwargs): + """ + Display the new show page which collects a tvdb id, folder, and extra options and + posts them to addNewShow + """ + t = PageTemplate(headers=self.request.headers, file='home_browseShows.tmpl') + t.submenu = self.HomeMenu() + t.browse_type = browse_type + t.browse_title = browse_title + t.all_shows = shows + t.kwargs = kwargs + + t.all_shows_inlibrary = 0 + for item in t.all_shows: + item['show_id'] = '' + for index, tvdb in enumerate(['tvdb', 'tvrage']): + try: + item['show_id'] = str(item['ids'][tvdb]) + tvshow = helpers.findCertainShow(sickbeard.showList, item['show_id']) + except: + continue + # check tvshow indexer is not using the same id from another indexer + if tvshow and (index + 1) == tvshow.indexer: + item['show_id'] = u'%s:%s' % (tvshow.indexer, tvshow.indexerid) + t.all_shows_inlibrary += 1 + break + + if None is not config.to_int(item['show_id'], None): + break return t.respond() @@ -2392,11 +2422,6 @@ class NewHomeAddShows(Home): return t.respond() - def addTraktShow(self, indexer_id, showName): - if helpers.findCertainShow(sickbeard.showList, config.to_int(indexer_id, '')): - return - return self.newShow('|'.join(['', '', indexer_id, showName]), use_show_name=True) - def addNewShow(self, whichSeries=None, indexerLang='en', rootDir=None, defaultStatus=None, quality_preset=None, anyQualities=None, bestQualities=None, flatten_folders=None, subtitles=None, fullShowPath=None, other_shows=None, skipShow=None, providedIndexer=None, anime=None, @@ -2436,15 +2461,15 @@ class NewHomeAddShows(Home): # figure out what show we're adding and where series_pieces = whichSeries.split('|') if (whichSeries and rootDir) or (whichSeries and fullShowPath and len(series_pieces) > 1): - if len(series_pieces) < 6: + if len(series_pieces) < 4: logger.log('Unable to add show due to show selection. Not enough arguments: %s' % (repr(series_pieces)), logger.ERROR) ui.notifications.error('Unknown error. Unable to add show due to problem with show selection.') return self.redirect('/home/addShows/existingShows/') - indexer = int(series_pieces[1]) - indexer_id = int(series_pieces[3]) - show_name = series_pieces[4] + indexer = int(series_pieces[0]) + indexer_id = int(series_pieces[2]) + show_name = series_pieces[3] else: # if no indexer was provided use the default indexer set in General settings if not providedIndexer: