Reorganise constants and simplify window property usage

- Remove need for script action for external player switching
This commit is contained in:
MoojMidge 2024-06-19 07:00:38 +10:00
parent 3726193d18
commit fca610cb25
23 changed files with 379 additions and 346 deletions

View file

@ -12,7 +12,7 @@ from __future__ import absolute_import, division, unicode_literals
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 @@ class AbstractProvider(object):
# 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<path>/[^?]+?)(?:/*[?].+|/*)$'
)), self.reroute)
self.register_path(r''.join((
'^',
paths.GOTO_PAGE,
PATHS.GOTO_PAGE,
'(?P<page>/[0-9]+)?'
'(?P<path>/[^?]+?)(?:/*[?].+|/*)$'
)), self._internal_goto_page)
self.register_path(r''.join((
'^',
paths.COMMAND,
PATHS.COMMAND,
'/(?P<command>[^?]+?)(?:/*[?].+|/*)$'
)), self._on_command)
self.register_path(r''.join((
'^',
paths.WATCH_LATER,
PATHS.WATCH_LATER,
'/(?P<command>add|clear|list|remove)/?$'
)), self.on_watch_later)
self.register_path(r''.join((
'^',
paths.BOOKMARKS,
PATHS.BOOKMARKS,
'/(?P<command>add|clear|list|remove)/?$'
)), self.on_bookmarks)
self.register_path(r''.join((
'^',
'(', paths.SEARCH, '|', paths.EXTERNAL_SEARCH, ')',
'(', PATHS.SEARCH, '|', PATHS.EXTERNAL_SEARCH, ')',
'/(?P<command>input|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 @@ class AbstractProvider(object):
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 @@ class AbstractProvider(object):
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)

View file

@ -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 @@ MEDIA_PATH = ADDON_PATH + '/resources/media'
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 @@ VALUE_FROM_STR = {
'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',
'BUSY_FLAG',
'CHANNEL_ID',
'CHECK_SETTINGS',
'CONTENT_TYPE',
'DATA_PATH',
'DEVELOPER_CONFIGS',
'LICENSE_TOKEN',
'LICENSE_URL',
'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',
'PLAY_FORCE_AUDIO',
'PLAY_PROMPT_QUALITY',
'PLAY_PROMPT_SUBTITLES',
'PLAYLIST_ID',
'PLAYLISTITEM_ID',
'SUBSCRIPTION_ID',
'VIDEO_ID',
# Events
'CHECK_SETTINGS',
'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',
# Play options
'PLAY_FORCE_AUDIO',
'PLAY_PROMPT_QUALITY',
'PLAY_PROMPT_SUBTITLES',
'PLAY_WITH',
# Stored data
'CONTENT_TYPE',
'DEVELOPER_CONFIGS',
'LICENSE_TOKEN',
'LICENSE_URL',
'PLAYER_DATA',
'PLAYLIST_PATH',
'PLAYLIST_POSITION',
'REROUTE_PATH',
# Other constants
'CONTENT',
'PATHS',
'SETTINGS',
'SORT',
)

View file

@ -14,7 +14,13 @@ import os
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',

View file

@ -27,10 +27,10 @@ from ...compatibility import (
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 @@ class XbmcContext(AbstractContext):
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):

View file

@ -12,7 +12,7 @@ from __future__ import absolute_import, division, unicode_literals
from . import menu_items
from .directory_item import DirectoryItem
from ..constants import paths
from ..constants import PATHS
class CommandItem(DirectoryItem):
@ -25,7 +25,7 @@ class CommandItem(DirectoryItem):
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,

View file

@ -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(),
))
)

View file

@ -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 @@ class NewSearchItem(DirectoryItem):
super(NewSearchItem, self).__init__(name,
context.create_uri(
(paths.SEARCH, 'input',),
(PATHS.SEARCH, 'input',),
params=params,
),
image=image,

View file

@ -12,7 +12,7 @@ from __future__ import absolute_import, division, unicode_literals
from . import menu_items
from .directory_item import DirectoryItem
from ..constants import paths
from ..constants import PATHS
class SearchHistoryItem(DirectoryItem):
@ -26,7 +26,7 @@ class SearchHistoryItem(DirectoryItem):
super(SearchHistoryItem, self).__init__(query,
context.create_uri(
(paths.SEARCH, 'query',),
(PATHS.SEARCH, 'query',),
params=params,
),
image=image,

View file

@ -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 @@ class SearchItem(DirectoryItem):
super(SearchItem, self).__init__(name,
context.create_uri(
(paths.SEARCH, 'list',),
(PATHS.SEARCH, 'list',),
params=params,
),
image=image,

View file

@ -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 @@ class WatchLaterItem(DirectoryItem):
super(WatchLaterItem, self).__init__(name,
context.create_uri(
(paths.WATCH_LATER, 'list',),
(PATHS.WATCH_LATER, 'list',),
),
image=image,
fanart=fanart)

View file

@ -16,11 +16,11 @@ from .. import AudioItem, DirectoryItem, ImageItem, VideoItem
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

View file

@ -19,8 +19,8 @@ from ..constants import (
PLAYBACK_STARTED,
PLAYBACK_STOPPED,
PLAYER_DATA,
PLAY_WITH,
REFRESH_CONTAINER,
SWITCH_PLAYER_FLAG,
)
@ -352,12 +352,12 @@ class PlayerMonitor(xbmc.Player):
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 @@ class PlayerMonitor(xbmc.Player):
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()

View file

@ -26,7 +26,7 @@ from ..compatibility import (
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 @@ class RequestHandler(BaseHTTPRequestHandler, object):
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 @@ class RequestHandler(BaseHTTPRequestHandler, object):
# 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 @@ class RequestHandler(BaseHTTPRequestHandler, object):
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 @@ class RequestHandler(BaseHTTPRequestHandler, object):
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 @@ class RequestHandler(BaseHTTPRequestHandler, object):
.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 @@ class RequestHandler(BaseHTTPRequestHandler, object):
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 @@ class RequestHandler(BaseHTTPRequestHandler, object):
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 @@ class RequestHandler(BaseHTTPRequestHandler, object):
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 @@ class RequestHandler(BaseHTTPRequestHandler, object):
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 @@ class RequestHandler(BaseHTTPRequestHandler, object):
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):
</div>
</body>
</html>
'''.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()

View file

@ -21,7 +21,7 @@ from ...constants import (
PLAYLIST_POSITION,
REFRESH_CONTAINER,
RELOAD_ACCESS_MANAGER,
REROUTE,
REROUTE_PATH,
SLEEPING,
VIDEO_ID,
)
@ -154,7 +154,7 @@ class XbmcPlugin(AbstractPlugin):
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 @@ class XbmcPlugin(AbstractPlugin):
_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:

View file

@ -16,7 +16,6 @@ from .compatibility import parse_qsl, urlsplit, xbmc, xbmcaddon, xbmcvfs
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

View file

@ -12,13 +12,13 @@ from __future__ import absolute_import, division, unicode_literals
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
}
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 @@ class AbstractSettings(object):
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 @@ class AbstractSettings(object):
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))

View file

@ -82,9 +82,11 @@ class Subtitles(object):
self.preferred_lang = ('en',)
ui = context.get_ui()
self.prompt_override = (ui.get_property(PLAY_PROMPT_SUBTITLES)
== video_id)
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:

View file

@ -14,7 +14,7 @@ import re
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(

View file

@ -23,7 +23,7 @@ from .utils import (
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']

View file

@ -32,7 +32,7 @@ from ...kodion.compatibility import (
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 @@ class VideoInfo(YouTubeRequestClient):
'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 @@ class VideoInfo(YouTubeRequestClient):
return 'http://{address}:{port}{path}{file}'.format(
address=address,
port=port,
path=paths.MPD,
path=PATHS.MPD,
file=filename,
), main_stream
return None, None

View file

@ -18,12 +18,12 @@ from ..helper import utils, v3
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,12 +53,12 @@ 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)
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)
@ -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']}),
'',
))

View file

@ -12,14 +12,14 @@ from __future__ import absolute_import, division, unicode_literals
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 _process_description_links(provider, context):
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()

View file

@ -35,12 +35,13 @@ from ..kodion import AbstractProvider, RegisterProviderPath
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 @@ class Provider(AbstractProvider):
@RegisterProviderPath('^(?:/channel/(?P<channel_id>[^/]+))?/playlist/(?P<playlist_id>[^/]+)/?$')
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 @@ class Provider(AbstractProvider):
@RegisterProviderPath('^/channel/(?P<channel_id>[^/]+)/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 @@ class Provider(AbstractProvider):
@RegisterProviderPath('^/channel/(?P<channel_id>[^/]+)/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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
# 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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
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 @@ class Provider(AbstractProvider):
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