Browse Source

Change move TVMaze get_premieres and get_returning functions to TVInfoBase.

Change switch to TVInfoBase.
Fix IMDb search.
tags/release_0.25.1
Prinz23 4 years ago
committed by JackDandy
parent
commit
509e686292
  1. 26
      lib/tvinfo_base/base.py
  2. 121
      lib/tvmaze_api/tvmaze_api.py
  3. 62
      sickbeard/webserve.py

26
lib/tvinfo_base/base.py

@ -126,6 +126,9 @@ class TVInfoIDs(object):
return {TVINFO_TVDB: self.tvdb, TVINFO_TMDB: self.tmdb, TVINFO_TVMAZE: self.tvmaze,
TVINFO_IMDB: self.imdb, TVINFO_TRAKT: self.trakt, TVINFO_TVRAGE: self.rage}.get(key)
def get(self, key):
return self.__getitem__(key)
def __iter__(self):
for s, v in [(TVINFO_TVDB, self.tvdb), (TVINFO_TMDB, self.tmdb), (TVINFO_TVMAZE, self.tvmaze),
(TVINFO_IMDB, self.imdb), (TVINFO_TRAKT, self.trakt), (TVINFO_TVRAGE, self.rage)]:
@ -502,14 +505,16 @@ class TVInfoEpisode(dict):
self.thumbadded = None # type: Optional[AnyStr]
self.rating = None # type: Union[integer_types, float]
self.siteratingcount = None # type: integer_types
self.show = None # type: Optional[TVInfoShow]
def __str__(self):
show_name = self.show and self.show.seriesname and '<Show %s> - ' % self.show.seriesname
seasno, epno = int(getattr(self, 'seasonnumber', 0)), int(getattr(self, 'episodenumber', 0))
epname = getattr(self, 'episodename', '')
if None is not epname:
return '<Episode %02dx%02d - %r>' % (seasno, epno, epname)
return '%s<Episode %02dx%02d - %r>' % (show_name, seasno, epno, epname)
else:
return '<Episode %02dx%02d>' % (seasno, epno)
return '%s<Episode %02dx%02d>' % (show_name, seasno, epno)
def __getattr__(self, key):
if key in self:
@ -554,6 +559,7 @@ class TVInfoEpisode(dict):
if cur_value.find(text_type(term).lower()) > -1:
return self
__unicode__ = __str__
__repr__ = __str__
__nonzero__ = __bool__
@ -1146,8 +1152,22 @@ class TVInfoBase(object):
"""
return []
def discover(self, result_count=100, **kwargs):
def discover(self, result_count=100, get_extra_images=False, **kwargs):
# type: (...) -> List[TVInfoEpisode]
return []
def get_premieres(self, result_count=100, **kwargs):
# type: (...) -> List[TVInfoEpisode]
"""
get all premiering shows
"""
return []
def get_returning(self, result_count=100, get_extra_images=False, **kwargs):
# type: (...) -> List[TVInfoShow]
"""
get all returning shows
"""
return []
def __getitem__(self, item):

121
lib/tvmaze_api/tvmaze_api.py

@ -30,6 +30,7 @@ from lib.pytvmaze import tvmaze
if False:
from typing import Any, AnyStr, Dict, List, Optional
from six import integer_types
from lib.pytvmaze.tvmaze import Episode as TVMazeEpisode, Show as TVMazeShow
log = logging.getLogger('tvmaze.api')
log.addHandler(logging.NullHandler())
@ -548,20 +549,116 @@ class TvMaze(TVInfoBase):
if p:
return self._convert_person(p)
def get_premieres(self):
# type: (...) -> List[tvmaze.Episode]
return self.filtered_schedule(lambda e: all([1 == e.season_number, 1 == e.episode_number]))
def get_returning(self):
# type: (...) -> List[tvmaze.Episode]
return self.filtered_schedule(lambda e: all([1 != e.season_number, 1 == e.episode_number]))
@staticmethod
def filtered_schedule(condition):
def get_premieres(self, result_count=100, get_extra_images=False, **kwargs):
# type: (...) -> List[TVInfoEpisode]
return self._filtered_schedule(lambda e: all([1 == e.season_number, 1 == e.episode_number]),
get_images=get_extra_images)
def get_returning(self, result_count=100, get_extra_images=False, **kwargs):
# type: (...) -> List[TVInfoEpisode]
return self._filtered_schedule(lambda e: all([1 != e.season_number, 1 == e.episode_number]),
get_images=get_extra_images)
def _make_episode(self, episode_data, show_data=None, get_images=False):
# type: (TVMazeEpisode, TVMazeShow, bool) -> TVInfoEpisode
"""
make out of TVMazeEpisode object and optionally TVMazeShow a TVInfoEpisode
"""
tv_s = TVInfoShow()
tv_s.seriesname = show_data.name
tv_s.id = show_data.maze_id
tv_s.seriesid = tv_s.id
tv_s.language = show_data.language
tv_s.overview = show_data.summary
tv_s.firstaired = show_data.premiered
tv_s.runtime = show_data.average_runtime or show_data.runtime
tv_s.vote_average = show_data.rating and show_data.rating.get('average')
tv_s.popularity = show_data.weight
tv_s.genre_list = show_data.genres or []
tv_s.genre = ', '.join(tv_s.genre_list)
tv_s.official_site = show_data.official_site
tv_s.status = show_data.status
tv_s.show_type = show_data.type
tv_s.lastupdated = show_data.updated
tv_s.poster = show_data.image and show_data.image.get('original')
tv_s.aliases = [a.name for a in show_data.akas]
if 'days' in show_data.schedule:
tv_s.airs_dayofweek = ', '.join(show_data.schedule['days'])
network = show_data.network or show_data.web_channel
if network:
tv_s.network_is_stream = None is not show_data.web_channel
tv_s.network = network.name
tv_s.network_id = network.maze_id
tv_s.network_country = network.country
tv_s.network_country_code = network.code
tv_s.network_timezone = network.timezone
if get_images and show_data.images:
b_set, f_set, p_set = False, False, False
for img in show_data.images:
img_type = img_type_map.get(img.type, TVInfoImageType.other)
img_width, img_height = img.resolutions['original'].get('width'), \
img.resolutions['original'].get('height')
img_ar = img_width and img_height and float(img_width) / float(img_height)
img_ar_type = self._which_type(img_width, img_ar)
if TVInfoImageType.poster == img_type and img_ar and img_ar_type != img_type and \
tv_s.poster == img.resolutions.get('original')['url']:
p_set = False
tv_s.poster = None
tv_s.poster_thumb = None
img_type = (TVInfoImageType.other, img_type)[
not img_ar or img_ar_type == img_type or
img_type not in (TVInfoImageType.banner, TVInfoImageType.poster, TVInfoImageType.fanart)]
img_src = {}
for res, img_url in iteritems(img.resolutions):
img_size = img_size_map.get(res)
if img_size:
img_src[img_size] = img_url.get('url')
tv_s.images.setdefault(img_type, []).append(
TVInfoImage(
image_type=img_type, sizes=img_src, img_id=img.id, main_image=img.main,
type_str=img.type, width=img_width, height=img_height, aspect_ratio=img_ar))
if not p_set and TVInfoImageType.poster == img_type:
p_set = True
tv_s.poster = img.resolutions.get('original')['url']
tv_s.poster_thumb = img.resolutions.get('original')['url']
elif not b_set and 'banner' == img.type and TVInfoImageType.banner == img_type:
b_set = True
tv_s.banner = img.resolutions.get('original')['url']
tv_s.banner_thumb = img.resolutions.get('medium')['url']
elif not f_set and 'background' == img.type and TVInfoImageType.fanart == img_type:
f_set = True
tv_s.fanart = img.resolutions.get('original')['url']
tv_s.ids = TVInfoIDs(
tvdb=show_data.externals.get('thetvdb'), rage=show_data.externals.get('tvrage'), tvmaze=show_data.id,
imdb=show_data.externals.get('imdb') and try_int(show_data.externals.get('imdb').replace('tt', ''), None))
tv_s.imdb_id = show_data.externals.get('imdb') and try_int(show_data.externals.get('imdb').replace('tt', ''))
ep_obj = TVInfoEpisode()
ep_obj.id = episode_data.maze_id
ep_obj.seasonnumber = episode_data.season_number
ep_obj.episodenumber = episode_data.episode_number
ep_obj.episodename = episode_data.title
ep_obj.airtime = episode_data.airtime
ep_obj.firstaired = episode_data.airdate
if episode_data.airstamp:
try:
at = _datetime_to_timestamp(tz_p.parse(episode_data.airstamp))
ep_obj.timestamp = at
except (BaseException, Exception):
pass
ep_obj.filename = episode_data.image and (episode_data.image.get('original') or
episode_data.image.get('medium'))
ep_obj.is_special = episode_data.is_special()
ep_obj.overview = episode_data.summary
ep_obj.runtime = episode_data.runtime
ep_obj.show = tv_s
return ep_obj
def _filtered_schedule(self, condition, get_images=False):
try:
return sorted([
result = sorted([
e for e in tvmaze.get_full_schedule()
if condition(e) and (None is e.show.language or re.search('(?i)eng|jap', e.show.language))],
key=lambda x: x.show.premiered or x.airstamp)
except(BaseException, Exception):
return [self._make_episode(r, r.show, get_images) for r in result]
except(BaseException, Exception) as e:
return []

62
sickbeard/webserve.py

@ -93,7 +93,6 @@ from lib.dateutil.relativedelta import relativedelta
from lib.fuzzywuzzy import fuzz
from lib.libtrakt import TraktAPI
from lib.libtrakt.exceptions import TraktException, TraktAuthException
from lib.tvmaze_api.tvmaze_api import TvMaze
import lib.rarfile.rarfile as rarfile
@ -5195,10 +5194,13 @@ class AddShows(Home):
if (int(_datetime_to_timestamp(datetime.datetime.now()))
< sickbeard.MEMCACHE.get(mem_key, {}).get('last_update', 0)):
return sickbeard.MEMCACHE.get(mem_key).get('data')
tvinfo_config = sickbeard.TVInfoAPI(TVINFO_TVMAZE).api_params.copy()
t = sickbeard.TVInfoAPI(TVINFO_TVMAZE).setup(**tvinfo_config)
if 'prem' in mem_key:
data = TvMaze().get_premieres()
data = t.get_premieres()
else:
data = TvMaze().get_returning()
data = t.get_returning()
sickbeard.MEMCACHE[mem_key] = dict(
last_update=(30*60) + int(_datetime_to_timestamp(datetime.datetime.now())), data=data)
return data
@ -5211,21 +5213,23 @@ class AddShows(Home):
oldest, newest, oldest_dt, newest_dt, use_networks = None, None, 9999999, 0, False
dedupe = []
parseinfo = dateutil.parser.parserinfo(dayfirst=False, yearfirst=True)
base_url = sickbeard.TVInfoAPI(TVINFO_TVMAZE).config['show_url']
for cur_episode_info in episodes:
if cur_episode_info.show.maze_id in dedupe:
if cur_episode_info.show.id in dedupe:
continue
dedupe += [cur_episode_info.show.maze_id]
dedupe += [cur_episode_info.show.id]
try:
if cur_episode_info.airtime:
airtime = dateutil.parser.parse(cur_episode_info.airtime).time()
else:
airtime = cur_episode_info.airstamp and dateutil.parser.parse(cur_episode_info.airstamp).time()
airtime = cur_episode_info.timestamp \
and SGDatetime.from_timestamp(cur_episode_info.timestamp).time()
if (0, 0) == (airtime.hour, airtime.minute):
airtime = dateutil.parser.parse('23:59').time()
dt = datetime.datetime.combine(
dateutil.parser.parse(
(cur_episode_info.show.premiered or cur_episode_info.airdate), parseinfo).date(), airtime)
(cur_episode_info.show.firstaired or cur_episode_info.firstaired), parseinfo).date(), airtime)
dt_ordinal = dt.toordinal()
now_ordinal = datetime.datetime.now().toordinal()
when_past = dt_ordinal < now_ordinal
@ -5242,36 +5246,36 @@ class AddShows(Home):
if 'Return' in browse_title:
returning = '9'
returning_str = 'TBC'
if cur_episode_info.airdate:
returning = cur_episode_info.airdate
if cur_episode_info.firstaired:
returning = cur_episode_info.firstaired
dt_returning = datetime.datetime.combine(
dateutil.parser.parse(returning, parseinfo).date(), airtime)
when_past = dt_returning.toordinal() < now_ordinal
returning_str = SGDatetime.sbfdate(dt_returning)
try:
img_uri = next(i for i in cur_episode_info.show.images
if i.main and 'poster' == i.type).resolutions['original']['url']
img_uri = cur_episode_info.show.poster
images = dict(poster=dict(thumb='imagecache?path=browse/thumb/tvmaze&source=%s' % img_uri))
sickbeard.CACHE_IMAGE_URL_LIST.add_url(img_uri)
except(BaseException, Exception):
images = {}
ids = dict(tvmaze=cur_episode_info.maze_id)
imdb_id = cur_episode_info.show.externals.get('imdb')
ids = dict(tvmaze=cur_episode_info.id)
imdb_id = cur_episode_info.show.imdb_id
if imdb_id:
ids.update(dict(imdb=imdb_id))
tvdb_id = cur_episode_info.show.externals.get('thetvdb')
if isinstance(imdb_id, string_types) and 'tt' in imdb_id:
ids.update(dict(imdb=imdb_id))
elif isinstance(imdb_id, integer_types):
ids.update(dict(imdb='tt%08d' % imdb_id))
tvdb_id = cur_episode_info.show.ids.get(TVINFO_TVDB)
if tvdb_id:
ids.update(dict(tvdb=tvdb_id))
network_name = (getattr(cur_episode_info.show.network, 'name', None)
or getattr(cur_episode_info.show.web_channel, 'name', None) or '')
network_name = cur_episode_info.show.network
cc = 'US'
if network_name:
use_networks = True
cc = (getattr(cur_episode_info.show.network, 'code', None)
or getattr(cur_episode_info.show.web_channel, 'code', None) or 'US')
cc = cur_episode_info.show.network_country_code or cc
language = ((cur_episode_info.show.language and 'jap' in cur_episode_info.show.language.lower())
and 'jp' or 'en')
@ -5282,23 +5286,23 @@ class AddShows(Home):
returning=returning,
returning_str=returning_str,
when_past=when_past,
episode_number=cur_episode_info.episode_number,
episode_season=cur_episode_info.season_number,
episode_overview='' if not cur_episode_info.summary else cur_episode_info.summary.strip(),
genres=(', '.join(['%s' % v for v in cur_episode_info.show.genres])
or cur_episode_info.show.type or ''),
episode_number=cur_episode_info.episodenumber,
episode_season=cur_episode_info.seasonnumber,
episode_overview='' if not cur_episode_info.overview else cur_episode_info.overview.strip(),
genres=(', '.join(['%s' % v for v in cur_episode_info.show.genre_list])
or cur_episode_info.show.show_type or ''),
images=images,
overview=('No overview yet' if not cur_episode_info.show.summary
else helpers.xhtml_escape(cur_episode_info.show.summary.strip()[:250:])
overview=('No overview yet' if not cur_episode_info.show.overview
else helpers.xhtml_escape(cur_episode_info.show.overview.strip()[:250:])
.strip('*').strip()),
title=cur_episode_info.show.name,
title=cur_episode_info.show.seriesname,
language=language,
language_img=sickbeard.MEMCACHE_FLAG_IMAGES.get(language, False),
country=cc,
country_img=sickbeard.MEMCACHE_FLAG_IMAGES.get(cc.lower(), False),
network=network_name,
rating=cur_episode_info.show.weight or 0,
url_src_db=cur_episode_info.show.url,
rating=cur_episode_info.show.rating or cur_episode_info.show.popularity or 0,
url_src_db=base_url % cur_episode_info.show.id,
))
except (BaseException, Exception):
pass

Loading…
Cancel
Save