Updated kodi settings on Lenovo

This commit is contained in:
2026-03-22 22:28:43 +01:00
parent 725dfa7157
commit 32b5a81da6
10925 changed files with 575678 additions and 5511 deletions

View File

@@ -0,0 +1,150 @@
# coding: utf-8
# (c) Roman Miroshnychenko <roman1972@gmail.com> 2020
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""Exception logger with extended diagnostic info"""
import inspect
import sys
from contextlib import contextmanager
from platform import uname
from pprint import pformat
from typing import Text, Callable, Generator
import xbmc
from .utils import logger
def _format_vars(variables):
# type: (dict) -> Text
"""
Format variables dictionary
:param variables: variables dict
:return: formatted string with sorted ``var = val`` pairs
"""
var_list = [(var, val) for var, val in variables.items()
if not (var.startswith('__') or var.endswith('__'))]
var_list.sort(key=lambda i: i[0])
lines = []
for var, val in var_list:
lines.append('{} = {}'.format(var, pformat(val)))
return '\n'.join(lines)
def _format_code_context(frame_info):
# type: (tuple) -> Text
context = ''
if frame_info[4] is not None:
for i, line in enumerate(frame_info[4], frame_info[2] - frame_info[5]):
if i == frame_info[2]:
context += '{}:>{}'.format(str(i).rjust(5), line)
else:
context += '{}: {}'.format(str(i).rjust(5), line)
return context
FRAME_INFO_TEMPLATE = """File:
{file_path}:{lineno}
----------------------------------------------------------------------------------------------------
Code context:
{code_context}
----------------------------------------------------------------------------------------------------
Local variables:
{local_vars}
====================================================================================================
"""
def _format_frame_info(frame_info):
# type: (tuple) -> Text
return FRAME_INFO_TEMPLATE.format(
file_path=frame_info[1],
lineno=frame_info[2],
code_context=_format_code_context(frame_info),
local_vars=_format_vars(frame_info[0].f_locals)
)
EXCEPTION_TEMPLATE = """
*********************************** Unhandled exception detected ***********************************
####################################################################################################
Diagnostic info
----------------------------------------------------------------------------------------------------
Exception type : {exc_type}
Exception value : {exc}
System info : {system_info}
Python version : {python_version}
Kodi version : {kodi_version}
sys.argv : {sys_argv}
----------------------------------------------------------------------------------------------------
sys.path:
{sys_path}
####################################################################################################
Stack Trace
====================================================================================================
{stack_trace}
************************************* End of diagnostic info ***************************************
"""
@contextmanager
def log_exception(logger_func=logger.error):
# type: (Callable[[Text], None]) -> Generator[None, None, None]
"""
Diagnostic helper context manager
It controls execution within its context and writes extended
diagnostic info to the Kodi log if an unhandled exception
happens within the context. The info includes the following items:
- System info
- Python version
- Kodi version
- Module path.
- Stack trace including:
* File path and line number where the exception happened
* Code fragment where the exception has happened.
* Local variables at the moment of the exception.
After logging the diagnostic info the exception is re-raised.
Example::
with debug_exception():
# Some risky code
raise RuntimeError('Fatal error!')
:param logger_func: logger function that accepts a single argument
that is a log message.
"""
try:
yield
except Exception as exc:
stack_trace = ''
for frame_info in inspect.trace(5):
stack_trace += _format_frame_info(frame_info)
message = EXCEPTION_TEMPLATE.format(
exc_type=exc.__class__.__name__,
exc=exc,
system_info=uname(),
python_version=sys.version.replace('\n', ' '),
kodi_version=xbmc.getInfoLabel('System.BuildVersion'),
sys_argv=pformat(sys.argv),
sys_path=pformat(sys.path),
stack_trace=stack_trace
)
logger_func(message)
raise exc