SimplePlugin micro-framework for Kodi content plugins - Roman_V_M - 2015-09-02
SimplePlugin micro-framework simplifies creating content plugins for Kodi. It was inspired by xbmcswift2 framework for the same purpose and has similar features like defining Kodi virtual folder contents using lists of dictionaries with item properties, persistent storage and cache decorator for functions.
Unfortunately, xbmcswift2 seems to have been abandoned by its author and does not support the newest features of the Kodi plugin API, so I've decided to create my own plugin micro-framework. Initially, it was used in my private projects, but now I've decided to make a public release.
A minimal example:
PHP Code: from simpleplugin import Plugin
plugin = Plugin()
# Free video sample is provided by www.vidsplay.com
# Define action via decorator @plugin.action() def root(params): """Root virtual folder""" # Create 1-item list with a link to subfolder item return [{'label': 'Subfolder', 'url': plugin.get_url(action='subfolder')}]
@plugin.action() def subfolder(params): """Virtual subfolder""" # Create 1-item list with a link to a playable video. return [{'label': 'Ocean Birds', 'thumb': 'http://www.vidsplay.com/vids/ocean_birds.jpg', 'url': plugin.get_url(action='play', url='http://www.vidsplay.com/vids/ocean_birds.mp4'), 'is_playable': True}]
@plugin.action() def play(params): """Play video""" # Return a string containing a playable video URL return params['url']
if __name__ == '__main__': plugin.run() # Start plugin
You will find more detailed info about SimplePlugin in the project documentation.
Links:
The latest release: https://github.com/romanvm/script.module.simpleplugin/releases/latest
Source code: https://github.com/romanvm/script.module.simpleplugin
An example SimplePlugin-based video plugin: https://github.com/romanvm/plugin.video.simpleplugin.example
License: GPL v.3.
RE: SimplePlugin micro-framework for Kodi content plugins - vl_maksime - 2017-02-23
Good evening.
When you plan to update this add-on in the official repositories?
RE: SimplePlugin micro-framework for Kodi content plugins - Roman_V_M - 2017-02-24
This is the very first post in this topic for more than a year, and you are like the 2nd or 3rd person who has asked me anything about this library via different channels. So I guess this library is used only by a couple of people except me and, to my knowledge, there are no addons depending on it in the official repo. So I have no plans to maintain it in the official repo and, in fact, want to remove that outdated version which is still there.
Those who want to use this library in their addons can download the latest version from GitHub.
RE: SimplePlugin micro-framework for Kodi content plugins - vl_maksime - 2017-02-24
In developing my addon, I would like to use addons from the official add-ons repository. To reduce the amount of redundant code, I decided to take your add-on. It's not difficult to add an addition to your repository.
Or you can advise some similar add-ons from the official repository?
RE: SimplePlugin micro-framework for Kodi content plugins - DarrenHill - 2017-02-24
The forum language is English only please
RE: SimplePlugin micro-framework for Kodi content plugins - vl_maksime - 2017-02-24
(2017-02-24, 16:49)DarrenHill Wrote: The forum language is English only please Message text changed on English
RE: SimplePlugin micro-framework for Kodi content plugins - Roman_V_M - 2017-02-24
There was xbmcswift2 library but it is seriously outdated and, I guess, incompatible with the current Kodi Python API. Actually, we have discussed this internally and decided that it's better not to bloat the official repo with niche addon libraries that aren't really used by anybody other than their developers themselves.
As for SimplePlugin, it is a single file with no third-party dependencies, only the Standard Library and Kodi Python API, so you can just drop simpleplugin.py in your addon.
RE: SimplePlugin micro-framework for Kodi content plugins - vl_maksime - 2017-02-24
I think better, it's include this add-on in my repository.
Thanks for the answer
RE: SimplePlugin micro-framework for Kodi content plugins - ventolin - 2017-03-02
Does simpleplugin have support for displaying progress bars? (e.g. of a long download)
RE: SimplePlugin micro-framework for Kodi content plugins - Roman_V_M - 2017-03-02
(2017-03-02, 21:54)ventolin Wrote: Does simpleplugin have support for displaying progress bars? (e.g. of a long download)
You don't need any third-party library for that. xbmcgui.DialogProgress and xbmcgui.DialogProgressBG work just fine.
SimplePlugin, as the name implies, is targeted primarily for content plugins. UI and user interaction are completely different stuff. And I'd recommend to read SimplePlugin documentation that describes in details what it actually can do.
RE: SimplePlugin micro-framework for Kodi content plugins - ventolin - 2017-03-02
Cool, I was just asking in case it provided a nice wrapper for that functionality. Thanks!
RE: SimplePlugin micro-framework for Kodi content plugins - ventolin - 2017-03-11
Let's say we have a plugin, "plugin.music.my_plugin", and in its addon_data directory, there's another directory containing MP3s called "some_directory".
The following code will display a single ListItem on the root menu which, when selected, will display the media files in the directory:
Code: PLUGIN_NAME = 'plugin.music.my_plugin'
@plugin.action()
def root(params):
return [
{'label': 'test', 'url': 'special://profile/addon_data/{}/some_directory/'.format(PLUGIN_NAME)}
]
Now, let's say we want to execute some code when the ListItem is selected and then *redirect* the user to this directory, displaying whatever media it contains. How is this best done?
I've tried it by simply returning the url string from the action function:
Code: PLUGIN_NAME = 'plugin.music.my_plugin'
@plugin.action()
def root(params):
return [
{'label': 'test', 'url': plugin.get_url(action='do_stuff')}
]
@plugin.action()
def do_stuff(params):
# do some stuff here
#
return 'special://profile/addon_data/{}/some_directory/'.format(PLUGIN_NAME)
However, this doesn't work - instead, an empty list is displayed. Does simpleplugin have a "redirect" function or something similar? Or is there another way to do what I'm trying to do?
RE: SimplePlugin micro-framework for Kodi content plugins - Roman_V_M - 2017-03-12
(2017-03-11, 18:46)ventolin Wrote: However, this doesn't work - instead, an empty list is displayed. Does simpleplugin have a "redirect" function or something similar? Or is there another way to do what I'm trying to do?
There is no hidden stuff or secret recipes. Everything is in the documentation.
Only playback actions can return strings that must contain paths to media files to play. If you want to use an URL in Kodi VFS notation, you need to either set it as 'url' property of a list item or use ActivateWindow built-in function.
RE: SimplePlugin micro-framework for Kodi content plugins - Wimpie - 2017-06-18
Hi,
I want to use this module, but I'm having a problem.
Code: # -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
import xbmcgui, xbmcplugin
import socket, pickle, struct
from simpleplugin import Plugin, debug_exception
plugin = Plugin()
# Free video sample is provided by www.vidsplay.com
@plugin.action()
def root():
"""
Root virtual folder
This action is mandatory.
"""
plugin.log_debug("Got till here...")
my_dict = {"path" : xbmc.getInfoLabel('ListItem.Path').decode("utf-8"), "filename" : xbmc.getInfoLabel('ListItem.FileName').decode("utf-8")}
plugin.log_debug("my_dict = %s" % my_dict)
if my_dict["path"] != "":
s = socket.socket()
host = 'localhost' # needs to be in quote
port = 1247
s.connect((host, port))
data = pickle.dumps(my_dict)
datasize = len(data)
s.send(struct.pack("<i", datasize))
s.send(data)
s.close()
else:
# We didn't get Listitem infolabels, abort
error_dialog = xbmcgui.Dialog()
error_dialog.notification('Bluray Iso Utils', 'Failed to get ListItems info!', xbmcgui.NOTIFICATION_ERROR, 5000)
plugin.log_debug("And got till here...")
if __name__ == '__main__':
with debug_exception(plugin.log_debug):
plugin.run()
Above is the code I'm using. I get the following in the kodi.log:
Code: 03:05:50.185 T:6724 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: <Plugin ['plugin://script.service.bluray_iso_utils/', '1', '?hello world']>
03:05:50.185 T:6724 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: Actions: ['root']
03:05:50.185 T:6724 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: Called action "root" with params "<Params {}>"
03:05:50.185 T:6724 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: Got till here...
03:05:50.185 T:6724 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: my_dict = {u'path': u'F:\\Over_te_copieren\\_test_strm\\', u'filename': u'test1.strm'}
03:05:50.192 T:6724 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: And got till here...
03:05:50.192 T:6724 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: Action return value: None
03:05:50.192 T:6724 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: The action "root" has not returned any valid data to process.
03:05:50.193 T:6724 INFO: CPythonInvoker(4, C:\Users\Max Renn\AppData\Roaming\Kodi\addons\script.service.bluray_iso_utils\mytestscript.py): script successfully run
03:05:50.202 T:6724 INFO: Python script stopped
03:05:50.202 T:6724 DEBUG: Thread LanguageInvoker 6724 terminating
03:05:50.222 T:2196 DEBUG: ------ Window Init (DialogBusy.xml) ------
03:05:50.222 T:6660 DEBUG: Thread scriptobs 6660 terminating
03:05:50.222 T:2196 ERROR: Playlist Player: skipping unplayable item: 0, path [plugin://script.service.bluray_iso_utils/?hello world]
03:05:50.222 T:2196 DEBUG: Keyboard: scancode: 0x1c, sym: 0x000d, unicode: 0x0000, modifier: 0x0
03:05:50.222 T:5328 DEBUG: Thread BackgroundLoader start, auto delete: false
03:05:50.225 T:2196 DEBUG: ------ Window Deinit (DialogBusy.xml) ------
03:05:50.226 T:2196 DEBUG: ------ Window Init (DialogNotification.xml) ------
03:05:50.229 T:5328 DEBUG: Thread BackgroundLoader 5328 terminating
03:05:51.093 T:2196 DEBUG: ------ Window Init (Pointer.xml) ------
03:05:51.744 T:7544 DEBUG: Version Check: Already notified one time for upgrading.
03:05:51.744 T:7544 INFO: CPythonInvoker(0, C:\Users\Max Renn\AppData\Roaming\Kodi\addons\service.xbmc.versioncheck\service.py): script successfully run
my_dict gets send to the server, so that works.
But I want to suppress the : ''Playlist" ' Can't find a next item to play' notification dialog.
How do I do this? I read the documentation (at: http://romanvm.github.io/script.module.simpleplugin/_actions/misc.html ), but I'm a bit slow today because I can't get it to work...
Code: # -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
import xbmcgui, xbmcplugin
import socket, pickle, struct
from simpleplugin import Plugin, debug_exception
plugin = Plugin()
# Free video sample is provided by www.vidsplay.com
@plugin.action()
def root():
"""
Root virtual folder
This action is mandatory.
"""
plugin.log_debug("Got till here...")
return [{'is_folder': False, 'url': plugin.get_url(action='my_play')}]
@plugin.action()
def my_play():
my_dict = {"path" : xbmc.getInfoLabel('ListItem.Path').decode("utf-8"), "filename" : xbmc.getInfoLabel('ListItem.FileName').decode("utf-8")}
plugin.log_debug("my_dict = %s" % my_dict)
if my_dict["path"] != "":
s = socket.socket()
host = 'localhost' # needs to be in quote
port = 1247
s.connect((host, port))
data = pickle.dumps(my_dict)
datasize = len(data)
s.send(struct.pack("<i", datasize))
s.send(data)
s.close()
else:
# We didn't get Listitem infolabels, abort
error_dialog = xbmcgui.Dialog()
error_dialog.notification('Bluray Iso Utils', 'Failed to get ListItems info!', xbmcgui.NOTIFICATION_ERROR, 5000)
plugin.log_debug("And got till here...")
if __name__ == '__main__':
with debug_exception(plugin.log_debug):
plugin.run()
Here, I even never enter the my_play function. I'm getting this in kodi.log:Code: 03:25:50.596 T:4212 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: <Plugin ['plugin://script.service.bluray_iso_utils/', '1', '?hello world']>
03:25:50.597 T:4212 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: Actions: ['my_play', 'root']
03:25:50.597 T:4212 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: Called action "root" with params "<Params {}>"
03:25:50.597 T:4212 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: Got till here...
03:25:50.598 T:4212 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: Action return value: [{u'url': 'plugin://script.service.bluray_iso_utils/?action=my_play', u'is_folder': False}]
03:25:50.598 T:4212 DEBUG: script.service.bluray_iso_utils [v.0.5.0]: Creating listing from ListContext(listing=[{u'url': 'plugin://script.service.bluray_iso_utils/?action=my_play', u'is_folder': False}], succeeded=True, update_listing=False, cache_to_disk=False, sort_methods=None, view_mode=None, content=None, category=None)
03:25:50.649 T:6860 DEBUG: ------ Window Init (DialogBusy.xml) ------
03:25:50.650 T:4212 INFO: CPythonInvoker(4, C:\Users\Max Renn\AppData\Roaming\Kodi\addons\script.service.bluray_iso_utils\mytestscript.py): script successfully run
03:25:50.665 T:4212 INFO: Python script stopped
03:25:50.665 T:4212 DEBUG: Thread LanguageInvoker 4212 terminating
03:25:50.666 T:6860 DEBUG: Loading settings for
03:25:50.666 T:6860 DEBUG: CPlayerCoreFactory::GetPlayers()
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: considering rule: system rules
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: matches rule: system rules
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: considering rule: mms/udp
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: considering rule: lastfm/shout
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: considering rule: rtmp
03:25:50.667 T:7332 DEBUG: Thread scriptobs 7332 terminating
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: considering rule: rtsp
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: considering rule: streams
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: considering rule: dvd
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: considering rule: dvdimage
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: considering rule: sdp/asf
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: considering rule: nsv
03:25:50.667 T:6860 DEBUG: CPlayerSelectionRule::GetPlayers: considering rule: radio
03:25:50.667 T:6860 DEBUG: CPlayerCoreFactory::GetPlayers: matched 0 rules with players
03:25:50.667 T:6860 DEBUG: CPlayerCoreFactory::GetPlayers: adding videodefaultplayer (VideoPlayer)
03:25:50.667 T:6860 DEBUG: CPlayerCoreFactory::GetPlayers: for video=1, audio=0
03:25:50.667 T:6860 DEBUG: CPlayerCoreFactory::GetPlayers: for video=1, audio=1
03:25:50.667 T:6860 DEBUG: CPlayerCoreFactory::GetPlayers: added 1 players
03:25:50.669 T:6860 DEBUG: Radio UECP (RDS) Processor - new CDVDRadioRDSData::CDVDRadioRDSData
03:25:50.669 T:6860 NOTICE: VideoPlayer: Opening:
03:25:50.669 T:6860 WARNING: CDVDMessageQueue(player)::Put MSGQ_NOT_INITIALIZED
03:25:50.669 T:6860 ERROR: DXVA::CProcessorHD::IsFormatSupported: Unsupported format 104 for 1.
03:25:50.669 T:6860 ERROR: DXVA::CProcessorHD::IsFormatSupported: Unsupported format 105 for 1.
03:25:50.669 T:2160 DEBUG: Thread VideoPlayer start, auto delete: false
03:25:50.669 T:2160 NOTICE: Creating InputStream
03:25:50.669 T:2160 ERROR: CVideoPlayer::OpenInputStream - error opening []
03:25:50.669 T:2160 NOTICE: CVideoPlayer::OnExit()
03:25:50.669 T:2160 DEBUG: CApplication::OnPlayBackStopped: play state was 1, starting 1
03:25:50.669 T:2160 DEBUG: Thread VideoPlayer 2160 terminating
03:25:50.670 T:6860 DEBUG: CApplication::OnPlayBackStopped: play state was 3, starting 0
03:25:50.670 T:6860 ERROR: Playlist Player: skipping unplayable item: 0, path [plugin://script.service.bluray_iso_utils/?hello world]
I'm probably missing some basic python thing, but what?
Help...
RE: SimplePlugin micro-framework for Kodi content plugins - Roman_V_M - 2017-06-18
@Wimpie
Please provide full debug logs via some pastebin site and describe your setup with as much details as possible. There's something weird is going on in your case.
|