diff --git a/resources/lib/youtube_plugin/kodion/__init__.py b/resources/lib/youtube_plugin/kodion/__init__.py index cb913bc4a..9b3fdb304 100644 --- a/resources/lib/youtube_plugin/kodion/__init__.py +++ b/resources/lib/youtube_plugin/kodion/__init__.py @@ -10,7 +10,6 @@ from __future__ import absolute_import, division, unicode_literals -from . import logger from .abstract_provider import ( # Abstract provider for implementation by the user AbstractProvider, diff --git a/resources/lib/youtube_plugin/kodion/constants/const_settings.py b/resources/lib/youtube_plugin/kodion/constants/const_settings.py index ed8ffef57..3f12718ee 100644 --- a/resources/lib/youtube_plugin/kodion/constants/const_settings.py +++ b/resources/lib/youtube_plugin/kodion/constants/const_settings.py @@ -90,3 +90,5 @@ HTTPD_LISTEN = 'kodion.http.listen' # (str) HTTPD_WHITELIST = 'kodion.http.ip.whitelist' # (str) HTTPD_IDLE_SLEEP = 'youtube.http.idle_sleep' # (bool) + +LOGGING_ENABLED = 'kodion.logging.enabled' # (bool) diff --git a/resources/lib/youtube_plugin/kodion/context/abstract_context.py b/resources/lib/youtube_plugin/kodion/context/abstract_context.py index 7f1db2a7c..add2755ff 100644 --- a/resources/lib/youtube_plugin/kodion/context/abstract_context.py +++ b/resources/lib/youtube_plugin/kodion/context/abstract_context.py @@ -12,7 +12,7 @@ import os -from .. import logger +from ..logger import Logger from ..compatibility import parse_qsl, quote, to_str, urlencode, urlsplit from ..constants import ( PATHS, @@ -37,7 +37,7 @@ from ..utils import current_system_version -class AbstractContext(object): +class AbstractContext(Logger): _initialized = False _addon = None _settings = None @@ -430,24 +430,6 @@ def set_content(self, content_type, sub_type=None, category_label=None): def add_sort_method(self, *sort_methods): raise NotImplementedError() - def log(self, text, log_level=logger.NOTICE): - logger.log(text, log_level, self.get_id()) - - def log_warning(self, text): - self.log(text, logger.WARNING) - - def log_error(self, text): - self.log(text, logger.ERROR) - - def log_notice(self, text): - self.log(text, logger.NOTICE) - - def log_debug(self, text): - self.log(text, logger.DEBUG) - - def log_info(self, text): - self.log(text, logger.INFO) - def clone(self, new_path=None, new_params=None): raise NotImplementedError() diff --git a/resources/lib/youtube_plugin/kodion/debug.py b/resources/lib/youtube_plugin/kodion/debug.py index 076836681..f99a5ad54 100644 --- a/resources/lib/youtube_plugin/kodion/debug.py +++ b/resources/lib/youtube_plugin/kodion/debug.py @@ -13,7 +13,7 @@ import atexit import os -from .logger import log_debug +from .logger import Logger def debug_here(host='localhost'): @@ -145,7 +145,7 @@ def __exit__(self, exc_type=None, exc_val=None, exc_tb=None): if not self._enabled: return - log_debug('Profiling stats: {0}'.format(self.get_stats( + Logger.log_debug('Profiling stats: {0}'.format(self.get_stats( num_lines=self._num_lines, print_callees=self._print_callees, reuse=self._reuse, @@ -270,7 +270,7 @@ def get_stats(self, return output def print_stats(self): - log_debug('Profiling stats: {0}'.format(self.get_stats( + Logger.log_debug('Profiling stats: {0}'.format(self.get_stats( num_lines=self._num_lines, print_callees=self._print_callees, reuse=self._reuse, diff --git a/resources/lib/youtube_plugin/kodion/json_store/json_store.py b/resources/lib/youtube_plugin/kodion/json_store/json_store.py index baede56d4..f74adff56 100644 --- a/resources/lib/youtube_plugin/kodion/json_store/json_store.py +++ b/resources/lib/youtube_plugin/kodion/json_store/json_store.py @@ -14,18 +14,18 @@ from io import open from ..constants import DATA_PATH -from ..logger import log_debug, log_error +from ..logger import Logger from ..utils import make_dirs, merge_dicts, to_unicode -class JSONStore(object): +class JSONStore(Logger): BASE_PATH = make_dirs(DATA_PATH) def __init__(self, filename): if self.BASE_PATH: self.filename = os.path.join(self.BASE_PATH, filename) else: - log_error('JSONStore.__init__ - unable to access temp directory') + self.log_error('JSONStore.__init__ - temp directory not available') self.filename = None self._data = {} @@ -42,13 +42,11 @@ def save(self, data, update=False, process=None): if update: data = merge_dicts(self._data, data) if data == self._data: - log_debug('JSONStore.save - data unchanged:\n|{filename}|'.format( - filename=self.filename - )) + self.log_debug('JSONStore.save - data unchanged:\n' + '|{filename}|'.format(filename=self.filename)) return - log_debug('JSONStore.save - saving:\n|{filename}|'.format( - filename=self.filename - )) + self.log_debug('JSONStore.save - saving:\n' + '|{filename}|'.format(filename=self.filename)) try: if not data: raise ValueError @@ -60,23 +58,20 @@ def save(self, data, update=False, process=None): sort_keys=True))) self._data = process(_data) if process is not None else _data except (IOError, OSError): - log_error('JSONStore.save - access error:\n|{filename}|'.format( - filename=self.filename - )) + self.log_error('JSONStore.save - access error:\n' + '|{filename}|'.format(filename=self.filename)) return except (TypeError, ValueError): - log_error('JSONStore.save - invalid data:\n|{data}|'.format( - data=data - )) + self.log_error('JSONStore.save - invalid data:\n' + '|{data}|'.format(data=data)) self.set_defaults(reset=True) def load(self, process=None): if not self.filename: return - log_debug('JSONStore.load - loading:\n|{filename}|'.format( - filename=self.filename - )) + self.log_debug('JSONStore.load - loading:\n' + '|{filename}|'.format(filename=self.filename)) try: with open(self.filename, mode='r', encoding='utf-8') as jsonfile: data = jsonfile.read() @@ -85,13 +80,11 @@ def load(self, process=None): _data = json.loads(data) self._data = process(_data) if process is not None else _data except (IOError, OSError): - log_error('JSONStore.load - access error:\n|{filename}|'.format( - filename=self.filename - )) + self.log_error('JSONStore.load - access error:\n' + '|{filename}|'.format(filename=self.filename)) except (TypeError, ValueError): - log_error('JSONStore.load - invalid data:\n|{data}|'.format( - data=data - )) + self.log_error('JSONStore.load - invalid data:\n' + '|{data}|'.format(data=data)) def get_data(self, process=None): try: @@ -100,9 +93,8 @@ def get_data(self, process=None): _data = json.loads(json.dumps(self._data, ensure_ascii=False)) return process(_data) if process is not None else _data except (TypeError, ValueError): - log_error('JSONStore.get_data - invalid data:\n|{data}|'.format( - data=self._data - )) + self.log_error('JSONStore.get_data - invalid data:\n' + '|{data}|'.format(data=self._data)) self.set_defaults(reset=True) _data = json.loads(json.dumps(self._data, ensure_ascii=False)) return process(_data) if process is not None else _data diff --git a/resources/lib/youtube_plugin/kodion/logger.py b/resources/lib/youtube_plugin/kodion/logger.py index b3968f2d6..063ede6ac 100644 --- a/resources/lib/youtube_plugin/kodion/logger.py +++ b/resources/lib/youtube_plugin/kodion/logger.py @@ -10,42 +10,55 @@ from __future__ import absolute_import, division, unicode_literals -from .compatibility import xbmc, xbmcaddon +from .compatibility import xbmc from .constants import ADDON_ID -DEBUG = xbmc.LOGDEBUG -INFO = xbmc.LOGINFO -NOTICE = xbmc.LOGNOTICE -WARNING = xbmc.LOGWARNING -ERROR = xbmc.LOGERROR -FATAL = xbmc.LOGFATAL -SEVERE = xbmc.LOGSEVERE -NONE = xbmc.LOGNONE -def log(text, log_level=DEBUG, addon_id=ADDON_ID): - if not addon_id: - addon_id = xbmcaddon.Addon().getAddonInfo('id') - log_line = '[%s] %s' % (addon_id, text) - xbmc.log(msg=log_line, level=log_level) - - -def log_debug(text, addon_id=ADDON_ID): - log(text, DEBUG, addon_id) - - -def log_info(text, addon_id=ADDON_ID): - log(text, INFO, addon_id) - - -def log_notice(text, addon_id=ADDON_ID): - log(text, NOTICE, addon_id) - - -def log_warning(text, addon_id=ADDON_ID): - log(text, WARNING, addon_id) - - -def log_error(text, addon_id=ADDON_ID): - log(text, ERROR, addon_id) +class Logger(object): + LOGDEBUG = xbmc.LOGDEBUG + LOGINFO = xbmc.LOGINFO + LOGNOTICE = xbmc.LOGNOTICE + LOGWARNING = xbmc.LOGWARNING + LOGERROR = xbmc.LOGERROR + LOGFATAL = xbmc.LOGFATAL + LOGSEVERE = xbmc.LOGSEVERE + LOGNONE = xbmc.LOGNONE + + @staticmethod + def log(text, log_level=LOGDEBUG, addon_id=ADDON_ID): + log_line = '[%s] %s' % (addon_id, text) + xbmc.log(msg=log_line, level=log_level) + + @staticmethod + def log_debug(text, addon_id=ADDON_ID): + log_line = '[%s] %s' % (addon_id, text) + xbmc.log(msg=log_line, level=Logger.LOGDEBUG) + + @staticmethod + def log_info(text, addon_id=ADDON_ID): + log_line = '[%s] %s' % (addon_id, text) + xbmc.log(msg=log_line, level=Logger.LOGINFO) + + @staticmethod + def log_notice(text, addon_id=ADDON_ID): + log_line = '[%s] %s' % (addon_id, text) + xbmc.log(msg=log_line, level=Logger.LOGNOTICE) + + @staticmethod + def log_warning(text, addon_id=ADDON_ID): + log_line = '[%s] %s' % (addon_id, text) + xbmc.log(msg=log_line, level=Logger.LOGWARNING) + + @staticmethod + def log_error(text, addon_id=ADDON_ID): + log_line = '[%s] %s' % (addon_id, text) + xbmc.log(msg=log_line, level=Logger.LOGERROR) + + @staticmethod + def debug_log(on=False, off=True): + if on: + Logger.LOGDEBUG = Logger.LOGNOTICE + elif off: + Logger.LOGDEBUG = xbmc.LOGDEBUG diff --git a/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py b/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py index 01cd50892..1d502d6cd 100644 --- a/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py +++ b/resources/lib/youtube_plugin/kodion/monitors/service_monitor.py @@ -23,35 +23,33 @@ SERVER_WAKEUP, WAKEUP, ) -from ..logger import log_debug from ..network import get_connect_address, get_http_server, httpd_status class ServiceMonitor(xbmc.Monitor): _settings_changes = 0 - _settings_state = None + _settings_collect = False get_idle_time = xbmc.getGlobalIdleTime def __init__(self, context): self._context = context - settings = context.get_settings() - 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_address = None + self._httpd_port = None + self._whitelist = None + self._old_httpd_address = None + self._old_httpd_port = None + self._use_httpd = None self.httpd = None self.httpd_thread = None - self.httpd_sleep_allowed = settings.httpd_sleep_allowed() + self.httpd_sleep_allowed = True self.system_idle = False self.refresh = False self.interrupt = False - self._use_httpd = None - if self.httpd_required(settings): - self.start_httpd() + self.onSettingsChanged(force=True) super(ServiceMonitor, self).__init__() @@ -110,11 +108,9 @@ def onNotification(self, sender, method, data): elif target == CHECK_SETTINGS: state = data.get('state') if state == 'defer': - self._settings_state = state + self._settings_collect = True elif state == 'process': - self._settings_state = state - self.onSettingsChanged() - self._settings_state = None + self.onSettingsChanged(force=True) if data.get('response_required'): self.set_property(WAKEUP, target) @@ -147,26 +143,38 @@ def onDPMSDeactivated(self): self.system_idle = False self.interrupt = True - def onSettingsChanged(self): - self._settings_changes += 1 - if self._settings_state == 'defer': - return - changes = self._settings_changes - if self._settings_state != 'process': + def onSettingsChanged(self, force=False): + context = self._context + + if force: + self._settings_collect = False + self._settings_changes = 0 + else: + self._settings_changes += 1 + if self._settings_collect: + return + + total = self._settings_changes self.waitForAbort(1) - if changes != self._settings_changes: + if total != self._settings_changes: return - log_debug('onSettingsChanged: {0} change(s)'.format(changes)) - self._settings_changes = 0 - settings = self._context.get_settings(refresh=True) + context.log_debug('onSettingsChanged: {0} change(s)'.format(total)) + self._settings_changes = 0 + + settings = context.get_settings(refresh=True) + if settings.logging_enabled(): + context.debug_log(on=True) + else: + context.debug_log(off=True) + self.set_property(CHECK_SETTINGS) self.refresh_container() httpd_started = bool(self.httpd) httpd_restart = False - address, port = get_connect_address(self._context) + address, port = get_connect_address(context) if port != self._httpd_port: self._old_httpd_port = self._httpd_port self._httpd_port = port @@ -201,12 +209,14 @@ def start_httpd(self): if self.httpd: return - log_debug('HTTPServer: Starting |{ip}:{port}|' - .format(ip=self._httpd_address, port=self._httpd_port)) + context = self._context + context.log_debug('HTTPServer: Starting |{ip}:{port}|' + .format(ip=self._httpd_address, + port=self._httpd_port)) self.httpd_address_sync() self.httpd = get_http_server(address=self._httpd_address, port=self._httpd_port, - context=self._context) + context=context) if not self.httpd: return @@ -214,16 +224,17 @@ def start_httpd(self): self.httpd_thread.start() address = self.httpd.socket.getsockname() - log_debug('HTTPServer: Listening on |{ip}:{port}|' - .format(ip=address[0], port=address[1])) + context.log_debug('HTTPServer: Listening on |{ip}:{port}|' + .format(ip=address[0], + port=address[1])) def shutdown_httpd(self, sleep=False): if self.httpd: if sleep and self.httpd_required(while_sleeping=True): return - log_debug('HTTPServer: Shutting down |{ip}:{port}|' - .format(ip=self._old_httpd_address, - port=self._old_httpd_port)) + self._context.log_debug('HTTPServer: Shutting down |{ip}:{port}|' + .format(ip=self._old_httpd_address, + port=self._old_httpd_port)) self.httpd_address_sync() self.httpd.shutdown() self.httpd.server_close() @@ -232,11 +243,12 @@ def shutdown_httpd(self, sleep=False): self.httpd = None def restart_httpd(self): - log_debug('HTTPServer: Restarting |{old_ip}:{old_port}| > |{ip}:{port}|' - .format(old_ip=self._old_httpd_address, - old_port=self._old_httpd_port, - ip=self._httpd_address, - port=self._httpd_port)) + self._context.log_debug('HTTPServer: Restarting' + ' |{old_ip}:{old_port}| > |{ip}:{port}|' + .format(old_ip=self._old_httpd_address, + old_port=self._old_httpd_port, + ip=self._httpd_address, + port=self._httpd_port)) self.shutdown_httpd() self.start_httpd() diff --git a/resources/lib/youtube_plugin/kodion/network/http_server.py b/resources/lib/youtube_plugin/kodion/network/http_server.py index 888969c4c..236619f30 100644 --- a/resources/lib/youtube_plugin/kodion/network/http_server.py +++ b/resources/lib/youtube_plugin/kodion/network/http_server.py @@ -34,7 +34,6 @@ PATHS, TEMP_PATH, ) -from ..logger import log_debug, log_error from ..utils import redact_ip, validate_ip_address, wait @@ -91,24 +90,25 @@ def connection_allowed(self): log_lines.append('Whitelisted: |%s|' % str(conn_allowed)) if not conn_allowed: - log_debug('HTTPServer: Connection from |{client_ip| not allowed' - .format(client_ip=client_ip)) + self._context.log_debug('HTTPServer: Connection blocked from' + ' |{client_ip|' + .format(client_ip=client_ip)) elif self.path != PATHS.PING: - log_debug(' '.join(log_lines)) + self._context.log_debug(' '.join(log_lines)) return conn_allowed # noinspection PyPep8Naming def do_GET(self): - settings = self._context.get_settings() - localize = self._context.localize + context = self._context + settings = context.get_settings() + localize = context.localize api_config_enabled = settings.api_config_page() # Strip trailing slash if present stripped_path = self.path.rstrip('/') if stripped_path != PATHS.PING: - log_debug('HTTPServer: GET |{path}|'.format( - path=redact_ip(self.path) - )) + context.log_debug('HTTPServer: GET |{path}|' + .format(path=redact_ip(self.path))) if not self.connection_allowed(): self.send_error(403) @@ -235,7 +235,8 @@ def do_GET(self): # noinspection PyPep8Naming def do_HEAD(self): - log_debug('HTTPServer: HEAD |{path}|'.format(path=self.path)) + self._context.log_debug('HTTPServer: HEAD |{path}|' + .format(path=self.path)) if not self.connection_allowed(): self.send_error(403) @@ -267,7 +268,8 @@ def do_HEAD(self): # noinspection PyPep8Naming def do_POST(self): - log_debug('HTTPServer: POST |{path}|'.format(path=self.path)) + self._context.log_debug('HTTPServer: POST |{path}|' + .format(path=self.path)) if not self.connection_allowed(): self.send_error(403) @@ -317,8 +319,9 @@ def do_POST(self): re.MULTILINE) if match: authorized_types = match.group('authorized_types').split(',') - log_debug('HTTPServer: Found authorized formats |{auth_fmts}|' - .format(auth_fmts=authorized_types)) + self._context.log_debug('HTTPServer: Found authorized formats' + ' |{auth_fmts}|' + .format(auth_fmts=authorized_types)) fmt_to_px = { 'SD': (1280 * 528) - 1, @@ -589,8 +592,10 @@ def get_http_server(address, port, context): server = HTTPServer((address, port), RequestHandler) return server except socket.error as exc: - log_error('HTTPServer: Failed to start |{address}:{port}| |{response}|' - .format(address=address, port=port, response=exc)) + context.log_error('HTTPServer: Failed to start\n' + 'Address: |{address}:{port}|\n' + 'Response: |{response}|' + .format(address=address, port=port, response=exc)) xbmcgui.Dialog().notification(context.get_name(), str(exc), context.get_icon(), @@ -615,9 +620,9 @@ def httpd_status(context): if result == 204: return True - log_debug('HTTPServer: Ping |{netloc}| - |{response}|' - .format(netloc=netloc, - response=result or 'failed')) + context.log_debug('HTTPServer: Ping |{netloc}| - |{response}|' + .format(netloc=netloc, + response=result or 'failed')) return False diff --git a/resources/lib/youtube_plugin/kodion/network/ip_api.py b/resources/lib/youtube_plugin/kodion/network/ip_api.py index 853ee216e..e3f9bc94b 100644 --- a/resources/lib/youtube_plugin/kodion/network/ip_api.py +++ b/resources/lib/youtube_plugin/kodion/network/ip_api.py @@ -10,7 +10,6 @@ from __future__ import absolute_import, division, unicode_literals from .requests import BaseRequestsClass -from .. import logger class Locator(BaseRequestsClass): @@ -32,9 +31,10 @@ def locate_requester(self): def success(self): successful = self.response().get('status', 'fail') == 'success' if successful: - logger.log_debug('Location request was successful') + self.log_debug('Location request was successful') else: - logger.log_error(self.response().get('message', 'Location request failed with no error message')) + msg = 'Location request failed with no error message' + self.log_error(self.response().get('message') or msg) return successful def coordinates(self): @@ -44,7 +44,7 @@ def coordinates(self): lat = self._response.get('lat') lon = self._response.get('lon') if lat is None or lon is None: - logger.log_error('No coordinates returned') + self.log_error('No coordinates returned') return None - logger.log_debug('Coordinates found') + self.log_debug('Coordinates found') return {'lat': lat, 'lon': lon} diff --git a/resources/lib/youtube_plugin/kodion/network/requests.py b/resources/lib/youtube_plugin/kodion/network/requests.py index deb19940a..52cd9dfdf 100644 --- a/resources/lib/youtube_plugin/kodion/network/requests.py +++ b/resources/lib/youtube_plugin/kodion/network/requests.py @@ -19,7 +19,7 @@ from requests.utils import DEFAULT_CA_BUNDLE_PATH, extract_zipped_paths from urllib3.util.ssl_ import create_urllib3_context -from ..logger import log_error +from ..logger import Logger __all__ = ( @@ -63,7 +63,7 @@ def cert_verify(self, conn, url, verify, cert): return super(SSLHTTPAdapter, self).cert_verify(conn, url, verify, cert) -class BaseRequestsClass(object): +class BaseRequestsClass(Logger): _session = Session() _session.mount('https://', SSLHTTPAdapter( pool_maxsize=10, @@ -198,7 +198,7 @@ def request(self, url, method='GET', ) ) - log_error('\n'.join([part for part in [ + self.log_error('\n'.join([part for part in [ error_title, error_info, response_text, stack_trace ] if part])) 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 01926f861..05a6c2a9a 100644 --- a/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py +++ b/resources/lib/youtube_plugin/kodion/plugin/xbmc/xbmc_plugin.py @@ -16,7 +16,6 @@ from ...compatibility import xbmcplugin from ...constants import ( BUSY_FLAG, - CHECK_SETTINGS, CONTAINER_FOCUS, CONTAINER_ID, CONTAINER_POSITION, @@ -153,12 +152,7 @@ def run(self, provider, context, focused=None): if ui.pop_property(RELOAD_ACCESS_MANAGER): context.reload_access_manager() - if ui.pop_property(CHECK_SETTINGS): - provider.reset_client() - settings = context.get_settings(refresh=True) - else: - settings = context.get_settings() - + settings = context.get_settings() if settings.setup_wizard_enabled(): provider.run_wizard(context) diff --git a/resources/lib/youtube_plugin/kodion/plugin_runner.py b/resources/lib/youtube_plugin/kodion/plugin_runner.py index c0e8b86d8..b009e19af 100644 --- a/resources/lib/youtube_plugin/kodion/plugin_runner.py +++ b/resources/lib/youtube_plugin/kodion/plugin_runner.py @@ -10,7 +10,9 @@ from __future__ import absolute_import, division, unicode_literals +from .constants import CHECK_SETTINGS from .context import XbmcContext +from .debug import Profiler from .plugin import XbmcPlugin from ..youtube import Provider @@ -20,21 +22,26 @@ _context = XbmcContext() _plugin = XbmcPlugin() _provider = Provider() - -_profiler = _context.get_infobool('System.GetBool(debug.showloginfo)') -_profiler = True -if _profiler: - from .debug import Profiler - - _profiler = Profiler(enabled=False, print_callees=False, num_lines=20) +_profiler = Profiler(enabled=False, print_callees=False, num_lines=20) def run(context=_context, plugin=_plugin, provider=_provider, profiler=_profiler): - if profiler: + + if context.get_ui().pop_property(CHECK_SETTINGS): + provider.reset_client() + settings = context.get_settings(refresh=True) + else: + settings = context.get_settings() + + debug = settings.logging_enabled() + if debug: + context.debug_log(on=True) profiler.enable(flush=True) + else: + context.debug_log(off=True) current_uri = context.get_uri() context.init() @@ -59,5 +66,5 @@ def run(context=_context, plugin.run(provider, context, focused=(current_uri == new_uri)) - if profiler: + if debug: profiler.print_stats() diff --git a/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py b/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py index 81dbc3812..fa47c1a41 100644 --- a/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py +++ b/resources/lib/youtube_plugin/kodion/settings/abstract_settings.py @@ -15,6 +15,7 @@ from ..constants import SETTINGS from ..utils import ( current_system_version, + get_kodi_setting_bool, get_kodi_setting_value, validate_ip_address, ) @@ -653,3 +654,7 @@ def get_label_color(self, label_part): def get_channel_name_aliases(self): return frozenset(self.get_string_list(SETTINGS.CHANNEL_NAME_ALIASES)) + + def logging_enabled(self): + return (self.get_bool(SETTINGS.LOGGING_ENABLED, False) + or get_kodi_setting_bool('debug.showloginfo')) diff --git a/resources/lib/youtube_plugin/kodion/settings/xbmc/xbmc_plugin_settings.py b/resources/lib/youtube_plugin/kodion/settings/xbmc/xbmc_plugin_settings.py index d8e82c413..6065af900 100644 --- a/resources/lib/youtube_plugin/kodion/settings/xbmc/xbmc_plugin_settings.py +++ b/resources/lib/youtube_plugin/kodion/settings/xbmc/xbmc_plugin_settings.py @@ -15,8 +15,7 @@ from ..abstract_settings import AbstractSettings from ...compatibility import xbmcaddon from ...constants import ADDON_ID, VALUE_FROM_STR -from ...logger import log_debug -from ...utils.methods import get_kodi_setting_bool +from ...logger import Logger from ...utils.system_version import current_system_version @@ -94,7 +93,7 @@ def ref(self): del self._ref -class XbmcPluginSettings(AbstractSettings): +class XbmcPluginSettings(AbstractSettings, Logger): _instances = set() _proxy = None @@ -119,7 +118,6 @@ def flush(self, xbmc_addon=None, fill=False, flush_all=True): else: fill = False - self._echo = get_kodi_setting_bool('debug.showloginfo') self._cache = {} if current_system_version.compatible(21): self._proxy = SettingsProxy(xbmc_addon.getSettings()) @@ -134,6 +132,8 @@ def flush(self, xbmc_addon=None, fill=False, flush_all=True): self.__class__._instances.add(xbmc_addon) self._proxy = SettingsProxy(xbmc_addon) + self._echo = self.logging_enabled() + def get_bool(self, setting, default=None, echo=None): if setting in self._cache: return self._cache[setting] @@ -154,11 +154,10 @@ def get_bool(self, setting, default=None, echo=None): value = default if self._echo and echo is not False: - log_debug('Get |{setting}|: {value} (bool, {status})'.format( - setting=setting, - value=value, - status=error if error else 'success' - )) + self.log_debug('Get |{setting}|: {value} (bool, {status})' + .format(setting=setting, + value=value, + status=error if error else 'success')) self._cache[setting] = value return value @@ -174,11 +173,10 @@ def set_bool(self, setting, value, echo=None): error = exc if self._echo and echo is not False: - log_debug('Set |{setting}|: {value} (bool, {status})'.format( - setting=setting, - value=value, - status=error if error else 'success' - )) + self.log_debug('Set |{setting}|: {value} (bool, {status})' + .format(setting=setting, + value=value, + status=error if error else 'success')) return not error def get_int(self, setting, default=-1, process=None, echo=None): @@ -203,11 +201,10 @@ def get_int(self, setting, default=-1, process=None, echo=None): value = default if self._echo and echo is not False: - log_debug('Get |{setting}|: {value} (int, {status})'.format( - setting=setting, - value=value, - status=error if error else 'success' - )) + self.log_debug('Get |{setting}|: {value} (int, {status})' + .format(setting=setting, + value=value, + status=error if error else 'success')) self._cache[setting] = value return value @@ -223,11 +220,10 @@ def set_int(self, setting, value, echo=None): error = exc if self._echo and echo is not False: - log_debug('Set |{setting}|: {value} (int, {status})'.format( - setting=setting, - value=value, - status=error if error else 'success' - )) + self.log_debug('Set |{setting}|: {value} (int, {status})' + .format(setting=setting, + value=value, + status=error if error else 'success')) return not error def get_string(self, setting, default='', echo=None): @@ -250,11 +246,10 @@ def get_string(self, setting, default='', echo=None): echo = '...'.join((value[:3], value[-3:])) else: echo = value - log_debug('Get |{setting}|: "{echo}" (str, {status})'.format( - setting=setting, - echo=echo, - status=error if error else 'success' - )) + self.log_debug('Get |{setting}|: "{echo}" (str, {status})' + .format(setting=setting, + echo=echo, + status=error if error else 'success')) self._cache[setting] = value return value @@ -278,11 +273,10 @@ def set_string(self, setting, value, echo=None): echo = '...'.join((value[:3], value[-3:])) else: echo = value - log_debug('Set |{setting}|: "{echo}" (str, {status})'.format( - setting=setting, - echo=echo, - status=error if error else 'success' - )) + self.log_debug('Set |{setting}|: "{echo}" (str, {status})' + .format(setting=setting, + echo=echo, + status=error if error else 'success')) return not error def get_string_list(self, setting, default=None, echo=None): @@ -299,11 +293,10 @@ def get_string_list(self, setting, default=None, echo=None): value = default if self._echo and echo is not False: - log_debug('Get |{setting}|: "{value}" (str list, {status})'.format( - setting=setting, - value=value, - status=error if error else 'success' - )) + self.log_debug('Get |{setting}|: "{value}" (str list, {status})' + .format(setting=setting, + value=value, + status=error if error else 'success')) self._cache[setting] = value return value @@ -319,9 +312,8 @@ def set_string_list(self, setting, value, echo=None): error = exc if self._echo and echo is not False: - log_debug('Set |{setting}|: "{value}" (str list, {status})'.format( - setting=setting, - value=value, - status=error if error else 'success' - )) + self.log_debug('Set |{setting}|: "{value}" (str list, {status})' + .format(setting=setting, + value=value, + status=error if error else 'success')) return not error diff --git a/resources/lib/youtube_plugin/kodion/sql_store/storage.py b/resources/lib/youtube_plugin/kodion/sql_store/storage.py index 1b49ec05e..099b22509 100644 --- a/resources/lib/youtube_plugin/kodion/sql_store/storage.py +++ b/resources/lib/youtube_plugin/kodion/sql_store/storage.py @@ -17,7 +17,7 @@ from threading import Lock from traceback import format_stack -from ..logger import log_warning, log_error +from ..logger import Logger from ..utils.datetime_parser import fromtimestamp, since_epoch from ..utils.methods import make_dirs @@ -236,10 +236,10 @@ def _open(self): exc=exc, details=''.join(format_stack()) ) if isinstance(exc, sqlite3.OperationalError): - log_warning(msg) + Logger.log_warning(msg) time.sleep(0.1) else: - log_error(msg) + Logger.log_error(msg) return False else: @@ -313,10 +313,10 @@ def _execute(cursor, query, values=None, many=False, script=False): exc=exc, details=''.join(format_stack()) ) if isinstance(exc, sqlite3.OperationalError): - log_warning(msg) + Logger.log_warning(msg) time.sleep(0.1) else: - log_error(msg) + Logger.log_error(msg) return [] return [] diff --git a/resources/lib/youtube_plugin/kodion/utils/datetime_parser.py b/resources/lib/youtube_plugin/kodion/utils/datetime_parser.py index b09097f73..8b8d7e346 100644 --- a/resources/lib/youtube_plugin/kodion/utils/datetime_parser.py +++ b/resources/lib/youtube_plugin/kodion/utils/datetime_parser.py @@ -17,7 +17,7 @@ from threading import Condition, Lock from ..exceptions import KodionException -from ..logger import log_error +from ..logger import Logger try: from datetime import timezone @@ -283,8 +283,8 @@ def strptime(datetime_str, fmt=None): if strptime.reloaded.acquire(False): _strptime = import_module('_strptime') modules['_strptime'] = _strptime - log_error('Python strptime bug workaround - ' - 'https://github.com/python/cpython/issues/71587') + Logger.log_error('Python strptime bug workaround - ' + 'https://github.com/python/cpython/issues/71587') strptime.reloaded.notify_all() strptime.reloaded.release() else: diff --git a/resources/lib/youtube_plugin/kodion/utils/methods.py b/resources/lib/youtube_plugin/kodion/utils/methods.py index 6847c5d97..029180cbb 100644 --- a/resources/lib/youtube_plugin/kodion/utils/methods.py +++ b/resources/lib/youtube_plugin/kodion/utils/methods.py @@ -18,7 +18,7 @@ from math import floor, log from ..compatibility import byte_string_type, string_type, xbmc, xbmcvfs -from ..logger import log_error +from ..logger import Logger __all__ = ( @@ -168,7 +168,7 @@ def make_dirs(path): if succeeded: return path - log_error('Failed to create directory: |{0}|'.format(path)) + Logger.log_error('Failed to create directory: |{0}|'.format(path)) return False @@ -188,7 +188,7 @@ def rm_dir(path): if succeeded: return True - log_error('Failed to remove directory: {0}'.format(path)) + Logger.log_error('Failed to remove directory: {0}'.format(path)) return False diff --git a/resources/lib/youtube_plugin/youtube/client/login_client.py b/resources/lib/youtube_plugin/youtube/client/login_client.py index 9b3549d08..23f1fdf2b 100644 --- a/resources/lib/youtube_plugin/youtube/client/login_client.py +++ b/resources/lib/youtube_plugin/youtube/client/login_client.py @@ -16,7 +16,6 @@ InvalidJSON, LoginException, ) -from ...kodion.logger import log_debug class LoginClient(YouTubeRequestClient): @@ -143,7 +142,7 @@ def refresh_token(self, token_type, refresh_token=None): id_end=client_id[-5:], secret_start=client_secret[:3], secret_end=client_secret[-3:])) - log_debug('Refresh token:{0}'.format(client)) + self.log_debug('Refresh token:{0}'.format(client)) json_data = self.request(self.TOKEN_URL, method='POST', @@ -193,7 +192,7 @@ def request_access_token(self, token_type, code=None): id_end=client_id[-5:], secret_start=client_secret[:3], secret_end=client_secret[-3:])) - log_debug('Requesting access token:{0}'.format(client)) + self.log_debug('Requesting access token:{0}'.format(client)) json_data = self.request(self.TOKEN_URL, method='POST', @@ -236,7 +235,7 @@ def request_device_and_user_code(self, token_type): .format(config_type=config_type, id_start=client_id[:3], id_end=client_id[-5:])) - log_debug('Requesting device and user code:{0}'.format(client)) + self.log_debug('Requesting device and user code:{0}'.format(client)) json_data = self.request(self.DEVICE_CODE_URL, method='POST', diff --git a/resources/lib/youtube_plugin/youtube/helper/ratebypass/ratebypass.py b/resources/lib/youtube_plugin/youtube/helper/ratebypass/ratebypass.py index d5c4e7473..876d6b43a 100644 --- a/resources/lib/youtube_plugin/youtube/helper/ratebypass/ratebypass.py +++ b/resources/lib/youtube_plugin/youtube/helper/ratebypass/ratebypass.py @@ -14,9 +14,9 @@ import re try: - from ....kodion import logger + from ....kodion.logger import Logger except: - class logger(object): + class Logger(object): @staticmethod def log_debug(txt): print(txt) @@ -259,17 +259,17 @@ def get_throttling_function_code(js): # This pattern is only present in the throttling function code. fiduciary_index = js.find('enhanced_except_') if fiduciary_index == -1: - logger.log_debug('ratebypass: fiduciary_index not found') + Logger.log_debug('ratebypass: fiduciary_index not found') return None start_index = js.rfind('=function(', 0, fiduciary_index) if start_index == -1: - logger.log_debug('ratebypass: function code start not found') + Logger.log_debug('ratebypass: function code start not found') return None end_index = js.find('};', fiduciary_index) if end_index == -1: - logger.log_debug('ratebypass: function code end not found') + Logger.log_debug('ratebypass: function code end not found') return None return js[start_index:end_index].replace('\n', '') @@ -294,7 +294,7 @@ def get_throttling_plan_gen(raw_code): plan_start_pattern = 'try{' plan_start_index = raw_code.find(plan_start_pattern) if plan_start_index == -1: - logger.log_debug('ratebypass: command block start not found') + Logger.log_debug('ratebypass: command block start not found') raise Exception() else: # Skip the whole start pattern, it's not needed. @@ -302,7 +302,7 @@ def get_throttling_plan_gen(raw_code): plan_end_index = raw_code.find('}', plan_start_index) if plan_end_index == -1: - logger.log_debug('ratebypass: command block end not found') + Logger.log_debug('ratebypass: command block end not found') raise Exception() plan_code = raw_code[plan_start_index:plan_end_index] @@ -365,14 +365,14 @@ def get_throttling_function_array(cls, mutable_n_list, raw_code): array_start_pattern = ",c=[" array_start_index = raw_code.find(array_start_pattern) if array_start_index == -1: - logger.log_debug('ratebypass: "c" array pattern not found') + Logger.log_debug('ratebypass: "c" array pattern not found') raise Exception() else: array_start_index += len(array_start_pattern) array_end_index = raw_code.rfind('];') if array_end_index == -1: - logger.log_debug('ratebypass: "c" array end not found') + Logger.log_debug('ratebypass: "c" array end not found') raise Exception() array_code = raw_code[array_start_index:array_end_index] @@ -404,7 +404,7 @@ def get_throttling_function_array(cls, mutable_n_list, raw_code): found = True break else: - logger.log_debug('ratebypass: mapping function not yet ' + Logger.log_debug('ratebypass: mapping function not yet ' 'listed: {unknown}'.format(unknown=el)) if found: continue @@ -428,7 +428,7 @@ def calculate_n(self, mutable_n_list): video stream URL. """ if self.calculated_n: - logger.log_debug('`n` already calculated: {calculated_n}. returning early...' + Logger.log_debug('`n` already calculated: {calculated_n}. returning early...' .format(calculated_n=self.calculated_n)) return self.calculated_n @@ -436,7 +436,7 @@ def calculate_n(self, mutable_n_list): return None initial_n_string = ''.join(mutable_n_list) - logger.log_debug('Attempting to calculate `n` from initial: {initial_n}' + Logger.log_debug('Attempting to calculate `n` from initial: {initial_n}' .format(initial_n=initial_n_string)) # For each step in the plan, get the first item of the step as the @@ -449,8 +449,8 @@ def calculate_n(self, mutable_n_list): for step in self.get_throttling_plan_gen(self.throttling_function_code): curr_func = throttling_array[int(step[0])] if not callable(curr_func): - logger.log_debug('{curr_func} is not callable.'.format(curr_func=curr_func)) - logger.log_debug('Throttling array:\n{throttling_array}\n' + Logger.log_debug('{curr_func} is not callable.'.format(curr_func=curr_func)) + Logger.log_debug('Throttling array:\n{throttling_array}\n' .format(throttling_array=throttling_array)) return None @@ -462,10 +462,10 @@ def calculate_n(self, mutable_n_list): second_arg = throttling_array[int(step[2])] curr_func(first_arg, second_arg) except: - logger.log_debug('Error calculating new `n`') + Logger.log_debug('Error calculating new `n`') return None self.calculated_n = ''.join(mutable_n_list) - logger.log_debug('Calculated `n`: {calculated_n}' + Logger.log_debug('Calculated `n`: {calculated_n}' .format(calculated_n=self.calculated_n)) return self.calculated_n diff --git a/resources/settings.xml b/resources/settings.xml index 3d27f3270..d11565eb7 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -593,7 +593,7 @@ - + 0 false @@ -647,7 +647,7 @@ - + 0 true @@ -721,7 +721,7 @@ - + 0 true @@ -757,7 +757,7 @@ - + 0 true @@ -857,7 +857,7 @@ - + 0 @@ -917,7 +917,7 @@ - + 0 90 @@ -941,7 +941,7 @@ - + 0 true @@ -1057,7 +1057,7 @@ - + 0 0.0.0.0 @@ -1110,6 +1110,13 @@ + + + 0 + false + + +