-
Notifications
You must be signed in to change notification settings - Fork 307
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
bossanova808
committed
Oct 9, 2024
1 parent
a0dccdb
commit 7a1b35d
Showing
10 changed files
with
1,136 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
|
||
Bossanova808 Common Code for Kodi Addons | ||
=================================== | ||
|
||
_script.module.bossanova808_ | ||
|
||
[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/bossanova808) | ||
|
||
|
||
Common code for all bossanova808 Kodi addons, including: | ||
|
||
**Available from the Kodi Official Repository:** | ||
|
||
* OzWeather | ||
* Unpause Jumpback | ||
* Playback Resumer | ||
* Check Previous Episode | ||
* Caber Toss | ||
|
||
|
||
**Available from the [Bossanova808 Repository](https://github.com/bossanova808/repository.bossanova808):** | ||
|
||
* OzWeather Skin Patcher | ||
* YoctoDisplay | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<addon id="script.module.bossanova808" name="Bossanova808 Dependencies" version="1.0.0" provider-name="bossanova808"> | ||
<requires> | ||
<import addon="xbmc.python" version="3.0.0"/> | ||
</requires> | ||
<extension point="xbmc.python.module" library="resources/lib" /> | ||
<extension point="xbmc.addon.metadata"> | ||
<description lang="en_GB">Common code needed by bossanova808 addons</description> | ||
<platform>all</platform> | ||
<license>GPL-3.0-only</license> | ||
<website>https://github.com/bossanova808/script.module.bossanova808</website> | ||
<source>https://github.com/bossanova808/script.module.bossanova808</source> | ||
<news>v1.0.0 Iniial release</news> | ||
<assets> | ||
<icon>resources/icon.png</icon> | ||
</assets> | ||
</extension> | ||
</addon> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
v0.0.1 | ||
Alpha pre-release | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions
26
script.module.bossanova808/resources/lib/bossanova808/constants.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import sys | ||
import xbmc | ||
import xbmcvfs | ||
import xbmcgui | ||
import xbmcaddon | ||
|
||
""" Just a bunch of very handy Kodi constants """ | ||
|
||
ADDON = xbmcaddon.Addon() | ||
ADDON_NAME = ADDON.getAddonInfo('name') | ||
ADDON_ID = ADDON.getAddonInfo('id') | ||
ADDON_ICON = ADDON.getAddonInfo('icon') | ||
ADDON_AUTHOR = ADDON.getAddonInfo('author') | ||
ADDON_VERSION = ADDON.getAddonInfo('version') | ||
ADDON_ARGUMENTS = f'{sys.argv}' | ||
CWD = ADDON.getAddonInfo('path') | ||
LANGUAGE = ADDON.getLocalizedString | ||
PROFILE = xbmcvfs.translatePath(ADDON.getAddonInfo('profile')) | ||
LOG_PATH = xbmcvfs.translatePath('special://logpath') | ||
KODI_VERSION = xbmc.getInfoLabel('System.BuildVersion') | ||
KODI_VERSION_INT = int(KODI_VERSION.split(".")[0]) | ||
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" | ||
HOME_WINDOW = xbmcgui.Window(10000) | ||
WEATHER_WINDOW = xbmcgui.Window(12600) |
154 changes: 154 additions & 0 deletions
154
script.module.bossanova808/resources/lib/bossanova808/exception_logger.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
# coding: utf-8 | ||
|
||
# (c) Roman Miroshnychenko <[email protected]> 2020 | ||
# Retrieved from: | ||
# https://github.com/thetvdb/metadata.tvshows.thetvdb.com.v4.python/blob/master/metadata.tvshows.thetvdb.com.v4.python/resources/lib/exception_logger.py | ||
# (Thanks Roman! - Modified by bossanova808 as needed...) | ||
# | ||
# 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 .constants import * | ||
from .logger 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 |
65 changes: 65 additions & 0 deletions
65
script.module.bossanova808/resources/lib/bossanova808/logger.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import xbmc | ||
from .constants import * | ||
|
||
|
||
class Logger: | ||
|
||
@staticmethod | ||
def log(message, level=xbmc.LOGDEBUG): | ||
""" | ||
Log a message to the Kodi log file. | ||
If we're unit testing a module outside Kodi, print to the console instead. | ||
:param message: the message to log | ||
:param level: the kodi log level to log at, default xbmc.LOGDEBUG | ||
:return: | ||
""" | ||
# | ||
if xbmc.getUserAgent(): | ||
xbmc.log(f'### {ADDON_NAME} {ADDON_VERSION}: {str(message)}', level) | ||
else: | ||
print(str(message)) | ||
|
||
@staticmethod | ||
def info(message): | ||
""" | ||
Log a message to the Kodi log file at INFO level. | ||
:param message: the message to log | ||
:return: | ||
""" | ||
Logger.log(message, xbmc.LOGINFO) | ||
|
||
@staticmethod | ||
def warning(message): | ||
""" | ||
Log a message to the Kodi log file at WARNING level. | ||
:param message: the message to log | ||
:return: | ||
""" | ||
Logger.log(message, xbmc.LOGWARNING) | ||
|
||
@staticmethod | ||
def error(message): | ||
""" | ||
Log a message to the Kodi log file at ERROR level. | ||
:param message: the message to log | ||
:return: | ||
""" | ||
Logger.log(message, xbmc.LOGERROR) | ||
|
||
@staticmethod | ||
def debug(*messages): | ||
""" | ||
Log messages to the Kodi log file at DEBUG level. | ||
:param messages: the message(s) to log | ||
:return: | ||
""" | ||
for message in messages: | ||
Logger.log(message, xbmc.LOGDEBUG) | ||
|
57 changes: 57 additions & 0 deletions
57
script.module.bossanova808/resources/lib/bossanova808/notify.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import xbmcgui | ||
from .constants import * | ||
|
||
|
||
class Notify: | ||
|
||
@staticmethod | ||
def kodi_notification(message, duration=5000, icon=xbmcgui.NOTIFICATION_INFO): | ||
""" | ||
Send a custom notification to the user via the Kodi GUI | ||
:param message: the message to send | ||
:param duration: time to display notification in milliseconds, default 5000 | ||
:param icon: xbmcgui.NOTIFICATION_INFO (default), xbmcgui.NOTIFICATION_WARNING, or xbmcgui.NOTIFICATION_ERROR (or custom icon) | ||
:return: None | ||
""" | ||
dialog = xbmcgui.Dialog() | ||
|
||
dialog.notification(heading=ADDON_NAME, | ||
message=message, | ||
icon=icon, | ||
time=duration) | ||
|
||
@staticmethod | ||
def info(message, duration=5000): | ||
""" | ||
Send an info level notification to the user via the Kodi GUI | ||
:param message: the message to display | ||
:param duration: the duration to show the message, default 5000ms | ||
:return: | ||
""" | ||
Notify.kodi_notification(message, duration, xbmcgui.NOTIFICATION_INFO) | ||
|
||
@staticmethod | ||
def warning(message, duration=5000): | ||
""" | ||
Send a warning notification to the user via the Kodi GUI | ||
:param message: the message to display | ||
:param duration: the duration to show the message, default 5000ms | ||
:return: | ||
""" | ||
Notify.kodi_notification(message, duration, xbmcgui.NOTIFICATION_WARNING) | ||
|
||
@staticmethod | ||
def error(message, duration=5000): | ||
""" | ||
Send an error level notification to the user via the Kodi GUI | ||
:param message: the message to display | ||
:param duration: the duration to show the message, default 5000ms | ||
:return: | ||
""" | ||
Notify.kodi_notification(message, duration, xbmcgui.NOTIFICATION_ERROR) |
Oops, something went wrong.