From 9ad06951bf5853e2c76684d4d29c8fb4471861c4 Mon Sep 17 00:00:00 2001 From: asciidisco Date: Sat, 5 Aug 2017 21:55:39 +0200 Subject: [PATCH] feat(core): Optimizes season and episode list sorting & removes extra dict lookup --- resources/lib/KodiHelper.py | 81 ++++++++++++++++--------------------- resources/lib/Navigation.py | 43 +++++++++++--------- 2 files changed, 59 insertions(+), 65 deletions(-) diff --git a/resources/lib/KodiHelper.py b/resources/lib/KodiHelper.py index 0e5b661..edd8313 100644 --- a/resources/lib/KodiHelper.py +++ b/resources/lib/KodiHelper.py @@ -319,7 +319,7 @@ class KodiHelper: Parameters ---------- - profiles : :obj:`dict` of :obj:`str` + profiles : :obj:`list` of :obj:`dict` of :obj:`str` List of user profiles action : :obj:`str` @@ -333,9 +333,8 @@ class KodiHelper: bool List could be build """ - for profile_id in profiles: - profile = profiles[profile_id] - url = build_url({'action': action, 'profile_id': profile_id}) + for profile in profiles: + url = build_url({'action': action, 'profile_id': profile['id']}) li = xbmcgui.ListItem(label=profile['profileName'], iconImage=profile['avatar']) li.setProperty('fanart_image', self.default_fanart) xbmcplugin.addDirectoryItem(handle=self.plugin_handle, url=url, listitem=li, isFolder=True) @@ -437,7 +436,7 @@ class KodiHelper: Dictionary of actions to build subsequent routes type : :obj:`str` - None or 'queue' f.e. when it´s a special video lists + None or 'queue' f.e. when it´s a special video lists build_url : :obj:`fn` Function to build the subsequent routes @@ -457,11 +456,11 @@ class KodiHelper: li = self._generate_context_menu_items(entry=video, li=li) # lists can be mixed with shows & movies, therefor we need to check if its a movie, so play it right away if video_list[video_list_id]['type'] == 'movie': - # it´s a movie, so we need no subfolder & a route to play it + # it´s a movie, so we need no subfolder & a route to play it isFolder = False url = build_url({'action': 'play_video', 'video_id': video_list_id, 'infoLabels': infos}) else: - # it´s a show, so we need a subfolder & route (for seasons) + # it´s a show, so we need a subfolder & route (for seasons) isFolder = True params = {'action': actions[video['type']], 'show_id': video_list_id} if 'tvshowtitle' in infos: @@ -561,16 +560,13 @@ class KodiHelper: xbmcplugin.endOfDirectory(self.plugin_handle) return True - def build_season_listing (self, seasons_sorted, season_list, build_url): + def build_season_listing (self, seasons_sorted, build_url): """Builds the season list screen for a show Parameters ---------- - seasons_sorted : :obj:`list` of :obj:`str` - Sorted season indexes - - season_list : :obj:`dict` of :obj:`str` - List of season entries + seasons_sorted : :obj:`list` of :obj:`dict` of :obj:`str` + Sorted list of season entries build_url : :obj:`fn` Function to build the subsequent routes @@ -580,21 +576,18 @@ class KodiHelper: bool List could be build """ - for index in seasons_sorted: - for season_id in season_list: - season = season_list[season_id] - if int(season['idx']) == index: - li = xbmcgui.ListItem(label=season['text']) - # add some art to the item - li = self._generate_art_info(entry=season, li=li) - # add list item info - li, infos = self._generate_entry_info(entry=season, li=li, base_info={'mediatype': 'season'}) - li = self._generate_context_menu_items(entry=season, li=li) - params = {'action': 'episode_list', 'season_id': season_id} - if 'tvshowtitle' in infos: - params['tvshowtitle'] = infos['tvshowtitle'] - url = build_url(params) - xbmcplugin.addDirectoryItem(handle=self.plugin_handle, url=url, listitem=li, isFolder=True) + for season in seasons_sorted: + li = xbmcgui.ListItem(label=season['text']) + # add some art to the item + li = self._generate_art_info(entry=season, li=li) + # add list item info + li, infos = self._generate_entry_info(entry=season, li=li, base_info={'mediatype': 'season'}) + li = self._generate_context_menu_items(entry=season, li=li) + params = {'action': 'episode_list', 'season_id': season['id']} + if 'tvshowtitle' in infos: + params['tvshowtitle'] = infos['tvshowtitle'] + url = build_url(params) + xbmcplugin.addDirectoryItem(handle=self.plugin_handle, url=url, listitem=li, isFolder=True) xbmcplugin.addSortMethod(handle=self.plugin_handle, sortMethod=xbmcplugin.SORT_METHOD_NONE) xbmcplugin.addSortMethod(handle=self.plugin_handle, sortMethod=xbmcplugin.SORT_METHOD_VIDEO_YEAR) @@ -604,16 +597,13 @@ class KodiHelper: xbmcplugin.endOfDirectory(self.plugin_handle) return True - def build_episode_listing (self, episodes_sorted, episode_list, build_url): + def build_episode_listing (self, episodes_sorted, build_url): """Builds the episode list screen for a season of a show Parameters ---------- - episodes_sorted : :obj:`list` of :obj:`str` - Sorted episode indexes - - episode_list : :obj:`dict` of :obj:`str` - List of episode entries + episodes_sorted : :obj:`list` of :obj:`dict` of :obj:`str` + Sorted list of episode entries build_url : :obj:`fn` Function to build the subsequent routes @@ -623,18 +613,15 @@ class KodiHelper: bool List could be build """ - for index in episodes_sorted: - for episode_id in episode_list: - episode = episode_list[episode_id] - if int(episode['episode']) == index: - li = xbmcgui.ListItem(label=episode['title']) - # add some art to the item - li = self._generate_art_info(entry=episode, li=li) - # add list item info - li, infos = self._generate_entry_info(entry=episode, li=li, base_info={'mediatype': 'episode'}) - li = self._generate_context_menu_items(entry=episode, li=li) - url = build_url({'action': 'play_video', 'video_id': episode_id, 'start_offset': episode['bookmark'], 'infoLabels': infos}) - xbmcplugin.addDirectoryItem(handle=self.plugin_handle, url=url, listitem=li, isFolder=False) + for episode in episodes_sorted: + li = xbmcgui.ListItem(label=episode['title']) + # add some art to the item + li = self._generate_art_info(entry=episode, li=li) + # add list item info + li, infos = self._generate_entry_info(entry=episode, li=li, base_info={'mediatype': 'episode'}) + li = self._generate_context_menu_items(entry=episode, li=li) + url = build_url({'action': 'play_video', 'video_id': episode['id'], 'start_offset': episode['bookmark'], 'infoLabels': infos}) + xbmcplugin.addDirectoryItem(handle=self.plugin_handle, url=url, listitem=li, isFolder=False) xbmcplugin.addSortMethod(handle=self.plugin_handle, sortMethod=xbmcplugin.SORT_METHOD_EPISODE) xbmcplugin.addSortMethod(handle=self.plugin_handle, sortMethod=xbmcplugin.SORT_METHOD_NONE) @@ -969,4 +956,4 @@ class KodiHelper: addon.setSetting('tracking_id', tracking_id) # Send the tracking event tracker = Tracker.create('UA-46081640-5', client_id=tracking_id) - tracker.send('event', event) + tracker.send('event', event) \ No newline at end of file diff --git a/resources/lib/Navigation.py b/resources/lib/Navigation.py index 2d690af..e233c0b 100644 --- a/resources/lib/Navigation.py +++ b/resources/lib/Navigation.py @@ -169,7 +169,7 @@ class Navigation: user_list_id : :obj:`str` Type of list to display """ - # determine if we´re in kids mode + # determine if we´re in kids mode user_data = self.call_netflix_service({'method': 'get_user_data'}) video_list_ids = self.call_netflix_service({'method': 'fetch_video_list_ids', 'guid': user_data['guid'], 'cache': True}) # check for any errors @@ -193,15 +193,18 @@ class Navigation: # check for any errors if self._is_dirty_response(response=episode_list): return False - # sort seasons by number (they´re coming back unsorted from the api) - episodes_sorted = [] - for episode_id in episode_list: - episode_list[episode_id]['tvshowtitle'] = tvshowtitle - episodes_sorted.append(int(episode_list[episode_id]['episode'])) - episodes_sorted.sort() + + # Extract episode numbers and associated keys. + d = [(v['episode'], k) for k, v in episode_list.items()] + + # sort episodes by number (they´re coming back unsorted from the api) + episodes_sorted = [episode_list[k] for (_, k) in sorted(d)] + + for episode in episodes_sorted: + episode['tvshowtitle'] = tvshowtitle # list the episodes - return self.kodi_helper.build_episode_listing(episodes_sorted=episodes_sorted, episode_list=episode_list, build_url=self.build_url) + return self.kodi_helper.build_episode_listing(episodes_sorted=episodes_sorted, build_url=self.build_url) def show_seasons (self, show_id, tvshowtitle): """Lists all seasons for a given show @@ -226,13 +229,17 @@ class Navigation: # check if we have sesons, announced shows that are not available yet have none if len(season_list) == 0: return self.kodi_helper.build_no_seasons_available() - # sort seasons by index by default (they´re coming back unsorted from the api) - seasons_sorted = [] - for season_id in season_list: - season_list[season_id]['tvshowtitle'] = tvshowtitle - seasons_sorted.append(int(season_list[season_id]['idx'])) - seasons_sorted.sort() - return self.kodi_helper.build_season_listing(seasons_sorted=seasons_sorted, season_list=season_list, build_url=self.build_url) + + # Extract episode numbers and associated keys. + d = [(v['idx'], k) for k, v in season_list.items()] + + # sort seasons by index by default (they´re coming back unsorted from the api) + seasons_sorted = [season_list[k] for (_, k) in sorted(d)] + + for season in seasons_sorted: + season['tvshowtitle'] = tvshowtitle + + return self.kodi_helper.build_season_listing(seasons_sorted=seasons_sorted, build_url=self.build_url) def show_video_list (self, video_list_id, type): """List shows/movies based on the given video list id @@ -243,7 +250,7 @@ class Navigation: ID of the video list that should be displayed type : :obj:`str` - None or 'queue' f.e. when it´s a special video lists + None or 'queue' f.e. when it´s a special video lists """ user_data = self.call_netflix_service({'method': 'get_user_data'}) video_list = self.call_netflix_service({'method': 'fetch_video_list', 'list_id': video_list_id, 'guid': user_data['guid'] ,'cache': True}) @@ -272,7 +279,7 @@ class Navigation: profiles = self.call_netflix_service({'method': 'list_profiles'}) if len(profiles) == 0: return self.kodi_helper.show_login_failed_notification() - return self.kodi_helper.build_profiles_listing(profiles=profiles, action='video_lists', build_url=self.build_url) + return self.kodi_helper.build_profiles_listing(profiles=profiles.values(), action='video_lists', build_url=self.build_url) @log def rate_on_netflix (self, video_id): @@ -563,4 +570,4 @@ class Navigation: """Opens a foreign settings dialog""" is_addon = self.kodi_helper.get_inputstream_addon() url = is_addon if url == 'is' else url - return Addon(url).openSettings() + return Addon(url).openSettings() \ No newline at end of file -- 2.30.2