Fixes to playQueues for Addon paths
This commit is contained in:
parent
49b5131dbb
commit
eec2c10cb4
4 changed files with 152 additions and 89 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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():
|
||||
|
|
Loading…
Reference in a new issue