Skip to content

Commit

Permalink
Simplified get_metadata and VideoId derive_parent
Browse files Browse the repository at this point in the history
  • Loading branch information
CastagnaIT committed Jun 27, 2020
1 parent e79ecae commit 857fca9
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 48 deletions.
32 changes: 13 additions & 19 deletions resources/lib/api/api_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,39 +220,33 @@ def _update_mylist_cache(videoid, operation, params):
def get_metadata(videoid, refresh=False):
"""Retrieve additional metadata for the given VideoId"""
metadata_data = {}, None
# Get the parent VideoId (when the 'videoid' is a type of EPISODE/SEASON)
parent_videoid = videoid.derive_parent(common.VideoId.SHOW)
# Delete the cache if we need to refresh the all metadata
if refresh:
videoid_cache = (videoid.derive_parent(0)
if videoid.mediatype in [common.VideoId.EPISODE, common.VideoId.SEASON]
else videoid)
g.CACHE.delete(cache_utils.CACHE_METADATA, str(videoid_cache))
if videoid.mediatype not in [common.VideoId.EPISODE, common.VideoId.SEASON]:
# videoid of type tvshow, movie, supplemental
metadata_data = _metadata(video_id=videoid), None
elif videoid.mediatype == common.VideoId.SEASON:
metadata_data = _metadata(video_id=videoid.derive_parent(None)), None
else: # it is an episode
g.CACHE.delete(cache_utils.CACHE_METADATA, str(parent_videoid))
if videoid.mediatype == common.VideoId.EPISODE:
try:
metadata_data = _episode_metadata(videoid)
metadata_data = _episode_metadata(videoid, parent_videoid)
except KeyError as exc:
# Episode metadata may not exist if its a new episode and cached
# data is outdated. In this case, delete the cache entry and
# try again safely (if it doesn't exist this time, there is no
# metadata for the episode, so we assign an empty dict).
# The episode metadata not exist (case of new episode and cached data outdated)
# In this case, delete the cache entry and try again safely
common.debug('find_episode_metadata raised an error: {}, refreshing cache', exc)
try:
metadata_data = _episode_metadata(videoid, refresh_cache=True)
metadata_data = _episode_metadata(videoid, parent_videoid, refresh_cache=True)
except KeyError as exc:
# The new metadata does not contain the episode
common.error('Episode metadata not found, find_episode_metadata raised an error: {}', exc)
else:
metadata_data = _metadata(video_id=parent_videoid), None
return metadata_data


def _episode_metadata(videoid, refresh_cache=False):
tvshow_videoid = videoid.derive_parent(0)
def _episode_metadata(episode_videoid, tvshow_videoid, refresh_cache=False):
if refresh_cache:
g.CACHE.delete(cache_utils.CACHE_METADATA, str(tvshow_videoid))
show_metadata = _metadata(video_id=tvshow_videoid)
episode_metadata, season_metadata = common.find_episode_metadata(videoid, show_metadata)
episode_metadata, season_metadata = common.find_episode_metadata(episode_videoid, show_metadata)
return episode_metadata, season_metadata, show_metadata


Expand Down
8 changes: 4 additions & 4 deletions resources/lib/common/misc_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ def find(value_to_find, attribute, search_space):
raise KeyError('Metadata for {} does not exist'.format(value_to_find))


def find_episode_metadata(videoid, metadata):
def find_episode_metadata(episode_videoid, metadata):
"""Find metadata for a specific episode within a show metadata dict"""
season = find(int(videoid.seasonid), 'id', metadata['seasons'])
return (find(int(videoid.episodeid), 'id', season.get('episodes', {})),
season)
season = find(int(episode_videoid.seasonid), 'id', metadata['seasons'])
episode = find(int(episode_videoid.episodeid), 'id', season.get('episodes', {}))
return episode, season


def get_class_methods(class_item=None):
Expand Down
42 changes: 23 additions & 19 deletions resources/lib/common/videoid.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ class InvalidVideoId(Exception):


class VideoId(object):
"""Universal representation of a video id. Video IDs can be of multiple
types:
"""Universal representation of a video id. Video IDs can be of multiple types:
- supplemental: a single identifier only for supplementalid, all other values must be None
- movie: a single identifier only for movieid, all other values must be None
- show: a single identifier only for tvshowid, all other values must be None
Expand Down Expand Up @@ -207,33 +206,38 @@ def derive_season(self, seasonid):
of this show. Raises InvalidVideoId is this instance does not
represent a show."""
if self.mediatype != VideoId.SHOW:
raise InvalidVideoId('Cannot derive season VideoId from {}'
.format(self))
raise InvalidVideoId('Cannot derive season VideoId from {}'.format(self))
return type(self)(tvshowid=self.tvshowid, seasonid=unicode(seasonid))

def derive_episode(self, episodeid):
"""Return a new VideoId instance that represents the given episode
of this season. Raises InvalidVideoId is this instance does not
represent a season."""
if self.mediatype != VideoId.SEASON:
raise InvalidVideoId('Cannot derive episode VideoId from {}'
.format(self))
raise InvalidVideoId('Cannot derive episode VideoId from {}'.format(self))
return type(self)(tvshowid=self.tvshowid, seasonid=self.seasonid,
episodeid=unicode(episodeid))

def derive_parent(self, depth):
"""Returns a new videoid for the parent mediatype (season for episodes,
show for seasons) that is at the depth's level of the mediatype
hierarchy or this instance if there is no parent mediatype."""
if self.mediatype == VideoId.SEASON:
def derive_parent(self, videoid_type):
"""
Derive a parent VideoId, you can obtain:
[tvshow] from season, episode
[season] from episode
When it is not possible get a derived VideoId, it is returned the same VideoId instance.
:param videoid_type: The type of VideoId to be derived
:return: The parent VideoId of specified type, or when not match the same VideoId instance.
"""
if videoid_type == VideoId.SHOW:
if self.mediatype not in [VideoId.SEASON, VideoId.EPISODE]:
return self
return type(self)(tvshowid=self.tvshowid)
if self.mediatype == VideoId.EPISODE:
if depth == 0:
return type(self)(tvshowid=self.tvshowid)
if depth == 1:
return type(self)(tvshowid=self.tvshowid,
seasonid=self.seasonid)
return self
if videoid_type == VideoId.SEASON:
if self.mediatype != VideoId.SEASON:
return self
return type(self)(tvshowid=self.tvshowid,
seasonid=self.seasonid)
raise InvalidVideoId('VideoId type {} not valid'.format(videoid_type))

def _assigned_id_values(self):
"""Return a list of all id_values that are not None"""
Expand All @@ -258,7 +262,7 @@ def __neq__(self, other):


def _get_unicode_kwargs(kwargs):
# Example of return value: (None, None, '70084801', None, None, None, None) this is a movieid
# Example of return value: (None, None, '70084801', None, None, None) this is a movieid
return tuple((unicode(kwargs[idpart])
if kwargs.get(idpart)
else None)
Expand Down
2 changes: 1 addition & 1 deletion resources/lib/navigation/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def _get_event_data(videoid):
req_videoids = [videoid]
if is_episode:
# Get also the tvshow data
req_videoids.append(videoid.derive_parent(0))
req_videoids.append(videoid.derive_parent(common.VideoId.SHOW))

raw_data = api.get_video_raw_data(req_videoids, EVENT_PATHS)
if not raw_data:
Expand Down
4 changes: 1 addition & 3 deletions resources/lib/services/playback/am_stream_continuity.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ def initialize(self, data):
if self.videoid.mediatype not in [common.VideoId.MOVIE, common.VideoId.EPISODE]:
self.enabled = False
return
self.current_videoid = self.videoid \
if self.videoid.mediatype == common.VideoId.MOVIE \
else self.videoid.derive_parent(0)
self.current_videoid = self.videoid.derive_parent(common.VideoId.SHOW)
self.sc_settings = g.SHARED_DB.get_stream_continuity(g.LOCAL_DB.get_active_profile_guid(),
self.current_videoid.value, {})
self.kodi_only_forced_subtitles = common.get_kodi_subtitle_language() == 'forced_only'
Expand Down
3 changes: 1 addition & 2 deletions resources/lib/services/playback/am_video_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ def initialize(self, data):
def on_playback_started(self, player_state):
# Clear continue watching list data on the cache, to force loading of new data
# but only when the videoid not exists in the continue watching list
current_videoid = (self.videoid if self.videoid.mediatype == common.VideoId.MOVIE
else self.videoid.derive_parent(0))
current_videoid = self.videoid.derive_parent(common.VideoId.SHOW)
videoid_exists, list_id = common.make_http_call('get_continuewatching_videoid_exists',
{'video_id': str(current_videoid.value)})
if not videoid_exists:
Expand Down

0 comments on commit 857fca9

Please sign in to comment.