diff --git a/resources/lib/PlexCompanion.py b/resources/lib/PlexCompanion.py index a16bf50e..9cf71bf5 100644 --- a/resources/lib/PlexCompanion.py +++ b/resources/lib/PlexCompanion.py @@ -12,6 +12,7 @@ from plexbmchelper import listener, plexgdm, subscribers, functions, \ httppersist, plexsettings from PlexFunctions import ParseContainerKey, GetPlexMetadata from PlexAPI import API +from playlist_func import get_pms_playqueue, get_plextype_from_xml import player import variables as v import state @@ -149,6 +150,26 @@ class PlexCompanion(Thread): offset=data.get('offset')) playqueue.plex_transient_token = token + elif task['action'] == 'refreshPlayQueue': + # example data: {'playQueueID': '8475', 'commandID': '11'} + xml = get_pms_playqueue(data['playQueueID']) + if xml is None: + return + if len(xml) == 0: + log.debug('Empty playqueue received - clearing playqueue') + plex_type = get_plextype_from_xml(xml) + if plex_type is None: + return + playqueue = self.mgr.playqueue.get_playqueue_from_type( + v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type]) + playqueue.clear() + return + playqueue = self.mgr.playqueue.get_playqueue_from_type( + v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[xml[0].attrib['type']]) + self.mgr.playqueue.update_playqueue_from_PMS( + playqueue, + data['playQueueID']) + def run(self): # Ensure that sockets will be closed no matter what try: diff --git a/resources/lib/companion.py b/resources/lib/companion.py index 1373b162..7608c920 100644 --- a/resources/lib/companion.py +++ b/resources/lib/companion.py @@ -110,6 +110,12 @@ def process_command(request_path, params, queue=None): 'data': params }) + elif request_path == 'player/playback/refreshPlayQueue': + queue.put({ + 'action': 'refreshPlayQueue', + 'data': params + }) + elif request_path == "player/playback/setParameters": if 'volume' in params: volume = int(params['volume']) diff --git a/resources/lib/playlist_func.py b/resources/lib/playlist_func.py index f1371acd..7ed52a52 100644 --- a/resources/lib/playlist_func.py +++ b/resources/lib/playlist_func.py @@ -1,16 +1,19 @@ import logging from urllib import quote from urlparse import parse_qsl, urlsplit +from re import compile as re_compile import plexdb_functions as plexdb from downloadutils import DownloadUtils as DU from utils import JSONRPC, tryEncode, escape_html from PlexAPI import API +from PlexFunctions import GetPlexMetadata ############################################################################### log = logging.getLogger("PLEX."+__name__) +REGEX = re_compile(r'''metadata%2F(\d+)''') ############################################################################### # kodi_item dict: @@ -566,3 +569,39 @@ def remove_from_Kodi_playlist(playlist, pos): del playlist.items[pos] except IndexError: log.error('Cannot delete position %s for %s' % (pos, playlist)) + + +def get_pms_playqueue(playqueue_id): + """ + Returns the Plex playqueue as an etree XML or None if unsuccessful + """ + xml = DU().downloadUrl( + "{server}/playQueues/%s" % playqueue_id, + headerOptions={'Accept': 'application/xml'}) + try: + xml.attrib + except AttributeError: + log.error('Could not download Plex playqueue %s' % playqueue_id) + xml = None + return xml + + +def get_plextype_from_xml(xml): + """ + Needed if PMS returns an empty playqueue. Will get the Plex type from the + empty playlist playQueueSourceURI. Feed with (empty) etree xml + + returns None if unsuccessful + """ + try: + plex_id = REGEX.findall(xml.attrib['playQueueSourceURI'])[0] + except IndexError: + log.error('Could not get plex_id from xml: %s' % xml.attrib) + return + new_xml = GetPlexMetadata(plex_id) + try: + new_xml[0].attrib + except (TypeError, IndexError, AttributeError): + log.error('Could not get plex metadata for plex id %s' % plex_id) + return + return new_xml[0].attrib.get('type')