Kodi Community Forum

Full Version: Virtual Python Folders
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5 6 7 8 9
Hi everybody,
as I'm currently trying to improve the TVLinks and Joox.net scripts, I got an idea for better integration of python scripts into the look and feel of XBMC. Couldn't we implement something like "virtual python folders" for the music and video screen?
I mean something like the integration of Last.FM. You open the special lastfm:// folder and you are presented other folders and playlist that are dynamically generated by the lastfm code. It would be great if we could have a special python://<script_directory>/<script_name.py> URL. When the user accesses this URL for the first time, the python script is called to initialize stuff and is asked for the initial folder contents. This can include other folders and also playable items. For each one of them, the python script can also specify a thumbnail. A special parameter string is attached to the folders, that is passed to the python script if the user enters a folder. The python script then evaluates this parameter string, thus it knows what folder is selected by the user and gives the new folder contents back to XBMC.
This way, a close integration of things like Apple movie trailers, TVLinks, Joox and others would be possible on a plugin base.
For Apple movie trailers for example, a special "details" function with information on the media and things like a search function would be awesome as well.
I think this should be possible and if any of the devs had some time to help, I'd be glad to help with this. I really like XBMC, but I'm not yet content with the look and feel of media streaming scripts.
My English is not so good, so if you don't understand what I'm trying to describe here, please let me know! I could then illustrate my ideas with examples.
I had a similar, maybe the same idea. If there was a special folder in XBMC, that a scripter could add a file, like windows sendto folder.

So if I dropped in "Apple Movie Trailers.cut"

when clicked this would call q:\\scripts\\Apple Movie Trailers\\Default.py with no args, which would return a list. Whatever info XBMC needed. e.g. id, title, url, plot, isfolder, context_items... All the infolabels available.

then when one of those items is clicked:

1. if url was not None or empty (kinda the isfolder item above), it would call q:\\scripts\\Apple Movie Trailers\\Default.py,id=id_no. Then your script would need to know what to do with it and return another list.

2. if the url existed, XBMC would just play it.

Some things that would be needed, would be custom context, by passing special codes back to XBMC, if you selected info it would be able to display the menu, then call q:\\scripts\\Apple Movie Trailers\\Default.py, context=id. So you would have to pass to xbmc a dictionary of {title: id}

It's interesting. It may be a nice feature, maybe unnecessary, probably not something a developer would implement. If you think you can, I'm sure we could take a look. You can do alot with windowXML though.

Maybe you could start by adding a python method that would allow scripters to set all the listitem.* infolabels. This feature would be nice if possible, anyways.

You would lose some abilties, like custom skins and formatting...

Good luck, I would be interested in hearing what a developer thought about this.
I like the idea alot. It makes alot more sence to add support for the obscure protocols like rtv/hdhomerun/tuxbox.. through some plugin architecture, I though a while back about adding support for compiled dll's, but python support would be a nice idea too.

I might have a look at it, but it'd be better with a dev with some more knowledge about the python integration.
I agree - sounds like a great idea.

I guess what needs to be done is to setup the way we'd pass info to and from the script.

One relatively simple starting point would be a directory class that calls a script with each GetDirectory() request (with the appropriate parameters), where the script executes, returns the requested data to XBMC, and exits.

Extra stuff (such as contextual menus, sorting methods, label formatting) can possibly be done in a similar fashion by extending the current classes that handle this to request it from the script, though this will mean executing the script over and over - I'm not sure how efficient this is?

Cheers,
Jonathan
You would definately want to use your default.py as a launcher script. Where all that would be in it is a minimal function to parse the argv and an if block that would either launch another script or better just import the module required.

Also shortcut buttons might be needed.

Edit maybe a setup.py, that could be called one time with certain parameters, like buttons, context menu(though that might change per item)...
I've been thinking about the possibility of "contextual" shortcut buttons on the left. It might be useful for some of the things we have hidden away in the context menu available in the GUI via a different manner - particularly those things that are contextual to the folder rather than the file. I am mindful of overcluttering the GUI however.

At anyrate, it's possibly something that can be solved in a similar manner to contextual formatting and sorting.

Perhaps we could start out simple with just the folder fetching for now - how do you see that implemented - having a function that the script calls that the directory class waits on in some way? We'd need have some sort of an id of the script so that we know which script is returning what I guess? You're probably more up with how to communicate between the two than most at this point!

Cheers,
Jonathan
Yes, a python method that passes a list of listitems to GetDirectory() or whatever you need.

If the listitem or a new listitem could be implemented so scripters could set every listitem.* that is available.

This could also be done just passing a dictionary and then parsing it in C++ if you wanted. Then you wouldn't need a new listitem. I'm not sure how well you could error check for invalid listitem.* infolabels. The benifits would be simpler code maintenance when new listitems.* infolabels are created.

I think the same method could be used for folders as it could with files, just by passing the correct parameter.

So when you first enter the special python:// folder, XBMC would grab a list of scripts like it does now with the scripts window. Setting a special listitem.* tag to None or Null.

Then from that point on every select action would call default.py with the special listitem.* tag set by the script or if listitem.filename is set with a url, path to a file or any valid media. Instead of calling default.py, just launch the filename.

Did I understand your question?
I'm more interested in the nuts and bolts - i.e. the method that the script calls, and how XBMC knows that it's the script it's waiting for.

I envision it goes something like this:

1. CPythonDirectory deciphers URL and calls script with whatever parameters have been set in the URL.

2. CPythonDirectory then waits on an event for some max timeout period.

3. Meanwhile (in another part of Gotham City), the script goes away and does whatever it needs to fetch the items it wants to display, and then calls a function xbmcSetDirectory() with the item list.

4. xbmcSetDirectory() then sends CPythonDirectory the contents and sets the event.

5. CPythonDirectory sees the event as set, and returns the data.

6. User is presented with the list.

The key issues are:

a. How does xbmcSetDirectory() know which instance of the CPythonDirectory class to call?

b. How does CPythonDirectory know it's been updated by the correct script?

Clear up that and the rest is pretty simple I think, or perhaps there's an alternative method that's easier?

Cheers,
Jonathan
It just came into my mind that maybe we need appropriate exception handling. I mean the possibility to tell XBMC that an error happened and what kind of error that is. Or would it be enough to return an empty list and display the error message via python?
BTW: It's awesome to see so many replys in such a short period of time! I'd really love to see this feature, it would seriously turn me into a scripting geek for quite some time. XBMC really seems to have a great developer community, so it's fun to contribute.
jmarshall Wrote:a. How does xbmcSetDirectory() know which instance of the CPythonDirectory class to call?
b. How does CPythonDirectory know it's been updated by the correct script?
Couldn't CPythonDirectory call the script with two parameters: the arguments (we had that before) and a unique handle ID? Then there could be a xbmcSetDirectory(ID) function that would call the appropriate instance (or pass the ID to some CPythonDirectory instance manager which would do this for it)
1. CPythonDirectory deciphers URL and calls script with whatever parameters have been set in the URL.
I'm not sure I understand this. If URL="http://apple.com/movie.mov" would it just play the url?

2. CPythonDirectory then waits on an event for some max timeout period.
This is tricky, Apple Movie Trailers could take 5-15 minutes to finish the first time you enter a genre(folder). If the script crashed you would have to also reset by the user backing out of the folder.
a. Would it make sense to have CPythonDirectory control a progress dialog and have a hook that the script could update? Then if it wasn't updated in a shorter amount of time it could force the script closed. (maybe ugly)

3. Meanwhile (in another part of Gotham City), the script goes away and does whatever it needs to fetch the items it wants to display, and then calls a function xbmcSetDirectory() with the item list.
4. xbmcSetDirectory() then sends CPythonDirectory the contents and sets the event.
5. CPythonDirectory sees the event as set, and returns the data.
If a. is used above, The script could send a finished parameter with the list.

6. User is presented with the list.
The key issues are:
a. How does xbmcSetDirectory() know which instance of the CPythonDirectory class to call?
b. How does CPythonDirectory know it's been updated by the correct script?
I think 2.a. takes care of that?
I like the idea too.. I'll try to flesh out how I see the UI working.

In the "Browse for new Share" dialog from "Add Source", we add a new item "Add Plugin Folder..." (or something similar) under "Add Network Location..."

The resultant dialog will be populated by scripts in q:\plugins\sources

These scripts are standard scripts within their own folder and with a default.py, only their location matters. (Other types of plugin scripts could be possible in the future).

As for the functioning of the scripts... there are two options I suppose,
the first is similar to JM's suggestion...
A) Call a python program with a directory specified via sys.argv
1) sys.argv specifies directory path and directory handle
2) script calls xbmc.SetDirectoryContents(handle, [listitems])
3) exits

the second might be faster and avoids passing handles
B) Extend a object like xbmc.Source and override its FetchDirectoryContents() funtion..
1) CPython object registers itself and gets its own pointer to CPythonDirectory
2) xbmc responds to events by calling xbmc.Source.GetDirectoryContents()
3) scripts calls xbmc.Source.SetDirectoryContents([listitems]) to add listitmes
4) always have the script run until xbmc calls xbmc.Source.close()

The main difference between A and B is that A has the script running off and on while B has the script launch once and respond to events. A sounds alot simpler from C++ side but I have a feeling it could cause problems with scripters, probably scripts would cache alot of results. B is more expandable though. Scripts would have an easier time specifying context menu items for example.


With both of these I think a plugin version number similar to what we have on the skin side of things might be a good idea.
I do and don't like the script always running.
1. What if it crashes?
2. Memory? not as much of a problem since we aren't createing a gui.
3. Most operations won't take that long, maybe if python could be initialized when entering python:// that may help some small amount?

About caching, is that something that XBMC could handle, Say I just passed a url to a poster. Would XBMC handle downloading and caching it?
I was thinking about situations where you might have to login and maintain some connection state between accesses sort of like an AFS token.

... but yeah.. the more we go down that route the more it is just another script as opposed to a plugin. The run and exit of method A seems easier and you could probably use the directory handle to extend the source just fine.

Any thoughts on integrating with the library?
There's nothing stopping you from calling anoth .py file and keep that running. But exiting it would be an issue.

1400 AMT records added, might not be good Smile But if we can set listitem.* labels we could have the same functionality.
Pages: 1 2 3 4 5 6 7 8 9