Fixed plex companion headers and resume point

This commit is contained in:
tomkat83 2016-01-23 15:53:24 +01:00
parent 58020021fa
commit e0330c1a28
8 changed files with 102 additions and 80 deletions

View file

@ -90,7 +90,7 @@ class Main:
folderid = params['folderid'][0]
modes[mode](itemid, folderid)
elif mode == "companion":
resume = params.get('resume', '')
resume = params.get('resume', '')[0]
modes[mode](itemid, resume=resume)
else:
modes[mode]()

View file

@ -90,8 +90,6 @@ class PlexAPI():
self.userId = utils.window('emby_currUser')
self.token = utils.window('emby_accessToken%s' % self.userId)
self.server = utils.window('emby_server%s' % self.userId)
self.plexLogin = utils.settings('plexLogin')
self.plexToken = utils.settings('plexToken')
self.doUtils = downloadutils.DownloadUtils()
@ -797,6 +795,8 @@ class PlexAPI():
"""
# Get addon infos
xargs = {
"Content-type": "application/x-www-form-urlencoded",
"Access-Control-Allow-Origin": "*",
'X-Plex-Language': 'en',
'X-Plex-Device': self.addonName,
'X-Plex-Client-Platform': self.platform,
@ -1052,8 +1052,8 @@ class PlexAPI():
Will return empty strings if failed.
"""
plexLogin = self.plexLogin
plexToken = self.plexToken
plexLogin = utils.settings('plexLogin')
plexToken = utils.settings('plexToken')
machineIdentifier = utils.settings('plex_machineIdentifier')
self.logMsg("Getting user list.", 1)
# Get list of Plex home users
@ -1412,7 +1412,7 @@ class PlexAPI():
def GetPlexSectionResults(self, viewId, headerOptions={}):
"""
Returns a list (raw JSON API dump) of all Plex items in the Plex
Returns a list (raw JSON or XML API dump) of all Plex items in the Plex
section with key = viewId.
"""
result = []
@ -1421,21 +1421,29 @@ class PlexAPI():
try:
result = jsondata['_children']
except TypeError:
# Received an XML
pass
except:
# Maybe we received an XML, check for that with tag attribute
try:
jsondata.tag
result = jsondata
# Nope, not an XML, abort
except AttributeError:
self.logMsg("Error retrieving all items for Plex section %s"
% viewId, -1)
return result
except KeyError:
self.logMsg("Error retrieving all items for Plex section %s"
% viewId, -1)
return []
return result
def GetAllPlexLeaves(self, viewId, headerOptions={}):
"""
Returns a list (raw JSON API dump) of all Plex subitems for the key.
Returns a list (raw JSON or XML API dump) of all Plex subitems for the
key.
(e.g. /library/sections/2/allLeaves pointing to all TV shows)
Input:
viewId Id of Plex library, e.g. '2'
headerOptions to override the download headers
"""
result = []
url = "{server}/library/sections/%s/allLeaves" % viewId
@ -1443,12 +1451,18 @@ class PlexAPI():
try:
result = jsondata['_children']
except TypeError:
# received an XMl
pass
except KeyError:
self.logMsg("Error retrieving all children for Plex viewId %s"
# Maybe we received an XML, check for that with tag attribute
try:
jsondata.tag
result = jsondata
# Nope, not an XML, abort
except AttributeError:
self.logMsg("Error retrieving all leaves for Plex section %s"
% viewId, -1)
return result
except KeyError:
self.logMsg("Error retrieving all leaves for Plex viewId %s"
% viewId, -1)
pass
return result
def GetAllPlexChildren(self, key):
@ -1471,10 +1485,12 @@ class PlexAPI():
def GetPlexMetadata(self, key):
"""
Returns raw API metadata for key.
Returns raw API metadata for key as an etree XML.
Can be called with either Plex key '/library/metadata/xxxx'metadata
OR with the digits 'xxxx' only.
Returns an empty string '' if something went wrong
"""
xml = ''
key = str(key)
@ -1495,9 +1511,13 @@ class PlexAPI():
url = url + '?' + urlencode(arguments)
headerOptions = {'Accept': 'application/xml'}
xml = self.doUtils.downloadUrl(url, headerOptions=headerOptions)
if not xml:
# Did we receive a valid XML?
try:
xml.tag
# Nope we did not receive a valid XML
except AttributeError:
self.logMsg("Error retrieving metadata for %s" % url, -1)
xml = None
xml = ''
return xml
@ -1534,7 +1554,6 @@ class API():
Which child in the XML response shall we look at and work with?
"""
self.child = int(number)
self.logMsg("Set child number to %s" % number, 1)
def getChildNumber(self):
"""
@ -1592,7 +1611,7 @@ class API():
def getChecksum(self):
"""
Can be used on both XML and JSON
Returns a string, not int!
Returns a string, not int
"""
item = self.item
# XML

View file

@ -80,15 +80,12 @@ class PlexCompanion(threading.Thread):
message_count += 1
if message_count > 30:
if self.stopped():
break
if self.client.check_client_registration():
self.logMsg("Client is still registered", 1)
else:
self.logMsg("Client is no longer registered",
1)
self.logMsg("PlexBMC Helper still running on "
"port %s" % self.port, 1)
self.logMsg("Client is no longer registered", 1)
self.logMsg("PlexBMC Helper still running on port %s"
% self.port, 1)
message_count = 0
if not is_running:

View file

@ -32,7 +32,7 @@ import embydb_functions
#################################################################################################
def plexCompanion(fullurl, resume=""):
def plexCompanion(fullurl, resume=None):
regex = re.compile(r'''/(\d+)$''')
itemid = regex.findall(fullurl)
try:
@ -49,9 +49,12 @@ def plexCompanion(fullurl, resume=""):
# Get dbid using itemid
dbid = emby.getItem_byId(itemid)[0]
embyconn.close()
# Fix resume timing
if resume:
resume = round(float(resume) / 1000.0, 6)
# Start playing
item = PlexAPI.PlexAPI().GetPlexMetadata(itemid)
pbutils.PlaybackUtils(item).play(itemid, dbid)
pbutils.PlaybackUtils(item).play(itemid, dbid, seektime=resume)
def doPlayback(itemid, dbid):

View file

@ -270,7 +270,7 @@ class Movies(Items):
Plex resume points for movies in progress.
"""
API = PlexAPI.API(itemList)
for itemNumber in range(0, len(itemList)):
for itemNumber in range(len(itemList)):
API.setChildNumber(itemNumber)
itemid = API.getKey()
# Get key and db entry on the Kodi db side
@ -890,7 +890,7 @@ class TVShows(Items):
Plex resume points for movies in progress.
"""
API = PlexAPI.API(itemList)
for itemNumber in range(0, len(itemList)):
for itemNumber in range(len(itemList)):
API.setChildNumber(itemNumber)
itemid = API.getKey()
# Get key and db entry on the Kodi db side

View file

@ -64,15 +64,12 @@ class ThreadedGetMetadata(threading.Thread):
except:
raise
# check whether valid XML
try:
# .tag works for XML
plexXML.tag
if plexXML:
updateItem['XML'] = plexXML
# place item into out queue
self.out_queue.put(updateItem)
# If we don't have a valid XML, don't put that into the queue
except AttributeError:
pass
# but skip this item for now
# Keep track of where we are at
with self.lock:
getMetadataCount += 1
@ -128,11 +125,9 @@ class ThreadedProcessMetadata(threading.Thread):
title = updateItem['title']
itemSubFkt = getattr(item, method)
with self.lock:
itemSubFkt(
plexitem,
itemSubFkt(plexitem,
viewtag=viewName,
viewid=viewId
)
viewid=viewId)
# Keep track of where we are at
processMetadataCount += 1
processingViewName = title
@ -170,10 +165,8 @@ class ThreadedShowSyncInfo(threading.Thread):
total = self.total
downloadLock = self.locks[0]
processLock = self.locks[1]
self.dialog.create(
"%s: Sync %s: %s items" % (self.addonName,
self.itemType,
str(total)),
self.dialog.create("%s: Sync %s: %s items"
% (self.addonName, self.itemType, str(total)),
"Starting")
global getMetadataCount
global processMetadataCount
@ -191,11 +184,11 @@ class ThreadedShowSyncInfo(threading.Thread):
percentage = int(float(totalProgress) / float(total)*100.0)
except ZeroDivisionError:
percentage = 0
self.dialog.update(
percentage,
message="Downloaded: %s, Processed: %s: %s" % (
getMetadataProgress, processMetadataProgress, viewName)
)
self.dialog.update(percentage,
message="Downloaded: %s, Processed: %s: %s"
% (getMetadataProgress,
processMetadataProgress, viewName))
# Sleep for x milliseconds
xbmc.sleep(500)
self.dialog.close()
@ -431,8 +424,8 @@ class LibrarySync(threading.Thread):
utils.window('emby_initialScan', clear=True)
xbmcgui.Dialog().notification(
heading=self.addonName,
message="%s completed in: %s" %
(message, str(elapsedtotal).split('.')[0]),
message="%s completed in: %s"
% (message, str(elapsedtotal).split('.')[0]),
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
sound=False)
return True
@ -567,22 +560,25 @@ class LibrarySync(threading.Thread):
Adds items to self.updatelist as well as self.allPlexElementsId dict
Input:
elementList: List of elements, e.g. a list of '_children'
movie elements as received via JSON from PMS
elementList: List of elements, e.g. list of '_children'
movie elements as received from PMS
itemType: 'Movies', 'TVShows', ...
method: Method name to be called with this itemtype
see itemtypes.py
viewName: Name of the Plex view (e.g. 'My TV shows')
viewId: Id/Key of Plex library (e.g. '1')
Output: self.updatelist, self.allPlexElementsId
self.updatelist APPENDED(!!) list itemids (Plex Keys as
as received from API.getKey())
= [
{
One item in this list is of the form:
'itemId': xxx,
'itemType': 'Movies'/'TVShows'/...,
'itemType': 'Movies','TVShows', ...
'method': 'add_update', 'add_updateSeason', ...
'viewName': xxx,
'viewId': xxx
}, ...
]
self.allPlexElementsId APPENDED(!!) dic
self.allPlexElementsId APPENDED(!!) dict
= {itemid: checksum}
"""
if self.compare:
@ -635,6 +631,7 @@ class LibrarySync(threading.Thread):
by then calling itemtypes.<itemType>()
Input:
itemType: 'Movies', 'TVShows', ...
self.updatelist
"""
# Some logging, just in case.
@ -672,7 +669,6 @@ class LibrarySync(threading.Thread):
thread.start()
threads.append(thread)
self.logMsg("%s download threads spawned" % self.syncThreadNumber, 1)
self.logMsg("Queue populated", 1)
# Spawn one more thread to process Metadata, once downloaded
thread = ThreadedProcessMetadata(processMetadataQueue,
itemType,
@ -783,17 +779,17 @@ class LibrarySync(threading.Thread):
"""
starttotal = datetime.now()
plx = PlexAPI.PlexAPI()
# Download XML, not JSON
# Download XML, not JSON, because PMS JSON seems to be damaged
headerOptions = {'Accept': 'application/xml'}
plexItems = plx.GetAllPlexLeaves(viewId,
headerOptions=headerOptions)
itemMth = getattr(itemtypes, itemType)
with itemMth() as method:
method.UpdateWatched(plexItems)
method.updateUserdata(plexItems)
elapsedtotal = datetime.now() - starttotal
self.logMsg("Syncing userdata for itemtype %s and viewid %s took "
"%s seconds" % (itemType, viewId, elapsedtotal), 0)
"%s seconds" % (itemType, viewId, elapsedtotal), 1)
def musicvideos(self, embycursor, kodicursor, pdialog):
# Get musicvideos from emby
@ -877,6 +873,7 @@ class LibrarySync(threading.Thread):
self.allKodiElementsId.update(all_kodiepisodes)
except ValueError:
pass
# Close DB connections
embyconn.close()
##### PROCESS TV Shows #####

View file

@ -47,7 +47,7 @@ class PlaybackUtils():
self.className = self.__class__.__name__
utils.logMsg("%s %s" % (self.addonName, self.className), msg, lvl)
def play(self, itemid, dbid=None):
def play(self, itemid, dbid=None, seektime=None):
self.logMsg("Play called.", 1)
@ -89,6 +89,7 @@ class PlaybackUtils():
############### RESUME POINT ################
if seektime is None:
userdata = API.getUserData()
seektime = userdata['Resume']

View file

@ -200,12 +200,17 @@ class Subscriber:
printDebug("sending xml to subscriber %s: %s" % (self.tostr(), msg))
url = self.protocol + '://' + self.host + ':' + self.port \
+ "/:/timeline"
response = self.download.downloadUrl(url,
# Override some headers
headerOptions = {
'Accept': '*/*'
}
response = self.download.downloadUrl(
url,
postBody=msg,
type="POSTXML")
type="POSTXML",
headerOptions=headerOptions)
# if not requests.post(self.host, self.port, "/:/timeline", msg, getPlexHeaders(), self.protocol):
# subMgr.removeSubscriber(self.uuid)
if response in [False, 401]:
subMgr.removeSubscriber(self.uuid)
subMgr = SubscriptionManager()