Is there anything dynamic available to skins/context menus?
#1
I'm trying to work out how I can dynamically change a context menu label but everything I come up with requires static values.

I even had a thought that I could just add context menus then control their visibility based on the output of a script but I don't see return values.

Ultimately, I would like to change the label of a context menu subitem based on the return value of an addon script.

At minimum control that context menu subitem visibility based on the return value of a script.

-----

example

<label>RunAddon(id[,opt])</label>

or

<visible>RunAddon(id[,opt])</visible>


The addon when ran would then be able to return a string for the label based on the current sys.listitem or at minimum return true or false if that menu item should be visible based on sys.listitem and sys.argv.


It feels like I am trying to do something that is not currently possible.
Reply
#2
I believe if you set a window property is the script you can use that as a conditional in the context menu visibility.  The only trick is that the window property may be empty when Kodi first starts, so either you need to plan for that possibility or have your script run as a service and set some default window properties at startup.

Window Property info:
https://xbmc.github.io/docs.kodi.tv/mast...eedded7b3e

and then get the Window property in the XML for the context menu using something like:

Window(Visualisation).Property(ArtistSlideshow.Image)

This is an example from Artist Slideshow which sets a window property to tell the skin what image to show.  For you, the window would be whatever one you set the property in and the name would be whatever you name it.
Reply
#3
(2023-06-28, 07:46)jepsizofye Wrote: Ultimately, I would like to change the label of a context menu subitem based on the return value of an addon script.

At minimum control that context menu subitem visibility based on the return value of a script.

-----

example

<label>RunAddon(id[,opt])</label>

or

<visible>RunAddon(id[,opt])</visible>


The addon when ran would then be able to return a string for the label based on the current sys.listitem or at minimum return true or false if that menu item should be visible based on sys.listitem and sys.argv.


It feels like I am trying to do something that is not currently possible.

I haven't tried this and I've avoided complex context menu items or nested context menu lists.  Instead I leverage a single context menu item and then create a dialog box(s) with the items I want to display / select.  Those items in the dialog box are conditional list items.  It's a bit clunky but works well and is likely to be less impacted by future Kodi context menu / window changes.

Here's an example of the current approach for how i do trailer selections from our other conversation.  It starts on line 398.  Down beginning on line 716 you see the sys.argv variables getting passed and parsed which then call other functions to dynamically display what I want.  In the case of the trailer display you can see the database query component beginning with line 408 of the example link.

FYI, here's the current test code that aligns to the new image in the other trailer thread.

Code:
        curtrail = dsfile.execute('SELECT trUrl, trPlay, trVar1 from mTrailers WHERE trTitle=? \
        ORDER BY trID ASC LIMIT ?', (mtitle, trcount,))
        mtrailers = curtrail.fetchall()                            # Get trailers from database
        dsfile.close()
        trselect = x = 1
        if mtrailers:        
            for a in range(len(mtrailers)):                        # Convert rows to list for dialog box
                if int(mtrailers[a][1]) > 0:
                    traillist.append("Trailer  #" + str(x) + "     [COLOR blue]Played[/COLOR]")
                elif '\imdb_' in str(mtrailers[a][2]):
                    traillist.append("Trailer  #" + str(x) + "     [COLOR yellow]Local IMDB[/COLOR]")
                elif 'www.youtube' not in str(mtrailers[a][2]):
                    traillist.append("Trailer  #" + str(x) + "     [COLOR green]Local YouTube[/COLOR]")  
                else:
                    traillist.append("Trailer  #" + str(x) + "     YouTube")
                x += 1
            trselect = msdialog.select('Select Trailer: ' + mtitle[:60], traillist)

Generates this output

I hope this might help a little.


Thanks,

Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#4
right on

if i go with @pkscout

i would have to add a service addon that is listening for a context menu event, if that does exist
if not then the service addon will be performing lookups every time i focus an item on the screen just in case i happen to open the context menu on that item so the context menu will show relevant items for that listitem

-----

i did see yours @jbinkley60 and i was trying to find a mid way point between yours with a full dialog and mine which is a single context item

the solution i was attempting to combine them was dynamic submenu items where it would list the available trailers in the context menu, when that didn't work i thought to go with conditional static ones which also doesn't work

Trailers ->
    Local (condition 'jellyfin' in listitem.getTrailer(), more conditions to determine local)
    IMDB (condition listitem.getVideoInfoTag().getUniqueID('imdb') is not empty)
    YouTube (condition 'youtube' in listitem.getTrailer())
    Search


im going to get back to this later on, thanks for the replies and ideas
Reply
#5
abandoning dynamic i can use skin variables to set some of this

<visible>String.Contains(ListItem.Trailer,jellyfin)</visible> - works

<visible>String.Contains(ListItem.Trailer,youtube)</visible> - works

then it's just a bunch of invisible items, not sure about imdb id yet

https://xbmc.github.io/docs.kodi.tv/mast...tions.html


so as long as i dont try to involve python code execution ...
Reply
#6
(2023-06-28, 16:42)jepsizofye Wrote: abandoning dynamic i can use skin variables to set some of this

<visible>String.Contains(ListItem.Trailer,jellyfin)</visible> - works

<visible>String.Contains(ListItem.Trailer,youtube)</visible> - works

then it's just a bunch of invisible items, not sure about imdb id yet

https://xbmc.github.io/docs.kodi.tv/mast...tions.html


so as long as i dont try to involve python code execution ...

Actually you probably already know that you can do both.  This is how I call context menus from native skin mode of operation with the Mezzmo Kodi addon.  My addonxml file looks like this:

addon.xml snippet:
  <extension point="kodi.context.item">
    <menu id="kodi.core.main">
      <item library="resources/lib/context.py">
          <label>30435</label>
          <visible>[String.IsEqual(ListItem.dbtype,episode) | String.IsEqual(ListItem.dbtype,movie) | String.IsEqual(ListItem.dbtype,tvshow) | String.IsEqual(ListItem.dbtype,musicvideo)] + !String.IsEqual(Container.PluginName,plugin.video.mezzmo)</visible>
      </item>
    </menu>
  </extension>


That then calls the context.py file which creates the second level context menu / dialog box. 


Thanks,

Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#7
im on top of that one, trying to make individual labels with multiple <item> tags since i cant generate items dynamically or label them dynamically

i would do multiple for the one labeled Trailer - Local with trailer contains jellyfin, mezzmo, smb

files on the local drive might be more interesting as i think the path is just /path/to/file on linux and android, C:\ D:\ E:\ on windows but it might start with file:// then i could detect that

-----

the idea here would be to differentiate ListItem.Trailer into Locally Stored or YouTube and label those "Trailer - Local" and "Trailer - YouTube"

have a 2nd item would be IMDB where it can call the imdb trailers addon directly like i do now -

infotag=sys.listitem.getVideoInfoTag()
uniqueid=infotag.getUniqueID('imdb')
if uniqueid!='':
    xbmc.executebuiltin("PlayMedia(plugin://plugin.video.imdb.trailers/?action=play_id&imdb={})".format(uniqueid))

but i wanted to make the 2nd item's visibility change depending on the if condition im already using in the python side, that way it wouldnt have a menu item that didn't work

then lastly have a 3rd item "Search" which would go ahead and bring up the search dialog from imdb trailers the way i have now

infotag=sys.listitem.getVideoInfoTag()
title=sys.listitem.getLabel() #inconsistent title from infotag, use label instead
year=str(infotag.getYear())

xbmc.executebuiltin("ActivateWindow(10025,\"plugin://plugin.video.imdb.trailers/?action=search_word&keyword={} {}\",return)".format(title,year))


-----

pretty much all that works in my existing code from a single context item using fall through
if trailer is local play it
else if uniqueid is available play from the imdb id found in uniqueid the way it is above

i suppose the code would be more descriptive so ... judge how you wish its not production its just for me
python:

            infotag=sys.listitem.getVideoInfoTag()
            title=sys.listitem.getLabel()
            trailer=infotag.getTrailer()
            year=str(infotag.getYear())
            uniqueid=infotag.getUniqueID('imdb')
            if 'jellyfin' in trailer:
                xbmc.executebuiltin("PlayMedia({})".format(trailer))
            elif uniqueid!='':
                xbmc.executebuiltin("PlayMedia(plugin://plugin.video.imdb.trailers/?action=play_id&imdb={})".format(uniqueid))
            else:
                xbmcgui.Dialog().notification("Trailers", "Finding trailers for {} {} ...".format(title,year))
                playpath="plugin://plugin.video.imdb.trailers/?action=search_word&keyword={} {}".format(title,year)
                payload = {'jsonrpc': '2.0', 'method': "Files.GetDirectory", 'params': {"properties": ['title'],"directory": playpath, "media": "video"}, 'id': 1}
                info = xbmc.executeJSONRPC(json.dumps(payload))
                info = json.loads(info)
                info = info["result"]
                if info['files'][0]:
                    xbmc.executebuiltin("PlayMedia({})".format(info['files'][0]['file']))
Reply
#8
(2023-06-28, 22:48)jepsizofye Wrote: pretty much all that works in my existing code from a single context item using fall through
if trailer is local play it
else if uniqueid is available play from the imdb id found in uniqueid the way it is above

i suppose the code would be more descriptive so ... judge how you wish its not production its just for me

So I am not familiar with how Jellyfin does trailers,  how they are shared, stored and the naming but it looks like the word "jellyfin" is in the trailer name somehow, maybe by part of the URL.  I can see what you are doing and it looks like it will work but it looks like it defaults to a jellyfin trailer and then will call the addon for an IMDB trailer, if available.  as long as you don't want to specifically play a certain trailer then this is fine (i.e. a jellyfin trailer exists but you want to play an IMDB trailer, then you should be fine.  Does Jellyfin or the Jelly fin Kodi client support multiple trailers for a movie ?


Thanks,

Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#9
when the jellyfin addon for kodi updates the kodi database from the jellyfin server it will load the trailer for that movie

the default for jellyfin is to scrape a youtube trailer, same way kodi does

when i load a locally stored movie trailer to the jellyfin server, it will update the url to the trailer in the kodi database


when ive added a locally stored trailer to jellyfin that url is (c19 in movie of the kodi myvideo database)
plugin://plugin.video.jellyfin/trailer?id=*&mode=play

when i havent done anything but scrape the movie and allow it to do its default that url is
plugin://plugin.video.youtube/play/?video_id=*

so it is detectable but labeling may not be easy as it only provides an id


afaik neither kodi or jellyfin natively support multiple trailers like your addon, when browsing from jellyfin i get a single button to play "The" trailer not a list of available trailers so it doesnt even seem to have the code to utilize multiple within jellyfin outside of kodi
Reply
#10
this submenu context is quite hard to work with and achieves very little

the full dialog jeff has is far superior so time to move along
Reply
#11
(2023-06-29, 07:17)jepsizofye Wrote: this submenu context is quite hard to work with and achieves very little

the full dialog jeff has is far superior so time to move along

We've plowed the same ground here Wink


Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#12
(2023-06-29, 04:05)jepsizofye Wrote: when the jellyfin addon for kodi updates the kodi database from the jellyfin server it will load the trailer for that movie

the default for jellyfin is to scrape a youtube trailer, same way kodi does

when i load a locally stored movie trailer to the jellyfin server, it will update the url to the trailer in the kodi database

This is similar to Mezzmo except Mezzmo can store many trailers per movie where Kodi is limited to storing 1 in the Kodi database.  With Mezzmo I get a list of trailers via the DLNA XML response, I parse them with the Mezzmo Kodi addon and then store them in the local Mezzmo Kodi addon database which the context menu then pulls from for multiple trailer playback.   This also handles distributing to all the clients.  I insert the first one into the Kodi database so the native Kodi trailer playback works.


Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#13
i will have to look into that more closely, with kodi being limited to 1 and only seeing 1 button in the jellyfin native client i only assume it is limited

might be nice to load teaser/official and fan trailers all together
Reply
#14
(2023-06-29, 16:41)jepsizofye Wrote: i will have to look into that more closely, with kodi being limited to 1 and only seeing 1 button in the jellyfin native client i only assume it is limited

might be nice to load teaser/official and fan trailers all together

I'd look at whether the Jelllyfin server can store multiple trailers.  Kodi isn't its only client type and many clients support multiple trailers so it is likely.  Then you'd have to figure out how to get the trailer name from jellyfin to a local Kodi database or similar.  I do it with a background sync process. 

The way I do multiple trailers with Mezzmo is have a context menu item which pulls from a database.  This approach can easily be done to an existing addon or a stand-alone solution that adds a context menu item.  The main question is the database.  If Jellyfin can't be used as a source to populate a local database in Kodi, like I do with Mezzmo, then another option is a central database, with SMB sharing of the database and the trailer file location.  I don't know if you use SMB mounts / sharing with Jellyfin.  SMB mounts aren't used with Mezzmo but I believe with Jellyfin it is an option or you could setup something totally outside of Jellyfin's SMB file structure.

Example:

Trailer database sits at smbmount\\sharename\trailers\database\database name.db
Trailer folder sits at:    smbmount\\sharename\trailers

The database has a trailer table with fields like:

Movie title
Jellyfin or Kodi movie ID number
trailer order number
local trailer file name (path and file name) or URL
trailer length
trailer resolution (i.e. 1080P, 720P, 480P etc..)
trailer playcount
movie playcount

The Pythons script called by the context menu would be passed some of the information required to query the database and build a list of trailers that then populate a dialog box and can be selected for playback.  

This is a high level view of how I do it.


Thanks,

Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply
#15
(2023-06-29, 07:17)jepsizofye Wrote: this submenu context is quite hard to work with and achieves very little

the full dialog jeff has is far superior so time to move along

I am curious where you ended up with this  and whether you needed any help with a database driven approach ?


Thanks,

Jeff
Running with the Mezzmo Kodi addon.  The easier way to share your media with multiple Kodi clients.
Service.autostop , CBC Sports, Kodi Selective Cleaner and Mezzmo Kodi addon author.
Reply

Logout Mark Read Team Forum Stats Members Help
Is there anything dynamic available to skins/context menus?0