2021-04-03 00:07:35 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
Utility functions to interact easily with Kodi
|
|
|
|
|
|
|
|
Copyright (C) 2021 Thomas Bétous
|
|
|
|
|
|
|
|
SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
See LICENSE.txt for more information.
|
|
|
|
"""
|
2021-04-22 22:48:20 +02:00
|
|
|
try:
|
|
|
|
# Python 3.x
|
|
|
|
from urllib.parse import parse_qsl
|
|
|
|
except ImportError:
|
|
|
|
# Python 2.x
|
|
|
|
from urlparse import parse_qsl
|
|
|
|
|
|
|
|
from requests.compat import urlencode
|
|
|
|
|
2021-04-11 23:51:35 +02:00
|
|
|
import xbmc # Kodistubs for Leia is not compatible with python3 / pylint: disable=syntax-error
|
2021-04-11 10:44:18 +02:00
|
|
|
import xbmcaddon
|
2021-04-11 23:51:35 +02:00
|
|
|
import xbmcgui # Kodistubs for Leia is not compatible with python3 / pylint: disable=syntax-error
|
2021-04-22 22:48:20 +02:00
|
|
|
import xbmcplugin
|
2021-04-03 00:07:35 +02:00
|
|
|
|
|
|
|
|
2021-04-22 22:48:20 +02:00
|
|
|
class KodiUtils:
|
|
|
|
"""Utility class to call Kodi APIs"""
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
"""Initialize the object with information about the add-on"""
|
|
|
|
self.addon_name = xbmcaddon.Addon().getAddonInfo("name")
|
|
|
|
self.addon_id = xbmcaddon.Addon().getAddonInfo("id")
|
|
|
|
|
|
|
|
# Prepare other attributes that will be initialized with sys.argv
|
|
|
|
self.addon_url = ""
|
|
|
|
self.addon_handle = 0
|
|
|
|
self.addon_parameters = ""
|
|
|
|
|
|
|
|
def build_kodi_url(self, parameters):
|
|
|
|
"""Build a Kodi URL based on the parameters.
|
|
|
|
|
|
|
|
This URL will be used to call the add-on with the expected parameters.
|
|
|
|
|
|
|
|
:param dict parameters: The parameters that will be encoded in the URL
|
|
|
|
"""
|
|
|
|
|
|
|
|
return "{}?{}".format(self.addon_url, urlencode(parameters))
|
|
|
|
|
|
|
|
def create_items_in_ui(self, items_info):
|
|
|
|
"""Create items in Kodi UI
|
|
|
|
|
|
|
|
:param list items_info: A list of dict containing all the required
|
|
|
|
information to create the items (i.e. the return value of the method
|
|
|
|
generate_item_info)
|
|
|
|
"""
|
|
|
|
# Tell Kodi to use the "video" viewtypes
|
|
|
|
xbmcplugin.setContent(handle=self.addon_handle, content="videos")
|
|
|
|
|
|
|
|
list_of_items = []
|
|
|
|
|
|
|
|
for info in items_info:
|
|
|
|
# Create the ListItem object
|
|
|
|
list_item = xbmcgui.ListItem(label=info["name"])
|
|
|
|
|
|
|
|
# Add the general info of the item
|
|
|
|
list_item.setInfo("video", info["info"])
|
|
|
|
|
|
|
|
# Add the art info of the item
|
|
|
|
list_item.setArt(info["art"])
|
|
|
|
|
|
|
|
if not info["is_folder"]:
|
|
|
|
list_item.setProperty("IsPlayable", "true")
|
|
|
|
|
|
|
|
# Add to the list the tuple expected by addDirectoryItems
|
|
|
|
list_of_items.append((info["url"], list_item, info["is_folder"]))
|
|
|
|
|
|
|
|
# Create the items
|
|
|
|
xbmcplugin.addDirectoryItems(
|
|
|
|
handle=self.addon_handle,
|
|
|
|
items=list_of_items,
|
|
|
|
totalItems=len(list_of_items)
|
|
|
|
)
|
|
|
|
|
|
|
|
# Terminate the items creation
|
|
|
|
xbmcplugin.endOfDirectory(self.addon_handle)
|
|
|
|
|
|
|
|
def debug(self, message, prefix=None):
|
|
|
|
"""Log a message in Kodi's log with the level xbmc.LOGDEBUG
|
|
|
|
|
|
|
|
The message will be prefixed with the prefix passed as argument or with
|
|
|
|
the name of the add-on.
|
|
|
|
|
|
|
|
:param str message: Message to log
|
|
|
|
:param str prefix: String to prefix the message with
|
|
|
|
"""
|
|
|
|
if not prefix:
|
|
|
|
prefix = self.addon_name
|
|
|
|
|
|
|
|
xbmc.log("[{}] {}".format(prefix, message), xbmc.LOGDEBUG)
|
|
|
|
|
|
|
|
def generate_item_info(self, name, url, is_folder=True, thumbnail="",
|
|
|
|
aired="", duration=0, plot="",):
|
|
|
|
"""Return all the information required to create an item in Kodi UI
|
|
|
|
|
|
|
|
This function makes the creation of an item easier: it allows to pass
|
|
|
|
to the function only the known information about an item, and it will
|
|
|
|
return a dict with all the keys expected by create_items_in_ui
|
|
|
|
correctly initialized (including the ones that were not passed).
|
|
|
|
|
|
|
|
:param str name: Name of the item
|
|
|
|
:param str url: URL to reach when the item is used
|
|
|
|
:param bool is_folder: Whether the item is a folder or is playable
|
|
|
|
:param <other>: The other parameters are the ones expected by
|
|
|
|
ListItem.setInfo() and ListItem.setArt()
|
|
|
|
:return: Information required to create the item in Kodi UI
|
|
|
|
:rtype: dict
|
|
|
|
"""
|
|
|
|
return {
|
|
|
|
"name": name,
|
|
|
|
"url": url,
|
|
|
|
"is_folder": is_folder,
|
|
|
|
"art": {
|
|
|
|
"thumb": thumbnail,
|
|
|
|
},
|
|
|
|
"info": {
|
|
|
|
"aired": aired,
|
|
|
|
"duration": duration,
|
|
|
|
"plot": plot,
|
|
|
|
"title": name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def get_run_parameters(self):
|
|
|
|
"""Return the parameter the add-on was called with
|
|
|
|
|
|
|
|
The parameters are read in the method "update_call_info"
|
|
|
|
|
|
|
|
:return: The extracted parameters
|
|
|
|
:rtype: dict
|
|
|
|
"""
|
|
|
|
# The first character ("?") is skipped
|
|
|
|
return dict(parse_qsl(self.addon_parameters[1:]))
|
|
|
|
|
|
|
|
def get_property(self, name):
|
|
|
|
"""Retrieve the value of a window property related to the add-on
|
|
|
|
|
|
|
|
:param str name: Name of the property which value will be retrieved (the
|
|
|
|
actual name of the property is prefixed with "peertube_")
|
|
|
|
:return: Value of the window property
|
|
|
|
:rtype: str
|
|
|
|
"""
|
|
|
|
return xbmcgui.Window(10000).getProperty("peertube_{}".format(name))
|
|
|
|
|
|
|
|
def get_setting(self, setting_name):
|
|
|
|
"""Retrieve the value of a setting
|
|
|
|
|
|
|
|
:param str setting_name: Name of the setting
|
|
|
|
:return: Value of the setting named setting_name
|
|
|
|
:rtype: str
|
|
|
|
"""
|
|
|
|
return xbmcaddon.Addon().getSetting(setting_name)
|
|
|
|
|
|
|
|
def notif_error(self, title, message):
|
|
|
|
"""Display a notification with the error icon
|
|
|
|
|
|
|
|
:param str title: Title of the notification
|
|
|
|
:param str message: Message of the notification
|
|
|
|
"""
|
|
|
|
xbmcgui.Dialog().notification(heading=title,
|
|
|
|
message=message,
|
|
|
|
icon=xbmcgui.NOTIFICATION_ERROR)
|
|
|
|
|
|
|
|
def notif_info(self, title, message):
|
|
|
|
"""Display a notification with the info icon
|
|
|
|
|
|
|
|
:param str title: Title of the notification
|
|
|
|
:param str message: Message of the notification
|
|
|
|
"""
|
|
|
|
xbmcgui.Dialog().notification(heading=title,
|
|
|
|
message=message,
|
|
|
|
icon=xbmcgui.NOTIFICATION_INFO)
|
|
|
|
|
|
|
|
def notif_warning(self, title, message):
|
|
|
|
"""Display a notification with the warning icon
|
|
|
|
|
|
|
|
:param str title: Title of the notification
|
|
|
|
:param str message: Message of the notification
|
|
|
|
"""
|
|
|
|
xbmcgui.Dialog().notification(heading=title,
|
|
|
|
message=message,
|
|
|
|
icon=xbmcgui.NOTIFICATION_WARNING)
|
|
|
|
|
|
|
|
def open_dialog(self, title, message):
|
|
|
|
"""Open a dialog box with an "OK" button
|
|
|
|
|
|
|
|
:param str title: Title of the box
|
|
|
|
:param str message: Message in the box
|
|
|
|
"""
|
|
|
|
xbmcgui.Dialog().ok(heading=title, line1=message)
|
|
|
|
|
|
|
|
def open_input_box(self, title):
|
|
|
|
"""Open a box for the user to input alphanumeric data
|
|
|
|
|
|
|
|
:param str title: Title of the box
|
|
|
|
:return: Entered data or an empty string
|
|
|
|
:rtype: str
|
|
|
|
"""
|
|
|
|
return xbmcgui.Dialog().input(heading=title,
|
|
|
|
type=xbmcgui.INPUT_ALPHANUM)
|
|
|
|
|
|
|
|
def play(self, url):
|
|
|
|
"""Play the media behind the URL
|
|
|
|
|
|
|
|
:param str url: URL of the media to play
|
|
|
|
"""
|
|
|
|
xbmcplugin.setResolvedUrl(handle=self.addon_handle,
|
|
|
|
succeeded=True,
|
|
|
|
listitem=xbmcgui.ListItem(path=url))
|
|
|
|
|
|
|
|
def set_property(self, name, value):
|
|
|
|
"""Modify the value of a window property related to the add-on
|
|
|
|
|
|
|
|
:param str name: Name of the property which value will be modified (the
|
|
|
|
actual name of the property is prefixed with "peertube_")
|
|
|
|
:param str value: New value of the property
|
|
|
|
"""
|
|
|
|
xbmcgui.Window(10000).setProperty("peertube_{}".format(name), value)
|
|
|
|
|
|
|
|
def set_setting(self, setting_name, setting_value):
|
|
|
|
"""Modify the value of a setting
|
|
|
|
|
|
|
|
:param str setting_name: Name of the setting
|
|
|
|
:param str setting_value: New value of the setting
|
|
|
|
"""
|
|
|
|
xbmcaddon.Addon().setSetting(setting_name, setting_value)
|
|
|
|
|
|
|
|
def sleep(self, time_us):
|
|
|
|
"""Sleep for some micro seconds
|
|
|
|
|
|
|
|
:param int time_us: Sleep time in micro seconds
|
|
|
|
"""
|
|
|
|
xbmc.sleep(time_us)
|
|
|
|
|
|
|
|
def update_call_info(self, argv):
|
|
|
|
"""Update the attributes related to the current call of the add-on
|
|
|
|
|
|
|
|
:param list argv: System arguments
|
|
|
|
"""
|
|
|
|
self.addon_url = argv[0]
|
|
|
|
self.addon_handle = int(argv[1])
|
|
|
|
self.addon_parameters = argv[2]
|
|
|
|
|
|
|
|
kodi = KodiUtils()
|