Finally support for Extras!

This commit is contained in:
Croneter 2018-05-04 19:03:27 +02:00
parent ce29f5a60e
commit 63f7d5615d
4 changed files with 99 additions and 9 deletions

View file

@ -99,6 +99,9 @@ class Main():
elif mode == 'channels': elif mode == 'channels':
entrypoint.channels() entrypoint.channels()
elif mode == 'extras':
entrypoint.extras(plex_id=params.get('plex_id'))
elif mode == 'settings': elif mode == 'settings':
executebuiltin('Addon.OpenSettings(%s)' % v.ADDON_ID) executebuiltin('Addon.OpenSettings(%s)' % v.ADDON_ID)

View file

@ -99,6 +99,35 @@ class API(object):
""" """
return self.item.get('ratingKey') return self.item.get('ratingKey')
def path(self, force_first_media=True):
"""
Returns a "fully qualified path": add-on paths or direct paths
depending on the current settings. Will NOT valide the playurl
Returns unicode or None if something went wrong.
"""
filename = self.file_path(force_first_media=force_first_media)
if not state.DIRECT_PATHS or self.plex_type() == v.PLEX_TYPE_CLIP:
if filename and '/' in filename:
filename = filename.rsplit('/', 1)
elif filename:
filename = filename.rsplit('\\', 1)
try:
filename = filename[1]
except (TypeError, IndexError):
filename = None
# Set plugin path and media flags using real filename
path = ('plugin://%s/?plex_id=%s&plex_type=%s&mode=play&filename=%s'
% (v.ADDON_TYPE[self.plex_type()],
self.plex_id(),
self.plex_type(),
filename))
else:
# Direct paths is set the Kodi way
path = self.validate_playurl(filename,
self.plex_type(),
omit_check=True)
return path
def path_and_plex_id(self): def path_and_plex_id(self):
""" """
Returns the Plex key such as '/library/metadata/246922' or None Returns the Plex key such as '/library/metadata/246922' or None
@ -655,6 +684,16 @@ class API(object):
answ['bitDepth'] = None answ['bitDepth'] = None
return answ return answ
def extras(self):
"""
Returns a list of XML etree elements for each extra, e.g. a trailer.
"""
answ = []
for extras in self.item.iterfind('Extras'):
for extra in extras:
answ.append(extra)
return answ
def trailer_id(self): def trailer_id(self):
""" """
Returns the ratingKey (plex_id) of the trailer or None Returns the ratingKey (plex_id) of the trailer or None

View file

@ -2,13 +2,16 @@
############################################################################### ###############################################################################
from logging import getLogger from logging import getLogger
from xbmc import getInfoLabel, sleep, executebuiltin
from xbmcaddon import Addon from xbmcaddon import Addon
import xbmc
import xbmcplugin
import xbmcgui
import plexdb_functions as plexdb import plexdb_functions as plexdb
from utils import window, settings, dialog, language as lang from utils import window, settings, dialog, language as lang
from dialogs import context from dialogs import context
from PlexFunctions import delete_item_from_pms import PlexFunctions as PF
from PlexAPI import API
import playqueue as PQ import playqueue as PQ
import variables as v import variables as v
import state import state
@ -25,7 +28,8 @@ OPTIONS = {
# 'RemoveFav': lang(30406), # 'RemoveFav': lang(30406),
# 'RateSong': lang(30407), # 'RateSong': lang(30407),
'Transcode': lang(30412), 'Transcode': lang(30412),
'PMS_Play': lang(30415) # Use PMS to start playback 'PMS_Play': lang(30415), # Use PMS to start playback
'Extras': lang(30235)
} }
############################################################################### ###############################################################################
@ -53,17 +57,24 @@ class ContextMenu(object):
self.plex_id, self.plex_type) self.plex_id, self.plex_type)
if not self.plex_id: if not self.plex_id:
return return
xml = PF.GetPlexMetadata(self.plex_id)
try:
xml[0].attrib
except (TypeError, IndexError, KeyError):
self.api = None
else:
self.api = API(xml[0])
if self._select_menu(): if self._select_menu():
self._action_menu() self._action_menu()
if self._selected_option in (OPTIONS['Delete'], if self._selected_option in (OPTIONS['Delete'],
OPTIONS['Refresh']): OPTIONS['Refresh']):
LOG.info("refreshing container") LOG.info("refreshing container")
sleep(500) xbmc.sleep(500)
executebuiltin('Container.Refresh') xbmc.executebuiltin('Container.Refresh')
@staticmethod @staticmethod
def _get_plex_id(kodi_id, kodi_type): def _get_plex_id(kodi_id, kodi_type):
plex_id = getInfoLabel('ListItem.Property(plexid)') or None plex_id = xbmc.getInfoLabel('ListItem.Property(plexid)') or None
if not plex_id and kodi_id and kodi_type: if not plex_id and kodi_id and kodi_type:
with plexdb.Get_Plex_DB() as plexcursor: with plexdb.Get_Plex_DB() as plexcursor:
item = plexcursor.getItem_byKodiId(kodi_id, kodi_type) item = plexcursor.getItem_byKodiId(kodi_id, kodi_type)
@ -79,6 +90,8 @@ class ContextMenu(object):
""" """
options = [] options = []
# if user uses direct paths, give option to initiate playback via PMS # if user uses direct paths, give option to initiate playback via PMS
if self.api and self.api.extras():
options.append(OPTIONS['Extras'])
if state.DIRECT_PATHS and self.kodi_type in v.KODI_VIDEOTYPES: if state.DIRECT_PATHS and self.kodi_type in v.KODI_VIDEOTYPES:
options.append(OPTIONS['PMS_Play']) options.append(OPTIONS['PMS_Play'])
if self.kodi_type in v.KODI_VIDEOTYPES: if self.kodi_type in v.KODI_VIDEOTYPES:
@ -122,6 +135,8 @@ class ContextMenu(object):
self._PMS_play() self._PMS_play()
elif selected == OPTIONS['PMS_Play']: elif selected == OPTIONS['PMS_Play']:
self._PMS_play() self._PMS_play()
elif selected == OPTIONS['Extras']:
self._extras()
# elif selected == OPTIONS['Refresh']: # elif selected == OPTIONS['Refresh']:
# self.emby.refreshItem(self.item_id) # self.emby.refreshItem(self.item_id)
# elif selected == OPTIONS['AddFav']: # elif selected == OPTIONS['AddFav']:
@ -131,7 +146,8 @@ class ContextMenu(object):
# elif selected == OPTIONS['RateSong']: # elif selected == OPTIONS['RateSong']:
# self._rate_song() # self._rate_song()
elif selected == OPTIONS['Addon']: elif selected == OPTIONS['Addon']:
executebuiltin('Addon.OpenSettings(plugin.video.plexkodiconnect)') xbmc.executebuiltin(
'Addon.OpenSettings(plugin.video.plexkodiconnect)')
elif selected == OPTIONS['Delete']: elif selected == OPTIONS['Delete']:
self._delete_item() self._delete_item()
@ -146,7 +162,7 @@ class ContextMenu(object):
delete = False delete = False
if delete: if delete:
LOG.info("Deleting Plex item with id %s", self.plex_id) LOG.info("Deleting Plex item with id %s", self.plex_id)
if delete_item_from_pms(self.plex_id) is False: if PF.delete_item_from_pms(self.plex_id) is False:
dialog("ok", heading="{plex}", line1=lang(30414)) dialog("ok", heading="{plex}", line1=lang(30414))
def _PMS_play(self): def _PMS_play(self):
@ -161,4 +177,16 @@ class ContextMenu(object):
% (v.ADDON_TYPE[self.plex_type], % (v.ADDON_TYPE[self.plex_type],
self.plex_id, self.plex_id,
self.plex_type)) self.plex_type))
executebuiltin('RunPlugin(%s)' % handle) xbmc.executebuiltin('RunPlugin(%s)' % handle)
def _extras(self):
"""
Displays a list of elements for all the extras of the Plex element
"""
handle = ('plugin://plugin.video.plexkodiconnect?mode=extras&plex_id=%s'
% self.plex_id)
if xbmcgui.getCurrentWindowId() == 10025:
# Video Window
xbmc.executebuiltin('Container.Update(\"%s\")' % handle)
else:
xbmc.executebuiltin('ActivateWindow(videos, \"%s\")' % handle)

View file

@ -841,6 +841,26 @@ def __build_item(xml_element):
listitem=listitem) listitem=listitem)
def extras(plex_id):
"""
Lists all extras for plex_id
"""
xbmcplugin.setContent(HANDLE, 'movies')
xml = GetPlexMetadata(plex_id)
try:
xml[0].attrib
except (TypeError, IndexError, KeyError):
xbmcplugin.endOfDirectory(HANDLE)
return
for item in API(xml[0]).extras():
api = API(item)
listitem = api.create_listitem()
xbmcplugin.addDirectoryItem(handle=HANDLE,
url=api.path(),
listitem=listitem)
xbmcplugin.endOfDirectory(HANDLE)
def enterPMS(): def enterPMS():
""" """
Opens dialogs for the user the plug in the PMS details Opens dialogs for the user the plug in the PMS details