simpleplugin¶
SimplePlugin micro-framework for Kodi content plugins
Author: Roman Miroshnychenko aka Roman V.M.
License: GPL v.3
Classes
Addon ([id_]) |
Base addon class |
Params (**kwargs) |
A class that stores parsed plugin call parameters |
Plugin ([id_]) |
Plugin class with URL query string routing. |
RoutedPlugin ([id_]) |
Plugin class that implements “pretty URL” routing similar to Flask and Bottle web-frameworks |
Storage (storage_dir[, filename]) |
Persistent storage for arbitrary data with a dictionary-like interface |
MemStorage (storage_id) |
In-memory storage with dict-like interface |
Exceptions
SimplePluginError |
Custom exception |
-
exception
simpleplugin.
SimplePluginError
[source]¶ Bases:
exceptions.Exception
Custom exception
-
simpleplugin.
py2_encode
(s, encoding=u'utf-8')[source]¶ Encode Python 2
unicode
tostr
In Python 3 the string is not changed.
-
simpleplugin.
py2_decode
(s, encoding=u'utf-8')[source]¶ Decode Python 2
str
tounicode
In Python 3 the string is not changed.
-
simpleplugin.
log_exception
(*args, **kwds)[source]¶ 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
- Kodi version
- Module path.
- Code fragment where the exception has happened.
- Global variables.
- Local variables.
After logging the diagnostic info the exception is re-raised.
Example:
with log_exception(): # Some risky code raise RuntimeError('Fatal error!')
Parameters: logger – logger function which must accept a single argument which is a log message. By default it is xbmc.log()
withERROR
level.
-
class
simpleplugin.
Params
(**kwargs)[source]¶ Bases:
future.types.newdict.newdict
A class that stores parsed plugin call parameters
Parameters can be accessed both through
dict
keys and instance properties.Note
For a missing parameter an instance property returns
None
.Example:
@plugin.action('foo') def action(params): foo = params['foo'] # Access by key bar = params.bar # Access through property. Both variants are equal
-
class
simpleplugin.
Storage
(storage_dir, filename='storage.pcl')[source]¶ Bases:
_abcoll.MutableMapping
Persistent storage for arbitrary data with a dictionary-like interface
It is designed as a context manager and better be used with ‘with’ statement.
Parameters: Usage:
with Storage('/foo/bar/storage/') as storage: storage['key1'] = value1 value2 = storage['key2']
Note
After exiting
with
block aStorage
instance is invalidated. Storage contents are saved to disk only for a new storage or if the contents have been changed.
-
class
simpleplugin.
MemStorage
(storage_id)[source]¶ Bases:
_abcoll.MutableMapping
In-memory storage with dict-like interface
The data is stored in the Kodi core so contents of a MemStorage instance with the same ID can be shared between different Python processes.
Note
Keys are case-insensitive
Warning
MemStorage
does not allow to modify mutable objects in place! You need to assign them to variables first, modify and store them back to a MemStorage instance.Example:
storage = MemStorage('foo') some_list = storage['bar'] some_list.append('spam') storage['bar'] = some_list
Parameters:
-
class
simpleplugin.
Addon
(id_=u'')[source]¶ Bases:
future.types.newobject.newobject
Base addon class
Provides access to basic addon parameters
Parameters: id (str) – addon id, e.g. ‘plugin.video.foo’ (optional) -
addon
¶ Kodi Addon instance that represents this Addon
Returns: Addon instance Return type: xbmcaddon.Addon
-
path
¶ Addon path
Returns: path to the addon folder Return type: unicode
Addon author
Returns: addon author Return type: str
-
get_localized_string
(id_)[source]¶ Get localized UI string
Parameters: id (int) – UI string ID Returns: UI string in the current language Return type: unicode
-
get_setting
(id_, convert=True)[source]¶ Get addon setting
If
convert=True
, ‘bool’ settings are converted to Pythonbool
values, and numeric strings to Pythonlong
orfloat
depending on their format.Note
Settings can also be read via
Addon
instance poperties named as the respective settings. I.e.addon.foo
is equal toaddon.get_setting('foo')
.Parameters: Returns: setting value
-
set_setting
(id_, value)[source]¶ Set addon setting
Python
bool
type are converted to'true'
or'false'
Non-string/non-unicode values are converted to strings.Warning
Setting values via
Addon
instance properties is not supported! Values can only be set usingAddon.set_setting()
method.Parameters: - id (str) – setting ID
- value – setting value
-
log_notice
(message)[source]¶ Add NOTICE message to the Kodi log
Parameters: message (str) – message to write to the Kodi log
-
log_warning
(message)[source]¶ Add WARNING message to the Kodi log
Parameters: message (str) – message to write to the Kodi log
-
log_error
(message)[source]¶ Add ERROR message to the Kodi log
Parameters: message (str) – message to write to the Kodi log
-
log_debug
(message)[source]¶ Add debug message to the Kodi log
Parameters: message (str) – message to write to the Kodi log
-
get_storage
(filename=u'storage.pcl')[source]¶ Get a persistent
Storage
instance for storing arbitrary values between addon calls.A
Storage
instance can be used as a context manager.Example:
with plugin.get_storage() as storage: storage['param1'] = value1 value2 = storage['param2']
Parameters: filename (str) – the name of a storage file (optional) Returns: Storage object Return type: Storage
-
get_mem_storage
(storage_id=u'', window_id=10000)[source]¶ Creates an in-memory storage for this addon with
dict
-like interfaceThe storage can store picklable Python objects as long as Kodi is running and storage contents can be shared between Python processes. Different addons have separate storages, so storages with the same names created with this method do not conflict.
Example:
addon = Addon() storage = addon.get_mem_storage() foo = storage['foo'] storage['bar'] = bar
Parameters: Returns: in-memory storage for this addon
Return type:
-
cached
(duration=10)[source]¶ Cached decorator
Used to cache function return data
Usage:
@plugin.cached(30) def my_func(*args, **kwargs): # Do some stuff return value
Parameters: duration (int) – caching duration in min (positive values only) Raises: ValueError – if duration is zero or negative
-
mem_cached
(duration=10)[source]¶ In-memory cache decorator
Usage:
@plugin.mem_cached(30) def my_func(*args, **kwargs): # Do some stuff return value
Parameters: duration (int) – caching duration in min (positive values only) Raises: ValueError – if duration is zero or negative
-
gettext
(ui_string)[source]¶ Get a translated UI string from addon localization files.
This function emulates GNU Gettext for more convenient access to localized addon UI strings. To reduce typing this method object can be assigned to a
_
(single underscore) variable.For using gettext emulation
Addon.initialize_gettext()
method needs to be called first. See documentation for that method for more info about Gettext emulation.Parameters: ui_string (str) – a UI string from English strings.po
.Returns: a UI string from translated strings.po
.Return type: unicode Raises: SimplePluginError – if Addon.initialize_gettext()
wasn’t called first or if a string is not found in Englishstrings.po
.
-
initialize_gettext
()[source]¶ Initialize GNU gettext emulation in addon
Kodi localization system for addons is not very convenient because you need to operate with numeric string codes instead of UI strings themselves which reduces code readability and may lead to errors. The
Addon
class provides facilities for emulating GNU Gettext localization system.This allows to use UI strings from addon’s English
strings.po
file instead of numeric codes to return localized strings from respective localized.po
files.This method returns
Addon.gettext()
method object that can be assigned to a short alias to reduce typing. Traditionally,_
(a single underscore) is used for this purpose.Example:
addon = simpleplugin.Addon() _ = addon.initialize_gettext() xbmcgui.Dialog().notification(_('Warning!'), _('Something happened'))
In the preceding example the notification strings will be replaced with localized versions if these strings are translated.
Returns: Addon.gettext()
method objectRaises: SimplePluginError – if the addon’s English strings.po
file is missing
-
-
class
simpleplugin.
Plugin
(id_=u'')[source]¶ Bases:
simpleplugin.Addon
Plugin class with URL query string routing.
It provides a simplified plugin call routing mechanism using URL query strings. A URL query string must contain “action” parameter that defines which function will be invoked during this plugin call.
Parameters: id (str) – plugin’s id, e.g. ‘plugin.video.foo’ (optional) -
static
get_params
(paramstring)[source]¶ Convert a URL-encoded paramstring to a Python dict
Parameters: paramstring (str) – URL-encoded paramstring Returns: parsed paramstring Return type: Params
-
get_url
(plugin_url=u'', **kwargs)[source]¶ Construct a callable URL for a virtual directory item
If plugin_url is empty, a current plugin URL is used. kwargs are converted to a URL-encoded string of plugin call parameters To call a plugin action, ‘action’ parameter must be used, if ‘action’ parameter is missing, then the plugin root action is called If the action is not added to
Plugin
actions,PluginError
will be raised.Parameters: - plugin_url (str) – plugin URL with trailing / (optional)
- kwargs – pairs of key=value items
Returns: a full plugin callback URL
Return type:
-
action
(name=None)[source]¶ Action decorator
Defines plugin callback action. If action’s name is not defined explicitly, then the action is named after the decorated function.
Warning
Action’s name must be unique.
A plugin must have at least one action named
'root'
implicitly or explicitly.Example:
# The action is implicitly named 'root' after the decorated function @plugin.action() def root(params): pass @plugin.action('foo') # The action name is set explicitly def foo_action(params): pass
Parameters: name (str) – action’s name (optional). Raises: SimplePluginError – if the action with such name is already defined.
-
run
()[source]¶ Run plugin
Raises: SimplePluginError – if unknown action string is provided.
-
static
-
class
simpleplugin.
RoutedPlugin
(id_=u'')[source]¶ Bases:
simpleplugin.Plugin
Plugin class that implements “pretty URL” routing similar to Flask and Bottle web-frameworks
Parameters: id (str) – plugin’s id, e.g. ‘plugin.video.foo’ (optional) -
url_for
(func_, *args, **kwargs)[source]¶ Build a URL for a plugin route
This method performs reverse resolving a plugin callback URL for the named route. If route’s name is not set explicitly, then the name of a decorated function is used as the name of the corresponding route. The method can optionally take positional args and kwargs. If any positional args are provided their values replace variable placeholders by position.
Warning
The number of positional args must not exceed the number of variable placeholders!
If any kwargs are provided their values replace variable placeholders by name. If the number of kwargs provided exceeds the number of variable placeholders, then the rest of the kwargs are added to the URL as a query string.
Note
All
unicode
arguments are encoded with UTF-8 encoding.Let’s assume that the ID of our plugin is
plugin.acme
. The following examples will show how to use this method to resolve callback URLs for this plugin.Example 1:
@plugin.route('/foo') def foo(): pass url = plugin.url_for('foo') # url = 'plugin://plugin.acme/foo'
Example 2:
@plugin.route('/foo/<param>') def foo(param): pass url = plugin.url_for('foo', param='bar') # url = 'plugin://plugin.acme/foo/bar'
Example 3:
plugin.route('/foo/<param>') def foo(param): pass url = plugin.url_for('foo', param='bar', ham='spam') # url = 'plugin://plugin.acme/foo/bar?ham=spam
Parameters: - func (str or types.FunctionType) – route’s name or a decorated function object.
- args – positional arguments.
- kwargs – keyword arguments.
Returns: full plugin call URL for the route.
Return type: Raises: simpleplugin.SimplePluginError – if a route with such name does not exist or on arguments mismatch.
-
get_url
(func_, *args, **kwargs)¶ Build a URL for a plugin route
This method performs reverse resolving a plugin callback URL for the named route. If route’s name is not set explicitly, then the name of a decorated function is used as the name of the corresponding route. The method can optionally take positional args and kwargs. If any positional args are provided their values replace variable placeholders by position.
Warning
The number of positional args must not exceed the number of variable placeholders!
If any kwargs are provided their values replace variable placeholders by name. If the number of kwargs provided exceeds the number of variable placeholders, then the rest of the kwargs are added to the URL as a query string.
Note
All
unicode
arguments are encoded with UTF-8 encoding.Let’s assume that the ID of our plugin is
plugin.acme
. The following examples will show how to use this method to resolve callback URLs for this plugin.Example 1:
@plugin.route('/foo') def foo(): pass url = plugin.url_for('foo') # url = 'plugin://plugin.acme/foo'
Example 2:
@plugin.route('/foo/<param>') def foo(param): pass url = plugin.url_for('foo', param='bar') # url = 'plugin://plugin.acme/foo/bar'
Example 3:
plugin.route('/foo/<param>') def foo(param): pass url = plugin.url_for('foo', param='bar', ham='spam') # url = 'plugin://plugin.acme/foo/bar?ham=spam
Parameters: - func (str or types.FunctionType) – route’s name or a decorated function object.
- args – positional arguments.
- kwargs – keyword arguments.
Returns: full plugin call URL for the route.
Return type: Raises: simpleplugin.SimplePluginError – if a route with such name does not exist or on arguments mismatch.
-
route
(pattern, name=None)[source]¶ Route decorator for plugin callback routes
The route decorator is used to define plugin callback routes similar to a URL routing mechanism in Flask and Bottle Python web-frameworks. The plugin routing mechanism calls decorated functions by matching a path in a plugin callback URL (passed as
sys.argv[0]
) to a route pattern. A route pattern must start with a forward slash/
. An end slash is optional. A plugin must have at least the root route with'/'
pattern. Bu default a route is named by the decorated function, but route’s name can be set explicitly by providing the 2nd optionalname
argument.Warning
Route names must be unique!
Example 1:
@plugin.route('/foo') def foo_function(): pass
In the preceding example
foo_function
will be called when the plugin is invoked withplugin://plugin.acme/foo/
callback URL. A route pattern can contain variable placeholders (marked with angular brackets<>
) that are used to pass arguments to a route function.Example 2:
@plugin.route('/foo/<param>') def foo_function(param): pass
In the preceding example the part of a callback path marked with
<param>
placeholder will be passed to the function as an argument. The name of a placeholder must be the same as the name of the corresponding parameter. By default arguments are passed as strings. Theint
andfloat
prefixes can be used to pass arguments asint
andfloat
numbers, for example<int:foo>
or<float:bar>
.Example 3:
@plugin.route('/add/<int:param1>/<int:param2>') def addition(param1, param2): sum = param1 + param2
A function can have multiple route decorators. In this case additional routes must have explicitly defined names. If a route has less variable placeholders than function parameters, “missing” function parameters must have default values.
Example 4:
@plugin.route('/foo/<param>', name='foo_route') @plugin.route('/bar') def some_function(param='spam'): # Do something
In the preceding example
some_function
can be called through 2 possible routes. If the function is called through the 1st route ('foo_route'
)<param>
value will be passed as an argument. The 2nd route will call the function with the default argument'spam'
because this route has no variable placeholders to pass arguments to the function. The order of theroute
decorators does not matter but each route must have a unique name.Note
A route pattern must start with a forward slash
/
and must not have a slash at the end.Parameters:
-