From 2f12afe3475f12be19e4762a5488543b97fba9dd Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Wed, 19 Jun 2024 06:43:42 +1000 Subject: [PATCH 01/14] Make live query parameter optional when playing channel live stream --- .../lib/youtube_plugin/youtube/helper/yt_play.py | 2 +- resources/lib/youtube_plugin/youtube/provider.py | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/resources/lib/youtube_plugin/youtube/helper/yt_play.py b/resources/lib/youtube_plugin/youtube/helper/yt_play.py index 6669c7c16..387b98575 100644 --- a/resources/lib/youtube_plugin/youtube/helper/yt_play.py +++ b/resources/lib/youtube_plugin/youtube/helper/yt_play.py @@ -265,7 +265,7 @@ def play_playlist(provider, context): def play_channel_live(provider, context): channel_id = context.get_param('channel_id') - index = context.get_param('live') - 1 + index = context.get_param('live', 1) - 1 if index < 0: index = 0 json_data = provider.get_client(context).search(q='', diff --git a/resources/lib/youtube_plugin/youtube/provider.py b/resources/lib/youtube_plugin/youtube/provider.py index 727f25530..c378347ad 100644 --- a/resources/lib/youtube_plugin/youtube/provider.py +++ b/resources/lib/youtube_plugin/youtube/provider.py @@ -647,10 +647,9 @@ def _on_my_location(self, context, re_match): path for playlist: '/play/?playlist_id=XXXXXXX&mode=[OPTION]' OPTION: [normal(default)|reverse|shuffle] - path for channel live streams: '/play/?channel_id=UCXXXXXXX&live=X - OPTION: - live parameter required, live=1 for first live stream - live = index of live stream if channel has multiple live streams + Channel live streams: '/play/?channel_id=UCXXXXXX[&live=X] + X: optional index of live stream to play if channel has multiple live + streams. 1 (default) for first live stream """ # noinspection PyUnusedLocal @@ -661,7 +660,7 @@ def on_play(self, context, re_match): force_play = False params = context.get_params() - if ({'channel_id', 'live', 'playlist_id', 'playlist_ids', 'video_id'} + if ({'channel_id', 'playlist_id', 'playlist_ids', 'video_id'} .isdisjoint(params.keys())): listitem_path = context.get_listitem_info('FileNameAndPath') if context.is_plugin_path(listitem_path, 'play'): @@ -707,7 +706,7 @@ def on_play(self, context, re_match): if playlist_id or 'playlist_ids' in params: return yt_play.play_playlist(self, context) - if 'channel_id' in params and params.get('live', 0) > 0: + if 'channel_id' in params: return yt_play.play_channel_live(self, context) return False From 3726193d1828a7bc2c934046a2bf00751724c2e7 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Wed, 19 Jun 2024 06:47:57 +1000 Subject: [PATCH 02/14] Simplify and tidy up ServiceMonitor --- .../kodion/monitors/service_monitor.py | 62 +++++++++---------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py b/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py index ec86358ca..b5762e7a3 100644 --- a/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py +++ b/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py @@ -32,12 +32,10 @@ class ServiceMonitor(xbmc.Monitor): def __init__(self, context): self._context = context settings = context.get_settings() - self._use_httpd = (settings.use_isa() - or settings.api_config_page() - or settings.support_alternative_player()) - address, port = get_connect_address(self._context) - self._old_httpd_address = self._httpd_address = address - self._old_httpd_port = self._httpd_port = port + + self._httpd_address, self._httpd_port = get_connect_address(context) + self._old_httpd_address = self._httpd_address + self._old_httpd_port = self._httpd_port self._whitelist = settings.httpd_whitelist() self.httpd = None @@ -46,7 +44,8 @@ def __init__(self, context): self.refresh = False self.interrupt = False - if self._use_httpd: + self._use_httpd = None + if self.httpd_required(settings): self.start_httpd() super(ServiceMonitor, self).__init__() @@ -125,44 +124,34 @@ def onSettingsChanged(self): self._settings_changes = 0 settings = self._context.get_settings(refresh=True) - self.set_property(CHECK_SETTINGS) self.refresh_container() - use_httpd = (settings.use_isa() - or settings.api_config_page() - or settings.support_alternative_player()) - address, port = get_connect_address(self._context) - whitelist = settings.httpd_whitelist() - - whitelist_changed = whitelist != self._whitelist - port_changed = port != self._httpd_port - address_changed = address != self._httpd_address - - if whitelist_changed: - self._whitelist = whitelist - - if self._use_httpd != use_httpd: - self._use_httpd = use_httpd + httpd_started = bool(self.httpd) + httpd_restart = False - if port_changed: + address, port = get_connect_address(self._context) + if port != self._httpd_port: self._old_httpd_port = self._httpd_port self._httpd_port = port - - if address_changed: + httpd_restart = httpd_started + if address != self._httpd_address: self._old_httpd_address = self._httpd_address self._httpd_address = address + httpd_restart = httpd_started - if not use_httpd: - if self.httpd: - self.shutdown_httpd() - elif not self.httpd: - self.start_httpd() - elif port_changed or whitelist_changed or address_changed: - if self.httpd: + whitelist = settings.httpd_whitelist() + if whitelist != self._whitelist: + self._whitelist = whitelist + httpd_restart = httpd_started + + if self.httpd_required(settings): + if httpd_restart: self.restart_httpd() else: self.start_httpd() + elif httpd_started: + self.shutdown_httpd() def httpd_address_sync(self): self._old_httpd_address = self._httpd_address @@ -214,9 +203,14 @@ def restart_httpd(self): def ping_httpd(self): return self.httpd and httpd_status(self._context) - def httpd_required(self, while_sleeping=False): + def httpd_required(self, settings=None, while_sleeping=False): if while_sleeping: settings = self._context.get_settings() return (settings.api_config_page() or settings.support_alternative_player()) + + if settings: + self._use_httpd = (settings.use_isa() + or settings.api_config_page() + or settings.support_alternative_player()) return self._use_httpd From fca610cb2556b3e819809379a62c8cddb2ac7ffa Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Wed, 19 Jun 2024 07:00:38 +1000 Subject: [PATCH 03/14] Reorganise constants and simplify window property usage - Remove need for script action for external player switching --- .../kodion/abstract_provider.py | 24 +-- .../kodion/constants/__init__.py | 128 ++++++++----- .../kodion/context/abstract_context.py | 15 +- .../kodion/context/xbmc/xbmc_context.py | 62 +++--- .../kodion/items/command_item.py | 4 +- .../youtube_plugin/kodion/items/menu_items.py | 70 ++++--- .../kodion/items/new_search_item.py | 4 +- .../kodion/items/search_history_item.py | 4 +- .../kodion/items/search_item.py | 4 +- .../kodion/items/watch_later_item.py | 4 +- .../kodion/items/xbmc/xbmc_items.py | 8 +- .../kodion/monitors/player_monitor.py | 10 +- .../kodion/network/http_server.py | 34 ++-- .../kodion/plugin/xbmc/xbmc_plugin.py | 6 +- .../youtube_plugin/kodion/script_actions.py | 6 - .../kodion/settings/abstract_settings.py | 178 +++++++++--------- .../youtube/helper/subtitles.py | 8 +- .../youtube_plugin/youtube/helper/utils.py | 22 +-- .../lib/youtube_plugin/youtube/helper/v3.py | 4 +- .../youtube/helper/video_info.py | 6 +- .../youtube_plugin/youtube/helper/yt_play.py | 20 +- .../youtube/helper/yt_specials.py | 24 +-- .../lib/youtube_plugin/youtube/provider.py | 78 ++++---- 23 files changed, 378 insertions(+), 345 deletions(-) diff --git a/resources/lib/youtube_plugin/kodion/abstract_provider.py b/resources/lib/youtube_plugin/kodion/abstract_provider.py index d3d60a31e..9a55d9e4e 100644 --- a/resources/lib/youtube_plugin/kodion/abstract_provider.py +++ b/resources/lib/youtube_plugin/kodion/abstract_provider.py @@ -12,7 +12,7 @@ import re -from .constants import CHECK_SETTINGS, REROUTE, content, paths +from .constants import CHECK_SETTINGS, CONTENT, PATHS, REROUTE_PATH from .exceptions import KodionException from .items import ( DirectoryItem, @@ -36,49 +36,49 @@ def __init__(self): # register some default paths self.register_path(r''.join(( '^', - '(?:', paths.HOME, ')?/?$' + '(?:', PATHS.HOME, ')?/?$' )), self._internal_root) self.register_path(r''.join(( '^', - paths.ROUTE, + PATHS.ROUTE, '(?P/[^?]+?)(?:/*[?].+|/*)$' )), self.reroute) self.register_path(r''.join(( '^', - paths.GOTO_PAGE, + PATHS.GOTO_PAGE, '(?P/[0-9]+)?' '(?P/[^?]+?)(?:/*[?].+|/*)$' )), self._internal_goto_page) self.register_path(r''.join(( '^', - paths.COMMAND, + PATHS.COMMAND, '/(?P[^?]+?)(?:/*[?].+|/*)$' )), self._on_command) self.register_path(r''.join(( '^', - paths.WATCH_LATER, + PATHS.WATCH_LATER, '/(?Padd|clear|list|remove)/?$' )), self.on_watch_later) self.register_path(r''.join(( '^', - paths.BOOKMARKS, + PATHS.BOOKMARKS, '/(?Padd|clear|list|remove)/?$' )), self.on_bookmarks) self.register_path(r''.join(( '^', - '(', paths.SEARCH, '|', paths.EXTERNAL_SEARCH, ')', + '(', PATHS.SEARCH, '|', PATHS.EXTERNAL_SEARCH, ')', '/(?Pinput|query|list|remove|clear|rename)?/?$' )), self._internal_search) self.register_path(r''.join(( '^', - paths.HISTORY, + PATHS.HISTORY, '/?$' )), self.on_playback_history) @@ -237,7 +237,7 @@ def reroute(self, context, re_match=None, path=None, params=None): finally: if not result: return False - context.get_ui().set_property(REROUTE, path) + context.get_ui().set_property(REROUTE_PATH, path) context.execute('ActivateWindow(Videos, {0}{1})'.format( context.create_uri(path, params), ', return' if window_return else '', @@ -312,10 +312,10 @@ def _internal_search(self, context, re_match): if not params.get('incognito') and not params.get('channel_id'): search_history.update(query) - context.set_path(paths.SEARCH, 'query') + context.set_path(PATHS.SEARCH, 'query') return self.on_search(query, context, re_match) - context.set_content(content.LIST_CONTENT) + context.set_content(CONTENT.LIST_CONTENT) result = [] location = context.get_param('location', False) diff --git a/resources/lib/youtube_plugin/kodion/constants/__init__.py b/resources/lib/youtube_plugin/kodion/constants/__init__.py index 0c7c6c682..6484f76c3 100644 --- a/resources/lib/youtube_plugin/kodion/constants/__init__.py +++ b/resources/lib/youtube_plugin/kodion/constants/__init__.py @@ -11,13 +11,14 @@ from __future__ import absolute_import, division, unicode_literals from . import ( - const_content_types as content, - const_paths as paths, - const_settings as settings, - const_sort_methods as sort, + const_content_types as CONTENT, + const_paths as PATHS, + const_settings as SETTINGS, + const_sort_methods as SORT, ) +# Addon paths ADDON_ID = 'plugin.video.youtube' ADDON_PATH = 'special://home/addons/{id}'.format(id=ADDON_ID) DATA_PATH = 'special://profile/addon_data/{id}'.format(id=ADDON_ID) @@ -25,6 +26,7 @@ RESOURCE_PATH = ADDON_PATH + '/resources' TEMP_PATH = 'special://temp/{id}'.format(id=ADDON_ID) +# Const values VALUE_FROM_STR = { '0': False, '1': True, @@ -32,75 +34,99 @@ 'true': True, } +# Flags ABORT_FLAG = 'abort_requested' BUSY_FLAG = 'busy' +SLEEPING = 'sleeping' +WAIT_FLAG = 'builtin_running' + +# ListItem Properties CHANNEL_ID = 'channel_id' -CHECK_SETTINGS = 'check_settings' -DEVELOPER_CONFIGS = 'configs' -CONTENT_TYPE = 'content_type' -LICENSE_TOKEN = 'license_token' -LICENSE_URL = 'license_url' PLAY_COUNT = 'video_play_count' -PLAY_FORCE_AUDIO = 'audio_only' -PLAY_PROMPT_QUALITY = 'ask_for_quality' -PLAY_PROMPT_SUBTITLES = 'prompt_for_subtitles' +PLAYLIST_ID = 'playlist_id' +PLAYLISTITEM_ID = 'playlistitem_id' +SUBSCRIPTION_ID = 'subscription_id' +VIDEO_ID = 'video_id' + +# Events +CHECK_SETTINGS = 'check_settings' PLAYBACK_INIT = 'playback_init' PLAYBACK_STARTED = 'playback_started' PLAYBACK_STOPPED = 'playback_stopped' -PLAYER_DATA = 'player_json' -PLAYLIST_ID = 'playlist_id' -PLAYLISTITEM_ID = 'playlistitem_id' -PLAYLIST_PATH = 'playlist_path' -PLAYLIST_POSITION = 'playlist_position' REFRESH_CONTAINER = 'refresh_container' RELOAD_ACCESS_MANAGER = 'reload_access_manager' -REROUTE = 'reroute' -SLEEPING = 'sleeping' -SUBSCRIPTION_ID = 'subscription_id' -SWITCH_PLAYER_FLAG = 'switch_player' -VIDEO_ID = 'video_id' -WAIT_FLAG = 'builtin_running' WAKEUP = 'wakeup' +# Play options +PLAY_FORCE_AUDIO = 'audio_only' +PLAY_PROMPT_QUALITY = 'ask_for_quality' +PLAY_PROMPT_SUBTITLES = 'prompt_for_subtitles' +PLAY_WITH = 'play_with' + +# Stored data +CONTENT_TYPE = 'content_type' +DEVELOPER_CONFIGS = 'configs' +LICENSE_TOKEN = 'license_token' +LICENSE_URL = 'license_url' +PLAYER_DATA = 'player_json' +PLAYLIST_PATH = 'playlist_path' +PLAYLIST_POSITION = 'playlist_position' +REROUTE_PATH = 'reroute_path' + __all__ = ( - 'ABORT_FLAG', + # Addon paths 'ADDON_ID', 'ADDON_PATH', + 'DATA_PATH', + 'MEDIA_PATH', + 'RESOURCE_PATH', + 'TEMP_PATH', + + # Const values + 'VALUE_FROM_STR', + + # Flags + 'ABORT_FLAG', 'BUSY_FLAG', + 'SLEEPING', + 'WAIT_FLAG', + + # ListItem properties 'CHANNEL_ID', + 'PLAY_COUNT', + 'PLAYLIST_ID', + 'PLAYLISTITEM_ID', + 'SUBSCRIPTION_ID', + 'VIDEO_ID', + + # Events 'CHECK_SETTINGS', + 'PLAYBACK_INIT', + 'PLAYBACK_STARTED', + 'PLAYBACK_STOPPED', + 'REFRESH_CONTAINER', + 'RELOAD_ACCESS_MANAGER', + 'WAKEUP', + + # Play options + 'PLAY_FORCE_AUDIO', + 'PLAY_PROMPT_QUALITY', + 'PLAY_PROMPT_SUBTITLES', + 'PLAY_WITH', + + # Stored data 'CONTENT_TYPE', - 'DATA_PATH', 'DEVELOPER_CONFIGS', 'LICENSE_TOKEN', 'LICENSE_URL', - 'MEDIA_PATH', - 'PLAY_COUNT', - 'PLAY_FORCE_AUDIO', - 'PLAY_PROMPT_QUALITY', - 'PLAY_PROMPT_SUBTITLES', - 'PLAYBACK_INIT', - 'PLAYBACK_STARTED', - 'PLAYBACK_STOPPED', 'PLAYER_DATA', - 'PLAYLIST_ID', - 'PLAYLISTITEM_ID', 'PLAYLIST_PATH', 'PLAYLIST_POSITION', - 'REFRESH_CONTAINER', - 'RELOAD_ACCESS_MANAGER', - 'RESOURCE_PATH', - 'REROUTE', - 'SLEEPING', - 'SUBSCRIPTION_ID', - 'SWITCH_PLAYER_FLAG', - 'TEMP_PATH', - 'VALUE_FROM_STR', - 'VIDEO_ID', - 'WAIT_FLAG', - 'WAKEUP', - 'content', - 'paths', - 'settings', - 'sort', + 'REROUTE_PATH', + + # Other constants + 'CONTENT', + 'PATHS', + 'SETTINGS', + 'SORT', ) diff --git a/resources/lib/youtube_plugin/kodion/context/abstract_context.py b/resources/lib/youtube_plugin/kodion/context/abstract_context.py index 365faa162..3fc802192 100644 --- a/resources/lib/youtube_plugin/kodion/context/abstract_context.py +++ b/resources/lib/youtube_plugin/kodion/context/abstract_context.py @@ -14,7 +14,13 @@ from .. import logger from ..compatibility import quote, to_str, urlencode -from ..constants import VALUE_FROM_STR +from ..constants import ( + PLAY_FORCE_AUDIO, + PLAY_PROMPT_QUALITY, + PLAY_PROMPT_SUBTITLES, + PLAY_WITH, + VALUE_FROM_STR, +) from ..json_store import AccessManager from ..sql_store import ( BookmarksList, @@ -34,8 +40,10 @@ class AbstractContext(object): _settings = None _BOOL_PARAMS = { - 'ask_for_quality', - 'audio_only', + PLAY_FORCE_AUDIO, + PLAY_PROMPT_SUBTITLES, + PLAY_PROMPT_QUALITY, + PLAY_WITH, 'confirmed', 'clip', 'enable', @@ -47,7 +55,6 @@ class AbstractContext(object): 'location', 'logged_in', 'play', - 'prompt_for_subtitles', 'resume', 'screensaver', 'strm', 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 e2652b4bc..81d1bd57b 100644 --- a/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py +++ b/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py @@ -27,10 +27,10 @@ from ...constants import ( ABORT_FLAG, ADDON_ID, + CONTENT, CONTENT_TYPE, + SORT, WAKEUP, - content, - sort, ) from ...player import XbmcPlayer, XbmcPlaylist from ...settings import XbmcPluginSettings @@ -534,43 +534,43 @@ def apply_content(self): detailed_labels = self.get_settings().show_detailed_labels() if sub_type == 'history': self.add_sort_method( - (sort.LASTPLAYED, '%T \u2022 %P', '%D | %J'), - (sort.PLAYCOUNT, '%T \u2022 %P', '%D | %J'), - (sort.UNSORTED, '%T \u2022 %P', '%D | %J'), - (sort.LABEL, '%T \u2022 %P', '%D | %J'), + (SORT.LASTPLAYED, '%T \u2022 %P', '%D | %J'), + (SORT.PLAYCOUNT, '%T \u2022 %P', '%D | %J'), + (SORT.UNSORTED, '%T \u2022 %P', '%D | %J'), + (SORT.LABEL, '%T \u2022 %P', '%D | %J'), ) if detailed_labels else self.add_sort_method( - (sort.LASTPLAYED,), - (sort.PLAYCOUNT,), - (sort.UNSORTED,), - (sort.LABEL,), + (SORT.LASTPLAYED,), + (SORT.PLAYCOUNT,), + (SORT.UNSORTED,), + (SORT.LABEL,), ) else: self.add_sort_method( - (sort.UNSORTED, '%T \u2022 %P', '%D | %J'), - (sort.LABEL, '%T \u2022 %P', '%D | %J'), + (SORT.UNSORTED, '%T \u2022 %P', '%D | %J'), + (SORT.LABEL, '%T \u2022 %P', '%D | %J'), ) if detailed_labels else self.add_sort_method( - (sort.UNSORTED,), - (sort.LABEL,), + (SORT.UNSORTED,), + (SORT.LABEL,), ) - if content_type == content.VIDEO_CONTENT: + if content_type == CONTENT.VIDEO_CONTENT: self.add_sort_method( - (sort.CHANNEL, '[%A - ]%T \u2022 %P', '%D | %J'), - (sort.ARTIST, '%T \u2022 %P | %D | %J', '%A'), - (sort.PROGRAM_COUNT, '%T \u2022 %P | %D | %J', '%C'), - (sort.VIDEO_RATING, '%T \u2022 %P | %D | %J', '%R'), - (sort.DATE, '%T \u2022 %P | %D', '%J'), - (sort.DATEADDED, '%T \u2022 %P | %D', '%a'), - (sort.VIDEO_RUNTIME, '%T \u2022 %P | %J', '%D'), - (sort.TRACKNUM, '[%N. ]%T \u2022 %P', '%D | %J'), + (SORT.CHANNEL, '[%A - ]%T \u2022 %P', '%D | %J'), + (SORT.ARTIST, '%T \u2022 %P | %D | %J', '%A'), + (SORT.PROGRAM_COUNT, '%T \u2022 %P | %D | %J', '%C'), + (SORT.VIDEO_RATING, '%T \u2022 %P | %D | %J', '%R'), + (SORT.DATE, '%T \u2022 %P | %D', '%J'), + (SORT.DATEADDED, '%T \u2022 %P | %D', '%a'), + (SORT.VIDEO_RUNTIME, '%T \u2022 %P | %J', '%D'), + (SORT.TRACKNUM, '[%N. ]%T \u2022 %P', '%D | %J'), ) if detailed_labels else self.add_sort_method( - (sort.CHANNEL, '[%A - ]%T'), - (sort.ARTIST,), - (sort.PROGRAM_COUNT,), - (sort.VIDEO_RATING,), - (sort.DATE,), - (sort.DATEADDED,), - (sort.VIDEO_RUNTIME,), - (sort.TRACKNUM, '[%N. ]%T '), + (SORT.CHANNEL, '[%A - ]%T'), + (SORT.ARTIST,), + (SORT.PROGRAM_COUNT,), + (SORT.VIDEO_RATING,), + (SORT.DATE,), + (SORT.DATEADDED,), + (SORT.VIDEO_RUNTIME,), + (SORT.TRACKNUM, '[%N. ]%T '), ) def add_sort_method(self, *sort_methods): diff --git a/resources/lib/youtube_plugin/kodion/items/command_item.py b/resources/lib/youtube_plugin/kodion/items/command_item.py index 8b90c156c..c4838c005 100644 --- a/resources/lib/youtube_plugin/kodion/items/command_item.py +++ b/resources/lib/youtube_plugin/kodion/items/command_item.py @@ -12,7 +12,7 @@ from . import menu_items from .directory_item import DirectoryItem -from ..constants import paths +from ..constants import PATHS class CommandItem(DirectoryItem): @@ -25,7 +25,7 @@ def __init__(self, plot=None): super(CommandItem, self).__init__( name, - context.create_uri((paths.COMMAND, command)), + context.create_uri((PATHS.COMMAND, command)), image=image, fanart=fanart, plot=plot, diff --git a/resources/lib/youtube_plugin/kodion/items/menu_items.py b/resources/lib/youtube_plugin/kodion/items/menu_items.py index 14020981f..a7a1d2735 100644 --- a/resources/lib/youtube_plugin/kodion/items/menu_items.py +++ b/resources/lib/youtube_plugin/kodion/items/menu_items.py @@ -10,7 +10,13 @@ from __future__ import absolute_import, division, unicode_literals -from ..constants import ADDON_ID, paths +from ..constants import ( + PATHS, + PLAY_FORCE_AUDIO, + PLAY_PROMPT_QUALITY, + PLAY_PROMPT_SUBTITLES, + PLAY_WITH, +) def more_for_video(context, video_id, logged_in=False, refresh=False): @@ -33,7 +39,7 @@ def related_videos(context, video_id): return ( context.localize('related_videos'), 'RunPlugin({0})'.format(context.create_uri( - (paths.ROUTE, 'special', 'related_videos',), + (PATHS.ROUTE, 'special', 'related_videos',), { 'video_id': video_id, }, @@ -45,7 +51,7 @@ def video_comments(context, video_id): return ( context.localize('video.comments'), 'RunPlugin({0})'.format(context.create_uri( - (paths.ROUTE, 'special', 'parent_comments',), + (PATHS.ROUTE, 'special', 'parent_comments',), { 'video_id': video_id, }, @@ -57,7 +63,7 @@ def content_from_description(context, video_id): return ( context.localize('video.description.links'), 'RunPlugin({0})'.format(context.create_uri( - (paths.ROUTE, 'special', 'description_links',), + (PATHS.ROUTE, 'special', 'description_links',), { 'video_id': video_id, }, @@ -65,10 +71,16 @@ def content_from_description(context, video_id): ) -def play_with(context): +def play_with(context, video_id): return ( context.localize('video.play.with'), - 'RunScript({addon_id},action/play_with)'.format(addon_id=ADDON_ID), + 'RunPlugin({0})'.format(context.create_uri( + ('play',), + { + 'video_id': video_id, + PLAY_WITH: True, + }, + )) ) @@ -77,7 +89,7 @@ def refresh(context): return ( context.localize('refresh'), 'RunPlugin({0})'.format(context.create_uri( - (paths.ROUTE, context.get_path(),), + (PATHS.ROUTE, context.get_path(),), dict(params, refresh=params.get('refresh', 0) + 1), )) ) @@ -279,7 +291,7 @@ def watch_later_local_add(context, item): return ( context.localize('watch_later.add'), 'RunPlugin({0})'.format(context.create_uri( - (paths.WATCH_LATER, 'add',), + (PATHS.WATCH_LATER, 'add',), { 'video_id': item.video_id, 'item': repr(item), @@ -292,7 +304,7 @@ def watch_later_local_remove(context, video_id): return ( context.localize('watch_later.remove'), 'RunPlugin({0})'.format(context.create_uri( - (paths.WATCH_LATER, 'remove',), + (PATHS.WATCH_LATER, 'remove',), { 'video_id': video_id, }, @@ -304,7 +316,7 @@ def watch_later_local_clear(context): return ( context.localize('watch_later.clear'), 'RunPlugin({0})'.format(context.create_uri( - (paths.WATCH_LATER, 'clear',), + (PATHS.WATCH_LATER, 'clear',), )) ) @@ -313,7 +325,7 @@ def go_to_channel(context, channel_id, channel_name): return ( context.localize('go_to_channel') % context.get_ui().bold(channel_name), 'RunPlugin({0})'.format(context.create_uri( - (paths.ROUTE, 'channel', channel_id,), + (PATHS.ROUTE, 'channel', channel_id,), )) ) @@ -357,7 +369,7 @@ def play_with_subtitles(context, video_id): ('play',), { 'video_id': video_id, - 'prompt_for_subtitles': True, + PLAY_PROMPT_SUBTITLES: True, }, )) ) @@ -370,7 +382,7 @@ def play_audio_only(context, video_id): ('play',), { 'video_id': video_id, - 'audio_only': True, + PLAY_FORCE_AUDIO: True, }, )) ) @@ -383,7 +395,7 @@ def play_ask_for_quality(context, video_id): ('play',), { 'video_id': video_id, - 'ask_for_quality': True, + PLAY_PROMPT_QUALITY: True, }, )) ) @@ -393,7 +405,7 @@ def history_remove(context, video_id): return ( context.localize('history.remove'), 'RunPlugin({0})'.format(context.create_uri( - (paths.HISTORY,), + (PATHS.HISTORY,), { 'action': 'remove', 'video_id': video_id @@ -406,7 +418,7 @@ def history_clear(context): return ( context.localize('history.clear'), 'RunPlugin({0})'.format(context.create_uri( - (paths.HISTORY,), + (PATHS.HISTORY,), { 'action': 'clear' }, @@ -418,7 +430,7 @@ def history_mark_watched(context, video_id): return ( context.localize('history.mark.watched'), 'RunPlugin({0})'.format(context.create_uri( - (paths.HISTORY,), + (PATHS.HISTORY,), { 'video_id': video_id, 'action': 'mark_watched', @@ -431,7 +443,7 @@ def history_mark_unwatched(context, video_id): return ( context.localize('history.mark.unwatched'), 'RunPlugin({0})'.format(context.create_uri( - (paths.HISTORY,), + (PATHS.HISTORY,), { 'video_id': video_id, 'action': 'mark_unwatched', @@ -444,7 +456,7 @@ def history_reset_resume(context, video_id): return ( context.localize('history.reset.resume_point'), 'RunPlugin({0})'.format(context.create_uri( - (paths.HISTORY,), + (PATHS.HISTORY,), { 'video_id': video_id, 'action': 'reset_resume', @@ -457,7 +469,7 @@ def bookmarks_add(context, item): return ( context.localize('bookmarks.add'), 'RunPlugin({0})'.format(context.create_uri( - (paths.BOOKMARKS, 'add',), + (PATHS.BOOKMARKS, 'add',), { 'item_id': item.get_id(), 'item': repr(item), @@ -473,7 +485,7 @@ def bookmarks_add_channel(context, channel_id, channel_name=''): context.localize(19029) )), 'RunPlugin({0})'.format(context.create_uri( - (paths.BOOKMARKS, 'add',), + (PATHS.BOOKMARKS, 'add',), { 'item_id': channel_id, 'item': None, @@ -486,7 +498,7 @@ def bookmarks_remove(context, item_id): return ( context.localize('bookmarks.remove'), 'RunPlugin({0})'.format(context.create_uri( - (paths.BOOKMARKS, 'remove',), + (PATHS.BOOKMARKS, 'remove',), { 'item_id': item_id, }, @@ -498,7 +510,7 @@ def bookmarks_clear(context): return ( context.localize('bookmarks.clear'), 'RunPlugin({0})'.format(context.create_uri( - (paths.BOOKMARKS, 'clear',), + (PATHS.BOOKMARKS, 'clear',), )) ) @@ -507,7 +519,7 @@ def search_remove(context, query): return ( context.localize('search.remove'), 'RunPlugin({0})'.format(context.create_uri( - (paths.SEARCH, 'remove',), + (PATHS.SEARCH, 'remove',), { 'q': query, }, @@ -519,7 +531,7 @@ def search_rename(context, query): return ( context.localize('search.rename'), 'RunPlugin({0})'.format(context.create_uri( - (paths.SEARCH, 'rename',), + (PATHS.SEARCH, 'rename',), { 'q': query, }, @@ -531,7 +543,7 @@ def search_clear(context): return ( context.localize('search.clear'), 'RunPlugin({0})'.format(context.create_uri( - (paths.SEARCH, 'clear',), + (PATHS.SEARCH, 'clear',), )) ) @@ -547,7 +559,7 @@ def goto_home(context): return ( context.localize(10000), 'RunPlugin({0})'.format(context.create_uri( - (paths.ROUTE, paths.HOME,), + (PATHS.ROUTE, PATHS.HOME,), { 'window_return': False, }, @@ -559,7 +571,7 @@ def goto_quick_search(context): return ( context.localize('search.quick'), 'RunPlugin({0})'.format(context.create_uri( - (paths.ROUTE, paths.SEARCH, 'input',), + (PATHS.ROUTE, PATHS.SEARCH, 'input',), )) ) @@ -568,7 +580,7 @@ def goto_page(context, params=None): return ( context.localize('page.choose'), 'RunPlugin({0})'.format(context.create_uri( - (paths.GOTO_PAGE, context.get_path(),), + (PATHS.GOTO_PAGE, context.get_path(),), params or context.get_params(), )) ) diff --git a/resources/lib/youtube_plugin/kodion/items/new_search_item.py b/resources/lib/youtube_plugin/kodion/items/new_search_item.py index c28dc2a11..3eeab206a 100644 --- a/resources/lib/youtube_plugin/kodion/items/new_search_item.py +++ b/resources/lib/youtube_plugin/kodion/items/new_search_item.py @@ -11,7 +11,7 @@ from __future__ import absolute_import, division, unicode_literals from .directory_item import DirectoryItem -from ..constants import paths +from ..constants import PATHS class NewSearchItem(DirectoryItem): @@ -42,7 +42,7 @@ def __init__(self, super(NewSearchItem, self).__init__(name, context.create_uri( - (paths.SEARCH, 'input',), + (PATHS.SEARCH, 'input',), params=params, ), image=image, diff --git a/resources/lib/youtube_plugin/kodion/items/search_history_item.py b/resources/lib/youtube_plugin/kodion/items/search_history_item.py index d5c9c29b8..737aa6701 100644 --- a/resources/lib/youtube_plugin/kodion/items/search_history_item.py +++ b/resources/lib/youtube_plugin/kodion/items/search_history_item.py @@ -12,7 +12,7 @@ from . import menu_items from .directory_item import DirectoryItem -from ..constants import paths +from ..constants import PATHS class SearchHistoryItem(DirectoryItem): @@ -26,7 +26,7 @@ def __init__(self, context, query, image=None, fanart=None, location=False): super(SearchHistoryItem, self).__init__(query, context.create_uri( - (paths.SEARCH, 'query',), + (PATHS.SEARCH, 'query',), params=params, ), image=image, diff --git a/resources/lib/youtube_plugin/kodion/items/search_item.py b/resources/lib/youtube_plugin/kodion/items/search_item.py index 1ecf676e8..4329c450b 100644 --- a/resources/lib/youtube_plugin/kodion/items/search_item.py +++ b/resources/lib/youtube_plugin/kodion/items/search_item.py @@ -11,7 +11,7 @@ from __future__ import absolute_import, division, unicode_literals from .directory_item import DirectoryItem -from ..constants import paths +from ..constants import PATHS class SearchItem(DirectoryItem): @@ -33,7 +33,7 @@ def __init__(self, super(SearchItem, self).__init__(name, context.create_uri( - (paths.SEARCH, 'list',), + (PATHS.SEARCH, 'list',), params=params, ), image=image, diff --git a/resources/lib/youtube_plugin/kodion/items/watch_later_item.py b/resources/lib/youtube_plugin/kodion/items/watch_later_item.py index a005371b7..9006720b6 100644 --- a/resources/lib/youtube_plugin/kodion/items/watch_later_item.py +++ b/resources/lib/youtube_plugin/kodion/items/watch_later_item.py @@ -11,7 +11,7 @@ from __future__ import absolute_import, division, unicode_literals from .directory_item import DirectoryItem -from ..constants import paths +from ..constants import PATHS class WatchLaterItem(DirectoryItem): @@ -24,7 +24,7 @@ def __init__(self, context, name=None, image=None, fanart=None): super(WatchLaterItem, self).__init__(name, context.create_uri( - (paths.WATCH_LATER, 'list',), + (PATHS.WATCH_LATER, 'list',), ), image=image, fanart=fanart) 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 bd81a5520..83e8d467d 100644 --- a/resources/lib/youtube_plugin/kodion/items/xbmc/xbmc_items.py +++ b/resources/lib/youtube_plugin/kodion/items/xbmc/xbmc_items.py @@ -16,11 +16,11 @@ from ...compatibility import to_str, xbmc, xbmcgui from ...constants import ( CHANNEL_ID, - PLAY_COUNT, - PLAYLIST_ID, PLAYLISTITEM_ID, + PLAYLIST_ID, + PLAY_COUNT, + PLAY_WITH, SUBSCRIPTION_ID, - SWITCH_PLAYER_FLAG, VIDEO_ID, ) from ...utils import current_system_version, datetime_parser, redact_ip_from_url @@ -380,7 +380,7 @@ def video_playback_item(context, video_item, show_fanart=None, **_kwargs): settings = context.get_settings() headers = video_item.get_headers() license_key = video_item.get_license_key() - is_external = context.get_ui().get_property(SWITCH_PLAYER_FLAG) + is_external = context.get_ui().get_property(PLAY_WITH) is_strm = context.get_param('strm') mime_type = None diff --git a/resources/lib/youtube_plugin/kodion/monitors/player_monitor.py b/resources/lib/youtube_plugin/kodion/monitors/player_monitor.py index ceeb98b2e..81a29b9ef 100644 --- a/resources/lib/youtube_plugin/kodion/monitors/player_monitor.py +++ b/resources/lib/youtube_plugin/kodion/monitors/player_monitor.py @@ -19,8 +19,8 @@ PLAYBACK_STARTED, PLAYBACK_STOPPED, PLAYER_DATA, + PLAY_WITH, REFRESH_CONTAINER, - SWITCH_PLAYER_FLAG, ) @@ -352,12 +352,12 @@ def cleanup_threads(self, only_ended=True): self.threads = active_threads def onPlayBackStarted(self): - if self._ui.get_property(SWITCH_PLAYER_FLAG): + if self._ui.get_property(PLAY_WITH): self._context.execute('Action(SwitchPlayer)') self._context.execute('Action(Stop)') def onAVStarted(self): - if self._ui.get_property(SWITCH_PLAYER_FLAG): + if self._ui.get_property(PLAY_WITH): return if not self._ui.busy_dialog_active(): @@ -393,8 +393,8 @@ def onPlayBackEnded(self): if not self._ui.busy_dialog_active(): self._ui.clear_property(BUSY_FLAG) - if self._ui.get_property(SWITCH_PLAYER_FLAG): - self._ui.clear_property(SWITCH_PLAYER_FLAG) + if self._ui.get_property(PLAY_WITH): + self._ui.clear_property(PLAY_WITH) self.stop_threads() self.cleanup_threads() diff --git a/resources/lib/youtube_plugin/kodion/network/http_server.py b/resources/lib/youtube_plugin/kodion/network/http_server.py index ecd21b61b..9e71befc1 100644 --- a/resources/lib/youtube_plugin/kodion/network/http_server.py +++ b/resources/lib/youtube_plugin/kodion/network/http_server.py @@ -26,7 +26,7 @@ xbmcgui, xbmcvfs, ) -from ..constants import ADDON_ID, LICENSE_TOKEN, LICENSE_URL, TEMP_PATH, paths +from ..constants import ADDON_ID, LICENSE_TOKEN, LICENSE_URL, PATHS, TEMP_PATH from ..logger import log_debug, log_error from ..utils import validate_ip_address, redact_ip_from_url, wait @@ -81,7 +81,7 @@ def connection_allowed(self): if not conn_allowed: log_debug('HTTPServer: Connection from |{client_ip| not allowed' .format(client_ip=client_ip)) - elif self.path != paths.PING: + elif self.path != PATHS.PING: log_debug(' '.join(log_lines)) return conn_allowed @@ -93,7 +93,7 @@ def do_GET(self): # Strip trailing slash if present stripped_path = self.path.rstrip('/') - if stripped_path != paths.PING: + if stripped_path != PATHS.PING: log_debug('HTTPServer: GET |{path}|'.format( path=redact_ip_from_url(self.path) )) @@ -101,7 +101,7 @@ def do_GET(self): if not self.connection_allowed(): self.send_error(403) - elif stripped_path == paths.IP: + elif stripped_path == PATHS.IP: client_json = json.dumps({"ip": "{ip}" .format(ip=self.client_address[0])}) self.send_response(200) @@ -110,8 +110,8 @@ def do_GET(self): self.end_headers() self.wfile.write(client_json.encode('utf-8')) - elif stripped_path.startswith(paths.MPD): - filepath = os.path.join(self.BASE_PATH, self.path[len(paths.MPD):]) + elif stripped_path.startswith(PATHS.MPD): + filepath = os.path.join(self.BASE_PATH, self.path[len(PATHS.MPD):]) file_chunk = True try: with open(filepath, 'rb') as f: @@ -129,7 +129,7 @@ def do_GET(self): .format(path=self.path, filepath=filepath)) self.send_error(404, response) - elif api_config_enabled and stripped_path == paths.API: + elif api_config_enabled and stripped_path == PATHS.API: html = self.api_config_page() html = html.encode('utf-8') @@ -141,7 +141,7 @@ def do_GET(self): for chunk in self.get_chunks(html): self.wfile.write(chunk) - elif api_config_enabled and stripped_path.startswith(paths.API_SUBMIT): + elif api_config_enabled and stripped_path.startswith(PATHS.API_SUBMIT): xbmc.executebuiltin('Dialog.Close(addonsettings,true)') query = urlsplit(self.path).query @@ -199,10 +199,10 @@ def do_GET(self): for chunk in self.get_chunks(html): self.wfile.write(chunk) - elif stripped_path == paths.PING: + elif stripped_path == PATHS.PING: self.send_error(204) - elif stripped_path.startswith(paths.REDIRECT): + elif stripped_path.startswith(PATHS.REDIRECT): url = parse_qs(urlsplit(self.path).query).get('url') if url: wait(1) @@ -222,8 +222,8 @@ def do_HEAD(self): if not self.connection_allowed(): self.send_error(403) - elif self.path.startswith(paths.MPD): - filepath = os.path.join(self.BASE_PATH, self.path[len(paths.MPD):]) + elif self.path.startswith(PATHS.MPD): + filepath = os.path.join(self.BASE_PATH, self.path[len(PATHS.MPD):]) if not os.path.isfile(filepath): response = ('File Not Found: |{path}| -> |{filepath}|' .format(path=self.path, filepath=filepath)) @@ -235,7 +235,7 @@ def do_HEAD(self): str(os.path.getsize(filepath))) self.end_headers() - elif self.path.startswith(paths.REDIRECT): + elif self.path.startswith(PATHS.REDIRECT): self.send_error(404) else: @@ -248,7 +248,7 @@ def do_POST(self): if not self.connection_allowed(): self.send_error(403) - elif self.path.startswith(paths.DRM): + elif self.path.startswith(PATHS.DRM): home = xbmcgui.Window(10000) lic_url = home.getProperty('-'.join((ADDON_ID, LICENSE_URL))) @@ -408,7 +408,7 @@ class Pages(object): - '''.format(action_url=paths.API_SUBMIT)), + '''.format(action_url=PATHS.API_SUBMIT)), 'css': ''.join('\t\t\t'.expandtabs(2) + line for line in dedent(''' body { background: #141718; @@ -579,7 +579,7 @@ def httpd_status(context): address, port = get_connect_address(context) url = 'http://{address}:{port}{path}'.format(address=address, port=port, - path=paths.PING) + path=PATHS.PING) response = RequestHandler.requests.request(url) result = response and response.status_code if result == 204: @@ -597,7 +597,7 @@ def get_client_ip_address(context): address, port = get_connect_address(context) url = 'http://{address}:{port}{path}'.format(address=address, port=port, - path=paths.IP) + path=PATHS.IP) response = RequestHandler.requests.request(url) if response and response.status_code == 200: response_json = response.json() diff --git a/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py b/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py index 08d33fcab..892990bf6 100644 --- a/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py +++ b/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py @@ -21,7 +21,7 @@ PLAYLIST_POSITION, REFRESH_CONTAINER, RELOAD_ACCESS_MANAGER, - REROUTE, + REROUTE_PATH, SLEEPING, VIDEO_ID, ) @@ -154,7 +154,7 @@ def run(self, provider, context, focused=None): provider.run_wizard(context) try: - route = ui.get_property(REROUTE) + route = ui.get_property(REROUTE_PATH) if route: function_cache = context.get_function_cache() result, options = function_cache.run( @@ -163,7 +163,7 @@ def run(self, provider, context, focused=None): _scope=function_cache.SCOPE_NONE, context=context.clone(route), ) - ui.clear_property(REROUTE) + ui.clear_property(REROUTE_PATH) else: result, options = provider.navigate(context) except KodionException as exc: diff --git a/resources/lib/youtube_plugin/kodion/script_actions.py b/resources/lib/youtube_plugin/kodion/script_actions.py index 32385d522..27a0dd66a 100644 --- a/resources/lib/youtube_plugin/kodion/script_actions.py +++ b/resources/lib/youtube_plugin/kodion/script_actions.py @@ -16,7 +16,6 @@ from .constants import ( DATA_PATH, RELOAD_ACCESS_MANAGER, - SWITCH_PLAYER_FLAG, TEMP_PATH, WAIT_FLAG, ) @@ -345,11 +344,6 @@ def run(argv): xbmcaddon.Addon().openSettings() return - if action == 'play_with': - ui.set_property(SWITCH_PLAYER_FLAG) - xbmc.executebuiltin('Action(Play)') - return - if category == 'config': _config_actions(context, action, params) return diff --git a/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py b/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py index bc8eb936c..da02fd67b 100644 --- a/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py +++ b/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py @@ -12,13 +12,13 @@ import sys -from ..constants import settings +from ..constants import SETTINGS from ..utils import current_system_version, validate_ip_address class AbstractSettings(object): _vars = vars() - for name, value in settings.__dict__.items(): + for name, value in SETTINGS.__dict__.items(): _vars[name] = value del _vars @@ -59,8 +59,8 @@ def open_settings(self): def items_per_page(self, value=None): if value is not None: - return self.set_int(settings.ITEMS_PER_PAGE, value) - return self.get_int(settings.ITEMS_PER_PAGE, 50) + return self.set_int(SETTINGS.ITEMS_PER_PAGE, value) + return self.get_int(SETTINGS.ITEMS_PER_PAGE, 50) _VIDEO_QUALITY_MAP = { 0: 240, @@ -73,94 +73,94 @@ def items_per_page(self, value=None): def fixed_video_quality(self, value=None): default = 3 if value is None: - _value = self.get_int(settings.VIDEO_QUALITY, default) + _value = self.get_int(SETTINGS.VIDEO_QUALITY, default) else: _value = value if _value not in self._VIDEO_QUALITY_MAP: _value = default if value is not None: - self.set_int(settings.VIDEO_QUALITY, _value) + self.set_int(SETTINGS.VIDEO_QUALITY, _value) return self._VIDEO_QUALITY_MAP[_value] def ask_for_video_quality(self): - return (self.get_bool(settings.VIDEO_QUALITY_ASK, False) - or self.get_int(settings.MPD_STREAM_SELECT) == 4) + return (self.get_bool(SETTINGS.VIDEO_QUALITY_ASK, False) + or self.get_int(SETTINGS.MPD_STREAM_SELECT) == 4) def fanart_selection(self): - return self.get_int(settings.FANART_SELECTION, 2) + return self.get_int(SETTINGS.FANART_SELECTION, 2) def cache_size(self, value=None): if value is not None: - return self.set_int(settings.CACHE_SIZE, value) - return self.get_int(settings.CACHE_SIZE, 20) + return self.set_int(SETTINGS.CACHE_SIZE, value) + return self.get_int(SETTINGS.CACHE_SIZE, 20) def get_search_history_size(self): - return self.get_int(settings.SEARCH_SIZE, 10) + return self.get_int(SETTINGS.SEARCH_SIZE, 10) def setup_wizard_enabled(self, value=None): # Increment min_required on new release to enable oneshot on first run min_required = 4 if value is False: - self.set_int(settings.SETUP_WIZARD_RUNS, min_required) - return self.set_bool(settings.SETUP_WIZARD, False) + self.set_int(SETTINGS.SETUP_WIZARD_RUNS, min_required) + return self.set_bool(SETTINGS.SETUP_WIZARD, False) if value is True: - self.set_int(settings.SETUP_WIZARD_RUNS, 0) - return self.set_bool(settings.SETUP_WIZARD, True) + self.set_int(SETTINGS.SETUP_WIZARD_RUNS, 0) + return self.set_bool(SETTINGS.SETUP_WIZARD, True) - forced_runs = self.get_int(settings.SETUP_WIZARD_RUNS, 0) + forced_runs = self.get_int(SETTINGS.SETUP_WIZARD_RUNS, 0) if forced_runs < min_required: - self.set_int(settings.SETUP_WIZARD_RUNS, min_required) - self.set_bool(settings.SETTINGS_END, True) + self.set_int(SETTINGS.SETUP_WIZARD_RUNS, min_required) + self.set_bool(SETTINGS.SETTINGS_END, True) return True - return self.get_bool(settings.SETUP_WIZARD, False) + return self.get_bool(SETTINGS.SETUP_WIZARD, False) def support_alternative_player(self, value=None): if value is not None: - return self.set_bool(settings.SUPPORT_ALTERNATIVE_PLAYER, value) - return self.get_bool(settings.SUPPORT_ALTERNATIVE_PLAYER, False) + return self.set_bool(SETTINGS.SUPPORT_ALTERNATIVE_PLAYER, value) + return self.get_bool(SETTINGS.SUPPORT_ALTERNATIVE_PLAYER, False) def default_player_web_urls(self, value=None): if value is not None: - return self.set_bool(settings.DEFAULT_PLAYER_WEB_URLS, value) + return self.set_bool(SETTINGS.DEFAULT_PLAYER_WEB_URLS, value) if self.support_alternative_player(): return False - return self.get_bool(settings.DEFAULT_PLAYER_WEB_URLS, False) + return self.get_bool(SETTINGS.DEFAULT_PLAYER_WEB_URLS, False) def alternative_player_web_urls(self, value=None): if value is not None: - return self.set_bool(settings.ALTERNATIVE_PLAYER_WEB_URLS, value) + return self.set_bool(SETTINGS.ALTERNATIVE_PLAYER_WEB_URLS, value) if (self.support_alternative_player() and not self.alternative_player_adaptive()): - return self.get_bool(settings.ALTERNATIVE_PLAYER_WEB_URLS, False) + return self.get_bool(SETTINGS.ALTERNATIVE_PLAYER_WEB_URLS, False) return False def alternative_player_adaptive(self, value=None): if value is not None: - return self.set_bool(settings.ALTERNATIVE_PLAYER_ADAPTIVE, value) + return self.set_bool(SETTINGS.ALTERNATIVE_PLAYER_ADAPTIVE, value) if self.support_alternative_player(): - return self.get_bool(settings.ALTERNATIVE_PLAYER_ADAPTIVE, False) + return self.get_bool(SETTINGS.ALTERNATIVE_PLAYER_ADAPTIVE, False) return False def use_isa(self, value=None): if value is not None: - return self.set_bool(settings.USE_ISA, value) - return self.get_bool(settings.USE_ISA, False) + return self.set_bool(SETTINGS.USE_ISA, value) + return self.get_bool(SETTINGS.USE_ISA, False) def subtitle_download(self): - return self.get_bool(settings.SUBTITLE_DOWNLOAD, False) + return self.get_bool(SETTINGS.SUBTITLE_DOWNLOAD, False) def audio_only(self): - return self.get_bool(settings.AUDIO_ONLY, False) + return self.get_bool(SETTINGS.AUDIO_ONLY, False) def get_subtitle_selection(self): - return self.get_int(settings.SUBTITLE_SELECTION, 0) + return self.get_int(SETTINGS.SUBTITLE_SELECTION, 0) def set_subtitle_selection(self, value): - return self.set_int(settings.SUBTITLE_SELECTION, value) + return self.set_int(SETTINGS.SUBTITLE_SELECTION, value) def set_subtitle_download(self, value): - return self.set_bool(settings.SUBTITLE_DOWNLOAD, value) + return self.set_bool(SETTINGS.SUBTITLE_DOWNLOAD, value) _THUMB_SIZES = { 0: { # Medium (16:9) @@ -180,38 +180,38 @@ def set_subtitle_download(self, value): def get_thumbnail_size(self, value=None): default = 1 if value is None: - value = self.get_int(settings.THUMB_SIZE, default) + value = self.get_int(SETTINGS.THUMB_SIZE, default) if value in self._THUMB_SIZES: return self._THUMB_SIZES[value] return self._THUMB_SIZES[default] def safe_search(self): - index = self.get_int(settings.SAFE_SEARCH, 0) + index = self.get_int(SETTINGS.SAFE_SEARCH, 0) values = {0: 'moderate', 1: 'none', 2: 'strict'} return values[index] def age_gate(self): - return self.get_bool(settings.AGE_GATE, True) + return self.get_bool(SETTINGS.AGE_GATE, True) def verify_ssl(self): - verify = self.get_bool(settings.VERIFY_SSL, False) + verify = self.get_bool(SETTINGS.VERIFY_SSL, False) if sys.version_info <= (2, 7, 9): verify = False return verify def get_timeout(self): - connect_timeout = self.get_int(settings.CONNECT_TIMEOUT, 9) + 0.5 - read_timout = self.get_int(settings.READ_TIMEOUT, 27) + connect_timeout = self.get_int(SETTINGS.CONNECT_TIMEOUT, 9) + 0.5 + read_timout = self.get_int(SETTINGS.READ_TIMEOUT, 27) return connect_timeout, read_timout def allow_dev_keys(self): - return self.get_bool(settings.ALLOW_DEV_KEYS, False) + return self.get_bool(SETTINGS.ALLOW_DEV_KEYS, False) def use_mpd_videos(self, value=None): if self.use_isa(): if value is not None: - return self.set_bool(settings.MPD_VIDEOS, value) - return self.get_bool(settings.MPD_VIDEOS, True) + return self.set_bool(SETTINGS.MPD_VIDEOS, value) + return self.get_bool(SETTINGS.MPD_VIDEOS, True) return False _LIVE_STREAM_TYPES = { @@ -224,10 +224,10 @@ def use_mpd_videos(self, value=None): def live_stream_type(self, value=None): if self.use_isa(): default = 2 - setting = settings.LIVE_STREAMS + '.1' + setting = SETTINGS.LIVE_STREAMS + '.1' else: default = 0 - setting = settings.LIVE_STREAMS + '.2' + setting = SETTINGS.LIVE_STREAMS + '.2' if value is not None: return self.set_int(setting, value) value = self.get_int(setting, default) @@ -237,19 +237,19 @@ def live_stream_type(self, value=None): def use_isa_live_streams(self): if self.use_isa(): - return self.get_int(settings.LIVE_STREAMS + '.1', 2) > 1 + return self.get_int(SETTINGS.LIVE_STREAMS + '.1', 2) > 1 return False def use_mpd_live_streams(self): if self.use_isa(): - return self.get_int(settings.LIVE_STREAMS + '.1', 2) == 3 + return self.get_int(SETTINGS.LIVE_STREAMS + '.1', 2) == 3 return False def httpd_port(self, value=None): default = 50152 if value is None: - port = self.get_int(settings.HTTPD_PORT, default) + port = self.get_int(SETTINGS.HTTPD_PORT, default) else: port = value @@ -259,14 +259,14 @@ def httpd_port(self, value=None): port = default if value is not None: - return self.set_int(settings.HTTPD_PORT, port) + return self.set_int(SETTINGS.HTTPD_PORT, port) return port def httpd_listen(self, value=None): default = '0.0.0.0' if value is None: - ip_address = self.get_string(settings.HTTPD_LISTEN, default) + ip_address = self.get_string(SETTINGS.HTTPD_LISTEN, default) else: ip_address = value @@ -274,11 +274,11 @@ def httpd_listen(self, value=None): ip_address = '.'.join(map(str, octets)) if value is not None: - return self.set_string(settings.HTTPD_LISTEN, ip_address) + return self.set_string(SETTINGS.HTTPD_LISTEN, ip_address) return ip_address def httpd_whitelist(self): - whitelist = self.get_string(settings.HTTPD_WHITELIST, '') + whitelist = self.get_string(SETTINGS.HTTPD_WHITELIST, '') whitelist = ''.join(whitelist.split()).split(',') allow_list = [] for ip_address in whitelist: @@ -289,28 +289,28 @@ def httpd_whitelist(self): return allow_list def api_config_page(self): - return self.get_bool(settings.API_CONFIG_PAGE, False) + return self.get_bool(SETTINGS.API_CONFIG_PAGE, False) def api_id(self, new_id=None): if new_id is not None: - self.set_string(settings.API_ID, new_id) + self.set_string(SETTINGS.API_ID, new_id) return new_id - return self.get_string(settings.API_ID) + return self.get_string(SETTINGS.API_ID) def api_key(self, new_key=None): if new_key is not None: - self.set_string(settings.API_KEY, new_key) + self.set_string(SETTINGS.API_KEY, new_key) return new_key - return self.get_string(settings.API_KEY) + return self.get_string(SETTINGS.API_KEY) def api_secret(self, new_secret=None): if new_secret is not None: - self.set_string(settings.API_SECRET, new_secret) + self.set_string(SETTINGS.API_SECRET, new_secret) return new_secret - return self.get_string(settings.API_SECRET) + return self.get_string(SETTINGS.API_SECRET) def get_location(self): - location = self.get_string(settings.LOCATION, '').replace(' ', '').strip() + location = self.get_string(SETTINGS.LOCATION, '').replace(' ', '').strip() coords = location.split(',') latitude = longitude = None if len(coords) == 2: @@ -328,19 +328,19 @@ def get_location(self): return '' def set_location(self, value): - self.set_string(settings.LOCATION, value) + self.set_string(SETTINGS.LOCATION, value) def get_location_radius(self): - return ''.join((self.get_int(settings.LOCATION_RADIUS, 500, str), 'km')) + return ''.join((self.get_int(SETTINGS.LOCATION_RADIUS, 500, str), 'km')) def get_play_count_min_percent(self): - return self.get_int(settings.PLAY_COUNT_MIN_PERCENT, 0) + return self.get_int(SETTINGS.PLAY_COUNT_MIN_PERCENT, 0) def use_local_history(self): - return self.get_bool(settings.USE_LOCAL_HISTORY, False) + return self.get_bool(SETTINGS.USE_LOCAL_HISTORY, False) def use_remote_history(self): - return self.get_bool(settings.USE_REMOTE_HISTORY, False) + return self.get_bool(SETTINGS.USE_REMOTE_HISTORY, False) # Selections based on max width and min height at common (utra-)wide aspect ratios _QUALITY_SELECTIONS = { # Setting | Resolution @@ -359,10 +359,10 @@ def use_remote_history(self): def mpd_video_qualities(self, value=None): if value is not None: - return self.set_int(settings.MPD_QUALITY_SELECTION, value) + return self.set_int(SETTINGS.MPD_QUALITY_SELECTION, value) if not self.use_mpd_videos(): return [] - value = self.get_int(settings.MPD_QUALITY_SELECTION, 4) + value = self.get_int(SETTINGS.MPD_QUALITY_SELECTION, 4) return [quality for key, quality in sorted(self._QUALITY_SELECTIONS.items(), reverse=True) @@ -370,8 +370,8 @@ def mpd_video_qualities(self, value=None): def stream_features(self, value=None): if value is not None: - return self.set_string_list(settings.MPD_STREAM_FEATURES, value) - return frozenset(self.get_string_list(settings.MPD_STREAM_FEATURES)) + return self.set_string_list(SETTINGS.MPD_STREAM_FEATURES, value) + return frozenset(self.get_string_list(SETTINGS.MPD_STREAM_FEATURES)) _STREAM_SELECT = { 1: 'auto', @@ -382,9 +382,9 @@ def stream_features(self, value=None): def stream_select(self, value=None): if value is not None: - return self.set_int(settings.MPD_STREAM_SELECT, value) + return self.set_int(SETTINGS.MPD_STREAM_SELECT, value) default = 3 - value = self.get_int(settings.MPD_STREAM_SELECT, default) + value = self.get_int(SETTINGS.MPD_STREAM_SELECT, default) if value in self._STREAM_SELECT: return self._STREAM_SELECT[value] return self._STREAM_SELECT[default] @@ -400,7 +400,7 @@ def stream_select(self, value=None): } def item_filter(self, update=None): - types = dict.fromkeys(self.get_string_list(settings.HIDE_VIDEOS), False) + types = dict.fromkeys(self.get_string_list(SETTINGS.HIDE_VIDEOS), False) types = dict(self._DEFAULT_FILTER, **types) if update: if 'live_folder' in update: @@ -421,46 +421,46 @@ def item_filter(self, update=None): def client_selection(self, value=None): if value is not None: - return self.set_int(settings.CLIENT_SELECTION, value) - return self.get_int(settings.CLIENT_SELECTION, 0) + return self.set_int(SETTINGS.CLIENT_SELECTION, value) + return self.get_int(SETTINGS.CLIENT_SELECTION, 0) def show_detailed_description(self, value=None): if value is not None: - return self.set_bool(settings.DETAILED_DESCRIPTION, value) - return self.get_bool(settings.DETAILED_DESCRIPTION, True) + return self.set_bool(SETTINGS.DETAILED_DESCRIPTION, value) + return self.get_bool(SETTINGS.DETAILED_DESCRIPTION, True) def show_detailed_labels(self, value=None): if value is not None: - return self.set_bool(settings.DETAILED_LABELS, value) - return self.get_bool(settings.DETAILED_LABELS, True) + return self.set_bool(SETTINGS.DETAILED_LABELS, value) + return self.get_bool(SETTINGS.DETAILED_LABELS, True) def get_language(self): - return self.get_string(settings.LANGUAGE, 'en_US').replace('_', '-') + return self.get_string(SETTINGS.LANGUAGE, 'en_US').replace('_', '-') def set_language(self, language_id): - return self.set_string(settings.LANGUAGE, language_id) + return self.set_string(SETTINGS.LANGUAGE, language_id) def get_region(self): - return self.get_string(settings.REGION, 'US') + return self.get_string(SETTINGS.REGION, 'US') def set_region(self, region_id): - return self.set_string(settings.REGION, region_id) + return self.set_string(SETTINGS.REGION, region_id) def get_watch_later_playlist(self): - return self.get_string(settings.WATCH_LATER_PLAYLIST, '').strip() + return self.get_string(SETTINGS.WATCH_LATER_PLAYLIST, '').strip() def set_watch_later_playlist(self, value): - return self.set_string(settings.WATCH_LATER_PLAYLIST, value) + return self.set_string(SETTINGS.WATCH_LATER_PLAYLIST, value) def get_history_playlist(self): - return self.get_string(settings.HISTORY_PLAYLIST, '').strip() + return self.get_string(SETTINGS.HISTORY_PLAYLIST, '').strip() def set_history_playlist(self, value): - return self.set_string(settings.HISTORY_PLAYLIST, value) + return self.set_string(SETTINGS.HISTORY_PLAYLIST, value) if current_system_version.compatible(20, 0): def get_label_color(self, label_part): - setting_name = '.'.join((settings.LABEL_COLOR, label_part)) + setting_name = '.'.join((SETTINGS.LABEL_COLOR, label_part)) return self.get_string(setting_name, 'white') else: _COLOR_MAP = { @@ -474,4 +474,4 @@ def get_label_color(self, label_part): return self._COLOR_MAP.get(label_part, 'white') def get_channel_name_aliases(self): - return frozenset(self.get_string_list(settings.CHANNEL_NAME_ALIASES)) + return frozenset(self.get_string_list(SETTINGS.CHANNEL_NAME_ALIASES)) diff --git a/resources/lib/youtube_plugin/youtube/helper/subtitles.py b/resources/lib/youtube_plugin/youtube/helper/subtitles.py index 025f6ffbd..46bc06fdc 100644 --- a/resources/lib/youtube_plugin/youtube/helper/subtitles.py +++ b/resources/lib/youtube_plugin/youtube/helper/subtitles.py @@ -82,9 +82,11 @@ def __init__(self, context, video_id): self.preferred_lang = ('en',) ui = context.get_ui() - self.prompt_override = (ui.get_property(PLAY_PROMPT_SUBTITLES) - == video_id) - ui.clear_property(PLAY_PROMPT_SUBTITLES) + if ui.get_property(PLAY_PROMPT_SUBTITLES): + self.prompt_override = True + ui.clear_property(PLAY_PROMPT_SUBTITLES) + else: + self.prompt_override = False def load(self, captions, headers=None): if headers: diff --git a/resources/lib/youtube_plugin/youtube/helper/utils.py b/resources/lib/youtube_plugin/youtube/helper/utils.py index 5a3b1d442..9b228374a 100644 --- a/resources/lib/youtube_plugin/youtube/helper/utils.py +++ b/resources/lib/youtube_plugin/youtube/helper/utils.py @@ -14,7 +14,7 @@ import time from math import log10 -from ...kodion.constants import LICENSE_TOKEN, LICENSE_URL, content, paths +from ...kodion.constants import CONTENT, LICENSE_TOKEN, LICENSE_URL, PATHS from ...kodion.items import DirectoryItem, menu_items from ...kodion.utils import ( datetime_parser, @@ -151,7 +151,7 @@ def update_channel_infos(provider, context, channel_id_dict, path = context.get_path() filter_list = None - if path.startswith(paths.SUBSCRIPTIONS): + if path.startswith(PATHS.SUBSCRIPTIONS): in_bookmarks_list = False in_subscription_list = True if settings.get_bool('youtube.folder.my_subscriptions_filtered.show', @@ -162,7 +162,7 @@ def update_channel_infos(provider, context, channel_id_dict, filter_string = filter_string.replace(', ', ',') filter_list = filter_string.split(',') filter_list = [x.lower() for x in filter_list] - elif path.startswith(paths.BOOKMARKS): + elif path.startswith(PATHS.BOOKMARKS): in_bookmarks_list = True in_subscription_list = False else: @@ -256,10 +256,10 @@ def update_playlist_infos(provider, context, playlist_id_dict, thumb_size = context.get_settings().get_thumbnail_size() # if the path directs to a playlist of our own, set channel id to 'mine' - if path.startswith(paths.MY_PLAYLISTS): + if path.startswith(PATHS.MY_PLAYLISTS): in_bookmarks_list = False in_my_playlists = True - elif path.startswith(paths.BOOKMARKS): + elif path.startswith(PATHS.BOOKMARKS): in_bookmarks_list = True in_my_playlists = False else: @@ -389,17 +389,17 @@ def update_video_infos(provider, context, video_id_dict, path = context.get_path() ui = context.get_ui() - if path.startswith(paths.MY_SUBSCRIPTIONS): + if path.startswith(PATHS.MY_SUBSCRIPTIONS): in_bookmarks_list = False in_my_subscriptions_list = True in_watched_later_list = False playlist_match = False - elif path.startswith(paths.WATCH_LATER): + elif path.startswith(PATHS.WATCH_LATER): in_bookmarks_list = False in_my_subscriptions_list = False in_watched_later_list = True playlist_match = False - elif path.startswith(paths.BOOKMARKS): + elif path.startswith(PATHS.BOOKMARKS): in_bookmarks_list = True in_my_subscriptions_list = False in_watched_later_list = False @@ -414,7 +414,7 @@ def update_video_infos(provider, context, video_id_dict, video_item = video_id_dict[video_id] # set mediatype - video_item.set_mediatype(content.VIDEO_TYPE) + video_item.set_mediatype(CONTENT.VIDEO_TYPE) if not yt_item or 'snippet' not in yt_item: continue @@ -768,7 +768,7 @@ def update_video_infos(provider, context, video_id_dict, ) # more... - refresh = path.startswith((paths.LIKED_VIDEOS, paths.DISLIKED_VIDEOS)) + refresh = path.startswith((PATHS.LIKED_VIDEOS, PATHS.DISLIKED_VIDEOS)) context_menu.append( menu_items.more_for_video( context, @@ -780,7 +780,7 @@ def update_video_infos(provider, context, video_id_dict, # 'play with...' (external player) if alternate_player: - context_menu.append(menu_items.play_with(context)) + context_menu.append(menu_items.play_with(context, video_id)) if not subtitles_prompt: context_menu.append( diff --git a/resources/lib/youtube_plugin/youtube/helper/v3.py b/resources/lib/youtube_plugin/youtube/helper/v3.py index 6b326aab5..232014e9f 100644 --- a/resources/lib/youtube_plugin/youtube/helper/v3.py +++ b/resources/lib/youtube_plugin/youtube/helper/v3.py @@ -23,7 +23,7 @@ update_video_infos, ) from ...kodion import KodionException -from ...kodion.constants import paths +from ...kodion.constants import PATHS from ...kodion.items import CommandItem, DirectoryItem, NextPageItem, VideoItem @@ -149,7 +149,7 @@ def _process_list_response(provider, context, json_data, item_filter): elif kind == 'playlist': # set channel id to 'mine' if the path is for a playlist of our own - if context.get_path().startswith(paths.MY_PLAYLISTS): + if context.get_path().startswith(PATHS.MY_PLAYLISTS): channel_id = 'mine' else: channel_id = snippet['channelId'] diff --git a/resources/lib/youtube_plugin/youtube/helper/video_info.py b/resources/lib/youtube_plugin/youtube/helper/video_info.py index a2810cf0f..da90f390e 100644 --- a/resources/lib/youtube_plugin/youtube/helper/video_info.py +++ b/resources/lib/youtube_plugin/youtube/helper/video_info.py @@ -32,7 +32,7 @@ urlsplit, xbmcvfs, ) -from ...kodion.constants import TEMP_PATH, paths +from ...kodion.constants import PATHS, TEMP_PATH from ...kodion.network import get_connect_address from ...kodion.utils import make_dirs, redact_ip_from_url @@ -1518,7 +1518,7 @@ def _get_video_info(self): 'proxy': 'http://{address}:{port}{path}||R{{SSM}}|'.format( address=address, port=port, - path=paths.DRM, + path=PATHS.DRM, ), 'token': self._access_token, } @@ -2247,7 +2247,7 @@ def _filter_group(previous_group, previous_stream, item): return 'http://{address}:{port}{path}{file}'.format( address=address, port=port, - path=paths.MPD, + path=PATHS.MPD, file=filename, ), main_stream return None, None diff --git a/resources/lib/youtube_plugin/youtube/helper/yt_play.py b/resources/lib/youtube_plugin/youtube/helper/yt_play.py index 387b98575..662a429d3 100644 --- a/resources/lib/youtube_plugin/youtube/helper/yt_play.py +++ b/resources/lib/youtube_plugin/youtube/helper/yt_play.py @@ -18,12 +18,12 @@ from ..youtube_exceptions import YouTubeException from ...kodion.compatibility import urlencode, urlunsplit from ...kodion.constants import ( - PLAY_FORCE_AUDIO, - PLAY_PROMPT_QUALITY, + PATHS, PLAYBACK_INIT, PLAYER_DATA, - SWITCH_PLAYER_FLAG, - paths, + PLAY_FORCE_AUDIO, + PLAY_PROMPT_QUALITY, + PLAY_WITH, ) from ...kodion.items import VideoItem from ...kodion.network import get_connect_address @@ -45,7 +45,7 @@ def play_video(provider, context): incognito = params.get('incognito', False) screensaver = params.get('screensaver', False) - is_external = ui.get_property(SWITCH_PLAYER_FLAG) + is_external = ui.get_property(PLAY_WITH) if ((is_external and settings.alternative_player_web_urls()) or settings.default_player_web_urls()): video_stream = { @@ -53,15 +53,15 @@ def play_video(provider, context): } else: ask_for_quality = None - if not screensaver and ui.get_property(PLAY_PROMPT_QUALITY) == video_id: + if not screensaver and ui.get_property(PLAY_PROMPT_QUALITY): ask_for_quality = True - ui.clear_property(PLAY_PROMPT_QUALITY) + ui.clear_property(PLAY_PROMPT_QUALITY) audio_only = None - if ui.get_property(PLAY_FORCE_AUDIO) == video_id: + if ui.get_property(PLAY_FORCE_AUDIO): ask_for_quality = False audio_only = True - ui.clear_property(PLAY_FORCE_AUDIO) + ui.clear_property(PLAY_FORCE_AUDIO) try: video_streams = client.get_video_streams(context, video_id) @@ -110,7 +110,7 @@ def play_video(provider, context): url = urlunsplit(( 'http', get_connect_address(context=context, as_netloc=True), - paths.REDIRECT, + PATHS.REDIRECT, urlencode({'url': video_stream['url']}), '', )) diff --git a/resources/lib/youtube_plugin/youtube/helper/yt_specials.py b/resources/lib/youtube_plugin/youtube/helper/yt_specials.py index 4e7301f97..8c8006d65 100644 --- a/resources/lib/youtube_plugin/youtube/helper/yt_specials.py +++ b/resources/lib/youtube_plugin/youtube/helper/yt_specials.py @@ -12,14 +12,14 @@ from . import UrlResolver, UrlToItemConverter, tv, utils, v3 from ...kodion import KodionException -from ...kodion.constants import content +from ...kodion.constants import CONTENT from ...kodion.items import DirectoryItem, UriItem from ...kodion.utils import strip_html_from_text from ...kodion.utils.datetime_parser import yt_datetime_offset def _process_related_videos(provider, context, client): - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) function_cache = context.get_function_cache() params = context.get_params() @@ -49,7 +49,7 @@ def _process_related_videos(provider, context, client): def _process_parent_comments(provider, context, client): - context.set_content(content.LIST_CONTENT) + context.set_content(CONTENT.LIST_CONTENT) video_id = context.get_param('video_id', '') if not video_id: @@ -65,7 +65,7 @@ def _process_parent_comments(provider, context, client): def _process_child_comments(provider, context, client): - context.set_content(content.LIST_CONTENT) + context.set_content(CONTENT.LIST_CONTENT) parent_id = context.get_param('parent_id', '') if not parent_id: @@ -81,7 +81,7 @@ def _process_child_comments(provider, context, client): def _process_recommendations(provider, context, client): - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) params = context.get_params() function_cache = context.get_function_cache() @@ -100,7 +100,7 @@ def _process_recommendations(provider, context, client): def _process_trending(provider, context, client): - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) json_data = client.get_trending_videos( page_token=context.get_param('page_token', '') @@ -112,7 +112,7 @@ def _process_trending(provider, context, client): def _process_browse_channels(provider, context, client): - context.set_content(content.LIST_CONTENT) + context.set_content(CONTENT.LIST_CONTENT) guide_id = context.get_param('guide_id', '') if guide_id: @@ -129,7 +129,7 @@ def _process_browse_channels(provider, context, client): def _process_disliked_videos(provider, context, client): - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) json_data = client.get_disliked_videos( page_token=context.get_param('page_token', '') @@ -141,7 +141,7 @@ def _process_disliked_videos(provider, context, client): def _process_live_events(provider, context, client, event_type='live'): - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) # TODO: cache result json_data = client.get_live_events( @@ -165,7 +165,7 @@ def _process_description_links(provider, context): addon_id = params.get('addon_id', '') def _extract_urls(video_id): - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) url_resolver = UrlResolver(context) with context.get_ui().create_progress_dialog( @@ -282,7 +282,7 @@ def _display_playlists(playlist_ids): def _process_saved_playlists_tv(provider, context, client): - context.set_content(content.LIST_CONTENT) + context.set_content(CONTENT.LIST_CONTENT) json_data = client.get_saved_playlists( page_token=context.get_param('next_page_token', 0), @@ -295,7 +295,7 @@ def _process_saved_playlists_tv(provider, context, client): def _process_new_uploaded_videos_tv(provider, context, client, filtered=False): - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) function_cache = context.get_function_cache() diff --git a/resources/lib/youtube_plugin/youtube/provider.py b/resources/lib/youtube_plugin/youtube/provider.py index c378347ad..2e6684238 100644 --- a/resources/lib/youtube_plugin/youtube/provider.py +++ b/resources/lib/youtube_plugin/youtube/provider.py @@ -35,12 +35,13 @@ from ..kodion.constants import ( ADDON_ID, CHANNEL_ID, + CONTENT, DEVELOPER_CONFIGS, + PATHS, PLAY_FORCE_AUDIO, PLAY_PROMPT_QUALITY, PLAY_PROMPT_SUBTITLES, - content, - paths, + PLAY_WITH, ) from ..kodion.items import ( BaseItem, @@ -330,7 +331,7 @@ def on_uri2addon(self, context, re_match, uri=None): @RegisterProviderPath('^(?:/channel/(?P[^/]+))?/playlist/(?P[^/]+)/?$') def _on_playlist(self, context, re_match): - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) resource_manager = self.get_resource_manager(context) batch_id = (re_match.group('playlist_id'), @@ -350,7 +351,7 @@ def _on_playlist(self, context, re_match): @RegisterProviderPath('^/channel/(?P[^/]+)/playlists/?$') def _on_channel_playlists(self, context, re_match): - context.set_content(content.LIST_CONTENT) + context.set_content(CONTENT.LIST_CONTENT) channel_id = re_match.group('channel_id') @@ -407,7 +408,7 @@ def _on_channel_playlists(self, context, re_match): @RegisterProviderPath('^/channel/(?P[^/]+)/live/?$') def _on_channel_live(self, context, re_match): - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) result = [] channel_id = re_match.group('channel_id') @@ -471,7 +472,7 @@ def _on_channel(self, context, re_match): if method == 'channel' and not channel_id: return False - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) resource_manager = self.get_resource_manager(context) @@ -588,7 +589,7 @@ def _on_channel(self, context, re_match): # noinspection PyUnusedLocal @RegisterProviderPath('^/location/mine/?$') def _on_my_location(self, context, re_match): - context.set_content(content.LIST_CONTENT) + context.set_content(CONTENT.LIST_CONTENT) create_uri = context.create_uri localize = context.localize @@ -641,11 +642,12 @@ def _on_my_location(self, context, re_match): return result """ - Plays a video. - path for video: '/play/?video_id=XXXXXXX' + Plays a video, playlist, or channel live stream. + Video: '/play/?video_id=XXXXXX' - path for playlist: '/play/?playlist_id=XXXXXXX&mode=[OPTION]' - OPTION: [normal(default)|reverse|shuffle] + Playlist: '/play/?playlist_id=XXXXXX[&order=ORDER][&action=ACTION]' + ORDER: [normal(default)|reverse|shuffle] optional playlist ordering + ACTION: [list|play|queue|None(default)] optional action to perform Channel live streams: '/play/?channel_id=UCXXXXXX[&live=X] X: optional index of live stream to play if channel has multiple live @@ -657,11 +659,11 @@ def _on_my_location(self, context, re_match): def on_play(self, context, re_match): ui = context.get_ui() - force_play = False params = context.get_params() + param_keys = params.keys() if ({'channel_id', 'playlist_id', 'playlist_ids', 'video_id'} - .isdisjoint(params.keys())): + .isdisjoint(param_keys)): listitem_path = context.get_listitem_info('FileNameAndPath') if context.is_plugin_path(listitem_path, 'play'): video_id = find_video_id(listitem_path) @@ -676,28 +678,18 @@ def on_play(self, context, re_match): video_id = params.get('video_id') playlist_id = params.get('playlist_id') - if ui.get_property(PLAY_PROMPT_SUBTITLES) != video_id: - ui.clear_property(PLAY_PROMPT_SUBTITLES) - - if ui.get_property(PLAY_FORCE_AUDIO) != video_id: - ui.clear_property(PLAY_FORCE_AUDIO) - - if ui.get_property(PLAY_PROMPT_QUALITY) != video_id: - ui.clear_property(PLAY_PROMPT_QUALITY) + force_play = False + for param in {PLAY_FORCE_AUDIO, + PLAY_PROMPT_QUALITY, + PLAY_PROMPT_SUBTITLES, + PLAY_WITH}.intersection(param_keys): + del params[param] + ui.set_property(param) + force_play = True if video_id and not playlist_id: - if params.pop(PLAY_PROMPT_SUBTITLES, None): - ui.set_property(PLAY_PROMPT_SUBTITLES, video_id) - force_play = True - - if params.pop('audio_only', None): - ui.set_property(PLAY_FORCE_AUDIO, video_id) - force_play = True - - if params.pop('ask_for_quality', None): - ui.set_property(PLAY_PROMPT_QUALITY, video_id) - force_play = True - + # This is required to trigger Kodi resume prompt, along with using + # RunPlugin. Prompt will not be used if using PlayMedia if force_play: context.execute('Action(Play)') return False @@ -735,7 +727,7 @@ def _on_subscriptions(self, context, re_match): subscriptions = yt_subscriptions.process(method, self, context) if method == 'list': - context.set_content(content.LIST_CONTENT) + context.set_content(CONTENT.LIST_CONTENT) return subscriptions @@ -809,9 +801,9 @@ def on_search(self, search_text, context, re_match): safe_search = context.get_settings().safe_search() if search_type == 'video': - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) else: - context.set_content(content.LIST_CONTENT) + context.set_content(CONTENT.LIST_CONTENT) if (page == 1 and search_type == 'video' @@ -1032,7 +1024,7 @@ def on_playback_history(self, context, re_match): playback_history = context.get_playback_history() if action == 'list': - context.set_content(content.VIDEO_CONTENT, sub_type='history') + context.set_content(CONTENT.VIDEO_CONTENT, sub_type='history') items = playback_history.get_items() if not items: return True @@ -1118,7 +1110,7 @@ def on_root(self, context, re_match): logged_in = self.is_logged_in() # _.get_my_playlists() - # context.set_content(content.LIST_CONTENT) + # context.set_content(CONTENT.LIST_CONTENT) result = [] @@ -1247,7 +1239,7 @@ def on_root(self, context, re_match): else: watch_history_item = DirectoryItem( localize('watch_later'), - create_uri((paths.WATCH_LATER, 'list')), + create_uri((PATHS.WATCH_LATER, 'list')), image='{media}/watch_later.png', ) result.append(watch_history_item) @@ -1297,7 +1289,7 @@ def on_root(self, context, re_match): elif local_history: watch_history_item = DirectoryItem( localize('history'), - create_uri((paths.HISTORY,), params={'action': 'list'}), + create_uri((PATHS.HISTORY,), params={'action': 'list'}), image='{media}/history.png', ) result.append(watch_history_item) @@ -1334,7 +1326,7 @@ def on_root(self, context, re_match): if settings.get_bool('youtube.folder.bookmarks.show', True): bookmarks_item = DirectoryItem( localize('bookmarks'), - create_uri((paths.BOOKMARKS, 'list')), + create_uri((PATHS.BOOKMARKS, 'list')), image='{media}/bookmarks.png', ) result.append(bookmarks_item) @@ -1422,7 +1414,7 @@ def on_bookmarks(self, context, re_match): return False if command == 'list': - context.set_content(content.VIDEO_CONTENT) + context.set_content(CONTENT.VIDEO_CONTENT) bookmarks_list = context.get_bookmarks_list() items = bookmarks_list.get_items() if not items: @@ -1499,7 +1491,7 @@ def on_watch_later(self, context, re_match): return False if command == 'list': - context.set_content(content.VIDEO_CONTENT, sub_type='watch_later') + context.set_content(CONTENT.VIDEO_CONTENT, sub_type='watch_later') items = context.get_watch_later_list().get_items() if not items: return True From 1611e2a81d8e30e59e5a476ec1acac17dafc4e47 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Thu, 20 Jun 2024 21:36:50 +1000 Subject: [PATCH 04/14] Further simplify window property usage --- .../kodion/context/xbmc/xbmc_context.py | 8 +++--- .../kodion/monitors/player_monitor.py | 6 ++--- .../kodion/plugin/xbmc/xbmc_plugin.py | 26 +++++-------------- .../youtube/helper/subtitles.py | 6 +---- .../youtube_plugin/youtube/helper/yt_play.py | 6 ++--- .../lib/youtube_plugin/youtube/provider.py | 3 +-- 6 files changed, 16 insertions(+), 39 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 81d1bd57b..80783a453 100644 --- a/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py +++ b/resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py @@ -516,13 +516,11 @@ def set_content(self, content_type, sub_type=None, category_label=None): def apply_content(self): ui = self.get_ui() - content_type = ui.get_property(CONTENT_TYPE) - if content_type: - ui.clear_property(CONTENT_TYPE) - content_type, sub_type, category_label = json.loads(content_type) - else: + content_type = ui.pop_property(CONTENT_TYPE) + if not content_type: return + content_type, sub_type, category_label = json.loads(content_type) self.log_debug('Applying content-type: |{type}| for |{path}|'.format( type=(sub_type or content_type), path=self.get_path() )) diff --git a/resources/lib/youtube_plugin/kodion/monitors/player_monitor.py b/resources/lib/youtube_plugin/kodion/monitors/player_monitor.py index 81a29b9ef..311939f9f 100644 --- a/resources/lib/youtube_plugin/kodion/monitors/player_monitor.py +++ b/resources/lib/youtube_plugin/kodion/monitors/player_monitor.py @@ -363,10 +363,9 @@ def onAVStarted(self): if not self._ui.busy_dialog_active(): self._ui.clear_property(BUSY_FLAG) - playback_data = self._ui.get_property(PLAYER_DATA) + playback_data = self._ui.pop_property(PLAYER_DATA) if not playback_data: return - self._ui.clear_property(PLAYER_DATA) self.cleanup_threads() playback_data = json.loads(playback_data) @@ -393,8 +392,7 @@ def onPlayBackEnded(self): if not self._ui.busy_dialog_active(): self._ui.clear_property(BUSY_FLAG) - if self._ui.get_property(PLAY_WITH): - self._ui.clear_property(PLAY_WITH) + self._ui.pop_property(PLAY_WITH) self.stop_threads() self.cleanup_threads() diff --git a/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py b/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py index 892990bf6..6cc5f35f3 100644 --- a/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py +++ b/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py @@ -65,7 +65,7 @@ def run(self, provider, context, focused=None): self.handle = context.get_handle() ui = context.get_ui() - if ui.get_property(BUSY_FLAG).lower() == 'true': + if ui.pop_property(BUSY_FLAG).lower() == 'true': if ui.busy_dialog_active(): xbmcplugin.endOfDirectory( self.handle, @@ -83,8 +83,8 @@ def run(self, provider, context, focused=None): if position and items: path = items[position - 1]['file'] - old_path = ui.get_property(PLAYLIST_PATH) - old_position = ui.get_property(PLAYLIST_POSITION) + old_path = ui.pop_property(PLAYLIST_PATH) + old_position = ui.pop_property(PLAYLIST_POSITION) if (old_position and position == int(old_position) and old_path and path == old_path): if remaining: @@ -120,33 +120,22 @@ def run(self, provider, context, focused=None): context.sleep(1) else: playlist.play_playlist_item(position) - - ui.clear_property(BUSY_FLAG) - ui.clear_property(PLAYLIST_PATH) - ui.clear_property(PLAYLIST_POSITION) return False - ui.clear_property(BUSY_FLAG) - ui.clear_property(PLAYLIST_PATH) - ui.clear_property(PLAYLIST_POSITION) - if ui.get_property(SLEEPING): context.wakeup('plugin') - if ui.get_property(REFRESH_CONTAINER): + if ui.pop_property(REFRESH_CONTAINER): focused = False - ui.clear_property(REFRESH_CONTAINER) elif focused: focused = ui.get_property(VIDEO_ID) - if ui.get_property(RELOAD_ACCESS_MANAGER): + if ui.pop_property(RELOAD_ACCESS_MANAGER): context.reload_access_manager() - ui.clear_property(RELOAD_ACCESS_MANAGER) - if ui.get_property(CHECK_SETTINGS): + if ui.pop_property(CHECK_SETTINGS): provider.reset_client() settings = context.get_settings(refresh=True) - ui.clear_property(CHECK_SETTINGS) else: settings = context.get_settings() @@ -154,7 +143,7 @@ def run(self, provider, context, focused=None): provider.run_wizard(context) try: - route = ui.get_property(REROUTE_PATH) + route = ui.pop_property(REROUTE_PATH) if route: function_cache = context.get_function_cache() result, options = function_cache.run( @@ -163,7 +152,6 @@ def run(self, provider, context, focused=None): _scope=function_cache.SCOPE_NONE, context=context.clone(route), ) - ui.clear_property(REROUTE_PATH) else: result, options = provider.navigate(context) except KodionException as exc: diff --git a/resources/lib/youtube_plugin/youtube/helper/subtitles.py b/resources/lib/youtube_plugin/youtube/helper/subtitles.py index 46bc06fdc..1a03455ee 100644 --- a/resources/lib/youtube_plugin/youtube/helper/subtitles.py +++ b/resources/lib/youtube_plugin/youtube/helper/subtitles.py @@ -82,11 +82,7 @@ def __init__(self, context, video_id): self.preferred_lang = ('en',) ui = context.get_ui() - if ui.get_property(PLAY_PROMPT_SUBTITLES): - self.prompt_override = True - ui.clear_property(PLAY_PROMPT_SUBTITLES) - else: - self.prompt_override = False + self.prompt_override = bool(ui.pop_property(PLAY_PROMPT_SUBTITLES)) def load(self, captions, headers=None): if headers: diff --git a/resources/lib/youtube_plugin/youtube/helper/yt_play.py b/resources/lib/youtube_plugin/youtube/helper/yt_play.py index 662a429d3..95c3d5865 100644 --- a/resources/lib/youtube_plugin/youtube/helper/yt_play.py +++ b/resources/lib/youtube_plugin/youtube/helper/yt_play.py @@ -53,15 +53,13 @@ def play_video(provider, context): } else: ask_for_quality = None - if not screensaver and ui.get_property(PLAY_PROMPT_QUALITY): + if ui.pop_property(PLAY_PROMPT_QUALITY) and not screensaver: ask_for_quality = True - ui.clear_property(PLAY_PROMPT_QUALITY) audio_only = None - if ui.get_property(PLAY_FORCE_AUDIO): + if ui.pop_property(PLAY_FORCE_AUDIO): ask_for_quality = False audio_only = True - ui.clear_property(PLAY_FORCE_AUDIO) try: video_streams = client.get_video_streams(context, video_id) diff --git a/resources/lib/youtube_plugin/youtube/provider.py b/resources/lib/youtube_plugin/youtube/provider.py index 2e6684238..38d4432d5 100644 --- a/resources/lib/youtube_plugin/youtube/provider.py +++ b/resources/lib/youtube_plugin/youtube/provider.py @@ -82,8 +82,7 @@ def is_logged_in(self): @staticmethod def get_dev_config(context, addon_id, dev_configs): - _dev_config = context.get_ui().get_property(DEVELOPER_CONFIGS) - context.get_ui().clear_property(DEVELOPER_CONFIGS) + _dev_config = context.get_ui().pop_property(DEVELOPER_CONFIGS) dev_config = {} if _dev_config: From ee8928889ea82425386288db4c86f80bfae3ca7c Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Sun, 23 Jun 2024 19:51:19 +1000 Subject: [PATCH 05/14] Misc tidy ups --- resources/lib/youtube_plugin/kodion/items/base_item.py | 4 +--- .../lib/youtube_plugin/kodion/json_store/access_manager.py | 4 +--- .../lib/youtube_plugin/kodion/monitors/service_monitor.py | 1 - .../lib/youtube_plugin/kodion/sql_store/function_cache.py | 4 +--- .../lib/youtube_plugin/kodion/sql_store/search_history.py | 4 +--- 5 files changed, 4 insertions(+), 13 deletions(-) diff --git a/resources/lib/youtube_plugin/kodion/items/base_item.py b/resources/lib/youtube_plugin/kodion/items/base_item.py index 040bba4e8..383250278 100644 --- a/resources/lib/youtube_plugin/kodion/items/base_item.py +++ b/resources/lib/youtube_plugin/kodion/items/base_item.py @@ -67,9 +67,7 @@ def get_id(self): Returns a unique id of the item. :return: unique id of the item. """ - md5_hash = md5() - md5_hash.update(''.join((self._name, self._uri)).encode('utf-8')) - return md5_hash.hexdigest() + return md5(''.join((self._name, self._uri)).encode('utf-8')).hexdigest() def set_name(self, name): try: diff --git a/resources/lib/youtube_plugin/kodion/json_store/access_manager.py b/resources/lib/youtube_plugin/kodion/json_store/access_manager.py index b39d98175..80d574ce2 100644 --- a/resources/lib/youtube_plugin/kodion/json_store/access_manager.py +++ b/resources/lib/youtube_plugin/kodion/json_store/access_manager.py @@ -522,6 +522,4 @@ def dev_keys_changed(self, addon_id, api_key, client_id, client_secret): @staticmethod def calc_key_hash(key, id, secret, **_kwargs): - md5_hash = md5() - md5_hash.update(''.join((key, id, secret)).encode('utf-8')) - return md5_hash.hexdigest() + return md5(''.join((key, id, secret)).encode('utf-8')).hexdigest() diff --git a/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py b/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py index b5762e7a3..51ec972e3 100644 --- a/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py +++ b/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py @@ -16,7 +16,6 @@ from ..constants import ( ADDON_ID, CHECK_SETTINGS, - PLAYBACK_INIT, REFRESH_CONTAINER, RELOAD_ACCESS_MANAGER, WAKEUP, diff --git a/resources/lib/youtube_plugin/kodion/sql_store/function_cache.py b/resources/lib/youtube_plugin/kodion/sql_store/function_cache.py index bf252002e..9491c3dbc 100644 --- a/resources/lib/youtube_plugin/kodion/sql_store/function_cache.py +++ b/resources/lib/youtube_plugin/kodion/sql_store/function_cache.py @@ -55,7 +55,6 @@ def _create_id_from_func(cls, partial_func, scope=SCOPE_ALL): :param partial_func: :return: id for the given function """ - md5_hash = md5() signature = ( partial_func.func.__module__, partial_func.func.__name__, @@ -80,8 +79,7 @@ def _create_id_from_func(cls, partial_func, scope=SCOPE_ALL): partial_func.args, partial_func.keywords.items(), ) - md5_hash.update(','.join(map(str, signature)).encode('utf-8')) - return md5_hash.hexdigest() + return md5(','.join(map(str, signature)).encode('utf-8')).hexdigest() def get_result(self, func, *args, **kwargs): partial_func = partial(func, *args, **kwargs) diff --git a/resources/lib/youtube_plugin/kodion/sql_store/search_history.py b/resources/lib/youtube_plugin/kodion/sql_store/search_history.py index d8c790951..1c504f468 100644 --- a/resources/lib/youtube_plugin/kodion/sql_store/search_history.py +++ b/resources/lib/youtube_plugin/kodion/sql_store/search_history.py @@ -34,9 +34,7 @@ def get_items(self, process=None): @staticmethod def _make_id(search_text): - md5_hash = md5() - md5_hash.update(search_text.encode('utf-8')) - return md5_hash.hexdigest() + return md5(search_text.encode('utf-8')).hexdigest() def rename(self, old_search_text, new_search_text): self.remove(old_search_text) From 5865cf8a612a136aafbcd0324619191901bcf563 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Mon, 24 Jun 2024 19:30:33 +1000 Subject: [PATCH 06/14] Allow for removal of custom watch later and history playlists from settings #818 - Use default value of "HL" for history or "WL" for watch later as reset value - This will then clear the setting and clear value from access_manager.json - Old values will be stored as a backup, just in case --- .../kodion/json_store/access_manager.py | 70 +++++++++++++------ .../youtube/helper/yt_playlist.py | 8 +-- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/resources/lib/youtube_plugin/kodion/json_store/access_manager.py b/resources/lib/youtube_plugin/kodion/json_store/access_manager.py index 80d574ce2..d02693884 100644 --- a/resources/lib/youtube_plugin/kodion/json_store/access_manager.py +++ b/resources/lib/youtube_plugin/kodion/json_store/access_manager.py @@ -283,33 +283,46 @@ def get_watch_later_id(self): Returns the current users watch later playlist id :return: the current users watch later playlist id """ - current_user = self.get_current_user_details() - current_id = current_user.get('watch_later', 'WL') - settings_id = self._context.get_settings().get_watch_later_playlist() + current_id = (self.get_current_user_details().get('watch_later') + or 'WL').strip() - if settings_id and current_id != settings_id: + settings = self._context.get_settings() + settings_id = settings.get_watch_later_playlist() + + if settings_id.lower() == 'wl': + current_id = self.set_watch_later_id(None) + elif settings_id and settings_id != current_id: current_id = self.set_watch_later_id(settings_id) + elif current_id: + if current_id.lower() == 'wl': + current_id = '' + elif settings_id: + settings.set_watch_later_playlist('') - if current_id and current_id.lower().strip() == 'wl': - return '' return current_id - def set_watch_later_id(self, playlist_id): + def set_watch_later_id(self, playlist_id=None): """ Sets the current users watch later playlist id :param playlist_id: string, watch later playlist id :return: """ - if playlist_id.lower().strip() == 'wl': + if not playlist_id: playlist_id = '' self._context.get_settings().set_watch_later_playlist('') + + playlists = { + 'watch_later': playlist_id, + } + current_id = self.get_current_user_details().get('watch_later') + if current_id: + playlists['watch_later_old'] = current_id + data = { 'access_manager': { 'users': { - self._user: { - 'watch_later': playlist_id, - }, + self._user: playlists, }, }, } @@ -321,33 +334,46 @@ def get_watch_history_id(self): Returns the current users watch history playlist id :return: the current users watch history playlist id """ - current_user = self.get_current_user_details() - current_id = current_user.get('watch_history', 'HL') - settings_id = self._context.get_settings().get_history_playlist() + current_id = (self.get_current_user_details().get('watch_history') + or 'HL').strip() - if settings_id and current_id != settings_id: + settings = self._context.get_settings() + settings_id = settings.get_history_playlist() + + if settings_id.lower() == 'hl': + current_id = self.set_watch_history_id(None) + elif settings_id and settings_id != current_id: current_id = self.set_watch_history_id(settings_id) + elif current_id: + if current_id.lower() == 'hl': + current_id = '' + elif settings_id: + settings.set_history_playlist('') - if current_id and current_id.lower().strip() == 'hl': - return '' return current_id - def set_watch_history_id(self, playlist_id): + def set_watch_history_id(self, playlist_id=None): """ Sets the current users watch history playlist id :param playlist_id: string, watch history playlist id :return: """ - if playlist_id.lower().strip() == 'hl': + if not playlist_id: playlist_id = '' self._context.get_settings().set_history_playlist('') + + playlists = { + 'watch_history': playlist_id, + } + current_id = self.get_current_user_details().get('watch_history') + if current_id: + playlists['watch_history_old'] = current_id + data = { 'access_manager': { 'users': { - self._user: { - 'watch_history': playlist_id, - }, + self._user: playlists, }, }, } diff --git a/resources/lib/youtube_plugin/youtube/helper/yt_playlist.py b/resources/lib/youtube_plugin/youtube/helper/yt_playlist.py index c60f3b30a..f2c3b2bce 100644 --- a/resources/lib/youtube_plugin/youtube/helper/yt_playlist.py +++ b/resources/lib/youtube_plugin/youtube/helper/yt_playlist.py @@ -310,16 +310,14 @@ def _playlist_id_change(context, playlist, method): type=playlist, method=method )) % playlist_name ): + if method == 'remove': + playlist_id = None if playlist == 'watch_later': - if method == 'remove': - playlist_id = 'WL' context.get_access_manager().set_watch_later_id(playlist_id) else: - if method == 'remove': - playlist_id = 'HL' context.get_access_manager().set_watch_history_id(playlist_id) - context.get_ui().refresh_container() + context.get_ui().refresh_container() def process(method, category, provider, context, **kwargs): From 3d50b1d8e771d79e7595a621aabd9a5d7baf0950 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Mon, 24 Jun 2024 19:43:58 +1000 Subject: [PATCH 07/14] Fix renaming playlists --- resources/lib/youtube_plugin/youtube/client/youtube.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/resources/lib/youtube_plugin/youtube/client/youtube.py b/resources/lib/youtube_plugin/youtube/client/youtube.py index 2f6ad78e3..77536a4ce 100644 --- a/resources/lib/youtube_plugin/youtube/client/youtube.py +++ b/resources/lib/youtube_plugin/youtube/client/youtube.py @@ -2046,8 +2046,12 @@ def api_request(self, } if headers: client_data['headers'] = headers - if post_data and method == 'POST': - client_data['json'] = post_data + if method in {'POST', 'PUT'}: + if post_data: + client_data['json'] = post_data + clear_data = False + else: + clear_data = True if params: client_data['params'] = params @@ -2065,7 +2069,7 @@ def api_request(self, else: del client['params']['key'] - if method != 'POST' and 'json' in client: + if clear_data and 'json' in client: del client['json'] params = client.get('params') From 1254bd877ff9cd8a472181c5d8237a13a9d7159c Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Mon, 24 Jun 2024 20:35:36 +1000 Subject: [PATCH 08/14] Add logging for AbstractProvider.reroute --- resources/lib/youtube_plugin/kodion/abstract_provider.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/resources/lib/youtube_plugin/kodion/abstract_provider.py b/resources/lib/youtube_plugin/kodion/abstract_provider.py index 9a55d9e4e..613f9514e 100644 --- a/resources/lib/youtube_plugin/kodion/abstract_provider.py +++ b/resources/lib/youtube_plugin/kodion/abstract_provider.py @@ -234,7 +234,13 @@ def reroute(self, context, re_match=None, path=None, params=None): _scope=function_cache.SCOPE_NONE, context=context.clone(path, params), ) + except Exception as exc: + context.log_error('Rerouting error: |{0}|'.format(exc)) finally: + context.log_debug('Rerouting to |{path}| |{params}|{status}' + .format(path=path, + params=params, + status='' if result else ' failed')) if not result: return False context.get_ui().set_property(REROUTE_PATH, path) From 6374d105e749f7a24d97948a129d57029a58fb32 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Mon, 24 Jun 2024 22:58:10 +1000 Subject: [PATCH 09/14] Allow for entries in data cache to be set to None to refresh them --- .../youtube/helper/resource_manager.py | 12 ++++++++--- .../youtube_plugin/youtube/helper/utils.py | 20 +++++++++++-------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/resources/lib/youtube_plugin/youtube/helper/resource_manager.py b/resources/lib/youtube_plugin/youtube/helper/resource_manager.py index 659bbcd96..63187e2b2 100644 --- a/resources/lib/youtube_plugin/youtube/helper/resource_manager.py +++ b/resources/lib/youtube_plugin/youtube/helper/resource_manager.py @@ -66,7 +66,9 @@ def get_channels(self, ids, defer_cache=False): else: result = data_cache.get_items(ids, data_cache.ONE_MONTH) to_update = [id_ for id_ in ids - if id_ not in result or result[id_].get('_partial')] + if id_ not in result + or not result[id_] + or result[id_].get('_partial')] if result: self._context.log_debug('Found cached data for channels:\n|{ids}|' @@ -139,7 +141,9 @@ def get_playlists(self, ids, defer_cache=False): data_cache = self._context.get_data_cache() result = data_cache.get_items(ids, data_cache.ONE_MONTH) to_update = [id_ for id_ in ids - if id_ not in result or result[id_].get('_partial')] + if id_ not in result + or not result[id_] + or result[id_].get('_partial')] if result: self._context.log_debug('Found cached data for playlists:\n|{ids}|' @@ -288,7 +292,9 @@ def get_videos(self, data_cache = self._context.get_data_cache() result = data_cache.get_items(ids, data_cache.ONE_MONTH) to_update = [id_ for id_ in ids - if id_ not in result or result[id_].get('_partial')] + if id_ not in result + or not result[id_] + or result[id_].get('_partial')] if result: self._context.log_debug('Found cached data for videos:\n|{ids}|' diff --git a/resources/lib/youtube_plugin/youtube/helper/utils.py b/resources/lib/youtube_plugin/youtube/helper/utils.py index 9b228374a..8ca667cf0 100644 --- a/resources/lib/youtube_plugin/youtube/helper/utils.py +++ b/resources/lib/youtube_plugin/youtube/helper/utils.py @@ -172,10 +172,12 @@ def update_channel_infos(provider, context, channel_id_dict, thumb_size = settings.get_thumbnail_size() for channel_id, yt_item in data.items(): - channel_item = channel_id_dict[channel_id] - + if not yt_item or 'snippet' not in yt_item: + continue snippet = yt_item['snippet'] + channel_item = channel_id_dict[channel_id] + # title title = snippet['title'] channel_item.set_name(title) @@ -267,11 +269,15 @@ def update_playlist_infos(provider, context, playlist_id_dict, in_my_playlists = False for playlist_id, yt_item in data.items(): + if not yt_item or 'snippet' not in yt_item: + continue + snippet = yt_item['snippet'] + playlist_item = playlist_id_dict[playlist_id] - snippet = yt_item['snippet'] title = snippet['title'] playlist_item.set_name(title) + image = get_thumbnail(thumb_size, snippet.get('thumbnails', {})) playlist_item.set_image(image) @@ -411,15 +417,13 @@ def update_video_infos(provider, context, video_id_dict, playlist_match = __RE_PLAYLIST.match(path) for video_id, yt_item in data.items(): - video_item = video_id_dict[video_id] - - # set mediatype - video_item.set_mediatype(CONTENT.VIDEO_TYPE) - if not yt_item or 'snippet' not in yt_item: continue snippet = yt_item['snippet'] + video_item = video_id_dict[video_id] + video_item.set_mediatype(CONTENT.VIDEO_TYPE) + play_data = use_play_data and yt_item.get('play_data') if play_data and 'total_time' in play_data: duration = play_data['total_time'] From 051f10116596ac3a47506cce6fa17baea9369dff Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Mon, 24 Jun 2024 23:38:06 +1000 Subject: [PATCH 10/14] Add playlist_id and channel_id to playlist listitems --- .../kodion/items/xbmc/xbmc_items.py | 22 ++++++++++++++----- .../lib/youtube_plugin/youtube/helper/v3.py | 8 ++++--- 2 files changed, 21 insertions(+), 9 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 83e8d467d..0dbf6fa11 100644 --- a/resources/lib/youtube_plugin/kodion/items/xbmc/xbmc_items.py +++ b/resources/lib/youtube_plugin/kodion/items/xbmc/xbmc_items.py @@ -530,15 +530,25 @@ def directory_listitem(context, directory_item, show_fanart=None, **_kwargs): if directory_item.next_page: props['specialSort'] = 'bottom' else: + special_sort = 'top' + prop_value = directory_item.get_subscription_id() if prop_value: + special_sort = None props[SUBSCRIPTION_ID] = prop_value - elif directory_item.get_channel_id(): - pass - elif directory_item.get_playlist_id(): - pass - else: - props['specialSort'] = 'top' + + prop_value = directory_item.get_channel_id() + if prop_value: + special_sort = None + props[CHANNEL_ID] = prop_value + + prop_value = directory_item.get_playlist_id() + if prop_value: + special_sort = None + props[PLAYLIST_ID] = prop_value + + if special_sort: + props['specialSort'] = special_sort list_item = xbmcgui.ListItem(**kwargs) diff --git a/resources/lib/youtube_plugin/youtube/helper/v3.py b/resources/lib/youtube_plugin/youtube/helper/v3.py index 232014e9f..0336fbcae 100644 --- a/resources/lib/youtube_plugin/youtube/helper/v3.py +++ b/resources/lib/youtube_plugin/youtube/helper/v3.py @@ -150,17 +150,19 @@ def _process_list_response(provider, context, json_data, item_filter): elif kind == 'playlist': # set channel id to 'mine' if the path is for a playlist of our own if context.get_path().startswith(PATHS.MY_PLAYLISTS): - channel_id = 'mine' - else: + uri_channel_id = 'mine' channel_id = snippet['channelId'] + else: + uri_channel_id = channel_id = snippet['channelId'] item_uri = context.create_uri( - ('channel', channel_id, 'playlist', item_id), + ('channel', uri_channel_id, 'playlist', item_id), item_params, ) item = DirectoryItem(title, item_uri, image=image, fanart=fanart, + channel_id=channel_id, playlist_id=item_id) playlist_id_dict[item_id] = item From a9c2f58dfbfa25d3dce5bd9ae3228e1fe8c4d1b0 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Mon, 24 Jun 2024 23:57:17 +1000 Subject: [PATCH 11/14] Update cached data when playlists are modified --- .../youtube/helper/yt_playlist.py | 76 +++++++++++-------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/resources/lib/youtube_plugin/youtube/helper/yt_playlist.py b/resources/lib/youtube_plugin/youtube/helper/yt_playlist.py index f2c3b2bce..60a137dd0 100644 --- a/resources/lib/youtube_plugin/youtube/helper/yt_playlist.py +++ b/resources/lib/youtube_plugin/youtube/helper/yt_playlist.py @@ -12,7 +12,7 @@ from .utils import get_thumbnail from ...kodion import KodionException -from ...kodion.constants import PLAYLIST_ID, PLAYLISTITEM_ID +from ...kodion.constants import CHANNEL_ID, PLAYLISTITEM_ID, PLAYLIST_ID from ...kodion.utils import find_video_id @@ -145,26 +145,34 @@ def _process_remove_video(provider, time_ms=2500, audible=False ) - return True + return False def _process_remove_playlist(provider, context): - playlist_id = context.get_param('playlist_id', '') + channel_id = context.get_listitem_property(CHANNEL_ID) + + params = context.get_params() + ui = context.get_ui() + + playlist_id = params.get('playlist_id', '') if not playlist_id: raise KodionException('Playlist/Remove: missing playlist_id') - playlist_name = context.get_param('playlist_name', '') + playlist_name = params.get('playlist_name', '') if not playlist_name: raise KodionException('Playlist/Remove: missing playlist_name') - if context.get_ui().on_delete_content(playlist_name): + if ui.on_delete_content(playlist_name): json_data = provider.get_client(context).remove_playlist(playlist_id) if not json_data: return False - context.get_ui().refresh_container() - return True + if channel_id: + data_cache = context.get_data_cache() + data_cache.remove(channel_id) + ui.refresh_container() + return False def _process_select_playlist(provider, context): @@ -250,48 +258,52 @@ def _process_select_playlist(provider, context): 'DefaultFolder.png', )) + playlist_id = None result = ui.on_select(context.localize('playlist.select'), items) - if result == 'playlist.create': + if result == 'playlist.next': + continue + elif result == 'playlist.create': result, text = ui.on_keyboard_input( context.localize('playlist.create')) if result and text: json_data = client.create_playlist(title=text) if not json_data: break - playlist_id = json_data.get('id', '') - if playlist_id: - new_params = dict(context.get_params(), - playlist_id=playlist_id) - new_context = context.clone(new_params=new_params) - _process_add_video(provider, new_context, keymap_action) - break - if result == 'playlist.next': - continue - if result != -1: - new_params = dict(context.get_params(), playlist_id=result) + elif result != -1: + playlist_id = result + + if playlist_id: + new_params = dict(context.get_params(), playlist_id=playlist_id) new_context = context.clone(new_params=new_params) _process_add_video(provider, new_context, keymap_action) break def _process_rename_playlist(provider, context): - playlist_id = context.get_param('playlist_id', '') + params = context.get_params() + ui = context.get_ui() + + playlist_id = params.get('playlist_id', '') if not playlist_id: raise KodionException('playlist/rename: missing playlist_id') - current_playlist_name = context.get_param('playlist_name', '') - result, text = context.get_ui().on_keyboard_input( - context.localize('rename'), default=current_playlist_name + result, text = ui.on_keyboard_input( + context.localize('rename'), default=params.get('playlist_name', ''), ) - if result and text: - json_data = provider.get_client(context).rename_playlist( - playlist_id=playlist_id, new_title=text - ) - if not json_data: - return + if not result or not text: + return False - context.get_ui().refresh_container() + json_data = provider.get_client(context).rename_playlist( + playlist_id=playlist_id, new_title=text, + ) + if not json_data: + return False + + data_cache = context.get_data_cache() + data_cache.remove(playlist_id) + ui.refresh_container() + return False def _playlist_id_change(context, playlist, method): @@ -316,8 +328,8 @@ def _playlist_id_change(context, playlist, method): context.get_access_manager().set_watch_later_id(playlist_id) else: context.get_access_manager().set_watch_history_id(playlist_id) - - context.get_ui().refresh_container() + return True + return False def process(method, category, provider, context, **kwargs): From a0350ba595a391ed4ec83eb30ca935818ca3cf55 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:21:13 +1000 Subject: [PATCH 12/14] Improve http server wakeup #746 #801 --- .../kodion/constants/__init__.py | 14 +++++- .../kodion/monitors/service_monitor.py | 6 ++- .../kodion/plugin/xbmc/xbmc_plugin.py | 7 +-- .../youtube_plugin/kodion/service_runner.py | 48 ++++++++++++------- .../youtube_plugin/youtube/helper/yt_play.py | 1 - .../lib/youtube_plugin/youtube/provider.py | 7 ++- 6 files changed, 58 insertions(+), 25 deletions(-) diff --git a/resources/lib/youtube_plugin/kodion/constants/__init__.py b/resources/lib/youtube_plugin/kodion/constants/__init__.py index 6484f76c3..46c6ab68d 100644 --- a/resources/lib/youtube_plugin/kodion/constants/__init__.py +++ b/resources/lib/youtube_plugin/kodion/constants/__init__.py @@ -37,7 +37,6 @@ # Flags ABORT_FLAG = 'abort_requested' BUSY_FLAG = 'busy' -SLEEPING = 'sleeping' WAIT_FLAG = 'builtin_running' # ListItem Properties @@ -55,6 +54,12 @@ PLAYBACK_STOPPED = 'playback_stopped' REFRESH_CONTAINER = 'refresh_container' RELOAD_ACCESS_MANAGER = 'reload_access_manager' + +# Sleep/wakeup states +PLUGIN_WAKEUP = 'plugin_wakeup' +PLUGIN_SLEEPING = 'plugin_sleeping' +SERVER_WAKEUP = 'server_wakeup' +SERVER_POST_START = 'server_post_start' WAKEUP = 'wakeup' # Play options @@ -88,7 +93,6 @@ # Flags 'ABORT_FLAG', 'BUSY_FLAG', - 'SLEEPING', 'WAIT_FLAG', # ListItem properties @@ -106,6 +110,12 @@ 'PLAYBACK_STOPPED', 'REFRESH_CONTAINER', 'RELOAD_ACCESS_MANAGER', + + # Sleep/wakeup states + 'PLUGIN_SLEEPING', + 'PLUGIN_WAKEUP', + 'SERVER_POST_START', + 'SERVER_WAKEUP', 'WAKEUP', # Play options diff --git a/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py b/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py index 51ec972e3..739f1ff9c 100644 --- a/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py +++ b/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py @@ -16,8 +16,10 @@ from ..constants import ( ADDON_ID, CHECK_SETTINGS, + PLUGIN_WAKEUP, REFRESH_CONTAINER, RELOAD_ACCESS_MANAGER, + SERVER_WAKEUP, WAKEUP, ) from ..logger import log_debug @@ -97,9 +99,9 @@ def onNotification(self, sender, method, data): if not data: return target = data.get('target') - if target == 'plugin': + if target == PLUGIN_WAKEUP: self.interrupt = True - elif target == 'server': + elif target == SERVER_WAKEUP: if not self.httpd and self.httpd_required(): self.start_httpd() if data.get('response_required'): diff --git a/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py b/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py index 6cc5f35f3..0d150dc8a 100644 --- a/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py +++ b/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py @@ -19,10 +19,11 @@ CHECK_SETTINGS, PLAYLIST_PATH, PLAYLIST_POSITION, + PLUGIN_SLEEPING, + PLUGIN_WAKEUP, REFRESH_CONTAINER, RELOAD_ACCESS_MANAGER, REROUTE_PATH, - SLEEPING, VIDEO_ID, ) from ...exceptions import KodionException @@ -122,8 +123,8 @@ def run(self, provider, context, focused=None): playlist.play_playlist_item(position) return False - if ui.get_property(SLEEPING): - context.wakeup('plugin') + if ui.get_property(PLUGIN_SLEEPING): + context.wakeup(PLUGIN_WAKEUP) if ui.pop_property(REFRESH_CONTAINER): focused = False diff --git a/resources/lib/youtube_plugin/kodion/service_runner.py b/resources/lib/youtube_plugin/kodion/service_runner.py index 2d87baf2a..31f4c66ba 100644 --- a/resources/lib/youtube_plugin/kodion/service_runner.py +++ b/resources/lib/youtube_plugin/kodion/service_runner.py @@ -12,7 +12,8 @@ from .constants import ( ABORT_FLAG, - SLEEPING, + PLUGIN_SLEEPING, + SERVER_POST_START, TEMP_PATH, VIDEO_ID, ) @@ -37,6 +38,7 @@ def run(): ui = context.get_ui() clear_property = ui.clear_property + pop_property = ui.pop_property set_property = ui.set_property clear_property(ABORT_FLAG) @@ -49,26 +51,39 @@ def run(): # wipe add-on temp folder on updates/restarts (subtitles, and mpd files) rm_dir(TEMP_PATH) - sleeping = False - ping_period = waited = 60 + plugin_sleeping = httpd_can_sleep = False + plugin_sleep_timeout = httpd_sleep_timeout = 0 + ping_period = 60 loop_num = sub_loop_num = 0 restart_attempts = 0 video_id = None container = monitor.is_plugin_container() while not monitor.abortRequested(): + idle = get_infobool('System.IdleTime(10)') + + if idle: + if plugin_sleep_timeout >= 30: + plugin_sleep_timeout = 0 + if not plugin_sleeping: + plugin_sleeping = set_property(PLUGIN_SLEEPING) + else: + plugin_sleep_timeout = 0 + if plugin_sleeping: + plugin_sleeping = clear_property(PLUGIN_SLEEPING) + if not monitor.httpd: - waited = 0 - elif get_infobool('System.IdleTime(10)'): - if waited >= 30: - waited = 0 + httpd_can_sleep = False + httpd_sleep_timeout = 0 + elif idle: + if pop_property(SERVER_POST_START): + httpd_can_sleep = True + httpd_sleep_timeout = 0 + if httpd_can_sleep and httpd_sleep_timeout >= 30: + httpd_can_sleep = False monitor.shutdown_httpd(sleep=True) - if not sleeping: - sleeping = set_property(SLEEPING) else: - if sleeping: - sleeping = clear_property(SLEEPING) - if waited >= ping_period: - waited = 0 + if httpd_sleep_timeout >= ping_period: + httpd_sleep_timeout = 0 if monitor.ping_httpd(): restart_attempts = 0 elif restart_attempts < 5: @@ -106,8 +121,8 @@ def run(): if sub_loop_num < 1: sub_loop_num = 5 - if not sleeping: - sleeping = set_property(SLEEPING) + if not plugin_sleeping: + plugin_sleeping = set_property(PLUGIN_SLEEPING) if sub_loop_num > 1: sub_loop_num -= 1 @@ -123,7 +138,8 @@ def run(): if wait_interval: monitor.waitForAbort(wait_interval) - waited += wait_interval + httpd_sleep_timeout += wait_interval + plugin_sleep_timeout += wait_interval if loop_num <= 0: break diff --git a/resources/lib/youtube_plugin/youtube/helper/yt_play.py b/resources/lib/youtube_plugin/youtube/helper/yt_play.py index 95c3d5865..1744b2d93 100644 --- a/resources/lib/youtube_plugin/youtube/helper/yt_play.py +++ b/resources/lib/youtube_plugin/youtube/helper/yt_play.py @@ -152,7 +152,6 @@ def play_video(provider, context): 'refresh_only': screensaver } - context.wakeup('server', timeout=30) ui.set_property(PLAYER_DATA, json.dumps(playback_data, ensure_ascii=False)) context.send_notification(PLAYBACK_INIT, playback_data) return video_item diff --git a/resources/lib/youtube_plugin/youtube/provider.py b/resources/lib/youtube_plugin/youtube/provider.py index 38d4432d5..78c3195a7 100644 --- a/resources/lib/youtube_plugin/youtube/provider.py +++ b/resources/lib/youtube_plugin/youtube/provider.py @@ -42,6 +42,8 @@ PLAY_PROMPT_QUALITY, PLAY_PROMPT_SUBTITLES, PLAY_WITH, + SERVER_POST_START, + SERVER_WAKEUP, ) from ..kodion.items import ( BaseItem, @@ -692,7 +694,10 @@ def on_play(self, context, re_match): if force_play: context.execute('Action(Play)') return False - return yt_play.play_video(self, context) + context.wakeup(SERVER_WAKEUP, timeout=5) + video = yt_play.play_video(self, context) + ui.set_property(SERVER_POST_START) + return video if playlist_id or 'playlist_ids' in params: return yt_play.play_playlist(self, context) From baff15d12a60a7e174f1dfafd924c5dadb98f19f Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Wed, 26 Jun 2024 08:18:58 +1000 Subject: [PATCH 13/14] Test setting bandwidth of MPD subtitle Representation to 0 --- resources/lib/youtube_plugin/youtube/helper/video_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/youtube_plugin/youtube/helper/video_info.py b/resources/lib/youtube_plugin/youtube/helper/video_info.py index da90f390e..bd3147abb 100644 --- a/resources/lib/youtube_plugin/youtube/helper/video_info.py +++ b/resources/lib/youtube_plugin/youtube/helper/video_info.py @@ -2215,7 +2215,7 @@ def _filter_group(previous_group, previous_stream, item): '\t\t\t\n' '\t\t\t\t', url, '\n' '\t\t\t\n' From 28b1c1e165f5da0d23d07c5fda6aab3efe70df9d Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Wed, 26 Jun 2024 08:19:56 +1000 Subject: [PATCH 14/14] Version bump v7.0.9+beta.1 --- addon.xml | 2 +- changelog.txt | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index 45b028b15..8a4169d11 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + diff --git a/changelog.txt b/changelog.txt index 5c8961d24..a982ebc6f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,17 @@ +## v7.0.9+beta.1 +### Fixed +- Fix renaming playlists +- Improve https server wakeup #746 #801 + +### Changed +- Make live query parameter optional when playing channel live stream +- Allow for removal of custom watch later and history playlists from settings #818 + - Use default value of "HL" for history or "WL" for watch later as reset value + - This will then clear the setting and clear value from access_manager.json + - Old values will be stored as a backup, just in case +- Update cached data when playlists are modified (removed/renamed) +- Changed bandwidth attribute of subtitles in MPEG-DASH manifest to 0 + ## v7.0.8 ### Fixed - Update selection and sorting of streams to fix missing live streams