From d6d776af224e99b724bf4b2bdf4163672d680415 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:37:25 +1000 Subject: [PATCH 01/10] Fix possible regression causing 6s delay on first play --- .../kodion/context/xbmc/xbmc_context.py | 4 +--- .../kodion/player/xbmc/xbmc_playlist_player.py | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py b/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py index b05a3ed1b..cb3d1acdc 100644 --- a/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py +++ b/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py @@ -425,9 +425,7 @@ def get_subtitle_language(self): def get_playlist_player(self, playlist_type=None): if not self._playlist or playlist_type: - self._playlist = XbmcPlaylistPlayer(playlist_type, - proxy(self), - retry=3) + self._playlist = XbmcPlaylistPlayer(proxy(self), playlist_type) return self._playlist def get_ui(self): diff --git a/resources/lib/youtube_plugin/kodion/player/xbmc/xbmc_playlist_player.py b/resources/lib/youtube_plugin/kodion/player/xbmc/xbmc_playlist_player.py index 16f54ba6e..05383c1b8 100644 --- a/resources/lib/youtube_plugin/kodion/player/xbmc/xbmc_playlist_player.py +++ b/resources/lib/youtube_plugin/kodion/player/xbmc/xbmc_playlist_player.py @@ -31,18 +31,26 @@ class XbmcPlaylistPlayer(AbstractPlaylistPlayer): 'audio': xbmc.PLAYLIST_MUSIC, # 0 } - def __init__(self, playlist_type, context, retry=0): + def __init__(self, context, playlist_type=None, retry=None): super(XbmcPlaylistPlayer, self).__init__() self._context = context - playlist_id = self._PLAYER_PLAYLIST.get(playlist_type) - if not playlist_type: + player = xbmc.Player() + if retry is None: + retry = 3 if player.isPlaying() else 0 + + if playlist_type is None: playlist_id = self.get_playlist_id(retry=retry) + else: + playlist_id = ( + self._PLAYER_PLAYLIST.get(playlist_type) + or self._PLAYER_PLAYLIST['video'] + ) self.set_playlist_id(playlist_id) self._playlist = xbmc.PlayList(playlist_id) - self._player = xbmc.Player() + self._player = player def clear(self): self._playlist.clear() From bf19eeee86a06ff692cb4c7593332dbfb6286230 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:39:05 +1000 Subject: [PATCH 02/10] Only reroute to new window if container was not filled by the plugin #896 --- resources/lib/youtube_plugin/kodion/abstract_provider.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/resources/lib/youtube_plugin/kodion/abstract_provider.py b/resources/lib/youtube_plugin/kodion/abstract_provider.py index e9789d074..06a6774d1 100644 --- a/resources/lib/youtube_plugin/kodion/abstract_provider.py +++ b/resources/lib/youtube_plugin/kodion/abstract_provider.py @@ -218,7 +218,13 @@ def on_goto_page(provider, context, re_match): else: page_token = '' params = dict(params, page=page, page_token=page_token) - return provider.reroute(context=context, path=path, params=params) + + if context.is_plugin_path( + context.get_infolabel('Container.FolderPath'), + partial=True, + ): + return provider.reroute(context=context, path=path, params=params) + return provider.navigate(context.clone(path, params)) @staticmethod def on_reroute(provider, context, re_match): From ffc0bf08f604156fcd574a491a11af7a4a7f881f Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:42:38 +1000 Subject: [PATCH 03/10] Add items_per_page query parameter to allow number of items in widgets to be customised #896 --- .../kodion/context/abstract_context.py | 1 + .../youtube_plugin/youtube/client/youtube.py | 58 +++++++++---------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/resources/lib/youtube_plugin/kodion/context/abstract_context.py b/resources/lib/youtube_plugin/kodion/context/abstract_context.py index 755501e8e..0756eb097 100644 --- a/resources/lib/youtube_plugin/kodion/context/abstract_context.py +++ b/resources/lib/youtube_plugin/kodion/context/abstract_context.py @@ -65,6 +65,7 @@ class AbstractContext(object): } _INT_PARAMS = { 'fanart_type', + 'items_per_page', 'live', 'next_page_token', 'offset', diff --git a/resources/lib/youtube_plugin/youtube/client/youtube.py b/resources/lib/youtube_plugin/youtube/client/youtube.py index a004e15b4..98a4a9154 100644 --- a/resources/lib/youtube_plugin/youtube/client/youtube.py +++ b/resources/lib/youtube_plugin/youtube/client/youtube.py @@ -127,8 +127,8 @@ def __init__(self, context, **kwargs): super(YouTube, self).__init__(context=context, **kwargs) - def get_max_results(self): - return self._max_results + def max_results(self): + return self._context.get_param('items_per_page') or self._max_results def get_language(self): return self._language @@ -348,7 +348,7 @@ def get_subscription(self, :return: """ params = {'part': 'snippet', - 'maxResults': str(self._max_results), + 'maxResults': str(self.max_results()), 'order': order} if channel_id == 'mine': params['mine'] = 'true' @@ -364,7 +364,7 @@ def get_subscription(self, def get_guide_category(self, guide_category_id, page_token='', **kwargs): params = {'part': 'snippet,contentDetails,brandingSettings', - 'maxResults': str(self._max_results), + 'maxResults': str(self.max_results()), 'categoryId': guide_category_id, 'regionCode': self._region, 'hl': self._language} @@ -377,7 +377,7 @@ def get_guide_category(self, guide_category_id, page_token='', **kwargs): def get_guide_categories(self, page_token='', **kwargs): params = {'part': 'snippet', - 'maxResults': str(self._max_results), + 'maxResults': str(self.max_results()), 'regionCode': self._region, 'hl': self._language} if page_token: @@ -390,7 +390,7 @@ def get_guide_categories(self, page_token='', **kwargs): def get_trending_videos(self, page_token='', **kwargs): params = {'part': 'snippet,status', - 'maxResults': str(self._max_results), + 'maxResults': str(self.max_results()), 'regionCode': self._region, 'hl': self._language, 'chart': 'mostPopular'} @@ -403,7 +403,7 @@ def get_trending_videos(self, page_token='', **kwargs): def get_video_category(self, video_category_id, page_token='', **kwargs): params = {'part': 'snippet,contentDetails,status', - 'maxResults': str(self._max_results), + 'maxResults': str(self.max_results()), 'videoCategoryId': video_category_id, 'chart': 'mostPopular', 'regionCode': self._region, @@ -417,7 +417,7 @@ def get_video_category(self, video_category_id, page_token='', **kwargs): def get_video_categories(self, page_token='', **kwargs): params = {'part': 'snippet', - 'maxResults': str(self._max_results), + 'maxResults': str(self.max_results()), 'regionCode': self._region, 'hl': self._language} if page_token: @@ -604,7 +604,7 @@ def get_related_for_home(self, page_token='', refresh=False): # Increase value to recursively retrieve recommendations for the first # recommended video, up to the set maximum recursion depth max_depth = 2 - items_per_page = self._max_results + items_per_page = self.max_results() diversity_limits = items_per_page // (num_items * max_depth) items = [[] for _ in range(max_depth * len(video_ids))] counts = { @@ -811,7 +811,7 @@ def rank_and_sort(item): def get_activities(self, channel_id, page_token='', **kwargs): params = {'part': 'snippet,contentDetails', - 'maxResults': str(self._max_results), + 'maxResults': str(self.max_results()), 'regionCode': self._region, 'hl': self._language} @@ -844,7 +844,7 @@ def get_channel_sections(self, channel_id, **kwargs): def get_playlists_of_channel(self, channel_id, page_token='', **kwargs): params = {'part': 'snippet', - 'maxResults': str(self._max_results)} + 'maxResults': str(self.max_results())} if channel_id != 'mine': params['channelId'] = channel_id else: @@ -864,7 +864,7 @@ def get_playlist_item_id_of_video_id(self, json_data = self.get_playlist_items( playlist_id=playlist_id, page_token=page_token, - max_results=50, + max_results=self.max_results(), ) if not json_data: return None @@ -890,7 +890,7 @@ def get_playlist_items(self, **kwargs): # prepare params if max_results is None: - max_results = self._max_results + max_results = self.max_results() params = {'part': 'snippet', 'maxResults': str(max_results), 'playlistId': playlist_id} @@ -954,7 +954,7 @@ def get_disliked_videos(self, page_token='', **kwargs): # prepare params params = {'part': 'snippet,status', 'myRating': 'dislike', - 'maxResults': str(self._max_results)} + 'maxResults': str(self.max_results())} if page_token: params['pageToken'] = page_token @@ -1022,7 +1022,7 @@ def get_live_events(self, 'regionCode': self._region, 'hl': self._language, 'relevanceLanguage': self._language, - 'maxResults': str(self._max_results)} + 'maxResults': str(self.max_results())} if location: settings = self._context.get_settings() @@ -1049,7 +1049,7 @@ def get_related_videos(self, offset=0, retry=0, **kwargs): - max_results = self._max_results if max_results <= 0 else max_results + max_results = self.max_results() if max_results <= 0 else max_results post_data = {'videoId': video_id} if page_token: @@ -1248,7 +1248,7 @@ def get_parent_comments(self, page_token='', max_results=0, **kwargs): - max_results = self._max_results if max_results <= 0 else max_results + max_results = self.max_results() if max_results <= 0 else max_results # prepare params params = {'part': 'snippet', @@ -1270,7 +1270,7 @@ def get_child_comments(self, page_token='', max_results=0, **kwargs): - max_results = self._max_results if max_results <= 0 else max_results + max_results = self.max_results() if max_results <= 0 else max_results # prepare params params = {'part': 'snippet', @@ -1293,7 +1293,7 @@ def get_channel_videos(self, channel_id, page_token='', **kwargs): params = {'part': 'snippet', 'hl': self._language, - 'maxResults': str(self._max_results), + 'maxResults': str(self.max_results()), 'type': 'video', 'safeSearch': 'none', 'order': 'date'} @@ -1355,7 +1355,7 @@ def search(self, 'regionCode': self._region, 'hl': self._language, 'relevanceLanguage': self._language, - 'maxResults': str(self._max_results)} + 'maxResults': str(self.max_results())} if event_type and event_type in {'live', 'upcoming', 'completed'}: params['eventType'] = event_type @@ -1405,7 +1405,7 @@ def get_my_subscriptions(self, 'items': [], 'pageInfo': { 'totalResults': 0, - 'resultsPerPage': self._max_results, + 'resultsPerPage': self.max_results(), }, } @@ -1430,8 +1430,8 @@ def get_my_subscriptions(self, page = page_token or 1 totals = { 'num': 0, - 'start': -self._max_results, - 'end': page * self._max_results, + 'start': -self.max_results(), + 'end': page * self.max_results(), 'video_ids': set(), } totals['start'] += totals['end'] @@ -1837,7 +1837,7 @@ def _perform(_playlist_idx, _page_token, _offset, _result): if not _result: _result = {'items': []} - _new_offset = self._max_results - len(_result['items']) + _offset + _new_offset = self.max_results() - len(_result['items']) + _offset if _offset > 0: _items = _items[_offset:] _result['offset'] = _new_offset @@ -1867,23 +1867,23 @@ def _perform(_playlist_idx, _page_token, _offset, _result): _continuations = (_data.get('continuations', [{}])[0] .get('nextContinuationData', {}) .get('continuation', '')) - if _continuations and len(_result['items']) <= self._max_results: + if _continuations and len(_result['items']) <= self.max_results(): _result['next_page_token'] = _continuations - if len(_result['items']) < self._max_results: + if len(_result['items']) < self.max_results(): _result = _perform(_playlist_idx=playlist_index, _page_token=_continuations, _offset=0, _result=_result) # trim result - if len(_result['items']) > self._max_results: + if len(_result['items']) > self.max_results(): _items = _result['items'] - _items = _items[:self._max_results] + _items = _items[:self.max_results()] _result['items'] = _items _result['continue'] = True - if len(_result['items']) < self._max_results: + if len(_result['items']) < self.max_results(): if 'continue' in _result: del _result['continue'] From 9a3a310aa9d49fe2bb124b3b97add1fbe3401f8b Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Fri, 13 Sep 2024 13:52:32 +1000 Subject: [PATCH 04/10] Only reroute to new window if modal dialog is not open #896 --- resources/lib/youtube_plugin/kodion/abstract_provider.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/resources/lib/youtube_plugin/kodion/abstract_provider.py b/resources/lib/youtube_plugin/kodion/abstract_provider.py index 06a6774d1..5998d686d 100644 --- a/resources/lib/youtube_plugin/kodion/abstract_provider.py +++ b/resources/lib/youtube_plugin/kodion/abstract_provider.py @@ -219,10 +219,11 @@ def on_goto_page(provider, context, re_match): page_token = '' params = dict(params, page=page, page_token=page_token) - if context.is_plugin_path( - context.get_infolabel('Container.FolderPath'), - partial=True, - ): + if (not context.get_infobool('System.HasActiveModalDialog') + and context.is_plugin_path( + context.get_infolabel('Container.FolderPath'), + partial=True, + )): return provider.reroute(context=context, path=path, params=params) return provider.navigate(context.clone(path, params)) From b2f20485f0a795ac36a3e0b4c7092d1a5204a45e Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Fri, 13 Sep 2024 20:18:55 +1000 Subject: [PATCH 05/10] Fix regression in building client details after 7f1945a1 - resulted in incorrect referer header being used and other possible issues --- .../lib/youtube_plugin/youtube/client/request_client.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/lib/youtube_plugin/youtube/client/request_client.py b/resources/lib/youtube_plugin/youtube/client/request_client.py index 506241b8b..133d141d4 100644 --- a/resources/lib/youtube_plugin/youtube/client/request_client.py +++ b/resources/lib/youtube_plugin/youtube/client/request_client.py @@ -352,6 +352,10 @@ def build_client(cls, client_name=None, data=None): client = merge_dicts(cls.CLIENTS['_common'], client, templates) client['_name'] = client_name + for values, template_id, template in templates.values(): + if template_id in values: + values[template_id] = template.format(**client) + try: params = client['params'] if client.get('_access_token'): @@ -373,8 +377,4 @@ def build_client(cls, client_name=None, data=None): except KeyError: pass - for values, template_id, template in templates.values(): - if template_id in values: - values[template_id] = template.format(**client) - return client From 625af54f3a991b6f294d395fd940aeabdc3a95a5 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Sat, 14 Sep 2024 02:46:30 +1000 Subject: [PATCH 06/10] Use a CommandItem for comments to avoid log spam - Would previously produce errors in log associated with - CDirectory::GetDirectory - error getting - CFileCache:Open - failed to open --- resources/lib/youtube_plugin/youtube/helper/utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/resources/lib/youtube_plugin/youtube/helper/utils.py b/resources/lib/youtube_plugin/youtube/helper/utils.py index 96878d12e..f8b9fdb20 100644 --- a/resources/lib/youtube_plugin/youtube/helper/utils.py +++ b/resources/lib/youtube_plugin/youtube/helper/utils.py @@ -15,7 +15,7 @@ from math import log10 from ...kodion.constants import CONTENT, LICENSE_TOKEN, LICENSE_URL, PATHS -from ...kodion.items import AudioItem, DirectoryItem, menu_items +from ...kodion.items import AudioItem, DirectoryItem, CommandItem, menu_items from ...kodion.utils import ( datetime_parser, friendly_number, @@ -118,7 +118,10 @@ def make_comment_item(context, snippet, uri, total_replies=0): ui.new_line(body, cr_before=2), )) - comment_item = DirectoryItem(label, uri, plot=plot, action=(not uri)) + if uri: + comment_item = DirectoryItem(label, uri, plot=plot) + else: + comment_item = CommandItem(label, 'Action(Info)', context, plot=plot) datetime = datetime_parser.parse(published_at) comment_item.set_added_utc(datetime) From 019e0bae20c7a189d00825c1e96c1200f0844acd Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Sat, 14 Sep 2024 02:52:26 +1000 Subject: [PATCH 07/10] Revert old workaround for Kodi treating a non-folder listitem as playable --- .../kodion/items/xbmc/xbmc_items.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/resources/lib/youtube_plugin/kodion/items/xbmc/xbmc_items.py b/resources/lib/youtube_plugin/kodion/items/xbmc/xbmc_items.py index f7396f929..2c9c6aa26 100644 --- a/resources/lib/youtube_plugin/kodion/items/xbmc/xbmc_items.py +++ b/resources/lib/youtube_plugin/kodion/items/xbmc/xbmc_items.py @@ -568,15 +568,17 @@ def directory_listitem(context, directory_item, show_fanart=None, **_kwargs): set_info(list_item, directory_item, props) """ - # ListItems that do not open a lower level list should have the isFolder - # parameter of the xbmcplugin.addDirectoryItem set to False, however this - # now appears to mark the ListItem as playable, even if the IsPlayable - # property is not set or set to "false". - # Set isFolder to True as a workaround, regardless of whether the ListItem - # is actually a folder. - is_folder = not directory_item.is_action() + ListItems that do not open a lower level list should have the isFolder + parameter of the xbmcplugin.addDirectoryItem set to False, however this + now appears to mark the ListItem as playable, even if the IsPlayable + property is not set or set to "false". + Set isFolder to True as a workaround, regardless of whether the ListItem + is actually a folder. """ - is_folder = True + # Workaround: + # is_folder = True + # Test correctly setting isFolder: + is_folder = not directory_item.is_action() context_menu = directory_item.get_context_menu() if context_menu is not None: From 3efb7e92b03fc1c4f5c3edca349d3925ddbacebd Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Sat, 14 Sep 2024 22:08:40 +1000 Subject: [PATCH 08/10] Improve parsing of plugin url query parameters - Allow empty values - Allow list values (originally comma separated string) to be re-parsed --- .../kodion/context/abstract_context.py | 13 +++++++++---- .../kodion/context/xbmc/xbmc_context.py | 4 +++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/resources/lib/youtube_plugin/kodion/context/abstract_context.py b/resources/lib/youtube_plugin/kodion/context/abstract_context.py index 0756eb097..581f06a98 100644 --- a/resources/lib/youtube_plugin/kodion/context/abstract_context.py +++ b/resources/lib/youtube_plugin/kodion/context/abstract_context.py @@ -306,7 +306,10 @@ def get_param(self, name, default=None): def parse_uri(self, uri): uri = urlsplit(uri) path = uri.path - params = self.parse_params(dict(parse_qsl(uri.query)), update=False) + params = self.parse_params( + dict(parse_qsl(uri.query, keep_blank_values=True)), + update=False, + ) return path, params def parse_params(self, params, update=True): @@ -328,9 +331,11 @@ def parse_params(self, params, update=True): elif param in self._FLOAT_PARAMS: parsed_value = float(value) elif param in self._LIST_PARAMS: - parsed_value = [ - val for val in value.split(',') if val - ] + parsed_value = ( + list(value) + if isinstance(value, (list, tuple)) else + [val for val in value.split(',') if val] + ) elif param in self._STRING_PARAMS: parsed_value = to_str(value) if param in self._STRING_BOOL_PARAMS: diff --git a/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py b/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py index cb3d1acdc..ece6ea1b6 100644 --- a/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py +++ b/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py @@ -346,7 +346,9 @@ def init(self): if num_args > 2: params = sys.argv[2][1:] if params: - self.parse_params(dict(parse_qsl(params))) + self.parse_params( + dict(parse_qsl(params, keep_blank_values=True)) + ) # then Kodi resume status if num_args > 3 and sys.argv[3].lower() == 'resume:true': From 3da06e1e3102e331fa2e2505229c8f0fdda6c97c Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Sat, 14 Sep 2024 22:17:30 +1000 Subject: [PATCH 09/10] Add new item_filter query parameter to override "Hide videos from listings" setting #896 - Comma seperated string of item types to be filtered out of listing - "?item_filter=shorts" will remove shorts from listing - "?item_filter=shorts,live" will remove shorts and live streams from listing - "?item_filter" will show all item types - Allowable item types: - shorts - upcoming - upcoming_live - live - premieres - completed - vod --- .../youtube_plugin/kodion/context/abstract_context.py | 1 + .../youtube_plugin/kodion/settings/abstract_settings.py | 9 +++++++-- resources/lib/youtube_plugin/youtube/helper/v3.py | 8 ++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/resources/lib/youtube_plugin/kodion/context/abstract_context.py b/resources/lib/youtube_plugin/kodion/context/abstract_context.py index 581f06a98..3473e2468 100644 --- a/resources/lib/youtube_plugin/kodion/context/abstract_context.py +++ b/resources/lib/youtube_plugin/kodion/context/abstract_context.py @@ -82,6 +82,7 @@ class AbstractContext(object): } _LIST_PARAMS = { 'channel_ids', + 'item_filter', 'playlist_ids', } _STRING_PARAMS = { diff --git a/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py b/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py index 928f09e0e..56c94b8fb 100644 --- a/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py +++ b/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py @@ -412,8 +412,13 @@ def stream_select(self, value=None): 'vod': True, } - def item_filter(self, update=None): - types = dict.fromkeys(self.get_string_list(SETTINGS.HIDE_VIDEOS), False) + def item_filter(self, update=None, override=None): + types = dict.fromkeys( + self.get_string_list(SETTINGS.HIDE_VIDEOS) + if override is None else + override, + False + ) types = dict(self._DEFAULT_FILTER, **types) if update: if 'live_folder' in update: diff --git a/resources/lib/youtube_plugin/youtube/helper/v3.py b/resources/lib/youtube_plugin/youtube/helper/v3.py index 9313de34f..d80a1365d 100644 --- a/resources/lib/youtube_plugin/youtube/helper/v3.py +++ b/resources/lib/youtube_plugin/youtube/helper/v3.py @@ -451,8 +451,13 @@ def response_to_items(provider, context.log_debug('v3 response discarded: |%s|' % kind) return [] + params = context.get_params() + if kind_type in _KNOWN_RESPONSE_KINDS: - item_filter = context.get_settings().item_filter(item_filter) + item_filter = context.get_settings().item_filter( + update=item_filter, + override=params.get('item_filter'), + ) result = _process_list_response( provider, context, json_data, item_filter ) @@ -477,7 +482,6 @@ def response_to_items(provider, We implemented our own calculation for the token into the YouTube client This should work for up to ~2000 entries. """ - params = context.get_params() current_page = params.get('page') next_page = current_page + 1 if current_page else 2 new_params = dict(params, page=next_page) From 81b5f9f2d3d46f836cc36f2a3b7612e030fc3fd5 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Sat, 14 Sep 2024 22:27:57 +1000 Subject: [PATCH 10/10] Version bump v7.1.0+beta.2 --- addon.xml | 2 +- changelog.txt | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/addon.xml b/addon.xml index e5a77d0e4..0fdfbc8c3 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + diff --git a/changelog.txt b/changelog.txt index 33e03c8e8..5cf89fc29 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,33 @@ +## v7.1.0+beta.2 +### Fixed +- Fix possible regression causing 6s delay on first play +- Fix regression in building client details causing wrong referer to be used +- Only reroute to new window if container was not filled by the plugin #896 +- Only reroute to new window if modal dialog is not open #896 + +### Changed +- Use a CommandItem that opens the Info dialog for comments to avoid log spam +- Revert old workaround for Kodi treating a non-folder listitem as playable +- Improve parsing of plugin url query parameters to allow empty values + +### New +- Add items_per_page query parameter to allow number of items in widgets to be customised #896 +- Add item_filter query parameter to override "Hide videos from listings" setting #896 + - Comma seperated string of item types to be filtered out of listing + - "?item_filter=shorts" will remove shorts from listing + - "?item_filter=shorts,live" will remove shorts and live streams from listing + - "?item_filter" will show all item types + - Allowable item types: + - shorts + - upcoming + - upcoming_live + - live + - premieres + - completed + - vod + ## v7.1.0+beta.1 -### +### Fixed - Fix logging/retry of sqlite3.OperationalError - Fix trying to use ISA for progressive live streams - Retain list position when refreshing listings