mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-01 17:03:38 +00:00
Merge branch 'feature/AddTvdbV4' into dev
Some checks are pending
Python Unit Tests / windows (windows-latest, 3.10) (push) Waiting to run
Python Unit Tests / windows (windows-latest, 3.11) (push) Waiting to run
Python Unit Tests / windows (windows-latest, 3.12) (push) Waiting to run
Python Unit Tests / windows (windows-latest, 3.8) (push) Waiting to run
Python Unit Tests / windows (windows-latest, 3.9) (push) Waiting to run
Python Unit Tests / linux (ubuntu-latest, 3.10) (push) Waiting to run
Python Unit Tests / linux (ubuntu-latest, 3.11) (push) Waiting to run
Python Unit Tests / linux (ubuntu-latest, 3.12) (push) Waiting to run
Python Unit Tests / linux (ubuntu-latest, 3.8) (push) Waiting to run
Python Unit Tests / linux (ubuntu-latest, 3.9) (push) Waiting to run
Python Unit Tests / macos (macos-latest, 3.10) (push) Waiting to run
Python Unit Tests / macos (macos-latest, 3.11) (push) Waiting to run
Python Unit Tests / macos (macos-latest, 3.12) (push) Waiting to run
Python Unit Tests / macos (macos-latest, 3.8) (push) Waiting to run
Python Unit Tests / macos (macos-latest, 3.9) (push) Waiting to run
Some checks are pending
Python Unit Tests / windows (windows-latest, 3.10) (push) Waiting to run
Python Unit Tests / windows (windows-latest, 3.11) (push) Waiting to run
Python Unit Tests / windows (windows-latest, 3.12) (push) Waiting to run
Python Unit Tests / windows (windows-latest, 3.8) (push) Waiting to run
Python Unit Tests / windows (windows-latest, 3.9) (push) Waiting to run
Python Unit Tests / linux (ubuntu-latest, 3.10) (push) Waiting to run
Python Unit Tests / linux (ubuntu-latest, 3.11) (push) Waiting to run
Python Unit Tests / linux (ubuntu-latest, 3.12) (push) Waiting to run
Python Unit Tests / linux (ubuntu-latest, 3.8) (push) Waiting to run
Python Unit Tests / linux (ubuntu-latest, 3.9) (push) Waiting to run
Python Unit Tests / macos (macos-latest, 3.10) (push) Waiting to run
Python Unit Tests / macos (macos-latest, 3.11) (push) Waiting to run
Python Unit Tests / macos (macos-latest, 3.12) (push) Waiting to run
Python Unit Tests / macos (macos-latest, 3.8) (push) Waiting to run
Python Unit Tests / macos (macos-latest, 3.9) (push) Waiting to run
This commit is contained in:
commit
29047e44d3
264 changed files with 1518 additions and 82 deletions
|
@ -3,6 +3,10 @@
|
||||||
* Update filelock 3.14.0 (8556141) to 3.15.4 (9a979df)
|
* Update filelock 3.14.0 (8556141) to 3.15.4 (9a979df)
|
||||||
* Update package resource API 68.2.2 (8ad627d) to 70.1.1 (222ebf9)
|
* Update package resource API 68.2.2 (8ad627d) to 70.1.1 (222ebf9)
|
||||||
* Update urllib3 2.2.1 (54d6edf) to 2.2.2 (27e2a5c)
|
* Update urllib3 2.2.1 (54d6edf) to 2.2.2 (27e2a5c)
|
||||||
|
* Change add TheTVDb v4 support
|
||||||
|
* Add menu Shows/"TVDb Cards"
|
||||||
|
* Add a persons available socials (Youtube, LinkedIn, Reddit, Fansite, TikTok, Wikidata)
|
||||||
|
* Change increase viewable history menu items from 13 to 15
|
||||||
|
|
||||||
|
|
||||||
### 3.32.8 (2024-10-07 00:30:00 UTC)
|
### 3.32.8 (2024-10-07 00:30:00 UTC)
|
||||||
|
@ -343,7 +347,6 @@
|
||||||
* Add config to change media process log message if there is no media to process
|
* Add config to change media process log message if there is no media to process
|
||||||
* Change view-show text "invalid timeformat" to "time unknown"
|
* Change view-show text "invalid timeformat" to "time unknown"
|
||||||
* Add menu Shows/"TMDB Cards"
|
* Add menu Shows/"TMDB Cards"
|
||||||
* Add a persons available socials (Youtube, LinkedIn, Reddit, Fansite, TikTok, Wikidata)
|
|
||||||
* Change use TVDb genres on view-show if config/General/Interface/"Enable IMDb info" is disabled
|
* Change use TVDb genres on view-show if config/General/Interface/"Enable IMDb info" is disabled
|
||||||
* Fix TVDb api episode issues
|
* Fix TVDb api episode issues
|
||||||
* Change remove Python 3.7 from CI
|
* Change remove Python 3.7 from CI
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#import re
|
#import re
|
||||||
#import sickgear
|
#import sickgear
|
||||||
#from sickgear import TVInfoAPI
|
#from sickgear import TVInfoAPI
|
||||||
#from sickgear.indexers.indexer_config import TVINFO_TMDB, TVINFO_TRAKT, TVINFO_TVMAZE
|
#from sickgear.indexers.indexer_config import TVINFO_TMDB, TVINFO_TVDB, TVINFO_TRAKT, TVINFO_TVMAZE
|
||||||
#from sickgear.helpers import anon_url
|
#from sickgear.helpers import anon_url
|
||||||
#from sickgear.tv import PersonGenders
|
#from sickgear.tv import PersonGenders
|
||||||
#from sg_helpers import spoken_height
|
#from sg_helpers import spoken_height
|
||||||
|
@ -186,7 +186,7 @@ def param(visible=True, rid=None, cache_person=None, cache_char=None, person=Non
|
||||||
#end if
|
#end if
|
||||||
|
|
||||||
#set $section_links = False
|
#set $section_links = False
|
||||||
#set $all_sources = $TVInfoAPI().all_sources
|
#set $all_sources = $TVInfoAPI().all_non_fallback_sources
|
||||||
#for $cur_src, $cur_sid in sorted(iteritems($person.ids))
|
#for $cur_src, $cur_sid in sorted(iteritems($person.ids))
|
||||||
#if $cur_src not in $all_sources:
|
#if $cur_src not in $all_sources:
|
||||||
#continue
|
#continue
|
||||||
|
@ -212,7 +212,7 @@ def param(visible=True, rid=None, cache_person=None, cache_char=None, person=Non
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
#end if
|
#end if
|
||||||
#set $src = (($TVINFO_TVMAZE, 'tvm'), ($TVINFO_TMDB, 'tmdb'), ($TVINFO_TRAKT, 'trakt'))
|
#set $src = (($TVINFO_TVDB, 'tvdb'), ($TVINFO_TVMAZE, 'tvm'), ($TVINFO_TMDB, 'tmdb'), ($TVINFO_TRAKT, 'trakt'))
|
||||||
#if any([$person.ids.get($cur_src) for ($cur_src, _) in $src])
|
#if any([$person.ids.get($cur_src) for ($cur_src, _) in $src])
|
||||||
<div>
|
<div>
|
||||||
<span class="details-title">Other shows</span>
|
<span class="details-title">Other shows</span>
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
|
|
||||||
// Set initial text
|
// Set initial text
|
||||||
overviewEl.html('Fetching overview...');
|
overviewEl.html('Fetching overview...');
|
||||||
$.getJSON($.SickGear.Root + '/add-shows/tvm-get-showinfo', {
|
$.getJSON($.SickGear.Root + '/add-shows/tvi-get-showinfo', {
|
||||||
tvid_prodid: showcardEl.attr('data-id'),
|
tvid_prodid: showcardEl.attr('data-id'),
|
||||||
oldest_dt: $('#oldest').attr('data-oldest-dt'),
|
oldest_dt: $('#oldest').attr('data-oldest-dt'),
|
||||||
newest_dt: $('#newest').attr('data-newest-dt'),
|
newest_dt: $('#newest').attr('data-newest-dt'),
|
||||||
|
@ -301,7 +301,7 @@ $(function() {
|
||||||
var filterValue = this.value;
|
var filterValue = this.value;
|
||||||
if (-1 == filterValue.indexOf('trakt') && -1 == filterValue.indexOf('imdb') && -1 == filterValue.indexOf('mc_')
|
if (-1 == filterValue.indexOf('trakt') && -1 == filterValue.indexOf('imdb') && -1 == filterValue.indexOf('mc_')
|
||||||
&& -1 == filterValue.indexOf('tmdb_') && -1 == filterValue.indexOf('tvc_')
|
&& -1 == filterValue.indexOf('tmdb_') && -1 == filterValue.indexOf('tvc_')
|
||||||
&& -1 == filterValue.indexOf('tvm_')
|
&& -1 == filterValue.indexOf('tvdb_') && -1 == filterValue.indexOf('tvm_')
|
||||||
&& -1 == filterValue.indexOf('ne_') && -1 == filterValue.indexOf('_ne')
|
&& -1 == filterValue.indexOf('ne_') && -1 == filterValue.indexOf('_ne')
|
||||||
&& -1 == filterValue.indexOf('default')) {
|
&& -1 == filterValue.indexOf('default')) {
|
||||||
var el$ = $('#container')
|
var el$ = $('#container')
|
||||||
|
@ -507,6 +507,14 @@ $(function() {
|
||||||
<option value="tmdb_trending_today"#echo ('', selected)['trending_today' == $mode]#>Trending today</option>
|
<option value="tmdb_trending_today"#echo ('', selected)['trending_today' == $mode]#>Trending today</option>
|
||||||
<option value="tmdb_trending_week"#echo ('', selected)['trending_week' == $mode]#>Trending this week</option>
|
<option value="tmdb_trending_week"#echo ('', selected)['trending_week' == $mode]#>Trending this week</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
|
#elif 'TVDb' == $browse_type
|
||||||
|
<optgroup label="TVDb">
|
||||||
|
<option value="tvdb_upcoming"#echo ('', selected)['upcoming' == $mode]#>Upcoming</option>
|
||||||
|
<option value="tvdb_toprated"#echo ('', selected)['toprated' == $mode and not $kwargs.get('year')]#>Top rated all time</option>
|
||||||
|
#for $cur_y in $kwargs.get('rate_years') or []
|
||||||
|
<option value="$cur_y[1]"#echo ('', selected)[$cur_y[0] == $kwargs.get('year')]#>$cur_y[2]</option>
|
||||||
|
#end for
|
||||||
|
</optgroup>
|
||||||
#elif 'TVCalendar' == $browse_type
|
#elif 'TVCalendar' == $browse_type
|
||||||
<optgroup label="TVCalendar">
|
<optgroup label="TVCalendar">
|
||||||
#for $page in $kwargs.get('pages') or []
|
#for $page in $kwargs.get('pages') or []
|
||||||
|
@ -623,7 +631,7 @@ $(function() {
|
||||||
#end if
|
#end if
|
||||||
<div class="clearfix">
|
<div class="clearfix">
|
||||||
#if $use_ratings or $use_votes
|
#if $use_ratings or $use_votes
|
||||||
<p>#if $use_ratings#<span class="rating">$this_show['rating']#if $re.search(r'^\d+(\.\d+)?$', (str($this_show['rating'])))#%</span>#end if##end if##if $use_votes#<i class="heart icon-glyph"></i><i>$this_show['votes'] $term_vote.lower()</i>#end if#</p>#slurp#
|
<p>#if $this_show.get('rank')##$this_show.get('rank') #end if##if $use_ratings#<span class="rating">$this_show['rating']#if $re.search(r'^\d+(\.\d+)?$', (str($this_show['rating'])))#%</span>#end if##end if##if $use_votes#<i class="heart icon-glyph"></i><i>$this_show['votes'] $term_vote.lower()</i>#end if#</p>#slurp#
|
||||||
#else
|
#else
|
||||||
<p> </p>
|
<p> </p>
|
||||||
#end if
|
#end if
|
||||||
|
|
|
@ -177,6 +177,10 @@
|
||||||
<li><a id="add-show-name" data-href="$sbRoot/add-shows/find/" tabindex="$tab#set $tab += 1#"><i class="sgicon-addshow"></i>
|
<li><a id="add-show-name" data-href="$sbRoot/add-shows/find/" tabindex="$tab#set $tab += 1#"><i class="sgicon-addshow"></i>
|
||||||
<input class="form-control form-control-inline input-sm" type="text" placeholder="Search" tabindex="$tab#set $tab += 1#">
|
<input class="form-control form-control-inline input-sm" type="text" placeholder="Search" tabindex="$tab#set $tab += 1#">
|
||||||
<div class="menu-item-desc opacity60">find show at TV info source</div></a></li>
|
<div class="menu-item-desc opacity60">find show at TV info source</div></a></li>
|
||||||
|
#set $tvdb_modes = dict(tvdb_upcoming='upcoming', tvdb_toprated='top rated')
|
||||||
|
#set $tvdb_mode = $tvdb_modes.get($sg_var('TVDB_MRU'), 'upcoming')
|
||||||
|
<li><a href="$sbRoot/add-shows/tvdb-default/" tabindex="$tab#set $tab += 1#"><i class="sgicon-addshow"></i>TVDb Cards
|
||||||
|
<div class="menu-item-desc opacity60">$tvdb_mode...</div></a></li>
|
||||||
#set $tvm_modes = dict(tvm_premieres='new shows', tvm_returning='returning')
|
#set $tvm_modes = dict(tvm_premieres='new shows', tvm_returning='returning')
|
||||||
#set $tvm_mode = $tvm_modes.get($sg_var('TVM_MRU'), 'new shows')
|
#set $tvm_mode = $tvm_modes.get($sg_var('TVM_MRU'), 'new shows')
|
||||||
<li><a href="$sbRoot/add-shows/tvm-default/" tabindex="$tab#set $tab += 1#"><i class="sgicon-tvmaze"></i>TVmaze Cards
|
<li><a href="$sbRoot/add-shows/tvm-default/" tabindex="$tab#set $tab += 1#"><i class="sgicon-tvmaze"></i>TVmaze Cards
|
||||||
|
|
|
@ -27,7 +27,6 @@ import warnings
|
||||||
from bs4_parser import BS4Parser
|
from bs4_parser import BS4Parser
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from sg_helpers import clean_data, get_url, try_int
|
from sg_helpers import clean_data, get_url, try_int
|
||||||
from sickgear import ENV
|
|
||||||
|
|
||||||
from lib.cachecontrol import CacheControl, caches
|
from lib.cachecontrol import CacheControl, caches
|
||||||
from lib.dateutil.parser import parse
|
from lib.dateutil.parser import parse
|
||||||
|
@ -46,6 +45,8 @@ if False:
|
||||||
from typing import Any, AnyStr, Dict, List, Optional, Union
|
from typing import Any, AnyStr, Dict, List, Optional, Union
|
||||||
|
|
||||||
|
|
||||||
|
ENV = os.environ
|
||||||
|
|
||||||
THETVDB_V2_API_TOKEN = {'token': None, 'datetime': datetime.datetime.fromordinal(1)}
|
THETVDB_V2_API_TOKEN = {'token': None, 'datetime': datetime.datetime.fromordinal(1)}
|
||||||
log = logging.getLogger('tvdb.api')
|
log = logging.getLogger('tvdb.api')
|
||||||
log.addHandler(logging.NullHandler())
|
log.addHandler(logging.NullHandler())
|
||||||
|
|
1218
lib/api_tvdb/tvdb_api_v4.py
Normal file
1218
lib/api_tvdb/tvdb_api_v4.py
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1809,7 +1809,7 @@ def is_virtualenv():
|
||||||
def enforce_type(value, allowed_types, default):
|
def enforce_type(value, allowed_types, default):
|
||||||
# type: (Any, Union[Type, Tuple[Type]], Any) -> Any
|
# type: (Any, Union[Type, Tuple[Type]], Any) -> Any
|
||||||
"""
|
"""
|
||||||
enforces that value is given type(s)
|
enforce value to supplied type(s)
|
||||||
:param value: value to check
|
:param value: value to check
|
||||||
:param allowed_types: type or tuple of types allowed
|
:param allowed_types: type or tuple of types allowed
|
||||||
:param default: value to return if other type
|
:param default: value to return if other type
|
||||||
|
@ -1817,3 +1817,12 @@ def enforce_type(value, allowed_types, default):
|
||||||
if not isinstance(value, allowed_types):
|
if not isinstance(value, allowed_types):
|
||||||
return default
|
return default
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def clean_str(value):
|
||||||
|
# type: (Any) -> AnyStr
|
||||||
|
"""
|
||||||
|
clean and enforced a value to a string type
|
||||||
|
:param value: to process
|
||||||
|
"""
|
||||||
|
return enforce_type(clean_data(value), str, '')
|
||||||
|
|
|
@ -247,13 +247,8 @@ class TVInfoSocialIDs(object):
|
||||||
return self.__getitem__(key)
|
return self.__getitem__(key)
|
||||||
|
|
||||||
def keys(self):
|
def keys(self):
|
||||||
for k, v in iter(((TVINFO_TWITTER, self.twitter), (TVINFO_INSTAGRAM, self.instagram),
|
for k, v in self.__iter__():
|
||||||
(TVINFO_FACEBOOK, self.facebook), (TVINFO_TIKTOK, self.tiktok),
|
yield k
|
||||||
(TVINFO_WIKIPEDIA, self.wikipedia), (TVINFO_WIKIDATA, self.wikidata),
|
|
||||||
(TVINFO_REDDIT, self.reddit), (TVINFO_YOUTUBE, self.youtube),
|
|
||||||
(TVINFO_LINKEDIN, self.linkedin), (TVINFO_FANSITE, self.fansite))):
|
|
||||||
if None is not v:
|
|
||||||
yield k
|
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for s, v in iter(((TVINFO_TWITTER, self.twitter), (TVINFO_INSTAGRAM, self.instagram),
|
for s, v in iter(((TVINFO_TWITTER, self.twitter), (TVINFO_INSTAGRAM, self.instagram),
|
||||||
|
@ -329,7 +324,7 @@ class TVInfoImageSize(object):
|
||||||
|
|
||||||
class TVInfoImage(object):
|
class TVInfoImage(object):
|
||||||
def __init__(self, image_type, sizes, img_id=None, main_image=False, type_str='', rating=None, votes=None,
|
def __init__(self, image_type, sizes, img_id=None, main_image=False, type_str='', rating=None, votes=None,
|
||||||
lang=None, height=None, width=None, aspect_ratio=None, updated_at=None):
|
lang=None, height=None, width=None, aspect_ratio=None, updated_at=None, has_text=None):
|
||||||
self.img_id = img_id # type: Optional[integer_types]
|
self.img_id = img_id # type: Optional[integer_types]
|
||||||
self.image_type = image_type # type: integer_types
|
self.image_type = image_type # type: integer_types
|
||||||
self.sizes = sizes # type: Union[TVInfoImageSize, Dict]
|
self.sizes = sizes # type: Union[TVInfoImageSize, Dict]
|
||||||
|
@ -341,6 +336,7 @@ class TVInfoImage(object):
|
||||||
self.height = height # type: Optional[integer_types]
|
self.height = height # type: Optional[integer_types]
|
||||||
self.width = width # type: Optional[integer_types]
|
self.width = width # type: Optional[integer_types]
|
||||||
self.aspect_ratio = aspect_ratio # type: Optional[Union[float, integer_types]]
|
self.aspect_ratio = aspect_ratio # type: Optional[Union[float, integer_types]]
|
||||||
|
self.has_text = has_text # type: Optional[bool]
|
||||||
self.updated_at = updated_at # type: Optional[integer_types]
|
self.updated_at = updated_at # type: Optional[integer_types]
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
|
@ -951,9 +947,21 @@ class TVInfoPerson(PersonBase):
|
||||||
|
|
||||||
|
|
||||||
class TVInfoCharacter(PersonBase):
|
class TVInfoCharacter(PersonBase):
|
||||||
def __init__(self, person=None, voice=None, plays_self=None, regular=None, ti_show=None, start_year=None,
|
def __init__(self,
|
||||||
end_year=None, ids=None, name=None, episode_count=None, guest_episodes_numbers=None, **kwargs):
|
person=None, # type: List[TVInfoPerson]
|
||||||
# type: (List[TVInfoPerson], bool, bool, bool, TVInfoShow, int, int, TVInfoIDs, AnyStr, int, Dict[int, List[int]], ...) -> None
|
voice=None, # type: bool
|
||||||
|
plays_self=None, # type: bool
|
||||||
|
regular=None, # type: bool
|
||||||
|
ti_show=None, # type: TVInfoShow
|
||||||
|
start_year=None, # type: int
|
||||||
|
end_year=None, # type: int
|
||||||
|
ids=None, # type: TVInfoIDs
|
||||||
|
name=None, # type: AnyStr
|
||||||
|
episode_count=None, # type: int
|
||||||
|
guest_episodes_numbers=None, # type: Dict[int, List[int]]
|
||||||
|
**kwargs):
|
||||||
|
# type: (...) -> None
|
||||||
|
|
||||||
super(TVInfoCharacter, self).__init__(ids=ids, **kwargs)
|
super(TVInfoCharacter, self).__init__(ids=ids, **kwargs)
|
||||||
self.person = person # type: List[TVInfoPerson]
|
self.person = person # type: List[TVInfoPerson]
|
||||||
self.voice = voice # type: Optional[bool]
|
self.voice = voice # type: Optional[bool]
|
||||||
|
@ -1187,14 +1195,15 @@ class TVInfoBase(object):
|
||||||
except (BaseException, Exception) as e:
|
except (BaseException, Exception) as e:
|
||||||
log.error('Error setting %s to cache: %s' % (key, ex(e)))
|
log.error('Error setting %s to cache: %s' % (key, ex(e)))
|
||||||
|
|
||||||
def get_person(self, p_id, get_show_credits=False, get_images=False, **kwargs):
|
def get_person(self, p_id, get_show_credits=False, get_images=False, include_guests=False, **kwargs):
|
||||||
# type: (integer_types, bool, bool, Any) -> Optional[TVInfoPerson]
|
# type: (integer_types, bool, bool, bool, Any) -> Optional[TVInfoPerson]
|
||||||
"""
|
"""
|
||||||
get person's data for id or list of matching persons for name
|
get person's data for id or list of matching persons for name
|
||||||
|
|
||||||
:param p_id: persons id
|
:param p_id: persons id
|
||||||
:param get_show_credits: get show credits
|
:param get_show_credits: get show credits
|
||||||
:param get_images: get images for person
|
:param get_images: get person images
|
||||||
|
:param include_guests: include guest roles
|
||||||
:return: person object
|
:return: person object
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -1202,7 +1211,7 @@ class TVInfoBase(object):
|
||||||
def _search_person(self, name=None, ids=None):
|
def _search_person(self, name=None, ids=None):
|
||||||
# type: (AnyStr, Dict[integer_types, integer_types]) -> List[TVInfoPerson]
|
# type: (AnyStr, Dict[integer_types, integer_types]) -> List[TVInfoPerson]
|
||||||
"""
|
"""
|
||||||
search for person by name
|
search by name for person
|
||||||
:param name: name to search for
|
:param name: name to search for
|
||||||
:param ids: dict of ids to search
|
:param ids: dict of ids to search
|
||||||
:return: list of found person's
|
:return: list of found person's
|
||||||
|
@ -1212,7 +1221,7 @@ class TVInfoBase(object):
|
||||||
def search_person(self, name=None, ids=None):
|
def search_person(self, name=None, ids=None):
|
||||||
# type: (AnyStr, Dict[integer_types, integer_types]) -> List[TVInfoPerson]
|
# type: (AnyStr, Dict[integer_types, integer_types]) -> List[TVInfoPerson]
|
||||||
"""
|
"""
|
||||||
search for person by name
|
search by name for person
|
||||||
:param name: name to search for
|
:param name: name to search for
|
||||||
:param ids: dict of ids to search
|
:param ids: dict of ids to search
|
||||||
:return: list of found person's
|
:return: list of found person's
|
||||||
|
@ -1234,8 +1243,8 @@ class TVInfoBase(object):
|
||||||
seasonwides=False, fanart=False, actors=False, **kwargs):
|
seasonwides=False, fanart=False, actors=False, **kwargs):
|
||||||
# type: (integer_types, AnyStr, bool, bool, bool, bool, bool, bool, bool, Optional[Any]) -> bool
|
# type: (integer_types, AnyStr, bool, bool, bool, bool, bool, bool, bool, Optional[Any]) -> bool
|
||||||
"""
|
"""
|
||||||
internal function that should be overwritten in class to get data for given show id
|
internal function that should be overwritten in subclass to get data
|
||||||
:param sid: show id
|
:param sid: show id to get data for
|
||||||
:param language: language
|
:param language: language
|
||||||
:param get_ep_info: get episodes
|
:param get_ep_info: get episodes
|
||||||
:param banners: load banners
|
:param banners: load banners
|
||||||
|
@ -1264,6 +1273,7 @@ class TVInfoBase(object):
|
||||||
# type: (...) -> Optional[TVInfoShow]
|
# type: (...) -> Optional[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
get data for show id
|
get data for show id
|
||||||
|
|
||||||
:param show_id: id of show
|
:param show_id: id of show
|
||||||
:param load_episodes: load episodes
|
:param load_episodes: load episodes
|
||||||
:param banners: load banners
|
:param banners: load banners
|
||||||
|
@ -1330,8 +1340,12 @@ class TVInfoBase(object):
|
||||||
self._old_config = None
|
self._old_config = None
|
||||||
|
|
||||||
# noinspection PyMethodMayBeStatic
|
# noinspection PyMethodMayBeStatic
|
||||||
def _search_show(self, name=None, ids=None, lang=None, **kwargs):
|
def _search_show(self,
|
||||||
# type: (Union[AnyStr, List[AnyStr]], Dict[integer_types, integer_types], Optional[string_types], Optional[Any]) -> List[Dict]
|
name=None, # type: Union[AnyStr, List[AnyStr]]
|
||||||
|
ids=None, # type: Dict[integer_types, integer_types]
|
||||||
|
lang=None, # type: Optional[string_types]
|
||||||
|
**kwargs):
|
||||||
|
# type: (...) -> List[Dict]
|
||||||
"""
|
"""
|
||||||
internal search function to find shows, should be overwritten in class
|
internal search function to find shows, should be overwritten in class
|
||||||
:param name: name to search for
|
:param name: name to search for
|
||||||
|
@ -1370,7 +1384,7 @@ class TVInfoBase(object):
|
||||||
if None is lang:
|
if None is lang:
|
||||||
if self.config.get('language'):
|
if self.config.get('language'):
|
||||||
lang = self.config['language']
|
lang = self.config['language']
|
||||||
lang = self.map_languages.get(lang, lang)
|
lang = self.map_languages.get(lang, lang)
|
||||||
if not name and not ids:
|
if not name and not ids:
|
||||||
log.debug('Nothing to search')
|
log.debug('Nothing to search')
|
||||||
raise BaseTVinfoShownotfound('Nothing to search')
|
raise BaseTVinfoShownotfound('Nothing to search')
|
||||||
|
@ -1398,8 +1412,8 @@ class TVInfoBase(object):
|
||||||
Since the nice-to-use tvinfo[1][24]['name] interface
|
Since the nice-to-use tvinfo[1][24]['name] interface
|
||||||
makes it impossible to do tvinfo[1][24]['name] = "name"
|
makes it impossible to do tvinfo[1][24]['name] = "name"
|
||||||
and still be capable of checking if an episode exists
|
and still be capable of checking if an episode exists
|
||||||
so we can raise tvinfo_shownotfound, we have a slightly
|
so that we can raise tvinfo_shownotfound, we have a slightly
|
||||||
less pretty method of setting items.. but since the API
|
less pretty method of setting items... but since the API
|
||||||
is supposed to be read-only, this is the best way to
|
is supposed to be read-only, this is the best way to
|
||||||
do it!
|
do it!
|
||||||
The problem is that calling tvinfo[1][24]['episodename'] = "name"
|
The problem is that calling tvinfo[1][24]['episodename'] = "name"
|
||||||
|
@ -1454,6 +1468,7 @@ class TVInfoBase(object):
|
||||||
# type: (integer_types, int, Any) -> List[TVInfoShow]
|
# type: (integer_types, int, Any) -> List[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
return list of similar shows to given id
|
return list of similar shows to given id
|
||||||
|
|
||||||
:param tvid: id to give similar shows for
|
:param tvid: id to give similar shows for
|
||||||
:param result_count: count of results requested
|
:param result_count: count of results requested
|
||||||
"""
|
"""
|
||||||
|
@ -1463,6 +1478,7 @@ class TVInfoBase(object):
|
||||||
# type: (integer_types, int, Any) -> List[TVInfoShow]
|
# type: (integer_types, int, Any) -> List[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
list of recommended shows to the provided tv id
|
list of recommended shows to the provided tv id
|
||||||
|
|
||||||
:param tvid: id to find recommended shows for
|
:param tvid: id to find recommended shows for
|
||||||
:param result_count: result count to returned
|
:param result_count: result count to returned
|
||||||
"""
|
"""
|
||||||
|
@ -1486,7 +1502,7 @@ class TVInfoBase(object):
|
||||||
def get_top_rated(self, result_count=100, **kwargs):
|
def get_top_rated(self, result_count=100, **kwargs):
|
||||||
# type: (...) -> List[TVInfoShow]
|
# type: (...) -> List[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
get top rated shows
|
get top-rated shows
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -1526,7 +1542,7 @@ class TVInfoBase(object):
|
||||||
# type: (...) -> List[TVInfoShow]
|
# type: (...) -> List[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
get most played shows
|
get most played shows
|
||||||
:param result_count: how many results are suppose to be returned
|
:param result_count: how many results are supposed to be returned
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -1534,7 +1550,7 @@ class TVInfoBase(object):
|
||||||
# type: (...) -> List[TVInfoShow]
|
# type: (...) -> List[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
get most watched shows
|
get most watched shows
|
||||||
:param result_count: how many results are suppose to be returned
|
:param result_count: how many results are supposed to be returned
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -1542,7 +1558,7 @@ class TVInfoBase(object):
|
||||||
# type: (...) -> List[TVInfoShow]
|
# type: (...) -> List[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
get most collected shows
|
get most collected shows
|
||||||
:param result_count: how many results are suppose to be returned
|
:param result_count: how many results are supposed to be returned
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -1550,7 +1566,7 @@ class TVInfoBase(object):
|
||||||
# type: (...) -> List[TVInfoShow]
|
# type: (...) -> List[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
get most recommended shows
|
get most recommended shows
|
||||||
:param result_count: how many results are suppose to be returned
|
:param result_count: how many results are supposed to be returned
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -1558,8 +1574,9 @@ class TVInfoBase(object):
|
||||||
# type: (...) -> List[TVInfoShow]
|
# type: (...) -> List[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
get recommended shows for account
|
get recommended shows for account
|
||||||
|
|
||||||
:param account: account to get recommendations for
|
:param account: account to get recommendations for
|
||||||
:param result_count: how many results are suppose to be returned
|
:param result_count: how many results are supposed to be returned
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -1567,6 +1584,7 @@ class TVInfoBase(object):
|
||||||
# type: (integer_types, List[integer_types], Any) -> List[integer_types]
|
# type: (integer_types, List[integer_types], Any) -> List[integer_types]
|
||||||
"""
|
"""
|
||||||
hide recommended show for account
|
hide recommended show for account
|
||||||
|
|
||||||
:param account: account to get recommendations for
|
:param account: account to get recommendations for
|
||||||
:param show_ids: list of show_ids to no longer recommend for account
|
:param show_ids: list of show_ids to no longer recommend for account
|
||||||
:return: list of added ids
|
:return: list of added ids
|
||||||
|
@ -1577,6 +1595,7 @@ class TVInfoBase(object):
|
||||||
# type: (integer_types, List[integer_types], Any) -> List[integer_types]
|
# type: (integer_types, List[integer_types], Any) -> List[integer_types]
|
||||||
"""
|
"""
|
||||||
unhide recommended show for account
|
unhide recommended show for account
|
||||||
|
|
||||||
:param account: account to get recommendations for
|
:param account: account to get recommendations for
|
||||||
:param show_ids: list of show_ids to be included in possible recommend for account
|
:param show_ids: list of show_ids to be included in possible recommend for account
|
||||||
:return: list of removed ids
|
:return: list of removed ids
|
||||||
|
@ -1587,6 +1606,7 @@ class TVInfoBase(object):
|
||||||
# type: (integer_types, Any) -> List[TVInfoShow]
|
# type: (integer_types, Any) -> List[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
list hidden recommended show for account
|
list hidden recommended show for account
|
||||||
|
|
||||||
:param account: account to get recommendations for
|
:param account: account to get recommendations for
|
||||||
:return: list of hidden shows
|
:return: list of hidden shows
|
||||||
"""
|
"""
|
||||||
|
@ -1596,8 +1616,9 @@ class TVInfoBase(object):
|
||||||
# type: (...) -> List[TVInfoShow]
|
# type: (...) -> List[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
get most watchlisted shows for account
|
get most watchlisted shows for account
|
||||||
|
|
||||||
:param account: account to get recommendations for
|
:param account: account to get recommendations for
|
||||||
:param result_count: how many results are suppose to be returned
|
:param result_count: how many results are supposed to be returned
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -1605,7 +1626,7 @@ class TVInfoBase(object):
|
||||||
# type: (...) -> List[TVInfoShow]
|
# type: (...) -> List[TVInfoShow]
|
||||||
"""
|
"""
|
||||||
get anticipated shows
|
get anticipated shows
|
||||||
:param result_count: how many results are suppose to be returned
|
:param result_count: how many results are supposed to be returned
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -1625,7 +1646,7 @@ class TVInfoBase(object):
|
||||||
# Item is integer, treat as show id
|
# Item is integer, treat as show id
|
||||||
return self.get_show(item, (True, arg)[None is not arg], old_call=True)
|
return self.get_show(item, (True, arg)[None is not arg], old_call=True)
|
||||||
|
|
||||||
# maybe adding this to make callee use showname so that i can bring in the new endpoint
|
# maybe adding this to make callee use showname so that I can bring in the new endpoint
|
||||||
if isinstance(arg, string_types) and 'Tvdb' == self.__class__.__name__:
|
if isinstance(arg, string_types) and 'Tvdb' == self.__class__.__name__:
|
||||||
return self.search_show(item)
|
return self.search_show(item)
|
||||||
|
|
||||||
|
|
|
@ -625,6 +625,7 @@ MC_MRU = ''
|
||||||
NE_MRU = ''
|
NE_MRU = ''
|
||||||
TMDB_MRU = ''
|
TMDB_MRU = ''
|
||||||
TVC_MRU = ''
|
TVC_MRU = ''
|
||||||
|
TVDB_MRU = ''
|
||||||
TVM_MRU = ''
|
TVM_MRU = ''
|
||||||
|
|
||||||
COOKIE_SECRET = b64encodestring(uuid.uuid4().bytes + uuid.uuid4().bytes)
|
COOKIE_SECRET = b64encodestring(uuid.uuid4().bytes + uuid.uuid4().bytes)
|
||||||
|
@ -773,7 +774,7 @@ def init_stage_1(console_logging):
|
||||||
global USE_TRAKT, TRAKT_CONNECTED_ACCOUNT, TRAKT_ACCOUNTS, TRAKT_MRU, TRAKT_VERIFY, \
|
global USE_TRAKT, TRAKT_CONNECTED_ACCOUNT, TRAKT_ACCOUNTS, TRAKT_MRU, TRAKT_VERIFY, \
|
||||||
TRAKT_USE_WATCHLIST, TRAKT_REMOVE_WATCHLIST, TRAKT_TIMEOUT, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, \
|
TRAKT_USE_WATCHLIST, TRAKT_REMOVE_WATCHLIST, TRAKT_TIMEOUT, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, \
|
||||||
TRAKT_SYNC, TRAKT_DEFAULT_INDEXER, TRAKT_REMOVE_SERIESLIST, TRAKT_UPDATE_COLLECTION, \
|
TRAKT_SYNC, TRAKT_DEFAULT_INDEXER, TRAKT_REMOVE_SERIESLIST, TRAKT_UPDATE_COLLECTION, \
|
||||||
MC_MRU, NE_MRU, TMDB_MRU, TVC_MRU, TVM_MRU, \
|
MC_MRU, NE_MRU, TMDB_MRU, TVC_MRU, TVDB_MRU, TVM_MRU, \
|
||||||
USE_SLACK, SLACK_NOTIFY_ONSNATCH, SLACK_NOTIFY_ONDOWNLOAD, SLACK_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
USE_SLACK, SLACK_NOTIFY_ONSNATCH, SLACK_NOTIFY_ONDOWNLOAD, SLACK_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||||
SLACK_CHANNEL, SLACK_AS_AUTHED, SLACK_BOT_NAME, SLACK_ICON_URL, SLACK_ACCESS_TOKEN, \
|
SLACK_CHANNEL, SLACK_AS_AUTHED, SLACK_BOT_NAME, SLACK_ICON_URL, SLACK_ACCESS_TOKEN, \
|
||||||
USE_DISCORD, DISCORD_NOTIFY_ONSNATCH, DISCORD_NOTIFY_ONDOWNLOAD, \
|
USE_DISCORD, DISCORD_NOTIFY_ONSNATCH, DISCORD_NOTIFY_ONDOWNLOAD, \
|
||||||
|
@ -1214,6 +1215,7 @@ def init_stage_1(console_logging):
|
||||||
NE_MRU = check_setting_str(CFG, 'NextEpisode', 'ne_mru', '')
|
NE_MRU = check_setting_str(CFG, 'NextEpisode', 'ne_mru', '')
|
||||||
TMDB_MRU = check_setting_str(CFG, 'TMDB', 'tmdb_mru', '')
|
TMDB_MRU = check_setting_str(CFG, 'TMDB', 'tmdb_mru', '')
|
||||||
TVC_MRU = check_setting_str(CFG, 'TVCalendar', 'tvc_mru', '')
|
TVC_MRU = check_setting_str(CFG, 'TVCalendar', 'tvc_mru', '')
|
||||||
|
TVDB_MRU = check_setting_str(CFG, 'TVDb', 'tvdb_mru', '')
|
||||||
TVM_MRU = check_setting_str(CFG, 'TVmaze', 'tvm_mru', '')
|
TVM_MRU = check_setting_str(CFG, 'TVmaze', 'tvm_mru', '')
|
||||||
|
|
||||||
USE_PYTIVO = bool(check_setting_int(CFG, 'pyTivo', 'use_pytivo', 0))
|
USE_PYTIVO = bool(check_setting_int(CFG, 'pyTivo', 'use_pytivo', 0))
|
||||||
|
@ -1727,7 +1729,7 @@ def init_stage_2():
|
||||||
background_mapping_task = threading.Thread(name='MAPPINGUPDATES', target=indexermapper.load_mapped_ids,
|
background_mapping_task = threading.Thread(name='MAPPINGUPDATES', target=indexermapper.load_mapped_ids,
|
||||||
kwargs={'load_all': True})
|
kwargs={'load_all': True})
|
||||||
|
|
||||||
MEMCACHE['history_tab_limit'] = 13
|
MEMCACHE['history_tab_limit'] = 15
|
||||||
MEMCACHE['history_tab'] = History.menu_tab(MEMCACHE['history_tab_limit'])
|
MEMCACHE['history_tab'] = History.menu_tab(MEMCACHE['history_tab_limit'])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -2298,6 +2300,9 @@ def _save_config(force=False, **kwargs):
|
||||||
('TVCalendar', [
|
('TVCalendar', [
|
||||||
('mru', TVC_MRU)
|
('mru', TVC_MRU)
|
||||||
]),
|
]),
|
||||||
|
('TVDb', [
|
||||||
|
('mru', TVDB_MRU)
|
||||||
|
]),
|
||||||
('TVmaze', [
|
('TVmaze', [
|
||||||
('mru', TVM_MRU)
|
('mru', TVM_MRU)
|
||||||
]),
|
]),
|
||||||
|
|
|
@ -78,27 +78,40 @@ class TVInfoAPI(object):
|
||||||
if sickgear.CACHE_DIR:
|
if sickgear.CACHE_DIR:
|
||||||
return self.api_params['cache']
|
return self.api_params['cache']
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _filter(condition):
|
||||||
|
return dict([(int(x['id']), x['name']) for x in list(tvinfo_config.values()) if condition(x)])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sources(self):
|
def sources(self):
|
||||||
# type: () -> Dict[int, AnyStr]
|
# type: () -> Dict[int, AnyStr]
|
||||||
return dict([(int(x['id']), x['name']) for x in list(tvinfo_config.values()) if not x['mapped_only'] and
|
return self._filter(lambda x:
|
||||||
True is not x.get('fallback') and True is not x.get('people_only')])
|
not x['mapped_only'] and
|
||||||
|
True is not x.get('fallback') and True is not x.get('people_only'))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def search_sources(self):
|
def search_sources(self):
|
||||||
# type: () -> Dict[int, AnyStr]
|
# type: () -> Dict[int, AnyStr]
|
||||||
return dict([(int(x['id']), x['name']) for x in list(tvinfo_config.values()) if not x['mapped_only'] and
|
return self._filter(lambda x:
|
||||||
x.get('active') and not x.get('defunct') and True is not x.get('fallback')
|
not x['mapped_only'] and x.get('active') and not x.get('defunct') and
|
||||||
and True is not x.get('people_only')])
|
True is not x.get('fallback') and True is not x.get('people_only'))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def all_sources(self):
|
def all_sources(self):
|
||||||
# type: () -> Dict[int, AnyStr]
|
# type: () -> Dict[int, AnyStr]
|
||||||
"""
|
"""
|
||||||
:return: return all indexers including mapped only indexers excluding fallback indexers
|
:return: return all indexers for show data including mapped only indexers excluding fallback indexers
|
||||||
"""
|
"""
|
||||||
return dict([(int(x['id']), x['name']) for x in list(tvinfo_config.values()) if True is not x.get('fallback')
|
return self._filter(lambda x:
|
||||||
and True is not x.get('people_only')])
|
True is not x.get('fallback') and True is not x.get('people_only'))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def all_non_fallback_sources(self):
|
||||||
|
# type: (...) -> Dict[int, AnyStr]
|
||||||
|
"""
|
||||||
|
return all sources with the exclusion of fallback indexer
|
||||||
|
"""
|
||||||
|
return self._filter(lambda x: True is not x.get('fallback'))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fallback_sources(self):
|
def fallback_sources(self):
|
||||||
|
@ -106,9 +119,9 @@ class TVInfoAPI(object):
|
||||||
"""
|
"""
|
||||||
:return: return all fallback indexers
|
:return: return all fallback indexers
|
||||||
"""
|
"""
|
||||||
return dict([(int(x['id']), x['name']) for x in list(tvinfo_config.values()) if True is x.get('fallback')])
|
return self._filter(lambda x: True is x.get('fallback'))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def xem_supported_sources(self):
|
def xem_supported_sources(self):
|
||||||
# type: () -> Dict[int, AnyStr]
|
# type: () -> Dict[int, AnyStr]
|
||||||
return dict([(int(x['id']), x['name']) for x in list(tvinfo_config.values()) if x.get('xem_origin')])
|
return self._filter(lambda x: x.get('xem_origin'))
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
from lib.api_tvdb.tvdb_api import Tvdb
|
from lib.api_tvdb.tvdb_api import Tvdb
|
||||||
|
from lib.api_tvdb.tvdb_api_v4 import TvdbAPIv4
|
||||||
|
import lib.api_tvdb.tvdb_api_v4
|
||||||
from lib.api_trakt.indexerapiinterface import TraktIndexer
|
from lib.api_trakt.indexerapiinterface import TraktIndexer
|
||||||
from lib.api_tvmaze.tvmaze_api import TvMaze
|
from lib.api_tvmaze.tvmaze_api import TvMaze
|
||||||
from lib.api_tmdb.tmdb_api import TmdbIndexer
|
from lib.api_tmdb.tmdb_api import TmdbIndexer
|
||||||
|
@ -23,8 +25,9 @@ tvinfo_config = {
|
||||||
api_url='https://api.thetvdb.com/',
|
api_url='https://api.thetvdb.com/',
|
||||||
id=TVINFO_TVDB,
|
id=TVINFO_TVDB,
|
||||||
name='TheTVDB', slug='tvdb', kodi_slug='tvdb',
|
name='TheTVDB', slug='tvdb', kodi_slug='tvdb',
|
||||||
module=Tvdb,
|
module=TvdbAPIv4,
|
||||||
api_params=dict(apikey='6cfd6399fd2bee018a8793da976f6522', language='en'),
|
api_params=dict(apikey='6cfd6399fd2bee018a8793da976f6522',
|
||||||
|
apikey_v4=b'm5uaxWhrm56TlWTGm5Jkk5uYZW-ea5uOnmqcmWmXZmVtxp2a', language='en'),
|
||||||
active=True,
|
active=True,
|
||||||
dupekey='',
|
dupekey='',
|
||||||
mapped_only=False,
|
mapped_only=False,
|
||||||
|
@ -260,3 +263,5 @@ tvinfo_config[src].update(dict(
|
||||||
show_url='%stv/%%d' % tvinfo_config[src]['main_url'],
|
show_url='%stv/%%d' % tvinfo_config[src]['main_url'],
|
||||||
finder='%ssearch/tv?query=%s' % (tvinfo_config[src]['main_url'], '%s'),
|
finder='%ssearch/tv?query=%s' % (tvinfo_config[src]['main_url'], '%s'),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
lib.api_tvdb.tvdb_api_v4.TVDB_API_CONFIG = tvinfo_config[TVINFO_TVDB]
|
||||||
|
|
|
@ -73,7 +73,7 @@ class SBRotatingLogHandler(object):
|
||||||
self.console_logging = False # type: bool
|
self.console_logging = False # type: bool
|
||||||
self.log_lock = threading.Lock()
|
self.log_lock = threading.Lock()
|
||||||
self.log_types = ['sickgear', 'tornado.application', 'tornado.general', 'subliminal', 'adba', 'encodingKludge',
|
self.log_types = ['sickgear', 'tornado.application', 'tornado.general', 'subliminal', 'adba', 'encodingKludge',
|
||||||
'tvdb.api', 'TVInfo']
|
'tvdb.api', 'TVInfo', 'tvdb_v4.api']
|
||||||
self.external_loggers = ['sg.helper', 'api_trakt', 'api_trakt.api']
|
self.external_loggers = ['sg.helper', 'api_trakt', 'api_trakt.api']
|
||||||
self.log_types_null = ['tornado.access']
|
self.log_types_null = ['tornado.access']
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ from lib.api_trakt import TraktAPI
|
||||||
from lib.api_trakt.exceptions import TraktException, TraktAuthException
|
from lib.api_trakt.exceptions import TraktException, TraktAuthException
|
||||||
from lib.tvinfo_base import TVInfoEpisode, RoleTypes
|
from lib.tvinfo_base import TVInfoEpisode, RoleTypes
|
||||||
from lib.tvinfo_base.base import tv_src_names
|
from lib.tvinfo_base.base import tv_src_names
|
||||||
|
from lib.tvinfo_base.exceptions import *
|
||||||
|
|
||||||
import lib.rarfile.rarfile as rarfile
|
import lib.rarfile.rarfile as rarfile
|
||||||
|
|
||||||
|
@ -112,6 +113,7 @@ if False:
|
||||||
# from api_imdb.imdb_api import IMDbIndexer
|
# from api_imdb.imdb_api import IMDbIndexer
|
||||||
from api_tmdb.tmdb_api import TmdbIndexer
|
from api_tmdb.tmdb_api import TmdbIndexer
|
||||||
from api_trakt.indexerapiinterface import TraktIndexer
|
from api_trakt.indexerapiinterface import TraktIndexer
|
||||||
|
from api_tvdb.tvdb_api_v4 import TvdbAPIv4 as TvdbIndexer
|
||||||
from api_tvmaze.tvmaze_api import TvMaze as TvmazeIndexer
|
from api_tvmaze.tvmaze_api import TvMaze as TvmazeIndexer
|
||||||
|
|
||||||
|
|
||||||
|
@ -6036,6 +6038,155 @@ class AddShows(Home):
|
||||||
|
|
||||||
return self.new_show('|'.join(['', '', '', show_name]), use_show_name=True)
|
return self.new_show('|'.join(['', '', '', show_name]), use_show_name=True)
|
||||||
|
|
||||||
|
def tvdb_default(self):
|
||||||
|
method = getattr(self, sickgear.TVDB_MRU, None)
|
||||||
|
if not callable(method) or not self.allow_browse_mru(sickgear.TVDB_MRU):
|
||||||
|
return self.tvdb_upcoming()
|
||||||
|
return method()
|
||||||
|
|
||||||
|
def tvdb_upcoming(self, **kwargs):
|
||||||
|
return self.browse_tvdb(
|
||||||
|
'Upcoming at TVDb', mode='upcoming', **kwargs)
|
||||||
|
|
||||||
|
def tvdb_toprated(self, **kwargs):
|
||||||
|
return self.browse_tvdb(
|
||||||
|
'Top rated at TVDb', mode='toprated', **kwargs)
|
||||||
|
|
||||||
|
def tvdb_person(self, person_tvdb_id=None, **kwargs):
|
||||||
|
return self.browse_tvdb(
|
||||||
|
'Person at TVDb', mode='person', p_id=person_tvdb_id, **kwargs)
|
||||||
|
|
||||||
|
def browse_tvdb(self, browse_title, **kwargs):
|
||||||
|
|
||||||
|
browse_type = 'TVDb'
|
||||||
|
mode = kwargs.get('mode', '')
|
||||||
|
|
||||||
|
footnote = None
|
||||||
|
filtered = []
|
||||||
|
p_ref = None
|
||||||
|
overview_ajax = 'person' == mode
|
||||||
|
|
||||||
|
tvid = TVINFO_TVDB
|
||||||
|
tvinfo_config = sickgear.TVInfoAPI(tvid).api_params.copy()
|
||||||
|
t = sickgear.TVInfoAPI(tvid).setup(**tvinfo_config) # type: Union[TvdbIndexer, TVInfoBase]
|
||||||
|
|
||||||
|
top_year = helpers.try_int(kwargs.get('year'), None)
|
||||||
|
try:
|
||||||
|
if 'upcoming' == mode:
|
||||||
|
items = t.discover()
|
||||||
|
elif 'person' == mode:
|
||||||
|
items = []
|
||||||
|
p_item = t.get_person(get_show_credits=True, include_guests=True, **kwargs) # type: TVInfoPerson
|
||||||
|
if p_item:
|
||||||
|
p_ref = f'{TVINFO_TVDB}:{p_item.id}'
|
||||||
|
dup = {} # type: Dict[int, TVInfoShow]
|
||||||
|
for c in p_item.characters: # type: TVInfoCharacter
|
||||||
|
c.ti_show.cast[(RoleTypes.ActorGuest, RoleTypes.ActorMain)[True is c.regular]].append(c)
|
||||||
|
if c.ti_show.id not in dup:
|
||||||
|
dup[c.ti_show.id] = c.ti_show
|
||||||
|
items.append(c.ti_show)
|
||||||
|
else:
|
||||||
|
dup[c.ti_show.id].cast[RoleTypes.ActorMain].extend(c.ti_show.cast[RoleTypes.ActorMain])
|
||||||
|
dup[c.ti_show.id].cast[RoleTypes.ActorGuest].extend(c.ti_show.cast[RoleTypes.ActorGuest])
|
||||||
|
del dup
|
||||||
|
else:
|
||||||
|
p_item = None
|
||||||
|
else:
|
||||||
|
items = t.get_top_rated(year=top_year, in_last_year=1 == dt_date.today().month and 7 > dt_date.today().day)
|
||||||
|
except (BaseTVinfoError, BaseException, Exception) as e:
|
||||||
|
return self.browse_shows(browse_type, browse_title, filtered, **kwargs)
|
||||||
|
|
||||||
|
ranking = dict((val, idx+1) for idx, val in
|
||||||
|
enumerate(sorted([cur_show_info.rating or 0 for cur_show_info in items], reverse=True)))
|
||||||
|
oldest, newest, oldest_dt, newest_dt, dedupe = None, None, 9999999, 0, []
|
||||||
|
use_networks = False
|
||||||
|
parseinfo = dateutil.parser.parserinfo(dayfirst=False, yearfirst=True)
|
||||||
|
base_url = sickgear.TVInfoAPI(TVINFO_TVDB).config['show_url']
|
||||||
|
for cur_show_info in items:
|
||||||
|
if cur_show_info.id in dedupe or not cur_show_info.seriesname:
|
||||||
|
continue
|
||||||
|
dedupe += [cur_show_info.id]
|
||||||
|
|
||||||
|
try:
|
||||||
|
airtime = cur_show_info.airs_time
|
||||||
|
if not airtime or (0, 0) == (airtime.hour, airtime.minute):
|
||||||
|
airtime = dateutil.parser.parse('23:59').time()
|
||||||
|
dt = datetime.combine(
|
||||||
|
dateutil.parser.parse(cur_show_info.firstaired, parseinfo).date(), airtime)
|
||||||
|
ord_premiered, str_premiered, started_past, oldest_dt, newest_dt, oldest, newest, _, _, _, _ \
|
||||||
|
= self.sanitise_dates(dt, oldest_dt, newest_dt, oldest, newest)
|
||||||
|
|
||||||
|
image = self._make_cache_image_url(tvid, cur_show_info)
|
||||||
|
images = {} if not image else dict(poster=dict(thumb=image))
|
||||||
|
|
||||||
|
ids = dict(tvdb=cur_show_info.id)
|
||||||
|
if cur_show_info.ids.imdb:
|
||||||
|
ids['imdb'] = cur_show_info.ids.imdb
|
||||||
|
|
||||||
|
network_name = cur_show_info.network
|
||||||
|
cc = 'US'
|
||||||
|
if network_name:
|
||||||
|
use_networks = True
|
||||||
|
cc = cur_show_info.network_country_code or cc
|
||||||
|
|
||||||
|
language = ((cur_show_info.language and 'jap' in cur_show_info.language.lower())
|
||||||
|
and 'jp' or 'en')
|
||||||
|
|
||||||
|
filtered.append(dict(
|
||||||
|
ord_premiered=ord_premiered,
|
||||||
|
str_premiered=str_premiered,
|
||||||
|
started_past=started_past,
|
||||||
|
episode_overview=self.clean_overview(cur_show_info),
|
||||||
|
episode_season=cur_show_info.season,
|
||||||
|
genres=(', '.join(cur_show_info.genre_list)
|
||||||
|
or (cur_show_info.genre and (cur_show_info.genre.strip('|').replace('|', ', ')) or '')
|
||||||
|
).lower(),
|
||||||
|
ids=ids,
|
||||||
|
images=images,
|
||||||
|
overview=self.clean_overview(cur_show_info),
|
||||||
|
overview_ajax=(0, 1)[overview_ajax],
|
||||||
|
title=cur_show_info.seriesname,
|
||||||
|
language=language,
|
||||||
|
language_img=sickgear.MEMCACHE_FLAG_IMAGES.get(language, False),
|
||||||
|
country=cc,
|
||||||
|
country_img=sickgear.MEMCACHE_FLAG_IMAGES.get(cc.lower(), False),
|
||||||
|
network=network_name,
|
||||||
|
rating=False,
|
||||||
|
url_src_db=base_url % cur_show_info.id,
|
||||||
|
votes=cur_show_info.rating or 0,
|
||||||
|
rank=cur_show_info.rating and ranking.get(cur_show_info.rating) or 0,
|
||||||
|
))
|
||||||
|
if p_ref:
|
||||||
|
filtered[-1].update(dict(
|
||||||
|
p_name=p_item.name or None,
|
||||||
|
p_ref=p_ref,
|
||||||
|
p_chars=self._make_char_person_list(cur_show_info)
|
||||||
|
))
|
||||||
|
except (BaseException, Exception):
|
||||||
|
pass
|
||||||
|
kwargs.update(dict(oldest=oldest, newest=newest, oldest_dt=oldest_dt, newest_dt=newest_dt, use_ratings=False, term_vote='Score'))
|
||||||
|
|
||||||
|
this_year = dt_date.today().year
|
||||||
|
years = [
|
||||||
|
(this_year - cur_y,
|
||||||
|
'tvdb_toprated?year=%s' % (this_year - cur_y),
|
||||||
|
'Top %s releases' % (this_year - cur_y))
|
||||||
|
for cur_y in range(0, 10)]
|
||||||
|
kwargs.update(dict(footnote=footnote, use_networks=use_networks, year=top_year or '', rate_years=years))
|
||||||
|
|
||||||
|
if mode and self.allow_browse_mru(mode):
|
||||||
|
func = 'tvdb_%s' % mode
|
||||||
|
if callable(getattr(self, func, None)):
|
||||||
|
sickgear.TVDB_MRU = func
|
||||||
|
sickgear.save_config()
|
||||||
|
return self.browse_shows(browse_type, browse_title, filtered, **kwargs)
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
|
def info_tvdb(self, ids, show_name):
|
||||||
|
|
||||||
|
if not list(filter(lambda tvid_prodid: helpers.find_show_by_id(tvid_prodid), ids.split(' '))):
|
||||||
|
return self.new_show('|'.join(['', '', '', ' '.join([ids, show_name])]), use_show_name=True)
|
||||||
|
|
||||||
def tvm_default(self):
|
def tvm_default(self):
|
||||||
method = getattr(self, sickgear.TVM_MRU, None)
|
method = getattr(self, sickgear.TVM_MRU, None)
|
||||||
if not callable(method) or not self.allow_browse_mru(sickgear.TMDB_MRU):
|
if not callable(method) or not self.allow_browse_mru(sickgear.TMDB_MRU):
|
||||||
|
@ -6065,13 +6216,16 @@ class AddShows(Home):
|
||||||
return result.replace('.....', '...')
|
return result.replace('.....', '...')
|
||||||
return 'No overview yet'
|
return 'No overview yet'
|
||||||
|
|
||||||
def tvm_get_showinfo(self, tvid_prodid=None, oldest_dt=9999999, newest_dt=0):
|
def tvi_get_showinfo(self, tvid_prodid=None, oldest_dt=9999999, newest_dt=0):
|
||||||
result = {}
|
result = {}
|
||||||
if 'tvmaze' in tvid_prodid:
|
if isinstance(tvid_prodid, str) and (tvid_prodid.startswith('tvmaze') or tvid_prodid.startswith('tvdb')):
|
||||||
tvid = TVINFO_TVMAZE
|
tvid = TVINFO_TVMAZE
|
||||||
|
if tvid_prodid.startswith('tvdb'):
|
||||||
|
tvid = TVINFO_TVDB
|
||||||
|
|
||||||
tvinfo_config = sickgear.TVInfoAPI(tvid).api_params.copy()
|
tvinfo_config = sickgear.TVInfoAPI(tvid).api_params.copy()
|
||||||
t = sickgear.TVInfoAPI(tvid).setup(**tvinfo_config) # type: Union[TvmazeIndexer, TVInfoBase]
|
t = sickgear.TVInfoAPI(tvid).setup(**tvinfo_config) # type: Union[TvmazeIndexer, TVInfoBase]
|
||||||
show_info = t.get_show(int(tvid_prodid.replace('tvmaze:','')), load_episodes=False)
|
show_info = t.get_show(int(re.sub('^[a-z]+?:', '', tvid_prodid)), load_episodes=False)
|
||||||
|
|
||||||
oldest_dt, newest_dt = int(oldest_dt), int(newest_dt)
|
oldest_dt, newest_dt = int(oldest_dt), int(newest_dt)
|
||||||
ord_premiered, str_premiered, started_past, old_dt, new_dt, oldest, newest, \
|
ord_premiered, str_premiered, started_past, old_dt, new_dt, oldest, newest, \
|
||||||
|
@ -6234,7 +6388,7 @@ class AddShows(Home):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def sanitise_dates(date, oldest_dt, newest_dt, oldest, newest, episode_info=None, combine_ep_airtime=False):
|
def sanitise_dates(date, oldest_dt, newest_dt, oldest, newest, episode_info=None, combine_ep_airtime=False):
|
||||||
# in case of person search (tvmaze) guest starring entires have only show name/id, no dates
|
# in case of person search (tvmaze) guest starring entries have only show name/id, no dates
|
||||||
if None is date:
|
if None is date:
|
||||||
return 9, '', True, oldest_dt, newest_dt, oldest, newest, True, 9, 'TBC', False
|
return 9, '', True, oldest_dt, newest_dt, oldest, newest, True, 9, 'TBC', False
|
||||||
parseinfo = dateutil.parser.parserinfo(dayfirst=False, yearfirst=True)
|
parseinfo = dateutil.parser.parserinfo(dayfirst=False, yearfirst=True)
|
||||||
|
@ -6283,7 +6437,7 @@ class AddShows(Home):
|
||||||
def browse_mru(browse_type, **kwargs):
|
def browse_mru(browse_type, **kwargs):
|
||||||
save_config = False
|
save_config = False
|
||||||
if browse_type in ('AniDB', 'IMDb', 'Metacritic', 'Trakt', 'TVCalendar',
|
if browse_type in ('AniDB', 'IMDb', 'Metacritic', 'Trakt', 'TVCalendar',
|
||||||
'TMDB', 'TVmaze', 'Nextepisode'):
|
'TMDB', 'TVDb', 'TVmaze', 'Nextepisode'):
|
||||||
save_config = True
|
save_config = True
|
||||||
if browse_type in ('TVmaze',) and kwargs.get('showfilter') and kwargs.get('showsort'):
|
if browse_type in ('TVmaze',) and kwargs.get('showfilter') and kwargs.get('showsort'):
|
||||||
sickgear.BROWSELIST_MRU.setdefault(browse_type, dict()) \
|
sickgear.BROWSELIST_MRU.setdefault(browse_type, dict()) \
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue