Fixes to playQueues for Addon paths

This commit is contained in:
tomkat83 2016-12-28 19:38:43 +01:00
parent 49b5131dbb
commit eec2c10cb4
4 changed files with 152 additions and 89 deletions

View file

@ -88,11 +88,16 @@ class PlexCompanion(Thread):
if ID != playqueue.ID:
# playqueue changed somehow
self.mgr.playqueue.update_playqueue_from_PMS(
playqueue, ID, int(query['repeat']), data['offset'])
playqueue,
ID,
query.get('repeat'),
data.get('offset'))
else:
# No change to the playqueue
self.mgr.playqueue.start_playqueue_initiated_by_companion(
playqueue, int(query['repeat']), data['offset'])
playqueue,
query.get('repeat'),
data.get('offset'))
def run(self):
httpd = False

View file

@ -17,6 +17,7 @@ import downloadutils
import PlexAPI
import PlexFunctions as PF
import playlist_func as PL
###############################################################################
@ -36,9 +37,12 @@ class PlaybackUtils():
self.userid = window('currUserId')
self.server = window('pms_server')
self.pl = Playqueue().get_playqueue_from_type(
PF.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[self.API.getType()])
playqueue = Playqueue()
# We need to initialize already existing items as we have a completely
# different Python instance!
playqueue.init_playlists()
self.pl = playqueue.get_playqueue_from_type(
PF.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[item[0].attrib.get('type')])
def play(self, itemid, dbid=None):
@ -51,6 +55,7 @@ class PlaybackUtils():
playutils = putils.PlayUtils(item[0])
log.info("Play called.")
log.debug('Playqueue: %s' % self.pl)
playurl = playutils.getPlayUrl()
if not playurl:
return xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem)
@ -108,6 +113,9 @@ class PlaybackUtils():
############### RESUME POINT ################
seektime, runtime = API.getRuntime()
if window('plex_customplaylist.seektime'):
# Already got seektime, e.g. from playqueue & Plex companion
seektime = int(window('plex_customplaylist.seektime'))
# We need to ensure we add the intro and additional parts only once.
# Otherwise we get a loop.
@ -120,12 +128,20 @@ class PlaybackUtils():
window('plex_customplaylist') != "true" and
not contextmenu_play):
log.debug("Adding dummy file to playlist.")
# Make sure Kodimonitor recognizes dummy
listitem.setLabel('plex_dummyfile')
dummyPlaylist = True
kodiPl.add(playurl, listitem, index=startPos)
PL.add_listitem_to_Kodi_playlist(
self.pl,
listitem,
playurl,
startPos)
# Remove the original item from playlist
self.pl.removefromPlaylist(startPos+1)
# Readd the original item to playlist - via jsonrpc so we have full metadata
self.pl.insertintoPlaylist(
PL.remove_from_Kodi_playlist(self.pl, startPos+1)
# Readd the original item to playlist - via jsonrpc so we have
# full metadata
PL.insert_into_Kodi_playlist(
self.pl,
self.currentPosition+1,
dbid,
PF.KODITYPE_FROM_PLEXTYPE[API.getType()])
@ -146,9 +162,10 @@ class PlaybackUtils():
# Extend our current playlist with the actual item to play
# only if there's no playlist first
log.info("Adding main item to playlist.")
self.pl.addtoPlaylist(
dbid,
PF.KODITYPE_FROM_PLEXTYPE[API.getType()])
PL.add_dbid_to_Kodi_playlist(
self.pl,
dbid=dbid,
mediatype=PF.KODITYPE_FROM_PLEXTYPE[API.getType()])
elif contextmenu_play:
if window('useDirectPaths') == 'true':
@ -168,10 +185,11 @@ class PlaybackUtils():
kodiPl.add(playurl, listitem, index=self.currentPosition+1)
else:
# Full metadata
self.pl.insertintoPlaylist(
PL.insert_into_Kodi_playlist(
self.pl,
self.currentPosition+1,
dbid,
PF.KODITYPE_FROM_PLEXTYPE[API.getType()])
dbid=dbid,
mediatype=PF.KODITYPE_FROM_PLEXTYPE[API.getType()])
self.currentPosition += 1
if seektime:
window('plex_customplaylist.seektime', value=str(seektime))
@ -201,7 +219,6 @@ class PlaybackUtils():
kodiPl.add(additionalPlayurl, additionalListItem,
index=self.currentPosition)
self.pl.verifyPlaylist()
self.currentPosition += 1
API.setPartNumber(0)
@ -287,7 +304,10 @@ class PlaybackUtils():
introPlayurl = path + '?' + urlencode(params)
log.info("Adding Intro: %s" % introPlayurl)
self.pl.insertintoPlaylist(self.currentPosition, url=introPlayurl)
PL.insert_into_Kodi_playlist(
self.pl,
self.currentPosition,
url=introPlayurl)
self.currentPosition += 1
return True

View file

@ -3,7 +3,7 @@ from urllib import quote
import embydb_functions as embydb
from downloadutils import DownloadUtils as DU
from utils import JSONRPC, tryEncode
from utils import window, JSONRPC, tryEncode
from PlexAPI import API
###############################################################################
@ -250,6 +250,57 @@ def move_playlist_item(playlist, before_pos, after_pos):
playlist.items.insert(after_pos, playlist.items.pop(before_pos))
def get_PMS_playlist(playlist, playlist_id=None):
"""
Fetches the PMS playlist/playqueue as an XML. Pass in playlist_id if we
need to fetch a new playlist
Returns None if something went wrong
"""
playlist_id = playlist_id if playlist_id else playlist.ID
xml = DU().downloadUrl(
"{server}/%ss/%s" % (playlist.kind, playlist_id),
headerOptions={'Accept': 'application/xml'})
try:
xml.attrib['%sID' % playlist.kind]
except (AttributeError, KeyError):
xml = None
return xml
def refresh_playlist_from_PMS(playlist):
"""
Only updates the selected item from the PMS side (e.g.
playQueueSelectedItemID). Will NOT check whether items still make sense.
"""
xml = get_PMS_playlist(playlist)
try:
xml.attrib['%sVersion' % playlist.kind]
except:
log.error('Could not download Plex playlist.')
return
_get_playlist_details_from_xml(playlist, xml)
def update_playlist_from_PMS(playlist, playlist_id=None):
"""
Updates Kodi playlist using a new PMS playlist. Pass in playlist_id if we
need to fetch a new playqueue
"""
xml = get_PMS_playlist(playlist, playlist_id)
try:
xml.attrib['%sVersion' % playlist.kind]
except:
log.error('Could not download Plex playlist.')
return
# Clear our existing playlist and the associated Kodi playlist
playlist.clear()
# Set new values
_get_playlist_details_from_xml(playlist, xml)
for plex_item in xml:
playlist.items.append(add_to_Kodi_playlist(playlist, plex_item))
def delete_playlist_item(playlist, pos):
"""
Delete the item at position pos [int]
@ -333,13 +384,43 @@ def add_to_Kodi_playlist(playlist, xml_video_element):
return item
def insertintoPlaylist(self,
position,
dbid=None,
mediatype=None,
url=None):
def add_listitem_to_Kodi_playlist(playlist, listitem, file, index):
"""
Adds an xbmc listitem to the Kodi playlist. Will be ignored by kodimonitor
by settings window('plex_ignore_Playlist.OnAdd')
"""
playlist.kodi_pl.add(file, listitem, index=index)
def add_dbid_to_Kodi_playlist(playlist, dbid=None, mediatype=None, url=None):
params = {
'playlistid': self.playlistId,
'playlistid': playlist.playlistid
}
if dbid is not None:
params['item'] = {'%sid' % tryEncode(mediatype): int(dbid)}
else:
params['item'] = {'file': url}
log.debug(JSONRPC('Playlist.Add').execute(params))
def remove_from_Kodi_playlist(playlist, position):
"""
Removes the item at position from the Kodi playlist using JSON. Will be
ignored by kodimonitor by settings window('plex_ignore_Playlist.OnRemove')
"""
log.debug('Removing position %s from playlist %s' % (position, playlist))
log.debug(JSONRPC('Playlist.Remove').execute({
'playlistid': playlist.playlistid,
'position': position
}))
def insert_into_Kodi_playlist(playlist, position, dbid=None, mediatype=None,
url=None):
"""
"""
params = {
'playlistid': playlist.playlistid,
'position': position
}
if dbid is not None:
@ -349,64 +430,7 @@ def insertintoPlaylist(self,
JSONRPC('Playlist.Insert').execute(params)
def removefromPlaylist(self, position):
params = {
'playlistid': self.playlistId,
'position': position
}
log.debug(JSONRPC('Playlist.Remove').execute(params))
def get_PMS_playlist(playlist, playlist_id=None):
"""
Fetches the PMS playlist/playqueue as an XML. Pass in playlist_id if we
need to fetch a new playlist
Returns None if something went wrong
"""
playlist_id = playlist_id if playlist_id else playlist.ID
xml = DU().downloadUrl(
"{server}/%ss/%s" % (playlist.kind, playlist_id),
headerOptions={'Accept': 'application/xml'})
try:
xml.attrib['%sID' % playlist.kind]
except (AttributeError, KeyError):
xml = None
return xml
def refresh_playlist_from_PMS(playlist):
"""
Only updates the selected item from the PMS side (e.g.
playQueueSelectedItemID). Will NOT check whether items still make sense.
"""
xml = get_PMS_playlist(playlist)
try:
xml.attrib['%sVersion' % playlist.kind]
except:
log.error('Could not download Plex playlist.')
return
_get_playlist_details_from_xml(playlist, xml)
def update_playlist_from_PMS(playlist, playlist_id=None):
"""
Updates Kodi playlist using a new PMS playlist. Pass in playlist_id if we
need to fetch a new playqueue
"""
xml = get_PMS_playlist(playlist, playlist_id)
try:
xml.attrib['%sVersion' % playlist.kind]
except:
log.error('Could not download Plex playlist.')
return
# Clear our existing playlist and the associated Kodi playlist
playlist.clear()
# Set new values
_get_playlist_details_from_xml(playlist, xml)
for plex_item in xml:
playlist.items.append(add_to_Kodi_playlist(playlist, plex_item))
# NOT YET UPDATED!!
def _processItems(self, startitem, startPlayer=False):
startpos = None

View file

@ -94,7 +94,7 @@ class Playqueue(Thread):
"""
log.info('New playqueue received from the PMS, updating!')
PL.update_playlist_from_PMS(playqueue, playqueue_id)
playqueue.repeat = repeat
playqueue.repeat = 0 if not repeat else int(repeat)
log.debug('Updated playqueue: %s' % playqueue)
window('plex_customplaylist', value="true")
@ -124,7 +124,7 @@ class Playqueue(Thread):
# Still need to get new playQueue from the server - don't know what has
# been selected
PL.refresh_playlist_from_PMS(playqueue)
playqueue.repeat = repeat
playqueue.repeat = 0 if not repeat else int(repeat)
window('plex_customplaylist', value="true")
if offset not in (None, "0"):
window('plex_customplaylist.seektime',
@ -153,6 +153,13 @@ class Playqueue(Thread):
}
"""
playqueue = self.playqueues[data['playlistid']]
if data['item'].get('id') is None and data['item'].get('file') is None:
# Kodi screwed up. Let's try to get the data anyway
items = PL.get_kodi_playlist_items(playqueue)
if items[data['position']].get('id') is not None:
data['item']['id'] = items[data['position']].get('id')
else:
data['item']['file'] = items[data['position']].get('file')
if playqueue.PKC_playlist_edits:
old = (data['item'].get('id') if data['item'].get('id')
else data['item'].get('file'))
@ -212,17 +219,24 @@ class Playqueue(Thread):
# monitor!
log.debug('New playqueue: %s' % playqueue)
def run(self):
threadStopped = self.threadStopped
threadSuspended = self.threadSuspended
log.info("----===## Starting PlayQueue client ##===----")
# Initialize the playqueues, if Kodi already got items in them
def init_playlists(self):
"""
Initializes the playqueues with already existing items.
Called on startup AND for addon paths!
"""
for playqueue in self.playqueues:
for i, item in enumerate(PL.get_kodi_playlist_items(playqueue)):
if i == 0:
PL.init_Plex_playlist(playqueue, kodi_item=item)
else:
PL.add_playlist_item(playqueue, item, i)
def run(self):
threadStopped = self.threadStopped
threadSuspended = self.threadSuspended
log.info("----===## Starting PlayQueue client ##===----")
# Initialize the playqueues, if Kodi already got items in them
self.init_playlists()
while not threadStopped():
while threadSuspended():
if threadStopped():