Kodi Community Forum
script.module.urlresolver development - Printable Version

+- Kodi Community Forum (http://forum.kodi.tv)
+-- Forum: Development (/forumdisplay.php?fid=32)
+--- Forum: Python Add-on Development (/forumdisplay.php?fid=26)
+--- Thread: script.module.urlresolver development (/showthread.php?tid=105707)

Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24


- t0mm0 - 2011-09-01 20:55

DragonWin Wrote:[EDIT]
Forgot to include the url that does not work: http://embed.novamov.com/embed.php?width=600&height=480&v=eczrahg83yvi5&px=1
[/EDIT]

this url works for me... maybe there was a problem with the site at the time or something?


- t0mm0 - 2011-09-01 21:12

DragonWin Wrote:Hi t0mm0

I just noticed that you change import pickle to cPickle. I omitted cPickle on purpose as there are some data type objects it can't handle (found it some where on the net can't remember what it is it can't handle) but pickle can.

Just thought I would mention it.

from what i can tell from the python docs the only difference is that you can't subclass Pickler and Unpickler (which we are not doing). cPickle is a lot faster, but i guess will only be available when using a system python in newer xbmc versions anyway? still if it is a problem i can change it back?

t0mm0


- t0mm0 - 2011-09-01 21:31

DragonWin Wrote:MyContextObject = create_contextmenu(menuname, scriptargs, mode=True/False, [contextobject]):
Where menuname, is what is displayed to the user on right click, scriptargs is the arguments passed to the plugin, mode indicates if the function that is hit creates a new listitem with add_dir, add_item ect, contextmenuitem object is an existing object. The object is a previously returned contextmenu, and only used if the user wants to add more menu items for that individual list item to be added using add_item add_video_item add_music_item (eg. Go to favories, Add item as favorite)

As far as I could make out using XBMC.Container.Update() forces it to clear the itemlist, and accept a new itemlist to be displayed (eg. Go to favorite menu item), or XBMC.RunPlugin() is used for eg. "add to favorites" as that would not generate a new itemlist. Which is why we need to know from the addon what type it is, hence the True/False in the create_contextmenu()

i'm not sure i understand the mode bit, or what XBMC.Container.Update() is for.

from the docs for xbmcgui, a ListItem has a method addContextMenuItems() which already lets you add context menu items as a list of tuples. couldn't we just add an extra kwarg to the add_item() methods to pass that through to the ListItem? what does the above do that makes it easier?

Code:
addContextMenuItems(...)
addContextMenuItems([(label, action,)*], replaceItems) -- Adds item(s) to the context menu for media lists.

items               : list - [(label, action,)*] A list of tuples consisting of label and action pairs.
  - label           : string or unicode - item's label.
  - action          : string or unicode - any built-in function to perform.
replaceItems        : [opt] bool - True=only your items will show/False=your items will be added to context menu(Default).

List of functions - http://wiki.xbmc.org/?title=List_of_Built_In_Functions

*Note, You can use the above as keywords for arguments and skip certain optional arguments.
       Once you use a keyword, all following arguments require the keyword.

example:
  - listitem.addContextMenuItems([('Theater Showtimes', 'XBMC.RunScript(special://home/scripts/showtimes/default.py,Iron Man)',)])

(i am probably missing something with this a i haven't really played with xbmc context menus before Wink)


- DragonWin - 2011-09-02 08:01

t0mm0 Wrote:this url works for me... maybe there was a problem with the site at the time or something?

hmm strange it still does not work for me. It works when I try it in my browser, but not when I put the link in the t0mm0 test addon.

Guess I'll have to try and look into it another time, I would like to get on with the contextmenu setup.


- DragonWin - 2011-09-02 08:03

t0mm0 Wrote:from what i can tell from the python docs the only difference is that you can't subclass Pickler and Unpickler (which we are not doing). cPickle is a lot faster, but i guess will only be available when using a system python in newer xbmc versions anyway? still if it is a problem i can change it back?

t0mm0

Hmm, I might have been confused about that then, as I were also looking at marshall, json and a few others to see what would give the most options.

Lets leave it in and see if any it there is an issue at all.


- DragonWin - 2011-09-02 08:30

t0mm0 Wrote:i'm not sure i understand the mode bit, or what XBMC.Container.Update() is for.

from the docs for xbmcgui, a ListItem has a method addContextMenuItems() which already lets you add context menu items as a list of tuples. couldn't we just add an extra kwarg to the add_item() methods to pass that through to the ListItem? what does the above do that makes it easier?

This function helps create the tuples, let me try and explain

It took me quite a bit of digging to figure this one out, let me see if I can explain myself better. The reason why I opted to put this function in, is because I found quite a few posts when searching on how to do this, from people with similar issue, but no resolution to there problem. With this function they don't need to know about RunPlugin or Container.Update, they just need to know, do I present a new list of items or not (True/False).

mode should properly be called newlist=True/False

Lets say that I want to add 2 context menu's to some movies. The first menu option is "Go to startup screen" which presents the catagories (mode=main), and the second menu option is "Add to favorites", which stays on the same screen (same dir) but just saves the url.

If I used this on both
Code:
contextmenuobj.append((menuname, u'XBMC.Container.Update(%s?%s)' %
                               (self.url, scriptargs)))
the "Go to main menu" would work as expected as it clears the listitems, ready to receive new add_dir, add_item calls, where as using "Save favorite" would save the favorite but present an emtpy listing the current movie listing would be gone.


If I used this on both
Code:
contextmenuobj.append((menuname, u'XBMC.RunPlugin(%s?%s)' %
                               (self.url, scriptargs)))
the "Go to main menu" would display an empty list due to (what I believe is the cause) the close_dir has been added to the items, and thus it can't be replaced without additional calls to the addon itself. Where as "Save Favorite" would work as expected, save the favorite, and stay on the current dir / display.

So the user would create there menu items and receive the contextmenu obj, which would then be passed to add_item, add_video_item, add_music_item, for each item the menu should be on, and they would have there menu up and running.

It was purely thought of as a way for the addon coder to have an easy way to add/del favorites, and also a fast way to jump to favorites. If they want to do more elaborate stuff they would have to mix in there own tuples and pass that to add_item etc.

t0mm0 Wrote:(i am probably missing something with this a i haven't really played with xbmc context menus before Wink)

Hehe as I said took me quite a bit of digging around, and I made my post early in the morning before work, I might not have been fully awake ;-)

I hope this explanation is a bit better, sorry if my first post were a bit confusing Sad


- DragonWin - 2011-09-02 09:45

Hi t0mm0

I have been messing a bit around with it now, from the addon creators point of view, it would look some thing like this:

Create my 2 menu's and add them.
Code:
mymenuobj = addon.create_contextmenu('Go to Main screen','mode=main',
                                              newlist=True)
mymenuobj = addon.create_contextmenu('Save Favorite','mode=savefav',
                                              newlist=False,
                                              contextmenuobj=mymenuobj)


addon.add_video_item( url, { 'title' : title }, img=thumbnail,
                                  contextmenuobj=mymenuobj)

of cause in the 2nd arg you can always add more info like url to save, what to do on loading it again etc.

End result: Save Favorite hits mode=favorite, but stays on the current screen, and Go to Main screen resets the list, and shows the mode=main initial directory.


[Image: xbmcmenu.png]


- t0mm0 - 2011-09-02 20:00

DragonWin Wrote:Hi t0mm0

I have been messing a bit around with it now, from the addon creators point of view, it would look some thing like this:

ah yeah i think i understand what you mean now! sorry for being a bit slow Wink

looks good to me so far - more building blocks for favourites....

t0mm0


- DragonWin - 2011-09-02 20:54

Hey t0mm0,

I have been busy today Wink

I have been able to create the "add favorite", and also to show them, and play them. Only movie links so far, I have not tested directories yet. It still needs a lot of work, but it's starting to look like some thing.

As it's not possible to call a module function directly, the user has to create 3 modes in the addon: savefavorite, deletefavorite, showfavorites

Code:
elif mode == 'savefavorite':
    test = addon.save_favorite(sys.argv[2])
    if test is False:
        addon.show_small_popup(msg='Unable to save favorite')

elif mode == 'deletefavorite':
    #Yet to be created
    pass
        
elif mode == 'showfavorites':
    test = addon.show_favorites()
    if test is False:
        addon.show_small_popup(msg='No saved favorites to show')

So far when they want to add the "Add favorite" context they then call this. I'll explain the tuple more when I have decided on a structure, but callback 'play' means add_item, it could also be a mode that is to be called.
Code:
favoritetuple = {'callback' : 'play', 'menuname' : 'Save solarmovie favorite',
                        'action' : 'savefavorite'}
add_video_item(addon.add_video_item( url, { 'title' : title }, img=thumbnail,
                        favorite=favoritetuple)

To display the favorites
Code:
addon.add_directory({'mode' : 'showfavorites' }, 'Favorites')

I hope this can be a useful addition to common.addon, if nothing else shown a way Not to do it Rolleyes

I'll give it some more attention tomorrow, right now dinner is almost done ;-)

Ps. I'm prob. going to need you to make the code more sturdy, and clean it up, like you did with the other commit, I hope you don't mind.


- t0mm0 - 2011-09-02 22:39

DragonWin Wrote:Hey t0mm0,

I have been busy today Wink
cool - looks like it's coming on nicely!

think i will get a chance to write some more code myself too this weekend.
DragonWin Wrote:Ps. I'm prob. going to need you to make the code more sturdy, and clean it up, like you did with the other commit, I hope you don't mind.

i'm happy to take a look when you're ready (but of course i may just make it worse Wink)

t0mm0


- DragonWin - 2011-09-03 22:19

Hey t0mm0

I need your help, I have been banging my head against this one for quite a few hours now. it seems to be related to functions and default values ... some how Eek

I have been messing around with it a lot so the code is not tidy, right now I'm just trying to figure out what is going on, and how to fix it.

The objective is to allow the addon author to add his own menu items while also making use of the favorite

Pastebin link to snippet of the code used: http://pastebin.com/Dbi5j7GD

What happens is that the object "mymenuobj" defined at line 6 is modified during the for loop at line 16.

At line 19 it's passed to addon.add_item as contextmenuobj=mymenuobj, and I think this is where it goes wrong.

After that at line 51 it's passed to self.create_contextmenu()

which send it to line 75 where I append the new menu to the contextmenuobj, which is the returned in line 51.

The 2nd time round through this process I would have expected mymenuobj to contain my original from line 6, but instead it contains the original and the previous menu item resulting in, the 2nd item in the list suddenly have 2 x 'Add solarmovie favorite' menu, 3rd time I have 3 x 'Add solarmovie favorite' etc.

I read that by using a none modifiable value for the default value, this should not happen, but I have tried False, None, '' etc, and none of those works..

How can I get around this ?


- t0mm0 - 2011-09-03 22:43

DragonWin Wrote:I need your help

hmmm, from a quick glance i guess you are running into some unwanted side effects of this type of thing?

specifically the contextmenuobj.append() on lines 80 or 83 will alter the original object that was passed to create_contextmenu() and NOT a copy of it as you might expect.

so i think when you get to line 51 both contextmenuobj and newcontextmenuobj are actually references to the same object!

t0mm0


- DragonWin - 2011-09-03 23:35

Thanks Big Grin that was just what I needed. The other explanations I had found did not explain it that clearly.

the fix
Code:
def create_contextmenu(self, menuname, scriptargs,
                            newlist=False, contextmenuobj=None):
        newobj = []
        if contextmenuobj is None:
            newobj = []
        else:
            for mytuple in contextmenuobj:
                newobj.append(mytuple)
        if newlist:
            newobj.append((menuname, u'XBMC.Container.Update(%s?%s)' %
                               (self.url, scriptargs)))
        else:
            newobj.append((menuname, u'XBMC.RunPlugin(%s?%s)' %
                               (self.url, scriptargs)))
        return newobj

So guess it's time to clean up all the test code, and add 'Delete favorite' contextmenu, do more testing, write documentation Wink


- DragonWin - 2011-09-04 12:59

Hey t0mm0,

Thanks for the help yesterday, I have been playing around with it a bit more, and I think I have some thing that could be useful.

instead of trying to explain it all I decided to do a quick movie (this is a one take, so it's not refined or any thing, and I seem to mumble at some places Wink )

favorites demo

It still needs more testing, but I think it's close to be ready.

Thoughts?


- t0mm0 - 2011-09-04 13:46

DragonWin Wrote:Hey t0mm0,

Thanks for the help yesterday, I have been playing around with it a bit more, and I think I have some thing that could be useful.

instead of trying to explain it all I decided to do a quick movie (this is a one take, so it's not refined or any thing, and I seem to mumble at some places Wink )

favorites demo

It still needs more testing, but I think it's close to be ready.

this looks great! thanks for the video - you are really good at that Wink

a couple of questions.....

i don't think there's any need to be passing sys.argv[2] around - that is already available to methods in addon as self.queries already parsed and as a dictionary. (just noticed that's not documented - i should fix that!)

rather than passing the context menu object back into addon.create_context_Menu(), would it be better to make a ContextMenu class? then you could do something like:
Code:
cm=ContextMenu()
cm.add(title, query, new_list)
(it would probably be nicer if the query bit were a dictionary rather than a string so it is the same as elsewhere {'mode': 'mymode'} which would make it easier to add more items too)

would that also make it possible to make create_favorite() a method on the context menu object so everything was kept together?

what do you think?

t0mm0