Skip to content

Commit

Permalink
[script.module.bossanova808] 1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
bossanova808 committed Oct 9, 2024
1 parent a0dccdb commit 7a1b35d
Show file tree
Hide file tree
Showing 10 changed files with 1,136 additions and 0 deletions.
674 changes: 674 additions & 0 deletions script.module.bossanova808/LICENSE.txt

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions script.module.bossanova808/README.md
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








18 changes: 18 additions & 0 deletions script.module.bossanova808/addon.xml
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>
3 changes: 3 additions & 0 deletions script.module.bossanova808/changelog.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
v0.0.1
Alpha pre-release

Binary file added script.module.bossanova808/resources/icon.png
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 script.module.bossanova808/resources/lib/bossanova808/constants.py
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)
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# coding: utf-8

# (c) Roman Miroshnychenko <roman1972@gmail.com> 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 script.module.bossanova808/resources/lib/bossanova808/logger.py
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 script.module.bossanova808/resources/lib/bossanova808/notify.py
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)
Loading

0 comments on commit 7a1b35d

Please sign in to comment.