SickGear/gui/slick/interfaces/default/displayShow.tmpl
Prinz23 7a6936823e Change improve tmdb_api, trakt_api, and TVInfoShow object.
Add `spoken_languages` to tmdb API and TVInfoShow object.
Add `trailers`, `homepage` to trakt API and TVInfoShow object.
Add trakt episode data if returned from api.
Add trakt API methods.
- get_most_played
- get_most_watched
- get_most_collected
- get_anticipated
- get_recommended
- get_trending
- get_popular
- get_recommended_for_account
- get_new_shows
- get_new_seasons
- get_watchlisted_for_account
- get_similar
- hide_recommended_for_account (to hide/remove recommended shows for account)
- unhide_recommended_for_account
- list_hidden_recommended_for_account

Fix caching tmdb language list over different runtime instances.
Add episode_count and fix ti_show in tmdb_api person object.
Change set additional properties in get_person trakt_api.

Add tmdb API methods and tvinfo_base.
- get_recommended_for_show
- get_similar
---
fix supported language caching
improve print output (source name) of tvinfo_api_tests
fix tvinfo_api_tests data creation
---
Add code so that it runs with all_test

use mock today() and now() dates
add option to only get new urls mock data
try also to make object creation only when needed
fix person parser in tmdb_api
add search_person test in tvinfo_api_tests
restore mocked methods at the end of the tvinfo_api_tests to prevent other tests to fail when called via all_tests
switch gzip with better lzma compression for mock files (default lib in py3)
move mock files in test unit sub folder
---
Fix trakt method `get_recommended`.
Fix browse trakt tests in tvinfo_api_tests.
Change set episode id in trakt api.
---
Add test_browse_endpoints to tvinfo_api_tests.
---
Add enforce_type to sg_helpers.
Change use enforce str for overviews.
Change remove `if PY2` code sections
Add support for  datetime.time in _make_airtime in tv.py
Refactor tvmaze_api show data setter.
Change test to not allow None for seriesname.
Add additional missing showdata with caller load_data().
Add load_data() to TVInfoShow.
Add guestcast, guestcrew to episodes in pytvmaze lib.
---
Change make seriesid of TVInfoShow a alias property of id.

Add tvinfo tests.
Add search tests.
Add show, person tests.
Change add trakt tests.
Change add tmdb search tests.
tvmaze_api exclude rating from mapping.
Allow None for seriesname.
Fix origin_countries in trakt_api search.
Fix show_type in tvmaze_api.
Fix airtime for episodes in tvmaze_api.
---
Change switch to property instead of legacy dict-like use for trakt search results.
Change optimize speed of get() function.
Fix make BaseTVinfoSeasonnotfound and BaseTVinfoAttributenotfound also a subclass of AttributeError and KeyError.
Change mock get() to work with and without default args just like dict get().
Change add language to tmdb_api search results.
Change improve person search by remote id, by getting the complete persons data when there is only 1 result.
Change trakt API search results to tvinfoshow.
Change search results to TVInfoShow objs in tvmaze_api.
Change simplify poster URL generation for search results.
Change search results to TVInfoShow objs.

Change add tvdb genre links to displayShow.

Change workaround for missing data in person data (series set to None).

Fix add show to characters of person if there is no name on IMDb (set to 'unknown name').

Change add config and icons for linkedin, reddit, wikidata, youtube.

Add TVInfoIDs, TVInfoSocialIDs to Trakt.
Add TVInfoIDs to tmdb_api.
Add TVInfoIDs to tvmaze_api.
add TVInfoIDs to imdb_api.

Change make character name '' if None.

Fix for 'unknown name' persons and characters.

Add contentrating.

Change fill in new fields to get_person results.

----

Change set new in/active dates to network.

Change add active_date, inactive_date to TVInfoNetwork class.

Change add default kwargs to tmdb discover method if no kwargs are set.
Change default: English language shows with first air date greater then today.

Change add slug field to returned data from discover.

Change add 'score' mapped to rating to discover returned results.

Fix valid_data for discover method.

Change add result_count to discover.

Change add _sanitise_image_uri to discover method.

Fix convert_person.

Change add missing  _sanitise_image_uri for images in some places.

Fix crew.

Change return type of tvinfo base: discover to list tvinfoshow.

Fix people remote id search.
Change add tmdb person id search.

Change fix people endpoint fieldname changes.

Change add biography to person object.

Change move 401 expired token handling into TvdbAuth class.

Change get new token if old token is expired.

Change add raise error if episodes fallback fails to load data.
Change add break if no valid_data to absolute and alternative numberings.
Change add filter only networks.
Change add new required parameter meta=translations to get translated (includes the original language) show overviews.
Change add check if show is set for person compare.
Fix person update properties with no show set.
Change add person image.

Change add alternative episode orders.
Change add alt_ep_numbering to TVINFO_Show.
Change add old interface for dvd order.

Change add trakt slug tvinfo search test cases.

Change add mock for old tvdb get new token.

Change old lib to newer tvinfo data.

Fix person id (not available on old api).

Change more places to new TVInfoAPI interface.
2023-05-03 00:43:59 +01:00

633 lines
32 KiB
Cheetah

#import re
#import sickgear
#from sickgear import TVInfoAPI, indexermapper, network_timezones
#from sickgear.common import Overview, qualityPresets, qualityPresetStrings, \
Quality, statusStrings, WANTED, SKIPPED, ARCHIVED, IGNORED, FAILED, DOWNLOADED
#from sickgear.helpers import anon_url, get_size, human, maybe_plural, generate_word_str
#from sickgear.indexers.indexer_config import TVINFO_TVDB, TVINFO_IMDB
#from six import iteritems
<% def sg_var(varname, default=False): return getattr(sickgear, varname, default) %>#slurp#
<% def sg_str(varname, default=''): return getattr(sickgear, varname, default) %>#slurp#
##
#set global $title = getattr($show_obj, 'unique_name', $show_obj.name)
#set global $topmenu = 'home'
#set $exceptions_string = ', '.join($show_obj.exceptions)
#set $css = $getVar('css', 'reg')
#set $has_art = $getVar('has_art', None)
#set $restart = 'Restart SickGear for new features on this page'
#set $show_message = ($show_message, $restart)[None is $has_art]
#set global $page_body_attr = 'display-show" class="' + $css
#set theme_suffix = ('', '-dark')['dark' == $sg_str('THEME_NAME', 'dark')]
##
#import os.path, os, re
#set global $inc_top_glide = True
#set global $inc_ofi = True
#include $os.path.join($sg_str('PROG_DIR'), 'gui/slick/interfaces/default/inc_top.tmpl')
<script type="text/javascript" src="$sbRoot/js/cast.js?v=$sbPID"></script>
<input type="hidden" id="sbRoot" value="$sbRoot">
<script>
<!--
var config = {
hasArt: #echo ('!0', '!1')[not $has_art]#,
TVShowList: ${tvshow_id_csv},
useIMDbInfo: #echo ('!1', '!0')[$sg_var('USE_IMDB_INFO')]
}
\$.SickGear.config = {
useFuzzy: #echo ('!1', '!0')[$sg_var('FUZZY_DATING')]##if $sg_var('FUZZY_DATING')#,
dateFormat: '$sg_str('DATE_PRESET', '%x')',
timeFormat: '$sg_str('TIME_PRESET', '%I:%M %p')',
fuzzyTrimZero: #echo ('!1', '!0')[$sg_var('TRIM_ZERO')]##end if#,
glideStartAt: '#echo $sg_var('DISPLAY_SHOW_GLIDE', {}).get($show_obj.tvid_prodid, {}).get('start_at', '')#',
glideSlideTime: #echo $sg_var('DISPLAY_SHOW_GLIDE_SLIDETIME')#
}
//-->
</script>
<script type="text/javascript" src="$sbRoot/js/displayShow.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/plotTooltip.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/sceneExceptionsTooltip.js?v=$sbPID"></script>
#if $sg_var('USE_IMDB_INFO')
<script type="text/javascript" src="$sbRoot/js/ratingTooltip.js?v=$sbPID"></script>
#end if
<script type="text/javascript" src="$sbRoot/js/ajaxEpSearch.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/ajaxEpSubtitles.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/lib/jquery.bookmarkscroll.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/lib/jquery.collapser.min.js?v=$sbPID"></script>
<script src="$sbRoot/js/lib/select2.full.min.js"></script>
<link href="$sbRoot/css/lib/select2.css" rel="stylesheet">
<style>
.bfr{position:absolute;left:-999px;top:-999px}.bfr img,.spinner,.spinner2,img.queued,img.search,img.success,img.upgrade{display:inline-block;width:16px;height:16px}.spinner{background:url(${sbRoot}/images/loading16${theme_suffix}.gif) no-repeat 0 0}.spinner2{background:url(${sbRoot}/images/loading16-red.gif) no-repeat 0 0}img.queued{background:url(${sbRoot}/images/queued.png) no-repeat 0 0}img.search{background:url(${sbRoot}/images/search16.png) no-repeat 0 0}img.success{background:url(${sbRoot}/images/down-success.png) no-repeat 0 0}img.upgrade{background:url(${sbRoot}/images/down-upgrade.png) no-repeat 0 0}
.images i{margin-right:6px;margin-top:5px}.hide{display:none}
.tvshowImg{border:1px solid transparent;min-width:226px;min-hieght:332px}.spinner2{margin-top:3px !important}
.select2-results__group{color: #eee; background-color: rgb(51,51,51)}
.select2-results__options .select2-results__option{color: #222; background-color: #ddd}
.select2-results__options .select2-results__option .ended{color: #888}
.select2-container .ended .label{background-color: #888; padding: 1px 4px; margin-right: 2px; line-height: 2; color: #ddd !important}
.select2-results__option--selected span{color:rgb(143, 21, 21) !important}
.select2-container--default .select2-results > .select2-results__options{max-height: 300px}
#select2-pickShow-results .select2-results__option,
#select2-pickShow-results .select2-results__group{padding-top: 2px !important; padding-bottom:2px !important}
#select2-pickShow-results .select2-results__option--highlighted.select2-results__option--selectable .ended{color:white}
</style>
<div class="bfr"><img src="$sbRoot/images/loading16${theme_suffix}.gif"><img src="$sbRoot/images/loading16-red.gif"><img src="$sbRoot/images/queued.png"><img src="$sbRoot/images/search16.png"><img src="$sbRoot/images/no16.png"><img src="$sbRoot/images/yes16.png"><img src="$sbRoot/images/down-success.png"><img src="$sbRoot/images/down-upgrade.png"></div>
<div id="background-container">
#if $has_art
<ul>
#for $k, ($image, $rating) in enumerate($fanart)
<li class="#echo ' '.join((x for x in ({10:'group', 20:'fave', 30:'avoid'}.get($rating, ''), ('', 'background first-load')[$start_image == $k]) if x)) #" style="background-image:url($sbRoot/show-poster/?tvid_prodid=$show_obj.tvid_prodid&which=fanart_$image)"></li>
#end for
</ul>
#end if
</div>
<div class="displayshow-wrapper">
<div id="change-show" class="pull-left form-inline">
Change show:
#set $displayshowlist = []
#set $cur_sel = 0
#for $cur_showlist in $sortedShowLists
#set $cur_showtype = $cur_showlist[0]
#set $cur_showlist = $cur_showlist[1]
#if 1 < len($sortedShowLists)
#set void = $displayshowlist.append('\t\t\t<optgroup label="%s">' % $cur_showtype)
#end if
#for $cur_show_obj in $cur_showlist
#set $show_ended = '' != $cur_show_obj.status and $cur_show_obj.status in ['ended', 'Ended', 'Canceled']
#set void = $displayshowlist.append('\t\t\t<option %svalue="%s"%s>%s</option>' % (('', 'class="ended" ')[$show_ended], $cur_show_obj.tvid_prodid, ('', ' selected="selected"')[$cur_show_obj == $show_obj], getattr($cur_show_obj, 'unique_name', $cur_show_obj.name)))
#end for
#if 1 < len($sortedShowLists)
#set void = $displayshowlist.append('\t\t\t</optgroup>')
#end if
#end for
##
<div id="prevShow" class="navShow addQTip" title="$prev_title">&nbsp;</div>
<select id="pickShow" class="form-control form-control-inline input-sm">
#echo '\n'.join($displayshowlist)#
</select>
<div id="nextShow" class="navShow addQTip" title="$next_title">&nbsp;</div>
</div>
<div class="clearfix" style="margin-bottom:15px"></div>
#if $show_message
<div class="alert alert-info">$show_message</div>
#end if
<div class="display-show-container">
<div id="posterCol" class="hidden-xs">
<a href="$sbRoot/show-poster/?tvid_prodid=$show_obj.tvid_prodid&amp;which=poster" rel="dialog">
<img src="$sbRoot/show-poster/?tvid_prodid=$show_obj.tvid_prodid&amp;which=poster_thumb" title="View poster for $show_obj.name" class="tvshowImg addQTip" alt="">
</a>
</div>
<div id="showCol">
<div class="details-wrapper">
<div class="details-right top">
#if 0 < len($seasons)
#set $show_ended = '' != $show_obj.status and $show_obj.status in ['ended', 'Ended', 'Canceled']
<div>
#if $getVar('has_special', 0 == $seasons[-1][0])
<span class="details-title">Specials</span>
<span class="details-info">#if $sg_var('DISPLAY_SHOW_SPECIALS')#<a href="#season-0">View</a><span style="margin:0 7px">-</span>#end if#<a class="inner" href="$sbRoot/toggle-specials-view-show/?tvid_prodid=$show_obj.tvid_prodid">#echo ('Show', 'Hide')[$sg_var('DISPLAY_SHOW_SPECIALS')]#</a></span>
#end if
</div>
#set $many_seasons = 12 < len($seasons)
<div class="details-seasons">
<span class="details-title#echo ('', ' combo-seasons')[$many_seasons]#">Season</span>
<span class="details-info">
#set $season_list = [s[0] for s in $seasons]
#if $many_seasons
<select id="seasonJump" class="form-control form-control-inline input-sm">
<option value="jump">Jump to season</option>
#for $number in $season_list
#if 0 != $number
<option value="#season-$number">Season $number</option>
#end if
#end for
</select>
#else
#for $number in $season_list
#if 0 != $number
<a href="#season-$number">$number</a>
#end if
#end for
#end if
</span>
</div>
#end if
</div>
<style>
#showtitle .label{float: left; margin:0 4px 3px 0; padding:6px 4px 5px}
#showtitle:after{display:block; content:"."; height:0; clear:both; visibility:hidden}
</style>
<div id="details-top">
<div id="showtitle" data-showname="$show_obj.name">
<h2 class="title" id="scene_exception_$show_obj.tvid_prodid"><span>$show_obj.name</span>#echo ('', '<em id="title-status"> (ended)</em>')[$show_ended]#</h2>
#set $genres_done = False
#if $sg_var('USE_IMDB_INFO') and 'genres' in $show_obj.imdb_info and '' != $show_obj.imdb_info['genres']
#for $imdbgenre in [$g for $g in $show_obj.imdb_info['genres'].split('|') if $g]
#set $genres_done = True
<span class="label"><a href="<%= anon_url('http://www.imdb.com/search/title?at=0&genres=', imdbgenre.lower().replace('-','_'),'&amp;sort=moviemeter,asc&amp;title_type=tv_series') %>" target="_blank" title="View other popular $imdbgenre shows on imdb.com" class="addQTip">$imdbgenre.replace('Sci-Fi','Science-Fiction')</a></span>
#end for
#end if
#if not $genres_done and $show_obj.genre
#for $genre in $show_obj.genre.split('|')
#set $genres_done = True
<span class="label">
#if $TVINFO_TVDB == $show_obj.tvid
<a href="https://thetvdb.com/genres/$genre" target="_blank" title="View other popular $genre shows on thetvdb.com" class="addQTip">$genre</a>
#else
$genre
#end if
</span>
#end for#
#end if
#if not $genres_done
<span class="label">No genres</span>
#end if
</div>
</div>
</div>
<div class="details-wrapper">
<div class="details-right">
#if int($show_obj.paused)
<div class="paused-holder">
<div class="paused paused-highlight">
<i class="sgicon-pause paused-outline"></i>
</div>
</div>
#end if
<div>
<span class="details-title">Links</span>
<span class="details-info">
<style>
.main span{border-bottom:1px solid #0a0}
</style>
#set $tvdb_id = None
#for $src_id, $src_name in iteritems($TVInfoAPI().all_sources)
#if $TVInfoAPI($src_id).config.get('defunct') and $src_id != $show_obj.tvid
#continue
#end if
#if $src_id in $show_obj.ids and $show_obj.ids[$src_id].get('id', 0) > 0 and $indexermapper.MapStatus.NOT_FOUND != $show_obj.ids[$src_id]['status']
#if $TVINFO_TVDB == $src_id
#set $tvdb_id = $show_obj.ids[$src_id]['id']
#end if
#if $TVINFO_IMDB == $src_id and not $sg_var('USE_IMDB_INFO')
#continue
#end if
#if not $TVInfoAPI($src_id).config.get('defunct')
<a class="service addQTip#if $show_obj.tvid == $src_id# main#end if#" href="$anon_url($TVInfoAPI($src_id).config['show_url'] % $show_obj.ids[$src_id]['id'])" rel="noreferrer" onclick="window.open(this.href, '_blank'); return !1;" title="View $src_name info in new tab">
#else#
<a class="service addQTip" href="$sbRoot/home/edit-show?tvid_prodid=$show_obj.tvid_prodid#core-component-group3" title="Edit related show IDs">
#end if#
<span><img alt="$src_name" height="16" width="16" src="$sbRoot/images/$TVInfoAPI($src_id).config['icon']" /></span>
</a>
#end if
#end for
#if $has_art and $tvdb_id
<a class="service addQTip" href="$anon_url('https://fanart.tv/series/', $tvdb_id)" rel="noreferrer" onclick="window.open(this.href, '_blank'); return !1;" title="View Fanart.tv info in new tab">
<img alt="Fanart.tv" height="16" width="16" src="$sbRoot/images/fanart.png" />
</a>
#end if
#if $xem_numbering or $xem_absolute_numbering
<a class="service addQTip" href="$anon_url('http://thexem.info/search?q=', $show_obj.name)" rel="noreferrer" onclick="window.open(this.href, '_blank'); return !1;" title="View XEM info in new tab"><img alt="[xem]" height="16" width="16" src="$sbRoot/images/xem.png" /></a>
#end if
</span>
</div>
#set $startyear, $flags, $runtime = (None, False, None)
#if $sg_var('USE_IMDB_INFO') and $show_obj.imdbid
#if 'year' in $show_obj.imdb_info
#set $startyear = $show_obj.imdb_info['year'] or None
#end if
#set $flags = 'country_codes' in $show_obj.imdb_info and '' != $show_obj.imdb_info['country_codes']
#if 'runtimes' in $show_obj.imdb_info
#set $runtime = $show_obj.imdb_info['runtimes'] or 0
#set $episode_count = $show_obj.imdb_info['episode_count'] or 0
## test if average mini-series runtime is reasonable before using it,
## apply only to a runtime > 60 minutes, and assume 9.x minutes is the minimum (e.g. robot chicken)
#if $show_obj.imdb_info['is_mini_series'] and 1 < $episode_count \
and $runtime and 90 < $runtime:
#set $average_runtime = $runtime/$episode_count
#if 9 < $average_runtime:
#set $runtime = '%s (av %s?)' % ($runtime, int($average_runtime))
#end if
#end if
#end if
#end if
#if None is $startyear and $show_obj.startyear
#set $startyear = $show_obj.startyear
#end if
#if None is $runtime and $show_obj.runtime
#set $runtime = $show_obj.runtime
#end if
#if $startyear or $flags
<div>
<span class="details-title">Premiered</span>
<span class="details-info">
<span class="space-right">#echo ($startyear, 'Unknown')[None is $startyear]#</span>
#if $flags
#for $country in $show_obj.imdb_info['country_codes'].split('|')
<img class="flag space-right" src="$sbRoot/images/flags/${$country.lower()}.png" width="16" height="11" />
#end for
#end if
</span>
</div>
#end if
#if $show_obj.airs
#set $showairs = '%s%s' % ($re.sub(r'(?:s|nes|rs|ur)?day', '', $re.sub(r'(y)[^\w]+', r'\1, ', $show_obj.airs)),
('', ' <span class="red-text" style="font-weight:bold">(time unknown)</span>')[not $network_timezones.test_timeformat($show_obj.airs)])
#set $showairs = $showairs.replace('Sat, Sun', 'Sat - Sun').replace('Mon, Tue, Wed, Thu, Fri', 'Mon - Fri').replace('Mon, Tue, Wed, Thu', 'Mon - Thu').replace('Tue, Wed, Thu', 'Tue - Thu')
<div>
<span class="details-title">Air#echo ('s', 'ed')[$show_ended]#</span>
<span class="details-info">$showairs</span>
</div>
#end if
#if $show_obj.network
<div>
<span class="details-title">Network</span>
<span class="details-info">$show_obj.network</span>
</div>
#end if
#if None is not $runtime
<div>
<span class="details-title">Runtime</span>
<span class="details-info">$runtime mins.</span>
</div>
#end if
#if $show_obj.status
<div>
<span class="details-title">Status</span>
<span class="details-info">$show_obj.status</span>
</div>
#end if
#if $sg_var('USE_IMDB_INFO') and 'rating' in $show_obj.imdb_info
<div>
<span class="details-title">IMDb rating</span>
<span class="details-info">
#if $show_obj.imdb_info['votes']
#set $rating_tip = '%s of 10 stars<br />%s votes' % (str($show_obj.imdb_info['rating']), str($show_obj.imdb_info['votes']))
<span class="imdbstars" qtip-content="$rating_tip">$show_obj.imdb_info['rating']</span>
#else
<span>No votes available</span>
#end if
</span>
</div>
#end if
#set $anyQualities, $bestQualities = $Quality.split_quality(int($show_obj.quality))
#if $show_obj.quality in $qualityPresets
<div>
<span class="details-title">Quality</span>
<span class="details-info">
<span class="quality $qualityPresetStrings[$show_obj.quality]">$qualityPresetStrings[$show_obj.quality]</span>
</span>
</div>
#else
#if $anyQualities
<div>
<span class="details-title">Qualities</span>
<span class="details-info">
#echo ', '.join([$Quality.get_quality_ui($x) for $x in sorted($anyQualities)])#
</span>
</div>
#end if
#if $bestQualities
<div>
<span class="details-title">Upgrade to</span>
<span class="details-info">
#echo ', '.join([$Quality.get_quality_ui($x) for $x in sorted($bestQualities)])#
</span>
</div>
#end if
#end if
</div>
<div id="details-left">
#set $has_overview = '' != $show_obj.overview
#set $ep_tally = ('', '(<span class="hint">%s episodes</span>)' % $ep_counts['eps_all'])[0 < $ep_counts['eps_all']]
<div class="#echo ('no', 'details')[$has_overview]#-plot">
#set $cast_list = $show_obj.cast_list
#if $cast_list
<%
def param(visible=True, rid=None, cache_person=None, cache_char=None, person=None, role=None, tvid_prodid=None, thumb=None, oid=None, pid=None):
"""
make the url param list
"""
if cache_char or role:
oid = ('oid=%s' % oid, '')[not visible or None is oid or str(rid) == str(oid)]
return ('imagecache/character?', '')[not cache_char] + '&amp;'.join([kv for kv in ('rid=%s' % rid, 'tvid_prodid=%s' % (cache_char or role).tvid_prodid, ('', 'thumb=%s' % thumb)[not role and None is not thumb], ('person_id=%s' % pid, '')[not pid], ('prefer_person=1', '')[not pid], oid) if kv])
if cache_person:
oid = ('oid=%s' % oid, '')[not visible or None is oid or str(rid) == str(oid)]
return 'imagecache/person?' + '&amp;'.join([kv for kv in ('pid=%s' % rid, ('', 'thumb=%s' % thumb)[None is not thumb], oid) if kv])
if person:
oid = ('oid=%s' % person.id, '')[not visible or str(person.ref_id()) == str(person.id)]
return '&amp;'.join([kv for kv in ('rid=%s' % person.ref_id(), oid) if kv])
return 'param not implemented properly'
%>
#set $cast = {'1st': [], '2nd': []}
#for $cur_cast in $cast_list
#set $cast[('1st', '2nd')[not $cur_cast.name]] += [$cur_cast]
#end for
<div class="contain-glide">
<span class="cast-holder glide--swipeable">
<div class="cast-panel glide__track" data-glide-el="track">
<ul class="glide__slides">
#for $cur_cast in $cast['1st'] + $cast['2nd']
#set $by_people = [] if not $cur_cast.person else [$cur_person.name for $cur_person in $cur_cast.person]
#set $by_people = ', '.join($by_people if 2 > len($by_people) else $by_people[0:-1] + ['and ' + $by_people[-1]])
#set $caption = ' '.join(([] if not $cur_cast.name else [$cur_cast.name]) + ([] if not $by_people else ['by', $by_people])).replace('"', '&quot;')
<li class="cast body glide__slide" data-rid="$next($iter($cur_cast.person)).ref_id()">
<a class="thumb" href="$sbRoot/$param(rid=$cur_cast.ref_id(), cache_char=$show_obj, thumb=0, oid=$cur_cast.id)"#if $caption# data-caption="$caption"#end if# rel="glide"><img class="cast-bg" style="display:none" height="150" src="$sbRoot/$param(False, rid=$cur_cast.id, cache_char=$show_obj)"#if $cur_cast.name# alt=""#end if#></a>
<div class="links" style="display:none">
#if $cur_cast.name
#set $name = ($cur_cast.name, 'themself')[$cur_cast.name == (('', $cur_cast.person[0].name)[1 == len($cur_cast.person)])]
<div class="role">#if not $cur_cast.id#$cur_cast.name#else#<a href="$sbRoot/home/role?$param(rid=$cur_cast.ref_id(), role=$show_obj, oid=$cur_cast.id)">$name</a>#end if#</div>
#else
<div class="role">unknown name</div>
#end if
#set $p_count = len($cur_cast.person)
#for $p_num, $cur_person in enumerate($cur_cast.person, 1)
<div class="person">#if not $cur_cast.id#$cur_person.name#else#<a href="$sbRoot/home/person?$param(person=$cur_person)">$cur_person.name</a>#end if##if $p_num < $p_count#<span>, </span>#end if#</div>
#end for
</div>
</li>
#end for
</ul>
</div>
<div class="glide-arrows" data-glide-el="controls" style="display:none">
<button class="glide-prev" data-glide-dir="<"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path d="M0 12l10.975 11 2.848-2.828-6.176-6.176H24v-3.992H7.646l6.176-6.176L10.975 1 0 12z" /></svg></button>
<button class="glide-next" data-glide-dir=">"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path d="M13.025 1l-2.847 2.828 6.176 6.176h-16.354v3.992h16.354l-6.176 6.176 2.847 2.828 10.975-11z" /></svg></button>
</div>
<button id="pin-glide" class="one addQTip boldest" style="display:none" title="10s, 6s, 3s, then II to save position"><i class="sgicon-pause one"></i><i class="two">10</i><i class="three">6</i><i class="four">3</i></button>
</span>
</div><!-- contain-glide -->
<span id="about-hide"><br><br></span>
<span id="about-show" class="hide">
#else
<span id="about-show">
#end if
$ep_tally
#if $has_overview
$show_obj.overview
#else
#echo ('', '<br><br>')[any($ep_tally)]
#if $show_ended
#if $varExists('force_update')
A <a href="$sbRoot/$force_update" title="Trigger force full update">force full update</a> may return a plot overview for this ended show
#else
Restart SickGear to get a new link here for this ended show
#end if
#else
No plot overview available
#end if
#end if
</span>
</div>
<div id="details-bottom">
<span class="label addQTip" title="Info language, $show_obj.lang"><img src="$sbRoot/images/flags/${show_obj.lang}.png" width="16" height="11" alt="" style="margin-top:-1px" /></span>
<span class="label addQTip" title="Location#echo (' no longer exists" style="background-color:#8f1515"', '"')[$showLoc[1]]#>$showLoc[0]</span>
<span id="data-size" class="label" style="cursor:help">$human($get_size($showLoc[0]))</span>
#set $filecount = sum([$c for $k, $c in $ep_counts['videos'].items()])
#set $to_prune = $show_obj.prune - $filecount
#set $keep_or_prune = ('', ' (%s)' % ('%s to prune' % abs($to_prune), 'keep %s' % $show_obj.prune)[0 <= $to_prune])[bool($show_obj.prune)]
<span class="label addQTip" title="Videos">#echo '%s file%s%s' % (('No', $filecount)[0 < $filecount], $maybe_plural($filecount), $keep_or_prune)#</span>
#if $show_obj.paused
<span class="label label-paused">Paused</span>
#end if
#if ($anyQualities + $bestQualities) and int($show_obj.upgrade_once)
<span class="label">Upgrade once</span>
#end if
#if $show_obj.exceptions
<span class="label addQTip" title="$exceptions_string.replace(', ', '<br />')">Scene names</span>
#end if
#if $show_obj.rls_ignore_words
<span class="label addQTip" title="#echo $generate_word_str($show_obj.rls_ignore_words, $show_obj.rls_ignore_words_regex, join_chr='<br />')#">Ignored words</span>
#end if
#if $show_obj.rls_require_words
<span class="label addQTip" title="#echo $generate_word_str($show_obj.rls_require_words, $show_obj.rls_require_words_regex, join_chr='<br />')#">Required words</span>
#end if
#if $show_obj.rls_global_exclude_ignore
<span class="label addQTip" title="#echo $generate_word_str($show_obj.rls_global_exclude_ignore, join_chr='<br />')#">Excluded global ignored words</span>
#end if
#if $show_obj.rls_global_exclude_require
<span class="label addQTip" title="#echo $generate_word_str($show_obj.rls_global_exclude_require, join_chr='<br />')#">Excluded global required words</span>
#end if
#if $show_obj.flatten_folders or $sg_var('NAMING_FORCE_FOLDERS')
<span class="label">Flat folders</span>
#end if
#if int($show_obj.air_by_date)
<span class="label">Air by date</span>
#end if
#if int($show_obj.dvdorder)
<span class="label">DVD order</span>
#end if
#if int($show_obj.scene)
<span class="label">Scene numbering</span>
#end if
#if $sg_var('USE_SUBTITLES') and int($show_obj.subtitles)
<span class="label">Subtitles</span>
#end if
#if int($show_obj.is_sports)
<span class="label">Sports</span>
#end if
#if int($show_obj.is_anime)
<span class="label">Anime</span>
#end if
#if $anigroups and $anigroups.allowlist
<span class="label addQTip" title="#echo ', '.join($anigroups.allowlist).replace(',', '<br />')#">Wanted group$maybe_plural(len($anigroups.allowlist))</span>
#end if
#if $anigroups and $anigroups.blocklist
<span class="label addQTip" title="#echo ', '.join($anigroups.blocklist).replace(',', '<br />')#">Unwanted group$maybe_plural(len($anigroups.blocklist))</span>
#end if
</div>
</div>
</div>
</div>
</div>
<div class="clearfix"></div>
<div id="change-status" class="pull-left">
<p style="margin-bottom:5px">Change selected episodes to</p>
<select id="statusSelect" class="form-control form-control-inline input-sm showlist-select">
#for $curStatus in [$WANTED, $SKIPPED, $IGNORED, $FAILED]
<option value="$curStatus">$statusStrings[$curStatus]</option>
#end for
<optgroup label="Downloaded">
#for $curStatus in sorted($Quality.DOWNLOADED)
#if $DOWNLOADED != $curStatus
<option value="$curStatus">$re.sub(r'Downloaded\s*\(([^\)]+)\)', r'\1', $statusStrings[$curStatus].replace('SD DVD', 'SD DVD/BR/BD'))</option>
#end if
#end for
<option value="$DOWNLOADED">with archived quality</option>
</optgroup>
<optgroup label="Archived with">
<option value="$ARCHIVED">downloaded quality</option>
<option value="-$ARCHIVED">default ($min_initial)</option>
</optgroup>
</select>
<input type="hidden" id="tvid-prodid" value="$show_obj.tvid_prodid">
<input class="btn btn-inline" type="button" id="changeStatus" value="Go">
</div>
<div class="pull-right clearfix" id="checkboxControls">
<div style="padding-bottom:5px" class="addQTip" title="Filter Episodes">
<label for="good"><span class="good"><input type="checkbox" id="good" checked="checked"> Downloaded: <b>$ep_counts[$Overview.GOOD]</b></span></label>
<label for="snatched"><span class="snatched"><input type="checkbox" id="snatched" checked="checked"> Snatched: <b>$ep_counts[$Overview.SNATCHED]</b></span></label>
<label for="wanted"><span class="wanted"><input type="checkbox" id="wanted" checked="checked"> Wanted: <b>$ep_counts[$Overview.WANTED]</b></span></label>
<label for="qual"><span class="qual"><input type="checkbox" id="qual" checked="checked"> Low Quality: <b>$ep_counts[$Overview.QUAL]</b></span></label>
<label for="skipped"><span class="skipped"><input type="checkbox" id="skipped" checked="checked"> Skipped: <b>$ep_counts[$Overview.SKIPPED]</b></span></label>
</div>
<div class="pull-right" >
<button class="btn btn-xs seriesCheck">Select filtered episodes</button>
<button class="btn btn-xs clearAll">Clear all</button>
</div>
</div>
<div class="clearfix"></div>
#if not len($seasons)
<div id="no-episode-data">
<h3>No episode details at TV info source
<a class="service" href="$anon_url($TVInfoAPI($show_obj.tvid).config['show_url'] % $show_obj.prodid)" onclick="window.open(this.href, '_blank'); return !1;" title="View $TVInfoAPI($show_obj.tvid).name info in new tab">$TVInfoAPI($show_obj.tvid).name</a>
</h3>
</div>
#else
#set $working_season = -1
#set $odd = 0
#set $scene, $scene_anime = (False, False)
#if not $show_obj.air_by_date and not $show_obj.is_sports and not $show_obj.is_anime and $show_obj.is_scene
#set $scene = True
#elif not $show_obj.air_by_date and not $show_obj.is_sports and $show_obj.is_anime and $show_obj.is_scene
#set $scene_anime = True
#end if
#for $season, $episodes, $has_season_exceptions in $seasons
#for $ep in $episodes
#if None is not $ep
#set $ep_str = '%sx%s' % ($season, $ep['episode'])
#if $ep_str not in $ep_cats or (0 == $season and not $sg_var('DISPLAY_SHOW_SPECIALS'))
#continue
#end if
#end if
#if $working_season != $season
#if 0 <= $working_season
</tbody>
</table>
#end if
#set $working_season = $season
#set $human_season = ('Season %s' % $season, 'Specials')[0 == $season]
#if $has_season_exceptions
#set $human_season += '<b class="season-mark-exception">*</b>'
#end if
## one off variable migration, on next version apply... (s/$getVar('display_seasons', [])/[]/),
<table class="sickbeardTable#echo '%s%s%s' % (('', ' season-min')[$season in $getVar('season_min', $getVar('display_seasons', []))], ('', ' latest-season')[$latest_season == $season], ('', ' open')[$season in $getVar('other_seasons', [])])#">
<thead>
<tr>
<th class="row-seasonheader" colspan="13">
#if None is $has_art#<span class="red-text pull-right">Restart SickGear to reveal new options here</span>
#elif not (1 == $lowest_season and 1 == $latest_season and $latest_season >= $highest_season)
<button id="showseason-$season" type="button" class="btn btn-default pull-right"><span class="onshow">Show $human_season.lower()<i class="sgicon-arrowdown"></i></span><span class="onhide">Hide $human_season.lower()<i class="sgicon-arrowup"></i></span></button>
<button type="button" class="btn btn-default pull-right allseasons"><span class="onshow">Show all</span><span class="onhide">Hide most</span><i class="icon-glyph"></i></button>
<span class="images pull-right hide"><i class="spinner"></i></span>
#end if
#set $videos = $ep_counts['videos'].get($season, '0')
#set $season_stats = $ep_counts['status'].get($season, {})
#set $snatched = $season_stats.get($Overview.SNATCHED, None)
#set $wanted = $season_stats.get($Overview.WANTED, None)
#set $qual = $season_stats.get($Overview.QUAL, None)
#set $good = $season_stats.get($Overview.GOOD, '0')
#set $archived = False if $season not in $ep_counts['archived'] else $ep_counts['archived'][$season]
<h3 id="season-$show_obj.tvid_prodid-$season"><span class="title">$human_season</span><a id="season-$season" name="season-$season"></a>
#if None is not $has_art
<span class="season-status"><span class="good status-badge">&nbsp;D: <strong>$good</strong>&nbsp;</span>#if snatched#<span class="snatched status-badge">&nbsp;S: <strong>$snatched</strong>&nbsp;</span>#end if##if $wanted#<span class="wanted status-badge">&nbsp;W: <strong>$wanted</strong>&nbsp;</span>#end if##if $qual#<span class="qual status-badge">&nbsp;LQ: <strong>$qual</strong>&nbsp;</span>#end if#&nbsp;of&nbsp;<span class="footerhighlight">$ep_counts['totals'][$season]</span>#if 0 < $archived#&nbsp;with <span class="footerhighlight">$archived</span> archived#end if##if int($videos)#&nbsp;#echo ('with', 'and')[0 < $archived]#&nbsp;<span class="footerhighlight">$videos</span> file$maybe_plural($videos)#end if#</span>
#end if
</h3>
</th>
</tr>
#set $attr_title_ep = ('', ' (Anime #)')[$show_obj.is_anime]
<tr id="season-$season-cols" class="seasoncols collapse tablesorter-headerRow">
<th class="col-checkbox tablesorter-no-sort"><input type="checkbox" class="seasonCheck" id="$season"></th>
<th class="col-metadata tablesorter-no-sort">Meta</th>
<th class="col-ep tablesorter-ep-num"><span title="Ep #$attr_title_ep"><span class="hdr-text">#</span></span></th>#if $scene or $scene_anime
<th class="col-ep tablesorter-ep-scene" style="padding-right:18px"><span class="hdr-text">Scene#if $scene_anime# absolute#end if#</span></th>#end if#
<th class="col-name"><span class="hdr-text">Name</span></th>
<th class="col-airdate tablesorter-airdate"><span class="hdr-text">Air Date</span></th>#if $sg_var('USE_SUBTITLES') and $show_obj.subtitles
<th class="col-subtitles tablesorter-no-sort">Subtitles</th>#end if
<th class="col-status"><span class="hdr-text">Status</span></th>
<th class="col-search tablesorter-no-sort">Search</th>
</tr>
</thead>
<tbody class="collapse">
#end if
#if None is $ep
</tbody>
#continue
#end if
#set global $episode = $ep
#include $os.path.join($sg_str('PROG_DIR'), 'gui/slick/interfaces/default/inc_displayShow.tmpl')
#end for
#end for
</tbody>
</table>
#end if
</div>
#if None is not $has_art
#include $os.path.join($sg_str('PROG_DIR'), 'gui/slick/interfaces/default/inc_livepanel.tmpl')
#end if
#include $os.path.join($sg_str('PROG_DIR'), 'gui/slick/interfaces/default/inc_bottom.tmpl')