Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Show current episode in season list and mark current episode in episode list #1667

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion resources/language/resource.language.en_gb/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,13 @@ msgctxt "#30216"
msgid "Color of the titles marked as \"Remind me\""
msgstr ""

#. Unused 30217 to 30218
msgctxt "#30217"
msgid "Color of the title of the current episode in a season"
msgstr "

msgctxt "#30218"
msgid "Show the current episode in the season list"
msgstr "

msgctxt "#30219"
msgid "Disable notification for synchronization completed"
Expand Down
7 changes: 5 additions & 2 deletions resources/lib/kodi/infolabels.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,14 @@ def get_info(videoid, item, raw_data, profile_language_code='', delayed_db_op=Fa


def add_info_list_item(list_item: ListItemW, videoid, item, raw_data, is_in_mylist, common_data, art_item=None,
is_in_remind_me=False):
is_in_remind_me=False, is_current_episode=False):
"""Add infolabels and art to a ListItem"""
infos, quality_infos = get_info(videoid, item, raw_data, delayed_db_op=True, common_data=common_data)
list_item.addStreamInfoFromDict(quality_infos)
if is_in_mylist and common_data.get('mylist_titles_color'):
if is_current_episode and common_data.get('current_episode_titles_color'):
# Highlight ListItem title when it is the current episode of the season
list_item.setLabel(_colorize_text(common_data['current_episode_titles_color'], list_item.getLabel()))
elif is_in_mylist and common_data.get('mylist_titles_color'):
# Highlight ListItem title when the videoid is contained in "My list"
list_item.setLabel(_colorize_text(common_data['mylist_titles_color'], list_item.getLabel()))
elif is_in_remind_me:
Expand Down
12 changes: 10 additions & 2 deletions resources/lib/services/nfsession/directorybuilder/dir_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,21 @@ def get_profiles(self, request_update, preselect_guid=None, detailed_info=True):
def get_seasons(self, pathitems, tvshowid_dict, perpetual_range_start):
tvshowid = VideoId.from_dict(tvshowid_dict)
season_list = self.req_seasons(tvshowid, perpetual_range_start=perpetual_range_start)
return build_season_listing(season_list, tvshowid, pathitems)
if len(season_list.seasons) > 1 and G.ADDON.getSettingBool('show_current_episode'):
current_episode = self.req_current_episode(season_list.current_seasonid)
else:
current_episode = None
return build_season_listing(season_list, tvshowid, current_episode, pathitems)

@measure_exec_time_decorator(is_immediate=True)
def get_episodes(self, pathitems, seasonid_dict, perpetual_range_start):
seasonid = VideoId.from_dict(seasonid_dict)
episodes_list = self.req_episodes(seasonid, perpetual_range_start=perpetual_range_start)
return build_episode_listing(episodes_list, seasonid, pathitems)
if G.ADDON.getSettingInt('current_episode_titles_color') > 0:
current_episode = self.req_current_episode(seasonid)
else:
current_episode = None
return build_episode_listing(episodes_list, seasonid, current_episode, pathitems)

@measure_exec_time_decorator(is_immediate=True)
def get_video_list(self, list_id, menu_data, is_dynamic_id):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,32 @@ def _create_profile_item(profile_guid, is_selected, is_autoselect, is_autoselect


@measure_exec_time_decorator(is_immediate=True)
def build_season_listing(season_list, tvshowid, pathitems=None):
def build_season_listing(season_list, tvshowid, current_episode=None, pathitems=None):
"""Build a season listing"""
common_data = get_common_data()
directory_items = [_create_season_item(tvshowid, seasonid_value, season, season_list, common_data)
for seasonid_value, season in season_list.seasons.items()]

if current_episode:
common_data_episode = get_common_data()
common_data_episode['params'] = get_param_watched_status_by_profile()
common_data_episode['set_watched_status'] = G.ADDON.getSettingBool('sync_watched_status')
common_data_episode['active_profile_guid'] = G.LOCAL_DB.get_active_profile_guid()

episodeid_value, episode_data = current_episode.episode
current_episode_item = _create_episode_item(season_list.current_seasonid, episodeid_value, episode_data, current_episode, common_data_episode)
list_item = current_episode_item[1]

if list_item.getProperty('isPlayable') == 'true':
episode_summary = episode_data['summary']['value']
label = f"{episode_summary['season']}x{episode_summary['episode']:02d}. {episode_data['title']['value']}"
list_item.setLabel(label)

episodeid = season_list.current_seasonid.derive_episode(episodeid_value)
add_info_list_item(list_item, episodeid, episode_data, current_episode.data, False, common_data_episode)

directory_items.insert(0, current_episode_item)

# add_items_previous_next_page use the new value of perpetual_range_selector
add_items_previous_next_page(directory_items, pathitems, season_list.perpetual_range_selector, tvshowid)
G.CACHE_MANAGEMENT.execute_pending_db_ops()
Expand All @@ -151,14 +172,20 @@ def _create_season_item(tvshowid, seasonid_value, season, season_list, common_da


@measure_exec_time_decorator(is_immediate=True)
def build_episode_listing(episodes_list, seasonid, pathitems=None):
def build_episode_listing(episodes_list, seasonid, current_episode=None, pathitems=None):
"""Build a episodes listing of a season"""
common_data = get_common_data()
common_data['params'] = get_param_watched_status_by_profile()
common_data['set_watched_status'] = G.ADDON.getSettingBool('sync_watched_status')
common_data['active_profile_guid'] = G.LOCAL_DB.get_active_profile_guid()

directory_items = [_create_episode_item(seasonid, episodeid_value, episode, episodes_list, common_data)
if current_episode:
common_data['current_episode_titles_color'] = get_color_name(G.ADDON.getSettingInt('current_episode_titles_color'))
current_episodeid_value = current_episode.episode[0]
else:
current_episodeid_value = None

directory_items = [_create_episode_item(seasonid, episodeid_value, episode, episodes_list, common_data, current_episodeid_value == episodeid_value)
for episodeid_value, episode
in episodes_list.episodes.items()]
# add_items_previous_next_page use the new value of perpetual_range_selector
Expand All @@ -168,15 +195,15 @@ def build_episode_listing(episodes_list, seasonid, pathitems=None):
'title': f'{episodes_list.tvshow["title"]["value"]} - {episodes_list.season["summary"]["value"]["name"]}'}


def _create_episode_item(seasonid, episodeid_value, episode, episodes_list, common_data):
def _create_episode_item(seasonid, episodeid_value, episode, episodes_list, common_data, is_current_episode=False):
is_playable = episode['availability'].get('value', {}).get('isPlayable', False)
episodeid = seasonid.derive_episode(episodeid_value)
list_item = ListItemW(label=episode['title']['value'])
list_item.setProperties({
'isPlayable': str(is_playable).lower(),
'nf_videoid': episodeid.to_string()
})
add_info_list_item(list_item, episodeid, episode, episodes_list.data, False, common_data)
add_info_list_item(list_item, episodeid, episode, episodes_list.data, False, common_data, None, False, is_current_episode)
set_watched_status(list_item, episode, common_data)
if is_playable:
url = common.build_url(videoid=episodeid, mode=G.MODE_PLAY, params=common_data['params'])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from resources.lib import common
from resources.lib.utils.data_types import (VideoListSorted, SubgenreList, SeasonList, EpisodeList, LoCo, VideoList,
SearchVideoList, CustomVideoList, LoLoMoCategory, VideoListSupplemental,
VideosList)
VideosList, CurrentEpisode)
from resources.lib.common.exceptions import InvalidVideoListTypeError, InvalidVideoId
from resources.lib.utils.api_paths import (VIDEO_LIST_PARTIAL_PATHS, RANGE_PLACEHOLDER, VIDEO_LIST_BASIC_PARTIAL_PATHS,
SEASONS_PARTIAL_PATHS, EPISODES_PARTIAL_PATHS, ART_PARTIAL_PATHS,
Expand Down Expand Up @@ -141,6 +141,24 @@ def req_episodes(self, videoid, perpetual_range_start=None):
path_response = self.nfsession.perpetual_path_request(**call_args)
return EpisodeList(videoid, path_response)

def req_current_episode(self, videoid):
"""Retrieve the current episode of a season"""
if videoid.mediatype != common.VideoId.SEASON:
raise InvalidVideoId(f'Cannot request episode list for {videoid}')
LOG.debug('Requesting current episode for {}', videoid)
paths = ([['seasons', videoid.seasonid, 'summary']] +
[['seasons', videoid.seasonid, 'componentSummary']] +
build_paths(['seasons', videoid.seasonid, 'episodes', 'current'], EPISODES_PARTIAL_PATHS) +
build_paths(['videos', videoid.tvshowid], ART_PARTIAL_PATHS + [[['title', 'delivery']]]))

call_args = {
'paths': paths,
'length_params': ['stdlist_wid', ['seasons', videoid.seasonid, 'episodes']]
}
path_response = self.nfsession.perpetual_path_request(**call_args)

return CurrentEpisode(videoid, path_response)

@cache_utils.cache_output(cache_utils.CACHE_COMMON, identify_append_from_kwarg_name='perpetual_range_start',
ignore_self_class=True)
def req_video_list(self, list_id, perpetual_range_start=None):
Expand Down
7 changes: 6 additions & 1 deletion resources/lib/utils/api_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@

SEASONS_PARTIAL_PATHS = [
['seasonList', RANGE_PLACEHOLDER, 'summary'],
['title']
['title'],
["seasonList","current"]
] + ART_PARTIAL_PATHS

EPISODES_PARTIAL_PATHS = [
Expand Down Expand Up @@ -174,6 +175,10 @@ def iterate_references(source):
continue
yield (index, path)

if 'current' in source:
path = reference_path(source['current'])
if path is not None:
yield ('current', path)
Comment on lines +178 to +181
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added current to iterate_references


def count_references(source):
counter = 0
Expand Down
9 changes: 9 additions & 0 deletions resources/lib/utils/data_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ def __init__(self, videoid, path_response):
self.tvshow = self.data['videos'][self.videoid.tvshowid]
self.seasons = OrderedDict(
resolve_refs(self.tvshow['seasonList'], self.data))
if 'current' in self.tvshow['seasonList']:
self.current_seasonid = videoid.derive_season(self.tvshow['seasonList']['current']['value'][1])
Copy link
Contributor Author

@Falke-Design Falke-Design Jan 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is getting the value like self.tvshow['seasonList']['current']['value'][1] ok?

"seasonList": {
                    "current": {
                        "$type": "ref",
                        "value": [
                            "seasons",
                            "81370447"
                        ]
                    }
                }



class EpisodeList:
Expand All @@ -269,6 +271,13 @@ def __init__(self, videoid, path_response):
self.episodes = OrderedDict(
resolve_refs(self.season['episodes'], self.data))

class CurrentEpisode:
def __init__(self, videoid, path_response):
self.data = path_response
self.videoid = videoid
self.tvshow = self.data['videos'][self.videoid.tvshowid]
self.season = self.data['seasons'][self.videoid.seasonid]
self.episode = next(resolve_refs(self.season['episodes'], self.data))

class SubgenreList:
"""A list of subgenre."""
Expand Down
22 changes: 22 additions & 0 deletions resources/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@
<default>false</default>
<control type="toggle"/>
</setting>
<setting id="show_current_episode" type="boolean" label="30218">
<level>0</level>
<default>true</default>
<control type="toggle"/>
</setting>
<setting id="mylist_titles_color" type="integer" label="30215" help="">
<level>0</level>
<default>1</default>
Expand Down Expand Up @@ -115,6 +120,23 @@
</constraints>
<control type="spinner" format="string"/>
</setting>
<setting id="current_episode_titles_color" type="integer" label="30217" help="">
<level>0</level>
<default>5</default>
<constraints>
<options>
<option label="13106">0</option>
<option label="762">1</option>
<option label="13343">2</option>
<option label="13341">3</option>
<option label="761">4</option>
<option label="760">5</option>
<option label="731">6</option>
<option label="767">7</option>
</options>
</constraints>
<control type="spinner" format="string"/>
</setting>
</group>
</category>
<!--CATEGORY: Library-->
Expand Down
Loading