mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-18 16:53:38 +00:00
Add try_date for use in attempting conversion of unspecified date format types birthdate, deathdate, aired.
Change tweaks, remove one warn, order imports. Change tidy up of other warnings, mismatched types, typos, a strange arg issue with deepcopy, and PEP8. Bug fix, bad key in get_item for TVInfoSocialIDs. Fix ambiguities of `show` used in sg versus external uses. Change add cast, crew type mappings Change only take Main Actors, Hosts, Interviewers, Presenters.
This commit is contained in:
parent
0fbf88651d
commit
5ff18a8652
10 changed files with 519 additions and 460 deletions
|
@ -13,12 +13,13 @@ import re
|
||||||
from bs4_parser import BS4Parser
|
from bs4_parser import BS4Parser
|
||||||
from exceptions_helper import ex
|
from exceptions_helper import ex
|
||||||
from lib import imdbpie
|
from lib import imdbpie
|
||||||
# from lib.tvinfo_base.exceptions import BaseTVinfoShownotfound
|
|
||||||
from lib.tvinfo_base import PersonGenders, TVInfoBase, TVInfoIDs, TVInfoCharacter, TVInfoPerson, TVInfoShow, \
|
|
||||||
TVINFO_IMDB
|
|
||||||
# , TVINFO_TMDB, TVINFO_TRAKT, TVINFO_TVDB, TVINFO_TVRAGE, \
|
|
||||||
# TVINFO_FACEBOOK, TVINFO_INSTAGRAM, TVINFO_TWITTER, TVINFO_WIKIPEDIA
|
|
||||||
from lib.dateutil.parser import parser
|
from lib.dateutil.parser import parser
|
||||||
|
# from lib.tvinfo_base.exceptions import BaseTVinfoShownotfound
|
||||||
|
from lib.tvinfo_base import (
|
||||||
|
TVInfoCharacter, TVInfoPerson, PersonGenders, TVINFO_IMDB,
|
||||||
|
# TVINFO_FACEBOOK, TVINFO_INSTAGRAM, TVINFO_TMDB, TVINFO_TRAKT,
|
||||||
|
# TVINFO_TVDB, TVINFO_TVRAGE, TVINFO_TWITTER, TVINFO_WIKIPEDIA,
|
||||||
|
TVInfoBase, TVInfoIDs, TVInfoShow)
|
||||||
from sg_helpers import get_url, try_int
|
from sg_helpers import get_url, try_int
|
||||||
|
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
|
@ -67,12 +68,13 @@ class IMDbIndexer(TVInfoBase):
|
||||||
"""
|
"""
|
||||||
def _make_result_dict(s):
|
def _make_result_dict(s):
|
||||||
imdb_id = try_int(re.search(r'tt(\d+)', s.get('id') or s.get('imdb_id')).group(1), None)
|
imdb_id = try_int(re.search(r'tt(\d+)', s.get('id') or s.get('imdb_id')).group(1), None)
|
||||||
tvs = TVInfoShow()
|
ti_show = TVInfoShow()
|
||||||
tvs.seriesname, tvs.id, tvs.firstaired, tvs.genre_list, tvs.overview, tvs.poster, tvs.ids = \
|
ti_show.seriesname, ti_show.id, ti_show.firstaired, ti_show.genre_list, ti_show.overview, \
|
||||||
|
ti_show.poster, ti_show.ids = \
|
||||||
s['title'], imdb_id, s.get('releaseDetails', {}).get('date') or s.get('year'), s.get('genres'), \
|
s['title'], imdb_id, s.get('releaseDetails', {}).get('date') or s.get('year'), s.get('genres'), \
|
||||||
s.get('plot', {}).get('outline', {}).get('text'), s.get('image') and s['image'].get('url'), \
|
s.get('plot', {}).get('outline', {}).get('text'), s.get('image') and s['image'].get('url'), \
|
||||||
TVInfoIDs(imdb=imdb_id)
|
TVInfoIDs(imdb=imdb_id)
|
||||||
return tvs
|
return ti_show
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
if ids:
|
if ids:
|
||||||
|
@ -112,14 +114,14 @@ class IMDbIndexer(TVInfoBase):
|
||||||
if known_for['titleType'] not in ('tvSeries', 'tvMiniSeries'):
|
if known_for['titleType'] not in ('tvSeries', 'tvMiniSeries'):
|
||||||
continue
|
continue
|
||||||
for character in known_for.get('characters') or []:
|
for character in known_for.get('characters') or []:
|
||||||
show = TVInfoShow()
|
ti_show = TVInfoShow()
|
||||||
show.id = try_int(re.search(r'(\d+)', known_for.get('id')).group(1))
|
ti_show.id = try_int(re.search(r'(\d+)', known_for.get('id')).group(1))
|
||||||
show.ids.imdb = show.id
|
ti_show.ids.imdb = ti_show.id
|
||||||
show.seriesname = known_for.get('title')
|
ti_show.seriesname = known_for.get('title')
|
||||||
show.firstaired = known_for.get('year')
|
ti_show.firstaired = known_for.get('year')
|
||||||
characters.append(
|
characters.append(
|
||||||
TVInfoCharacter(name=character, show=show,
|
TVInfoCharacter(name=character, ti_show=ti_show, start_year=known_for.get('startYear'),
|
||||||
start_year=known_for.get('startYear'), end_year=known_for.get('endYear'))
|
end_year=known_for.get('endYear'))
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
birthdate = person_obj['base']['birthDate'] and tz_p.parse(person_obj['base']['birthDate']).date()
|
birthdate = person_obj['base']['birthDate'] and tz_p.parse(person_obj['base']['birthDate']).date()
|
||||||
|
@ -175,7 +177,8 @@ class IMDbIndexer(TVInfoBase):
|
||||||
results.append(self._convert_person(cp))
|
results.append(self._convert_person(cp))
|
||||||
return results
|
return results
|
||||||
|
|
||||||
def _get_bio(self, p_id):
|
@staticmethod
|
||||||
|
def _get_bio(p_id):
|
||||||
try:
|
try:
|
||||||
bio = get_url('https://www.imdb.com/name/nm%07d/bio' % p_id, headers={'Accept-Language': 'en'})
|
bio = get_url('https://www.imdb.com/name/nm%07d/bio' % p_id, headers={'Accept-Language': 'en'})
|
||||||
if not bio:
|
if not bio:
|
||||||
|
@ -217,4 +220,3 @@ class IMDbIndexer(TVInfoBase):
|
||||||
self._set_cache_entry(cache_credits_key, fg)
|
self._set_cache_entry(cache_credits_key, fg)
|
||||||
if p:
|
if p:
|
||||||
return self._convert_person(p, filmography=fg, bio=bio)
|
return self._convert_person(p, filmography=fg, bio=bio)
|
||||||
|
|
||||||
|
|
|
@ -184,9 +184,9 @@ class TmdbIndexer(TVInfoBase):
|
||||||
"""This searches TMDB for the series name,
|
"""This searches TMDB for the series name,
|
||||||
"""
|
"""
|
||||||
def _make_result_dict(s):
|
def _make_result_dict(s):
|
||||||
tvs = TVInfoShow()
|
ti_show = TVInfoShow()
|
||||||
tvs.seriesname, tvs.id, tvs.seriesid, tvs.firstaired, tvs.genre_list, tvs.overview, tvs.poster, tvs.ids, \
|
ti_show.seriesname, ti_show.id, ti_show.seriesid, ti_show.firstaired, ti_show.genre_list, \
|
||||||
tvs.language, tvs.popularity, tvs.rating = \
|
ti_show.overview, ti_show.poster, ti_show.ids, ti_show.language, ti_show.popularity, ti_show.rating = \
|
||||||
clean_data(s['name']), s['id'], s['id'], clean_data(s.get('first_air_date')) or None, \
|
clean_data(s['name']), s['id'], s['id'], clean_data(s.get('first_air_date')) or None, \
|
||||||
clean_data([self.tv_genres.get(g) for g in s.get('genre_ids') or []]), \
|
clean_data([self.tv_genres.get(g) for g in s.get('genre_ids') or []]), \
|
||||||
clean_data(s.get('overview')), s.get('poster_path') and '%s%s%s' % (
|
clean_data(s.get('overview')), s.get('poster_path') and '%s%s%s' % (
|
||||||
|
@ -197,8 +197,8 @@ class TmdbIndexer(TVInfoBase):
|
||||||
imdb=s.get('external_ids') and s['external_ids'].get('imdb_id') and
|
imdb=s.get('external_ids') and s['external_ids'].get('imdb_id') and
|
||||||
try_int(s['external_ids'].get('imdb_id', '').replace('tt', ''), None)), \
|
try_int(s['external_ids'].get('imdb_id', '').replace('tt', ''), None)), \
|
||||||
clean_data(s.get('original_language')), s.get('popularity'), s.get('vote_average')
|
clean_data(s.get('original_language')), s.get('popularity'), s.get('vote_average')
|
||||||
tvs.genre = '|'.join(tvs.genre_list or [])
|
ti_show.genre = '|'.join(ti_show.genre_list or [])
|
||||||
return tvs
|
return ti_show
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
if ids:
|
if ids:
|
||||||
|
@ -267,14 +267,14 @@ class TmdbIndexer(TVInfoBase):
|
||||||
|
|
||||||
characters = []
|
characters = []
|
||||||
for character in cast or []:
|
for character in cast or []:
|
||||||
show = TVInfoShow()
|
ti_show = TVInfoShow()
|
||||||
show.id = character.get('id')
|
ti_show.id = character.get('id')
|
||||||
show.ids = TVInfoIDs(ids={TVINFO_TMDB: show.id})
|
ti_show.ids = TVInfoIDs(ids={TVINFO_TMDB: ti_show.id})
|
||||||
show.seriesname = clean_data(character.get('original_name'))
|
ti_show.seriesname = clean_data(character.get('original_name'))
|
||||||
show.overview = clean_data(character.get('overview'))
|
ti_show.overview = clean_data(character.get('overview'))
|
||||||
show.firstaired = clean_data(character.get('first_air_date'))
|
ti_show.firstaired = clean_data(character.get('first_air_date'))
|
||||||
characters.append(
|
characters.append(
|
||||||
TVInfoCharacter(name=clean_data(character.get('character')), show=show)
|
TVInfoCharacter(name=clean_data(character.get('character')), show=ti_show)
|
||||||
)
|
)
|
||||||
|
|
||||||
pi = person_obj.get('images')
|
pi = person_obj.get('images')
|
||||||
|
@ -408,31 +408,32 @@ class TmdbIndexer(TVInfoBase):
|
||||||
def _convert_show(self, show_dict, show_obj=None):
|
def _convert_show(self, show_dict, show_obj=None):
|
||||||
# type: (Dict, TVInfoShow) -> TVInfoShow
|
# type: (Dict, TVInfoShow) -> TVInfoShow
|
||||||
if None is show_obj:
|
if None is show_obj:
|
||||||
tv_s = TVInfoShow()
|
ti_show = TVInfoShow()
|
||||||
else:
|
else:
|
||||||
tv_s = show_obj
|
ti_show = show_obj
|
||||||
if show_dict:
|
if show_dict:
|
||||||
tv_s.seriesname = clean_data(show_dict.get('name') or show_dict.get('original_name')
|
ti_show.seriesname = clean_data(show_dict.get('name') or show_dict.get('original_name')
|
||||||
or show_dict.get('original_title'))
|
or show_dict.get('original_title'))
|
||||||
org_title = clean_data(show_dict.get('original_name') or show_dict.get('original_title'))
|
org_title = clean_data(show_dict.get('original_name') or show_dict.get('original_title'))
|
||||||
if org_title != tv_s.seriesname:
|
if org_title != ti_show.seriesname:
|
||||||
tv_s.aliases = [org_title]
|
ti_show.aliases = [org_title]
|
||||||
tv_s.id = show_dict.get('id')
|
ti_show.id = show_dict.get('id')
|
||||||
tv_s.seriesid = tv_s.id
|
ti_show.seriesid = ti_show.id
|
||||||
tv_s.language = clean_data(show_dict.get('original_language'))
|
ti_show.language = clean_data(show_dict.get('original_language'))
|
||||||
tv_s.overview = clean_data(show_dict.get('overview'))
|
ti_show.overview = clean_data(show_dict.get('overview'))
|
||||||
tv_s.status = clean_data(show_dict.get('status', ''))
|
ti_show.status = clean_data(show_dict.get('status', ''))
|
||||||
tv_s.show_type = clean_data((show_dict.get('type') and [show_dict['type']]) or [])
|
ti_show.show_type = clean_data((show_dict.get('type') and [show_dict['type']]) or [])
|
||||||
tv_s.firstaired = clean_data(show_dict.get('first_air_date'))
|
ti_show.firstaired = clean_data(show_dict.get('first_air_date'))
|
||||||
tv_s.vote_count = show_dict.get('vote_count')
|
ti_show.popularity = show_dict.get('popularity')
|
||||||
tv_s.vote_average = show_dict.get('vote_average')
|
ti_show.vote_count = show_dict.get('vote_count')
|
||||||
tv_s.popularity = show_dict.get('popularity')
|
ti_show.vote_average = show_dict.get('vote_average')
|
||||||
tv_s.origin_countries = clean_data(show_dict.get('origin_country') or [])
|
ti_show.origin_countries = show_dict.get('origin_country') or []
|
||||||
tv_s.genre_list = []
|
ti_show.genre_list = []
|
||||||
|
ti_show.origin_countries = clean_data(show_dict.get('origin_country') or [])
|
||||||
for g in show_dict.get('genre_ids') or []:
|
for g in show_dict.get('genre_ids') or []:
|
||||||
if g in self.tv_genres:
|
if g in self.tv_genres:
|
||||||
tv_s.genre_list.append(self.tv_genres.get(g))
|
ti_show.genre_list.append(self.tv_genres.get(g))
|
||||||
tv_s.genre = '|'.join(tv_s.genre_list)
|
ti_show.genre = '|'.join(ti_show.genre_list)
|
||||||
runtime = None
|
runtime = None
|
||||||
for r in sorted(show_dict.get('episode_run_time') or [], reverse=True):
|
for r in sorted(show_dict.get('episode_run_time') or [], reverse=True):
|
||||||
if 40 < r < 50:
|
if 40 < r < 50:
|
||||||
|
@ -443,18 +444,18 @@ class TmdbIndexer(TVInfoBase):
|
||||||
break
|
break
|
||||||
if not runtime and show_dict.get('episode_run_time'):
|
if not runtime and show_dict.get('episode_run_time'):
|
||||||
runtime = max(show_dict.get('episode_run_time') or [0]) or None
|
runtime = max(show_dict.get('episode_run_time') or [0]) or None
|
||||||
tv_s.runtime = runtime
|
ti_show.runtime = runtime
|
||||||
|
|
||||||
tv_s.networks = [
|
ti_show.networks = [
|
||||||
TVInfoNetwork(name=clean_data(n.get('name')), n_id=n.get('id'),
|
TVInfoNetwork(name=clean_data(n.get('name')), n_id=n.get('id'),
|
||||||
country_code=clean_data(n.get('origin_country')))
|
country_code=clean_data(n.get('origin_country')))
|
||||||
for n in reversed(show_dict.get('networks') or [])
|
for n in reversed(show_dict.get('networks') or [])
|
||||||
]
|
]
|
||||||
|
|
||||||
if show_dict.get('networks'):
|
if show_dict.get('networks'):
|
||||||
tv_s.network = clean_data(show_dict['networks'][-1]['name'])
|
ti_show.network = clean_data(show_dict['networks'][-1]['name'])
|
||||||
tv_s.network_id = show_dict['networks'][-1].get('id')
|
ti_show.network_id = show_dict['networks'][-1].get('id')
|
||||||
tv_s.network_country_code = clean_data(show_dict['networks'][-1].get('origin_country'))
|
ti_show.network_country_code = clean_data(show_dict['networks'][-1].get('origin_country'))
|
||||||
|
|
||||||
image_url = show_dict.get('poster_path') and '%s%s%s' % \
|
image_url = show_dict.get('poster_path') and '%s%s%s' % \
|
||||||
(self.img_base_url, self.size_map[TVInfoImageType.poster][TVInfoImageSize.original],
|
(self.img_base_url, self.size_map[TVInfoImageType.poster][TVInfoImageSize.original],
|
||||||
|
@ -465,19 +466,19 @@ class TmdbIndexer(TVInfoBase):
|
||||||
backdrop_url = show_dict.get('backdrop_path') and '%s%s%s' % \
|
backdrop_url = show_dict.get('backdrop_path') and '%s%s%s' % \
|
||||||
(self.img_base_url, self.size_map[TVInfoImageType.fanart][TVInfoImageSize.original],
|
(self.img_base_url, self.size_map[TVInfoImageType.fanart][TVInfoImageSize.original],
|
||||||
show_dict.get('backdrop_path'))
|
show_dict.get('backdrop_path'))
|
||||||
tv_s.ids = TVInfoIDs(tvdb=show_dict.get('external_ids', {}).get('tvdb_id'),
|
ti_show.ids = TVInfoIDs(tvdb=show_dict.get('external_ids', {}).get('tvdb_id'),
|
||||||
tmdb=show_dict['id'],
|
tmdb=show_dict['id'],
|
||||||
rage=show_dict.get('external_ids', {}).get('tvrage_id'),
|
rage=show_dict.get('external_ids', {}).get('tvrage_id'),
|
||||||
imdb=show_dict.get('external_ids', {}).get('imdb_id') and
|
imdb=show_dict.get('external_ids', {}).get('imdb_id') and
|
||||||
try_int(show_dict.get('external_ids', {}).get('imdb_id', '').replace('tt', ''), None))
|
try_int(show_dict.get('external_ids', {}).get('imdb_id', '').replace('tt', ''), None))
|
||||||
tv_s.social_ids = TVInfoSocialIDs(twitter=show_dict.get('external_ids', {}).get('twitter_id'),
|
ti_show.social_ids = TVInfoSocialIDs(twitter=show_dict.get('external_ids', {}).get('twitter_id'),
|
||||||
instagram=show_dict.get('external_ids', {}).get('instagram_id'),
|
instagram=show_dict.get('external_ids', {}).get('instagram_id'),
|
||||||
facebook=show_dict.get('external_ids', {}).get('facebook_id'))
|
facebook=show_dict.get('external_ids', {}).get('facebook_id'))
|
||||||
|
|
||||||
tv_s.poster = image_url
|
ti_show.poster = image_url
|
||||||
tv_s.poster_thumb = thumb_image_url
|
ti_show.poster_thumb = thumb_image_url
|
||||||
tv_s.fanart = backdrop_url
|
ti_show.fanart = backdrop_url
|
||||||
return tv_s
|
return ti_show
|
||||||
|
|
||||||
def _get_show_list(self, src_method, result_count, **kwargs):
|
def _get_show_list(self, src_method, result_count, **kwargs):
|
||||||
result = []
|
result = []
|
||||||
|
@ -606,9 +607,9 @@ class TmdbIndexer(TVInfoBase):
|
||||||
tmdb_lang = ('en-US', language)[language in self._tmdb_supported_lang_list]
|
tmdb_lang = ('en-US', language)[language in self._tmdb_supported_lang_list]
|
||||||
if any((banners, posters, seasons, seasonwides, fanart)):
|
if any((banners, posters, seasons, seasonwides, fanart)):
|
||||||
to_append.append('images')
|
to_append.append('images')
|
||||||
if (actors or self.config['actors_enabled']) and not getattr(self.shows.get(sid), 'actors_loaded', False):
|
if (actors or self.config['actors_enabled']) and not getattr(self.ti_shows.get(sid), 'actors_loaded', False):
|
||||||
to_append.append('aggregate_credits')
|
to_append.append('aggregate_credits')
|
||||||
if get_ep_info and not getattr(self.shows.get(sid), 'ep_loaded', False):
|
if get_ep_info and not getattr(self.ti_shows.get(sid), 'ep_loaded', False):
|
||||||
to_append.append('episode_groups')
|
to_append.append('episode_groups')
|
||||||
try:
|
try:
|
||||||
tmdb = tmdbsimple.TV(sid)
|
tmdb = tmdbsimple.TV(sid)
|
||||||
|
@ -624,7 +625,7 @@ class TmdbIndexer(TVInfoBase):
|
||||||
self.show_not_found = True
|
self.show_not_found = True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
show_obj = self.shows[sid]
|
show_obj = self.ti_shows[sid]
|
||||||
|
|
||||||
self._convert_show(show_data, show_obj)
|
self._convert_show(show_data, show_obj)
|
||||||
|
|
||||||
|
@ -656,7 +657,7 @@ class TmdbIndexer(TVInfoBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
season_cast_objs = {}
|
season_cast_objs = {}
|
||||||
if (actors or self.config['actors_enabled']) and not getattr(self.shows.get(sid), 'actors_loaded', False):
|
if (actors or self.config['actors_enabled']) and not getattr(self.ti_shows.get(sid), 'actors_loaded', False):
|
||||||
cast, show_obj.actors_loaded = CastList(), True
|
cast, show_obj.actors_loaded = CastList(), True
|
||||||
if isinstance(show_data.get('aggregate_credits'), dict) and 'cast' in show_data['aggregate_credits'] and\
|
if isinstance(show_data.get('aggregate_credits'), dict) and 'cast' in show_data['aggregate_credits'] and\
|
||||||
isinstance(show_data['aggregate_credits']['cast'], list):
|
isinstance(show_data['aggregate_credits']['cast'], list):
|
||||||
|
@ -723,7 +724,7 @@ class TmdbIndexer(TVInfoBase):
|
||||||
},
|
},
|
||||||
} for ch in cast[RoleTypes.ActorMain]]
|
} for ch in cast[RoleTypes.ActorMain]]
|
||||||
|
|
||||||
if get_ep_info and not getattr(self.shows.get(sid), 'ep_loaded', False):
|
if get_ep_info and not getattr(self.ti_shows.get(sid), 'ep_loaded', False):
|
||||||
show_obj.ep_loaded = True
|
show_obj.ep_loaded = True
|
||||||
seasons = ['season/%d' % s['season_number'] for s in show_data.get('seasons') or []]
|
seasons = ['season/%d' % s['season_number'] for s in show_data.get('seasons') or []]
|
||||||
# call limited to 20 seasons per call
|
# call limited to 20 seasons per call
|
||||||
|
|
|
@ -292,24 +292,21 @@ class TraktIndexer(TVInfoBase):
|
||||||
if show_credits:
|
if show_credits:
|
||||||
pc = []
|
pc = []
|
||||||
for c in resp.get('cast') or []:
|
for c in resp.get('cast') or []:
|
||||||
show = TVInfoShow()
|
ti_show = TVInfoShow()
|
||||||
show.id = c['show']['ids'].get('trakt')
|
ti_show.id = c['show']['ids'].get('trakt')
|
||||||
show.seriesname = c['show']['title']
|
ti_show.seriesname = c['show']['title']
|
||||||
show.ids = TVInfoIDs(ids={id_map[src]: _convert_imdb_id(id_map[src], sid)
|
ti_show.ids = TVInfoIDs(ids={id_map[src]: _convert_imdb_id(id_map[src], sid)
|
||||||
for src, sid in iteritems(c['show']['ids']) if src in id_map})
|
for src, sid in iteritems(c['show']['ids']) if src in id_map})
|
||||||
show.network = c['show']['network']
|
ti_show.network = c['show']['network']
|
||||||
show.firstaired = c['show']['first_aired']
|
ti_show.firstaired = c['show']['first_aired']
|
||||||
show.overview = c['show']['overview']
|
ti_show.overview = c['show']['overview']
|
||||||
show.status = c['show']['status']
|
ti_show.status = c['show']['status']
|
||||||
show.imdb_id = c['show']['ids'].get('imdb')
|
ti_show.imdb_id = c['show']['ids'].get('imdb')
|
||||||
show.runtime = c['show']['runtime']
|
ti_show.runtime = c['show']['runtime']
|
||||||
show.genre_list = c['show']['genres']
|
ti_show.genre_list = c['show']['genres']
|
||||||
for ch in c.get('characters') or []:
|
for ch in c.get('characters') or []:
|
||||||
pc.append(
|
pc.append(
|
||||||
TVInfoCharacter(
|
TVInfoCharacter(name=ch, regular=c.get('series_regular'), ti_show=ti_show)
|
||||||
name=ch, regular=c.get('series_regular'),
|
|
||||||
show=show
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
result.characters = pc
|
result.characters = pc
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -52,7 +52,7 @@ log = logging.getLogger('tvdb.api')
|
||||||
log.addHandler(logging.NullHandler())
|
log.addHandler(logging.NullHandler())
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyUnusedLocal
|
# noinspection HttpUrlsUsage,PyUnusedLocal
|
||||||
def _record_hook(r, *args, **kwargs):
|
def _record_hook(r, *args, **kwargs):
|
||||||
r.hook_called = True
|
r.hook_called = True
|
||||||
if 301 == r.status_code and isinstance(r.headers.get('Location'), string_types) \
|
if 301 == r.status_code and isinstance(r.headers.get('Location'), string_types) \
|
||||||
|
@ -64,8 +64,8 @@ def _record_hook(r, *args, **kwargs):
|
||||||
def retry(exception_to_check, tries=4, delay=3, backoff=2):
|
def retry(exception_to_check, tries=4, delay=3, backoff=2):
|
||||||
"""Retry calling the decorated function using an exponential backoff.
|
"""Retry calling the decorated function using an exponential backoff.
|
||||||
|
|
||||||
http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
|
www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
|
||||||
original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
|
original from: wiki.python.org/moin/PythonDecoratorLibrary#Retry
|
||||||
|
|
||||||
:param exception_to_check: the exception to check. may be a tuple of
|
:param exception_to_check: the exception to check. may be a tuple of
|
||||||
exceptions to check
|
exceptions to check
|
||||||
|
@ -222,7 +222,7 @@ class Tvdb(TVInfoBase):
|
||||||
tvdb_api's own key (fine for small scripts), but you can use your
|
tvdb_api's own key (fine for small scripts), but you can use your
|
||||||
own key if desired - this is recommended if you are embedding
|
own key if desired - this is recommended if you are embedding
|
||||||
tvdb_api in a larger application)
|
tvdb_api in a larger application)
|
||||||
See http://thetvdb.com/?tab=apiregister to get your own key
|
See thetvdb.com/?tab=apiregister to get your own key
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -976,7 +976,7 @@ class Tvdb(TVInfoBase):
|
||||||
pass
|
pass
|
||||||
self._set_show_data(sid, 'actors', a)
|
self._set_show_data(sid, 'actors', a)
|
||||||
self._set_show_data(sid, 'cast', cast)
|
self._set_show_data(sid, 'cast', cast)
|
||||||
self.shows[sid].actors_loaded = True
|
self.ti_shows[sid].actors_loaded = True
|
||||||
|
|
||||||
def get_episode_data(self, epid):
|
def get_episode_data(self, epid):
|
||||||
# Parse episode information
|
# Parse episode information
|
||||||
|
@ -1004,7 +1004,7 @@ class Tvdb(TVInfoBase):
|
||||||
mapped_img_types = {'banner': 'series'}
|
mapped_img_types = {'banner': 'series'}
|
||||||
excluded_main_data = enabled_type in ['seasons_enabled', 'seasonwides_enabled']
|
excluded_main_data = enabled_type in ['seasons_enabled', 'seasonwides_enabled']
|
||||||
loaded_name = '%s_loaded' % image_type
|
loaded_name = '%s_loaded' % image_type
|
||||||
if (type_bool or self.config[enabled_type]) and not getattr(self.shows.get(sid), loaded_name, False):
|
if (type_bool or self.config[enabled_type]) and not getattr(self.ti_shows.get(sid), loaded_name, False):
|
||||||
image_data = self._getetsrc(self.config['url_series_images'] %
|
image_data = self._getetsrc(self.config['url_series_images'] %
|
||||||
(sid, mapped_img_types.get(image_type, image_type)), language=language)
|
(sid, mapped_img_types.get(image_type, image_type)), language=language)
|
||||||
if image_data and 0 < len(image_data.get('data', '') or ''):
|
if image_data and 0 < len(image_data.get('data', '') or ''):
|
||||||
|
@ -1017,7 +1017,7 @@ class Tvdb(TVInfoBase):
|
||||||
self._set_show_data(sid, f'{image_type}_thumb', url_thumb)
|
self._set_show_data(sid, f'{image_type}_thumb', url_thumb)
|
||||||
excluded_main_data = True # artwork found so prevent fallback
|
excluded_main_data = True # artwork found so prevent fallback
|
||||||
self._parse_banners(sid, image_data['data'])
|
self._parse_banners(sid, image_data['data'])
|
||||||
self.shows[sid].__dict__[loaded_name] = True
|
self.ti_shows[sid].__dict__[loaded_name] = True
|
||||||
|
|
||||||
# fallback image thumbnail for none excluded_main_data if artwork is not found
|
# fallback image thumbnail for none excluded_main_data if artwork is not found
|
||||||
if not excluded_main_data and show_data['data'].get(image_type):
|
if not excluded_main_data and show_data['data'].get(image_type):
|
||||||
|
@ -1073,13 +1073,13 @@ class Tvdb(TVInfoBase):
|
||||||
('seasonwide', 'seasonwides_enabled', seasonwides)]:
|
('seasonwide', 'seasonwides_enabled', seasonwides)]:
|
||||||
self._parse_images(sid, language, show_data, img_type, en_type, p_type)
|
self._parse_images(sid, language, show_data, img_type, en_type, p_type)
|
||||||
|
|
||||||
if (actors or self.config['actors_enabled']) and not getattr(self.shows.get(sid), 'actors_loaded', False):
|
if (actors or self.config['actors_enabled']) and not getattr(self.ti_shows.get(sid), 'actors_loaded', False):
|
||||||
actor_data = self._getetsrc(self.config['url_actors_info'] % sid, language=language)
|
actor_data = self._getetsrc(self.config['url_actors_info'] % sid, language=language)
|
||||||
actor_data_alt = self._getetsrc(self.config['url_series_people'] % sid, language=language)
|
actor_data_alt = self._getetsrc(self.config['url_series_people'] % sid, language=language)
|
||||||
if actor_data and 0 < len(actor_data.get('data', '') or '') or actor_data_alt and actor_data_alt['data']:
|
if actor_data and 0 < len(actor_data.get('data', '') or '') or actor_data_alt and actor_data_alt['data']:
|
||||||
self._parse_actors(sid, actor_data and actor_data.get('data', ''), actor_data_alt and actor_data_alt['data'])
|
self._parse_actors(sid, actor_data and actor_data.get('data', ''), actor_data_alt and actor_data_alt['data'])
|
||||||
|
|
||||||
if get_ep_info and not getattr(self.shows.get(sid), 'ep_loaded', False):
|
if get_ep_info and not getattr(self.ti_shows.get(sid), 'ep_loaded', False):
|
||||||
# Parse episode data
|
# Parse episode data
|
||||||
log.debug('Getting all episodes of %s' % sid)
|
log.debug('Getting all episodes of %s' % sid)
|
||||||
|
|
||||||
|
@ -1200,7 +1200,7 @@ class Tvdb(TVInfoBase):
|
||||||
ep_no = int(float(elem_epno))
|
ep_no = int(float(elem_epno))
|
||||||
|
|
||||||
if not cur_ep.get('network'):
|
if not cur_ep.get('network'):
|
||||||
cur_ep['network'] = self.shows[sid].network
|
cur_ep['network'] = self.ti_shows[sid].network
|
||||||
for k, v in iteritems(cur_ep):
|
for k, v in iteritems(cur_ep):
|
||||||
k = k.lower()
|
k = k.lower()
|
||||||
|
|
||||||
|
@ -1236,7 +1236,7 @@ class Tvdb(TVInfoBase):
|
||||||
self._set_item(sid, seas_no, ep_no, 'crew', crew)
|
self._set_item(sid, seas_no, ep_no, 'crew', crew)
|
||||||
self._set_item(sid, seas_no, ep_no, 'cast', cast)
|
self._set_item(sid, seas_no, ep_no, 'cast', cast)
|
||||||
|
|
||||||
self.shows[sid].ep_loaded = True
|
self.ti_shows[sid].ep_loaded = True
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ __author__ = 'dbr/Ben'
|
||||||
__version__ = '1.9'
|
__version__ = '1.9'
|
||||||
|
|
||||||
__all__ = ['TvdbException', 'TvdbError', 'TvdbUserabort', 'TvdbShownotfound',
|
__all__ = ['TvdbException', 'TvdbError', 'TvdbUserabort', 'TvdbShownotfound',
|
||||||
'TvdbSeasonnotfound', 'TvdbEpisodenotfound', 'TvdbAttributenotfound', 'TvdbTokenexpired', 'TvdbTokenFailre']
|
'TvdbSeasonnotfound', 'TvdbEpisodenotfound', 'TvdbAttributenotfound', 'TvdbTokenexpired', 'TvdbTokenFailure']
|
||||||
|
|
||||||
from lib.tvinfo_base.exceptions import *
|
from lib.tvinfo_base.exceptions import *
|
||||||
|
|
||||||
|
@ -66,8 +66,7 @@ class TvdbTokenexpired(BaseTVinfoAuthenticationerror, TvdbError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TvdbTokenFailre(BaseTVinfoAuthenticationerror, TvdbError):
|
class TvdbTokenFailure(BaseTVinfoAuthenticationerror, TvdbError):
|
||||||
"""getting token failed
|
"""getting token failed
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ from requests.adapters import HTTPAdapter
|
||||||
from tornado._locale_data import LOCALE_NAMES
|
from tornado._locale_data import LOCALE_NAMES
|
||||||
from urllib3.util.retry import Retry
|
from urllib3.util.retry import Retry
|
||||||
|
|
||||||
from sg_helpers import clean_data, get_url, try_int
|
from sg_helpers import clean_data, enforce_type, get_url, try_int
|
||||||
from lib.dateutil.parser import parser
|
from lib.dateutil.parser import parser
|
||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
||||||
from lib.dateutil.tz.tz import _datetime_to_timestamp
|
from lib.dateutil.tz.tz import _datetime_to_timestamp
|
||||||
|
@ -317,7 +317,7 @@ class TvMaze(TVInfoBase):
|
||||||
if not show_data:
|
if not show_data:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
ti_show = self.shows[sid] # type: TVInfoShow
|
ti_show = self.ti_shows[sid] # type: TVInfoShow
|
||||||
show_obj = ti_show.__dict__
|
show_obj = ti_show.__dict__
|
||||||
for k, v in iteritems(show_obj):
|
for k, v in iteritems(show_obj):
|
||||||
if k not in ('cast', 'crew', 'images', 'aliases'):
|
if k not in ('cast', 'crew', 'images', 'aliases'):
|
||||||
|
@ -354,7 +354,7 @@ class TvMaze(TVInfoBase):
|
||||||
if show_data.genres:
|
if show_data.genres:
|
||||||
ti_show.genre = '|'.join(show_data.genres).lower()
|
ti_show.genre = '|'.join(show_data.genres).lower()
|
||||||
|
|
||||||
if (actors or self.config['actors_enabled']) and not getattr(self.shows.get(sid), 'actors_loaded', False):
|
if (actors or self.config['actors_enabled']) and not getattr(self.ti_shows.get(sid), 'actors_loaded', False):
|
||||||
if show_data.cast:
|
if show_data.cast:
|
||||||
character_person_ids = {}
|
character_person_ids = {}
|
||||||
for cur_ch in ti_show.cast[RoleTypes.ActorMain]:
|
for cur_ch in ti_show.cast[RoleTypes.ActorMain]:
|
||||||
|
@ -450,7 +450,7 @@ class TvMaze(TVInfoBase):
|
||||||
elif show_data.web_channel:
|
elif show_data.web_channel:
|
||||||
self._set_network(ti_show, show_data.web_channel, True)
|
self._set_network(ti_show, show_data.web_channel, True)
|
||||||
|
|
||||||
if get_ep_info and not getattr(self.shows.get(sid), 'ep_loaded', False):
|
if get_ep_info and not getattr(self.ti_shows.get(sid), 'ep_loaded', False):
|
||||||
log.debug('Getting all episodes of %s' % sid)
|
log.debug('Getting all episodes of %s' % sid)
|
||||||
if None is show_data:
|
if None is show_data:
|
||||||
show_data = self._get_tvm_show(sid, get_ep_info)
|
show_data = self._get_tvm_show(sid, get_ep_info)
|
||||||
|
@ -513,23 +513,23 @@ class TvMaze(TVInfoBase):
|
||||||
def _convert_person(person_obj):
|
def _convert_person(person_obj):
|
||||||
# type: (tvmaze.Person) -> TVInfoPerson
|
# type: (tvmaze.Person) -> TVInfoPerson
|
||||||
ch = []
|
ch = []
|
||||||
for c in person_obj.castcredits or []:
|
for c in tvmaze_person_obj.castcredits or []:
|
||||||
show = TVInfoShow()
|
ti_show = TVInfoShow()
|
||||||
show.seriesname = clean_data(c.show.name)
|
ti_show.seriesname = clean_data(c.show.name)
|
||||||
show.id = c.show.id
|
ti_show.id = c.show.id
|
||||||
show.firstaired = clean_data(c.show.premiered)
|
ti_show.firstaired = clean_data(c.show.premiered)
|
||||||
show.ids = TVInfoIDs(ids={TVINFO_TVMAZE: show.id})
|
ti_show.ids = TVInfoIDs(ids={TVINFO_TVMAZE: ti_show.id})
|
||||||
show.overview = clean_data(c.show.summary)
|
ti_show.overview = clean_data(c.show.summary)
|
||||||
show.status = clean_data(c.show.status)
|
ti_show.status = clean_data(c.show.status)
|
||||||
net = c.show.network or c.show.web_channel
|
net = c.show.network or c.show.web_channel
|
||||||
if net:
|
if net:
|
||||||
show.network = clean_data(net.name)
|
ti_show.network = clean_data(net.name)
|
||||||
show.network_id = net.maze_id
|
ti_show.network_id = net.maze_id
|
||||||
show.network_country = clean_data(net.country)
|
ti_show.network_country = clean_data(net.country)
|
||||||
show.network_timezone = clean_data(net.timezone)
|
ti_show.network_country_code = clean_data(net.code)
|
||||||
show.network_country_code = clean_data(net.code)
|
ti_show.network_timezone = clean_data(net.timezone)
|
||||||
show.network_is_stream = None is not c.show.web_channel
|
ti_show.network_is_stream = None is not c.show.web_channel
|
||||||
ch.append(TVInfoCharacter(name=clean_data(c.character.name), show=show))
|
ch.append(TVInfoCharacter(name=clean_data(c.character.name), ti_show=ti_show, episode_count=1))
|
||||||
try:
|
try:
|
||||||
birthdate = person_obj.birthday and tz_p.parse(person_obj.birthday).date()
|
birthdate = person_obj.birthday and tz_p.parse(person_obj.birthday).date()
|
||||||
except (BaseException, Exception):
|
except (BaseException, Exception):
|
||||||
|
|
|
@ -25,6 +25,7 @@ import unicodedata
|
||||||
from exceptions_helper import ex, ConnectionSkipException
|
from exceptions_helper import ex, ConnectionSkipException
|
||||||
from json_helper import json_loads
|
from json_helper import json_loads
|
||||||
from cachecontrol import CacheControl, caches
|
from cachecontrol import CacheControl, caches
|
||||||
|
from lib.dateutil.parser import parser
|
||||||
# from lib.tmdbsimple.configuration import Configuration
|
# from lib.tmdbsimple.configuration import Configuration
|
||||||
# from lib.tmdbsimple.genres import Genres
|
# from lib.tmdbsimple.genres import Genres
|
||||||
from cfscrape import CloudflareScraper
|
from cfscrape import CloudflareScraper
|
||||||
|
@ -41,6 +42,7 @@ from six import integer_types, iteritems, iterkeys, itervalues, moves, PY2, stri
|
||||||
import zipfile
|
import zipfile
|
||||||
# py7z hardwired removed, see comment below
|
# py7z hardwired removed, see comment below
|
||||||
py7zr = None
|
py7zr = None
|
||||||
|
tz_p = parser()
|
||||||
|
|
||||||
# noinspection PyUnreachableCode
|
# noinspection PyUnreachableCode
|
||||||
if False:
|
if False:
|
||||||
|
@ -634,6 +636,21 @@ def try_int(s, s_default=0):
|
||||||
return s_default
|
return s_default
|
||||||
|
|
||||||
|
|
||||||
|
def try_date(s, s_default=None):
|
||||||
|
# type: (AnyStr, Any) -> Optional[AnyStr]
|
||||||
|
"""
|
||||||
|
Convert string to a standard UTC date string
|
||||||
|
:param s:
|
||||||
|
:param s_default:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
parse = tz_p.parse(clean_data(s))
|
||||||
|
return '%04d-%02d-%02d' % (parse.year, parse.month, parse.day)
|
||||||
|
except(BaseException, Exception):
|
||||||
|
return s_default
|
||||||
|
|
||||||
|
|
||||||
def _maybe_request_url(e, def_url=''):
|
def _maybe_request_url(e, def_url=''):
|
||||||
return hasattr(e, 'request') and hasattr(e.request, 'url') and ' ' + e.request.url or def_url
|
return hasattr(e, 'request') and hasattr(e.request, 'url') and ' ' + e.request.url or def_url
|
||||||
|
|
||||||
|
@ -644,6 +661,7 @@ def clean_data(data):
|
||||||
|
|
||||||
Issues corrected:
|
Issues corrected:
|
||||||
- Replaces & with &
|
- Replaces & with &
|
||||||
|
- Replace multiple spaces with one space
|
||||||
- Trailing whitespace
|
- Trailing whitespace
|
||||||
- Decode html entities
|
- Decode html entities
|
||||||
:param data: data
|
:param data: data
|
||||||
|
@ -659,7 +677,7 @@ def clean_data(data):
|
||||||
if isinstance(data, dict):
|
if isinstance(data, dict):
|
||||||
return {k: clean_data(v) for k, v in iteritems(data)}
|
return {k: clean_data(v) for k, v in iteritems(data)}
|
||||||
if isinstance(data, string_types):
|
if isinstance(data, string_types):
|
||||||
return unicodedata.normalize('NFKD', html_unescape(data).strip().replace('&', '&'))
|
return unicodedata.normalize('NFKD', re.sub(r' {2,}', ' ', html_unescape(data).strip().replace('&', '&')))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ tv_src_names = {
|
||||||
|
|
||||||
log = logging.getLogger('TVInfo')
|
log = logging.getLogger('TVInfo')
|
||||||
log.addHandler(logging.NullHandler())
|
log.addHandler(logging.NullHandler())
|
||||||
TVInfoShowContainer = {} # type: Dict[str, ShowContainer]
|
TVInfoShowContainer = {} # type: Union[ShowContainer, Dict]
|
||||||
|
|
||||||
|
|
||||||
class ShowContainer(dict):
|
class ShowContainer(dict):
|
||||||
|
@ -158,9 +158,16 @@ class TVInfoIDs(object):
|
||||||
|
|
||||||
|
|
||||||
class TVInfoSocialIDs(object):
|
class TVInfoSocialIDs(object):
|
||||||
def __init__(self, twitter=None, instagram=None, facebook=None, wikipedia=None, ids=None, reddit=None,
|
def __init__(
|
||||||
youtube=None):
|
self,
|
||||||
# type: (str_int, str_int, str_int, str_int, Dict[int, str_int], str_int, str) -> None
|
twitter=None, # type: str_int
|
||||||
|
instagram=None, # type: str_int
|
||||||
|
facebook=None, # type: str_int
|
||||||
|
wikipedia=None, # type: str_int
|
||||||
|
ids=None, # type: Dict[int, str_int]
|
||||||
|
reddit=None, # type: str_int
|
||||||
|
youtube=None # type: AnyStr
|
||||||
|
):
|
||||||
ids = ids or {}
|
ids = ids or {}
|
||||||
self.twitter = twitter or ids.get(TVINFO_TWITTER)
|
self.twitter = twitter or ids.get(TVINFO_TWITTER)
|
||||||
self.instagram = instagram or ids.get(TVINFO_INSTAGRAM)
|
self.instagram = instagram or ids.get(TVINFO_INSTAGRAM)
|
||||||
|
@ -171,7 +178,7 @@ class TVInfoSocialIDs(object):
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
return {TVINFO_TWITTER: self.twitter, TVINFO_INSTAGRAM: self.instagram, TVINFO_FACEBOOK: self.facebook,
|
return {TVINFO_TWITTER: self.twitter, TVINFO_INSTAGRAM: self.instagram, TVINFO_FACEBOOK: self.facebook,
|
||||||
TVINFO_WIKIPEDIA: self.wikipedia, TVINFO_REDDIT: self.reddit, TVINFO_TWITTER: self.youtube}.get(key)
|
TVINFO_WIKIPEDIA: self.wikipedia, TVINFO_REDDIT: self.reddit, TVINFO_YOUTUBE: self.youtube}.get(key)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for s, v in [(TVINFO_TWITTER, self.twitter), (TVINFO_INSTAGRAM, self.instagram),
|
for s, v in [(TVINFO_TWITTER, self.twitter), (TVINFO_INSTAGRAM, self.instagram),
|
||||||
|
@ -238,7 +245,7 @@ class TVInfoImage(object):
|
||||||
lang=None, height=None, width=None, aspect_ratio=None):
|
lang=None, height=None, width=None, aspect_ratio=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: Dict[int, AnyStr]
|
self.sizes = sizes # type: Union[TVInfoImageSize, Dict]
|
||||||
self.type_str = type_str # type: AnyStr
|
self.type_str = type_str # type: AnyStr
|
||||||
self.main_image = main_image # type: bool
|
self.main_image = main_image # type: bool
|
||||||
self.rating = rating # type: Optional[Union[float, integer_types]]
|
self.rating = rating # type: Optional[Union[float, integer_types]]
|
||||||
|
@ -392,6 +399,8 @@ class TVInfoShow(dict):
|
||||||
setattr(result, k, copy.deepcopy(v, memo))
|
setattr(result, k, copy.deepcopy(v, memo))
|
||||||
for k, v in self.items():
|
for k, v in self.items():
|
||||||
result[k] = copy.deepcopy(v, memo)
|
result[k] = copy.deepcopy(v, memo)
|
||||||
|
if isinstance(k, integer_types):
|
||||||
|
setattr(result[k], 'show', result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
|
@ -484,9 +493,12 @@ class TVInfoSeason(dict):
|
||||||
result = cls.__new__(cls)
|
result = cls.__new__(cls)
|
||||||
memo[id(self)] = result
|
memo[id(self)] = result
|
||||||
for k, v in self.__dict__.items():
|
for k, v in self.__dict__.items():
|
||||||
|
# noinspection PyArgumentList
|
||||||
setattr(result, k, copy.deepcopy(v, memo))
|
setattr(result, k, copy.deepcopy(v, memo))
|
||||||
for k, v in self.items():
|
for k, v in self.items():
|
||||||
result[k] = copy.deepcopy(v, memo)
|
result[k] = copy.deepcopy(v, memo)
|
||||||
|
if isinstance(k, integer_types):
|
||||||
|
setattr(result[k], 'season', result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def search(self, term=None, key=None):
|
def search(self, term=None, key=None):
|
||||||
|
@ -580,6 +592,7 @@ class TVInfoEpisode(dict):
|
||||||
result = cls.__new__(cls)
|
result = cls.__new__(cls)
|
||||||
memo[id(self)] = result
|
memo[id(self)] = result
|
||||||
for k, v in self.__dict__.items():
|
for k, v in self.__dict__.items():
|
||||||
|
# noinspection PyArgumentList
|
||||||
setattr(result, k, copy.deepcopy(v, memo))
|
setattr(result, k, copy.deepcopy(v, memo))
|
||||||
for k, v in self.items():
|
for k, v in self.items():
|
||||||
result[k] = copy.deepcopy(v, memo)
|
result[k] = copy.deepcopy(v, memo)
|
||||||
|
@ -671,12 +684,12 @@ class PersonBase(dict):
|
||||||
sortorder
|
sortorder
|
||||||
"""
|
"""
|
||||||
def __init__(
|
def __init__(
|
||||||
self, # type:
|
self,
|
||||||
p_id=None, # type: integer_types
|
p_id=None, # type: integer_types
|
||||||
name=None, # type: AnyStr
|
name=None, # type: AnyStr
|
||||||
image=None, # type: AnyStr
|
image=None, # type: AnyStr
|
||||||
images=None, # type: List[TVInfoImage]
|
images=None, # type: List[TVInfoImage]
|
||||||
gender=None, # type: int
|
gender=None, # type: integer_types
|
||||||
bio=None, # type: AnyStr
|
bio=None, # type: AnyStr
|
||||||
birthdate=None, # type: datetime.date
|
birthdate=None, # type: datetime.date
|
||||||
deathdate=None, # type: datetime.date
|
deathdate=None, # type: datetime.date
|
||||||
|
@ -758,7 +771,7 @@ class TVInfoPerson(PersonBase):
|
||||||
image=None, # type: Optional[AnyStr]
|
image=None, # type: Optional[AnyStr]
|
||||||
images=None, # type: List[TVInfoImage]
|
images=None, # type: List[TVInfoImage]
|
||||||
thumb_url=None, # type: AnyStr
|
thumb_url=None, # type: AnyStr
|
||||||
gender=None, # type: int
|
gender=None, # type: integer_types
|
||||||
bio=None, # type: AnyStr
|
bio=None, # type: AnyStr
|
||||||
birthdate=None, # type: datetime.date
|
birthdate=None, # type: datetime.date
|
||||||
deathdate=None, # type: datetime.date
|
deathdate=None, # type: datetime.date
|
||||||
|
@ -766,13 +779,13 @@ class TVInfoPerson(PersonBase):
|
||||||
country_code=None, # type: AnyStr
|
country_code=None, # type: AnyStr
|
||||||
country_timezone=None, # type: AnyStr
|
country_timezone=None, # type: AnyStr
|
||||||
ids=None, # type: Dict
|
ids=None, # type: Dict
|
||||||
homepage=None, # type: AnyStr
|
homepage=None, # type: Optional[AnyStr]
|
||||||
social_ids=None, # type: Dict
|
social_ids=None, # type: Dict
|
||||||
birthplace=None, # type: AnyStr
|
birthplace=None, # type: AnyStr
|
||||||
|
deathplace=None, # type: AnyStr
|
||||||
url=None, # type: AnyStr
|
url=None, # type: AnyStr
|
||||||
characters=None, # type: List[TVInfoCharacter]
|
characters=None, # type: List[TVInfoCharacter]
|
||||||
height=None, # type: Union[integer_types, float]
|
height=None, # type: Union[integer_types, float]
|
||||||
deathplace=None, # type: AnyStr
|
|
||||||
nicknames=None, # type: Set[AnyStr]
|
nicknames=None, # type: Set[AnyStr]
|
||||||
real_name=None, # type: AnyStr
|
real_name=None, # type: AnyStr
|
||||||
akas=None, # type: Set[AnyStr]
|
akas=None, # type: Set[AnyStr]
|
||||||
|
@ -801,7 +814,7 @@ class TVInfoPerson(PersonBase):
|
||||||
|
|
||||||
|
|
||||||
class TVInfoCharacter(PersonBase):
|
class TVInfoCharacter(PersonBase):
|
||||||
def __init__(self, person=None, voice=None, plays_self=None, regular=None, show=None, start_year=None,
|
def __init__(self, person=None, voice=None, plays_self=None, regular=None, ti_show=None, start_year=None,
|
||||||
end_year=None, **kwargs):
|
end_year=None, **kwargs):
|
||||||
# type: (List[TVInfoPerson], bool, bool, bool, TVInfoShow, int, int, Dict) -> None
|
# type: (List[TVInfoPerson], bool, bool, bool, TVInfoShow, int, int, Dict) -> None
|
||||||
super(TVInfoCharacter, self).__init__(**kwargs)
|
super(TVInfoCharacter, self).__init__(**kwargs)
|
||||||
|
@ -809,7 +822,7 @@ class TVInfoCharacter(PersonBase):
|
||||||
self.voice = voice # type: Optional[bool]
|
self.voice = voice # type: Optional[bool]
|
||||||
self.plays_self = plays_self # type: Optional[bool]
|
self.plays_self = plays_self # type: Optional[bool]
|
||||||
self.regular = regular # type: Optional[bool]
|
self.regular = regular # type: Optional[bool]
|
||||||
self.show = show # type: Optional[TVInfoShow]
|
self.ti_show = ti_show # type: Optional[TVInfoShow]
|
||||||
self.start_year = start_year # type: Optional[integer_types]
|
self.start_year = start_year # type: Optional[integer_types]
|
||||||
self.end_year = end_year # type: Optional[integer_types]
|
self.end_year = end_year # type: Optional[integer_types]
|
||||||
|
|
||||||
|
@ -857,12 +870,21 @@ class RoleTypes(object):
|
||||||
CrewShowrunner = 72
|
CrewShowrunner = 72
|
||||||
CrewOther = 100
|
CrewOther = 100
|
||||||
|
|
||||||
reverse = {1: 'Main', 2: 'Recurring', 3: 'Guest', 4: 'Special Guest', 50: 'Director', 51: 'Writer', 52: 'Producer',
|
reverse = {1: 'Main', 2: 'Recurring', 3: 'Guest', 4: 'Special Guest', 10: 'Host', 11: 'Host Guest',
|
||||||
53: 'Executive Producer', 60: 'Creator', 61: 'Editor', 62: 'Camera', 63: 'Music', 64: 'Stylist',
|
12: 'Presenter', 13: 'Presenter Guest', 14: 'Interviewer', 15: 'Interviewer Guest',
|
||||||
65: 'Makeup', 66: 'Photography', 67: 'Sound', 68: 'Designer', 69: 'Developer', 70: 'Animation',
|
16: 'Musical Guest', 50: 'Director', 51: 'Writer', 52: 'Producer', 53: 'Executive Producer',
|
||||||
71: 'Visual Effects', 100: 'Other'}
|
60: 'Creator', 61: 'Editor', 62: 'Camera', 63: 'Music', 64: 'Stylist', 65: 'Makeup',
|
||||||
|
66: 'Photography', 67: 'Sound', 68: 'Designer', 69: 'Developer', 70: 'Animation',
|
||||||
|
71: 'Visual Effects', 72: 'Showrunner', 100: 'Other'}
|
||||||
crew_limit = 50
|
crew_limit = 50
|
||||||
|
|
||||||
|
# just a helper to generate the reverse data
|
||||||
|
# def __init__(self):
|
||||||
|
# import re
|
||||||
|
# {value: re.sub(r'([a-z])([A-Z])', r'\1 \2', name.replace('Actor', '').replace('Crew', ''))
|
||||||
|
# for name, value in iteritems(vars(RoleTypes)) if not name.startswith('_')
|
||||||
|
# and name not in ('reverse', 'crew_limit')}
|
||||||
|
|
||||||
|
|
||||||
crew_type_names = {c.lower(): v for v, c in iteritems(RoleTypes.reverse) if v >= RoleTypes.crew_limit}
|
crew_type_names = {c.lower(): v for v, c in iteritems(RoleTypes.reverse) if v >= RoleTypes.crew_limit}
|
||||||
|
|
||||||
|
@ -882,8 +904,8 @@ class TVInfoBase(object):
|
||||||
global TVInfoShowContainer
|
global TVInfoShowContainer
|
||||||
if self.__class__.__name__ not in TVInfoShowContainer:
|
if self.__class__.__name__ not in TVInfoShowContainer:
|
||||||
TVInfoShowContainer[self.__class__.__name__] = ShowContainer()
|
TVInfoShowContainer[self.__class__.__name__] = ShowContainer()
|
||||||
self.shows = TVInfoShowContainer[self.__class__.__name__] # type: ShowContainer[integer_types, TVInfoShow]
|
self.ti_shows = TVInfoShowContainer[self.__class__.__name__] # type: ShowContainer[integer_types, TVInfoShow]
|
||||||
self.shows.cleanup_old()
|
self.ti_shows.cleanup_old()
|
||||||
self.lang = None # type: Optional[AnyStr]
|
self.lang = None # type: Optional[AnyStr]
|
||||||
self.corrections = {} # type: Dict
|
self.corrections = {} # type: Dict
|
||||||
self.show_not_found = False # type: bool
|
self.show_not_found = False # type: bool
|
||||||
|
@ -929,10 +951,10 @@ class TVInfoBase(object):
|
||||||
:param actors: should load actors
|
:param actors: should load actors
|
||||||
:param lang: requested language
|
:param lang: requested language
|
||||||
"""
|
"""
|
||||||
if sid not in self.shows or None is self.shows[sid].id or \
|
if sid not in self.ti_shows or None is self.ti_shows[sid].id or \
|
||||||
(load_episodes and not getattr(self.shows[sid], 'ep_loaded', False)):
|
(load_episodes and not getattr(self.ti_shows[sid], 'ep_loaded', False)):
|
||||||
return True
|
return True
|
||||||
_show = self.shows[sid] # type: TVInfoShow
|
_show = self.ti_shows[sid] # type: TVInfoShow
|
||||||
if _show.requested_language != lang:
|
if _show.requested_language != lang:
|
||||||
_show.ep_loaded = _show.poster_loaded = _show.banner_loaded = _show.actors_loaded = _show.fanart_loaded = \
|
_show.ep_loaded = _show.poster_loaded = _show.banner_loaded = _show.actors_loaded = _show.fanart_loaded = \
|
||||||
_show.seasonwide_images_loaded = _show.season_images_loaded = False
|
_show.seasonwide_images_loaded = _show.season_images_loaded = False
|
||||||
|
@ -1088,8 +1110,9 @@ class TVInfoBase(object):
|
||||||
actors=False, # type: bool
|
actors=False, # type: bool
|
||||||
old_call=False, # type: bool
|
old_call=False, # type: bool
|
||||||
language=None, # type: AnyStr
|
language=None, # type: AnyStr
|
||||||
**kwargs # type: Optional[Any]
|
# **kwargs # type: dict
|
||||||
): # 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
|
||||||
|
@ -1109,33 +1132,33 @@ class TVInfoBase(object):
|
||||||
self.config.update({'banners_enabled': banners, 'posters_enabled': posters, 'seasons_enabled': seasons,
|
self.config.update({'banners_enabled': banners, 'posters_enabled': posters, 'seasons_enabled': seasons,
|
||||||
'seasonwides_enabled': seasonwides, 'fanart_enabled': fanart, 'actors_enabled': actors,
|
'seasonwides_enabled': seasonwides, 'fanart_enabled': fanart, 'actors_enabled': actors,
|
||||||
'language': language or 'en'})
|
'language': language or 'en'})
|
||||||
self.shows.lock.acquire()
|
self.ti_shows.lock.acquire()
|
||||||
try:
|
try:
|
||||||
if show_id not in self.shows:
|
if show_id not in self.ti_shows:
|
||||||
self.shows[show_id] = TVInfoShow() # type: TVInfoShow
|
self.ti_shows[show_id] = TVInfoShow() # type: TVInfoShow
|
||||||
with self.shows[show_id].lock:
|
with self.ti_shows[show_id].lock:
|
||||||
self.shows.lock.release()
|
self.ti_shows.lock.release()
|
||||||
try:
|
try:
|
||||||
if self._must_load_data(show_id, load_episodes, banners, posters, seasons, seasonwides, fanart,
|
if self._must_load_data(show_id, load_episodes, banners, posters, seasons, seasonwides, fanart,
|
||||||
actors, self.config['language']):
|
actors, self.config['language']):
|
||||||
self.shows[show_id].requested_language = self.config['language']
|
self.ti_shows[show_id].requested_language = self.config['language']
|
||||||
self._get_show_data(show_id, self.map_languages.get(self.config['language'],
|
self._get_show_data(show_id, self.map_languages.get(self.config['language'],
|
||||||
self.config['language']),
|
self.config['language']),
|
||||||
load_episodes, banners, posters, seasons, seasonwides, fanart, actors)
|
load_episodes, banners, posters, seasons, seasonwides, fanart, actors)
|
||||||
if None is self.shows[show_id].id:
|
if None is self.ti_shows[show_id].id:
|
||||||
with self.shows.lock:
|
with self.ti_shows.lock:
|
||||||
del self.shows[show_id]
|
del self.ti_shows[show_id]
|
||||||
return None if show_id not in self.shows else copy.deepcopy(self.shows[show_id])
|
return None if show_id not in self.ti_shows else copy.deepcopy(self.ti_shows[show_id])
|
||||||
finally:
|
finally:
|
||||||
try:
|
try:
|
||||||
if None is self.shows[show_id].id:
|
if None is self.ti_shows[show_id].id:
|
||||||
with self.shows.lock:
|
with self.ti_shows.lock:
|
||||||
del self.shows[show_id]
|
del self.ti_shows[show_id]
|
||||||
except (BaseException, Exception):
|
except (BaseException, Exception):
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
try:
|
try:
|
||||||
self.shows.lock.release()
|
self.ti_shows.lock.release()
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
pass
|
pass
|
||||||
if not old_call and None is not self._old_config:
|
if not old_call and None is not self._old_config:
|
||||||
|
@ -1163,8 +1186,13 @@ class TVInfoBase(object):
|
||||||
return names
|
return names
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def search_show(self, name=None, ids=None, **kwargs):
|
def search_show(
|
||||||
# type: (Union[AnyStr, List[AnyStr]], Dict[integer_types, integer_types], Optional[Any]) -> List[Dict]
|
self,
|
||||||
|
name=None, # type: Union[AnyStr, List[AnyStr]]
|
||||||
|
ids=None, # type: Dict[integer_types, integer_types]
|
||||||
|
# **kwargs # type: Optional[Any]
|
||||||
|
):
|
||||||
|
# type: (...) -> List[Dict]
|
||||||
"""
|
"""
|
||||||
search for series with name(s) or ids
|
search for series with name(s) or ids
|
||||||
|
|
||||||
|
@ -1206,41 +1234,41 @@ class TVInfoBase(object):
|
||||||
calls __getitem__ on tvinfo[1], there is no way to check if
|
calls __getitem__ on tvinfo[1], there is no way to check if
|
||||||
tvinfo.__dict__ should have a key "1" before we auto-create it
|
tvinfo.__dict__ should have a key "1" before we auto-create it
|
||||||
"""
|
"""
|
||||||
# if sid not in self.shows:
|
# if sid not in self.ti_shows:
|
||||||
# self.shows[sid] = TVInfoShow()
|
# self.ti_shows[sid] = TVInfoShow()
|
||||||
if seas not in self.shows[sid]:
|
if seas not in self.ti_shows[sid]:
|
||||||
self.shows[sid][seas] = TVInfoSeason(show=self.shows[sid])
|
self.ti_shows[sid][seas] = TVInfoSeason(show=self.ti_shows[sid])
|
||||||
self.shows[sid][seas].number = seas
|
self.ti_shows[sid][seas].number = seas
|
||||||
if ep not in self.shows[sid][seas]:
|
if ep not in self.ti_shows[sid][seas]:
|
||||||
self.shows[sid][seas][ep] = TVInfoEpisode(season=self.shows[sid][seas], show=self.shows[sid])
|
self.ti_shows[sid][seas][ep] = TVInfoEpisode(season=self.ti_shows[sid][seas], show=self.ti_shows[sid])
|
||||||
if attrib not in ('cast', 'crew'):
|
if attrib not in ('cast', 'crew'):
|
||||||
self.shows[sid][seas][ep][attrib] = value
|
self.ti_shows[sid][seas][ep][attrib] = value
|
||||||
self.shows[sid][seas][ep].__dict__[attrib] = value
|
self.ti_shows[sid][seas][ep].__dict__[attrib] = value
|
||||||
|
|
||||||
def _set_show_data(self, sid, key, value, add=False):
|
def _set_show_data(self, sid, key, value, add=False):
|
||||||
# type: (integer_types, Any, Any, bool) -> None
|
# type: (integer_types, Any, Any, bool) -> None
|
||||||
"""Sets self.shows[sid] to a new Show instance, or sets the data
|
"""Sets self.ti_shows[sid] to a new Show instance, or sets the data
|
||||||
"""
|
"""
|
||||||
# if sid not in self.shows:
|
# if sid not in self.ti_shows:
|
||||||
# self.shows[sid] = TVInfoShow()
|
# self.ti_shows[sid] = TVInfoShow()
|
||||||
if key not in ('cast', 'crew'):
|
if key not in ('cast', 'crew'):
|
||||||
if add and isinstance(self.shows[sid].data, dict) and key in self.shows[sid].data:
|
if add and isinstance(self.ti_shows[sid].data, dict) and key in self.ti_shows[sid].data:
|
||||||
self.shows[sid].data[key].update(value)
|
self.ti_shows[sid].data[key].update(value)
|
||||||
else:
|
else:
|
||||||
self.shows[sid].data[key] = value
|
self.ti_shows[sid].data[key] = value
|
||||||
if '_banners' == key:
|
if '_banners' == key:
|
||||||
p_key = 'banners'
|
p_key = 'banners'
|
||||||
else:
|
else:
|
||||||
p_key = key
|
p_key = key
|
||||||
if add and key in self.shows[sid].__dict__ and isinstance(self.shows[sid].__dict__[p_key], dict):
|
if add and key in self.ti_shows[sid].__dict__ and isinstance(self.ti_shows[sid].__dict__[p_key], dict):
|
||||||
self.shows[sid].__dict__[p_key].update(self.shows[sid].data[key])
|
self.ti_shows[sid].__dict__[p_key].update(self.ti_shows[sid].data[key])
|
||||||
else:
|
else:
|
||||||
self.shows[sid].__dict__[p_key] = self.shows[sid].data[key]
|
self.ti_shows[sid].__dict__[p_key] = self.ti_shows[sid].data[key]
|
||||||
else:
|
else:
|
||||||
if add and key in self.shows[sid].__dict__ and isinstance(self.shows[sid].__dict__[key], dict):
|
if add and key in self.ti_shows[sid].__dict__ and isinstance(self.ti_shows[sid].__dict__[key], dict):
|
||||||
self.shows[sid].__dict__[key].update(value)
|
self.ti_shows[sid].__dict__[key].update(value)
|
||||||
else:
|
else:
|
||||||
self.shows[sid].__dict__[key] = value
|
self.ti_shows[sid].__dict__[key] = value
|
||||||
|
|
||||||
def get_updated_shows(self):
|
def get_updated_shows(self):
|
||||||
# type: (...) -> Dict[integer_types, integer_types]
|
# type: (...) -> Dict[integer_types, integer_types]
|
||||||
|
@ -1331,6 +1359,7 @@ class TVInfoBase(object):
|
||||||
|
|
||||||
msg_success = 'Treating image as %s with extracted aspect ratio'
|
msg_success = 'Treating image as %s with extracted aspect ratio'
|
||||||
# most posters are around 0.68 width/height ratio (eg. 680/1000)
|
# most posters are around 0.68 width/height ratio (eg. 680/1000)
|
||||||
|
# noinspection DuplicatedCode
|
||||||
if 0.55 <= img_ratio <= 0.8:
|
if 0.55 <= img_ratio <= 0.8:
|
||||||
log.debug(msg_success % 'poster')
|
log.debug(msg_success % 'poster')
|
||||||
return TVInfoImageType.poster
|
return TVInfoImageType.poster
|
||||||
|
@ -1368,6 +1397,6 @@ class TVInfoBase(object):
|
||||||
return self._supported_languages or []
|
return self._supported_languages or []
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '<TVInfo(%s) (containing: %s)>' % (self.__class__.__name__, text_type(self.shows))
|
return '<TVInfo(%s) (containing: %s)>' % (self.__class__.__name__, text_type(self.ti_shows))
|
||||||
|
|
||||||
__repr__ = __str__
|
__repr__ = __str__
|
||||||
|
|
579
sickgear/tv.py
579
sickgear/tv.py
File diff suppressed because it is too large
Load diff
|
@ -4173,7 +4173,7 @@ class AddShows(Home):
|
||||||
+ ('', '&lid=%s' % sickgear.TVInfoAPI().config.get('langabbv_to_id', {}).get(lang, lang))[TVINFO_TVDB == tvid],
|
+ ('', '&lid=%s' % sickgear.TVInfoAPI().config.get('langabbv_to_id', {}).get(lang, lang))[TVINFO_TVDB == tvid],
|
||||||
int(show['id']),
|
int(show['id']),
|
||||||
show['seriesname'], helpers.xhtml_escape(show['seriesname']), show['firstaired'],
|
show['seriesname'], helpers.xhtml_escape(show['seriesname']), show['firstaired'],
|
||||||
(isinstance(show['firstaired'], string_types)
|
(isinstance(show['firstaired'], string_types) and show['firstaired']
|
||||||
and SGDatetime.sbfdate(_parse_date(show['firstaired'])) or ''),
|
and SGDatetime.sbfdate(_parse_date(show['firstaired'])) or ''),
|
||||||
show.get('network', '') or '', # 11
|
show.get('network', '') or '', # 11
|
||||||
(show.get('genres', '') or show.get('genre', '') or '').replace('|', ', '), # 12
|
(show.get('genres', '') or show.get('genre', '') or '').replace('|', ', '), # 12
|
||||||
|
|
Loading…
Reference in a new issue