Plex home user switch working
This commit is contained in:
parent
0d4c8ae53e
commit
42bd570187
7 changed files with 66 additions and 39 deletions
|
@ -39,9 +39,9 @@ def plexCompanion(fullurl, resume=None):
|
|||
except IndexError:
|
||||
# No matches found, url not like:
|
||||
# http://192.168.0.2:32400/library/metadata/243480
|
||||
utils.logMsg("plexCompanion", "Could not parse url: %s" % fullurl, -1)
|
||||
utils.logMsg("entrypoint - plexCompanion",
|
||||
"Could not parse url: %s" % fullurl, -1)
|
||||
return False
|
||||
# TODO: direct play an URL
|
||||
# Initialize embydb
|
||||
embyconn = utils.kodiSQL('emby')
|
||||
embycursor = embyconn.cursor()
|
||||
|
@ -272,14 +272,16 @@ def switchPlexUser():
|
|||
# Delete any userimages. Since there's always only 1 user: position = 0
|
||||
# position = 0
|
||||
# utils.window('EmbyAdditionalUserImage.%s' % position, clear=True)
|
||||
utils.logMsg("PLEX", "Plex home user switch requested", 0)
|
||||
utils.logMsg("entrypoint switchPlexUser",
|
||||
"Plex home user switch requested", 0)
|
||||
# Pause library sync thread - user needs to be auth in order to sync
|
||||
utils.window('suspend_LibraryThread', value='true')
|
||||
# Wait 1 second to ensure that library thread is indeed suspended
|
||||
xbmc.sleep(1000)
|
||||
# Log out currently signed in user:
|
||||
utils.window('emby_serverStatus', value="401")
|
||||
# Request lib sync to get user view data (e.g. watched/unwatched)
|
||||
utils.window('plex_runLibScan', value='true')
|
||||
# Reset Plex userdata: resume points, watched/unwatched status
|
||||
|
||||
|
||||
##### THEME MUSIC/VIDEOS #####
|
||||
|
|
|
@ -178,6 +178,7 @@ class ThreadedShowSyncInfo(threading.Thread):
|
|||
|
||||
|
||||
@utils.logging
|
||||
@utils.ThreadMethodsAdditionalSuspend('suspend_LibraryThread')
|
||||
@utils.ThreadMethodsStopsync
|
||||
@utils.ThreadMethods
|
||||
class LibrarySync(threading.Thread):
|
||||
|
@ -225,7 +226,7 @@ class LibrarySync(threading.Thread):
|
|||
self.maintainViews()
|
||||
completed = False
|
||||
|
||||
completed = self.fastSync()
|
||||
# completed = self.fastSync()
|
||||
|
||||
if not completed:
|
||||
# Fast sync failed or server plugin is not found
|
||||
|
@ -1158,9 +1159,14 @@ class LibrarySync(threading.Thread):
|
|||
# This will prevent an infinite loop in case something goes wrong.
|
||||
startupComplete = True
|
||||
|
||||
# Process updates
|
||||
if utils.window('emby_dbScan') != "true":
|
||||
self.incrementalSync()
|
||||
# Currently no db scan, so we can start a new scan
|
||||
if utils.window('plex_runLibScan') == "true":
|
||||
self.logMsg('Full library scan requested, starting', 1)
|
||||
utils.window('plex_runLibScan', value='false')
|
||||
self.fullSync(manualrun=True)
|
||||
else:
|
||||
self.incrementalSync()
|
||||
|
||||
if (utils.window('emby_onWake') == "true" and
|
||||
utils.window('emby_online') == "true"):
|
||||
|
@ -1172,10 +1178,7 @@ class LibrarySync(threading.Thread):
|
|||
librarySync = self.startSync()
|
||||
self.logMsg("SyncDatabase onWake (finished) %s" % librarySync, 0)
|
||||
|
||||
if self.threadStopped():
|
||||
# Set in service.py
|
||||
self.logMsg("Service terminated thread.", 2)
|
||||
break
|
||||
xbmc.sleep(1000)
|
||||
|
||||
self.logMsg("###===--- LibrarySync Stopped ---===###", 0)
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ class PlaybackUtils():
|
|||
|
||||
def play(self, itemid, dbid=None, seektime=None):
|
||||
|
||||
self.logMsg("Play called.", 1)
|
||||
self.logMsg("Play called with itemid: %s, dbid: %s, seektime: %s."
|
||||
% (itemid, dbid, seektime), 1)
|
||||
|
||||
doUtils = self.doUtils
|
||||
item = self.item
|
||||
|
|
|
@ -82,6 +82,7 @@ class Player(xbmc.Player):
|
|||
else: tryCount += 1
|
||||
|
||||
else:
|
||||
utils.window('Plex_currently_playing_itemid', value=itemId)
|
||||
self.logMsg("ONPLAYBACK_STARTED: %s itemid: %s" % (currentFile, itemId), 0)
|
||||
|
||||
# Only proceed if an itemId was found.
|
||||
|
@ -113,7 +114,7 @@ class Player(xbmc.Player):
|
|||
muted = result.get('muted')
|
||||
|
||||
# Postdata structure to send to Emby server
|
||||
url = "{server}/emby/Sessions/Playing"
|
||||
url = "{server}/:/timeline?"
|
||||
postdata = {
|
||||
|
||||
'QueueableMediaTypes': "Video",
|
||||
|
@ -194,8 +195,8 @@ class Player(xbmc.Player):
|
|||
|
||||
|
||||
# Post playback to server
|
||||
self.logMsg("Sending POST play started: %s." % postdata, 2)
|
||||
self.doUtils.downloadUrl(url, postBody=postdata, type="POST")
|
||||
# self.logMsg("Sending POST play started: %s." % postdata, 2)
|
||||
# self.doUtils.downloadUrl(url, postBody=postdata, type="POST")
|
||||
|
||||
# Ensure we do have a runtime
|
||||
try:
|
||||
|
@ -370,10 +371,9 @@ class Player(xbmc.Player):
|
|||
|
||||
# Report progress via websocketclient
|
||||
# postdata = json.dumps(postdata)
|
||||
self.logMsg("Report: %s" % postdata, 2)
|
||||
# self.ws.sendProgressUpdate(postdata)
|
||||
url = "{server}/:/timeline?" + urlencode(postdata)
|
||||
self.doUtils.downloadUrl(url, type="GET")
|
||||
self.doUtils.downloadUrl(
|
||||
"{server}/:/timeline?" + urlencode(postdata), type="GET")
|
||||
|
||||
def onPlayBackPaused( self ):
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ class SubscriptionManager:
|
|||
self.protocol = "http"
|
||||
self.port = ""
|
||||
self.playerprops = {}
|
||||
self.sentstopped = True
|
||||
self.download = downloadutils.DownloadUtils()
|
||||
|
||||
def getVolume(self):
|
||||
|
@ -60,11 +59,25 @@ class SubscriptionManager:
|
|||
ret = "\r\n"+'<Timeline location="%s" state="%s" time="%s" type="%s"' % (self.mainlocation, state, time, ptype)
|
||||
if playerid is not None:
|
||||
WINDOW = xbmcgui.Window(10000)
|
||||
pbmc_server = str(WINDOW.getProperty('plexbmc.nowplaying.server'))
|
||||
keyid = str(WINDOW.getProperty('plexbmc.nowplaying.id'))
|
||||
|
||||
# pbmc_server = str(WINDOW.getProperty('plexbmc.nowplaying.server'))
|
||||
# userId = str(WINDOW.getProperty('emby_currUser'))
|
||||
# pbmc_server = str(WINDOW.getProperty('emby_server%s' % userId))
|
||||
pbmc_server = None
|
||||
keyid = None
|
||||
count = 0
|
||||
while not keyid:
|
||||
if count > 10:
|
||||
break
|
||||
keyid = str(WINDOW.getProperty('Plex_currently_playing_itemid'))
|
||||
xbmc.sleep(1000)
|
||||
count += 1
|
||||
if keyid:
|
||||
self.lastkey = "/library/metadata/%s"%keyid
|
||||
self.lastratingkey = keyid
|
||||
ret += ' containerKey="%s"' % (self.lastkey)
|
||||
ret += ' key="%s"' % (self.lastkey)
|
||||
ret += ' ratingKey="%s"' % (self.lastratingkey)
|
||||
if pbmc_server:
|
||||
(self.server, self.port) = pbmc_server.split(':')
|
||||
serv = getServerByHost(self.server)
|
||||
|
@ -76,9 +89,6 @@ class SubscriptionManager:
|
|||
ret += ' address="%s"' % serv.get('server', self.server)
|
||||
ret += ' port="%s"' % serv.get('port', self.port)
|
||||
ret += ' guid="%s"' % info['guid']
|
||||
ret += ' containerKey="%s"' % (self.lastkey or "/library/metadata/900000")
|
||||
ret += ' key="%s"' % (self.lastkey or "/library/metadata/900000")
|
||||
ret += ' ratingKey="%s"' % (self.lastratingkey or "900000")
|
||||
ret += ' volume="%s"' % info['volume']
|
||||
ret += ' shuffle="%s"' % info['shuffle']
|
||||
|
||||
|
@ -103,7 +113,8 @@ class SubscriptionManager:
|
|||
return True
|
||||
|
||||
def notifyServer(self, players):
|
||||
if not players and self.sentstopped: return True
|
||||
if not players:
|
||||
return True
|
||||
params = {'state': 'stopped'}
|
||||
for p in players.values():
|
||||
info = self.playerprops[p.get('playerid')]
|
||||
|
@ -120,14 +131,12 @@ class SubscriptionManager:
|
|||
+ serv.get('port', 32400) + "/:/timeline"
|
||||
self.download.downloadUrl(url, type="GET", parameters=params)
|
||||
# requests.getwithparams(serv.get('server', 'localhost'), serv.get('port', 32400), "/:/timeline", params, getPlexHeaders(), serv.get('protocol', 'http'))
|
||||
printDebug("params: %s" % params)
|
||||
printDebug("players: %s" % players)
|
||||
printDebug("sent server notification with state = %s" % params['state'])
|
||||
WINDOW = xbmcgui.Window(10000)
|
||||
WINDOW.setProperty('plexbmc.nowplaying.sent', '1')
|
||||
if players:
|
||||
self.sentstopped = False
|
||||
else:
|
||||
self.sentstopped = True
|
||||
|
||||
|
||||
def controllable(self):
|
||||
return "playPause,play,stop,skipPrevious,skipNext,volume,stepBack,stepForward,seekTo"
|
||||
|
||||
|
|
|
@ -260,7 +260,6 @@ class UserClient(threading.Thread):
|
|||
def authenticate(self):
|
||||
# Get /profile/addon_data
|
||||
plx = PlexAPI.PlexAPI()
|
||||
lib = librarysync.LibrarySync()
|
||||
addondir = xbmc.translatePath(self.addon.getAddonInfo('profile')).decode('utf-8')
|
||||
hasSettings = xbmcvfs.exists("%ssettings.xml" % addondir)
|
||||
|
||||
|
@ -288,7 +287,8 @@ class UserClient(threading.Thread):
|
|||
self.logMsg("Current user: %s" % self.currUser, 1)
|
||||
self.logMsg("Current userId: %s" % self.currUserId, 1)
|
||||
self.logMsg("Current accessToken: xxxx", 1)
|
||||
lib.resumeThread()
|
||||
|
||||
utils.window('suspend_LibraryThread', value='false')
|
||||
return
|
||||
|
||||
##### AUTHENTICATE USER #####
|
||||
|
@ -326,7 +326,7 @@ class UserClient(threading.Thread):
|
|||
utils.window('plex_machineIdentifier', plex_machineIdentifier)
|
||||
self.retry = 0
|
||||
# Make sure that lib sync thread is not paused
|
||||
lib.resumeThread()
|
||||
utils.window('suspend_LibraryThread', value='false')
|
||||
else:
|
||||
self.logMsg("Error: user authentication failed.", -1)
|
||||
utils.settings('accessToken', value="")
|
||||
|
|
|
@ -37,6 +37,22 @@ def ThreadMethodsStopsync(cls):
|
|||
return cls
|
||||
|
||||
|
||||
def ThreadMethodsAdditionalSuspend(windowAttribute):
|
||||
"""
|
||||
Decorator to replace threadSuspended(): thread now also suspends if a
|
||||
Kodi windowAttribute is set to 'true', e.g. 'suspend_LibraryThread'
|
||||
|
||||
Use with any library sync threads. @ThreadMethods still required FIRST
|
||||
"""
|
||||
def wrapper(cls):
|
||||
def threadSuspended(self):
|
||||
return (self._threadSuspended or True if
|
||||
window(windowAttribute) == 'true' else False)
|
||||
cls.threadSuspended = threadSuspended
|
||||
return cls
|
||||
return wrapper
|
||||
|
||||
|
||||
def ThreadMethods(cls):
|
||||
"""
|
||||
Decorator to add the following methods to a threading class:
|
||||
|
@ -86,8 +102,8 @@ def ThreadMethods(cls):
|
|||
|
||||
def logging(cls):
|
||||
"""
|
||||
A decorator adding logging capabilities to classes. Also adds
|
||||
self.addonName to the class
|
||||
A decorator adding logging capabilities to classes.
|
||||
Also adds self.addonName to the class
|
||||
|
||||
Syntax: self.logMsg(message, loglevel)
|
||||
|
||||
|
@ -102,9 +118,6 @@ def logging(cls):
|
|||
logMsg(title, msg, lvl)
|
||||
cls.logMsg = newFunction
|
||||
|
||||
# Override the name, we don't want the decorators name showing up
|
||||
__name__ = cls.__name__
|
||||
|
||||
# Return class to render this a decorator
|
||||
return cls
|
||||
|
||||
|
@ -143,7 +156,6 @@ def window(property, value=None, clear=False, windowid=10000):
|
|||
property = property.encode("utf-8")
|
||||
if isinstance(value, unicode):
|
||||
value = value.encode("utf-8")'''
|
||||
|
||||
if clear:
|
||||
WINDOW.clearProperty(property)
|
||||
elif value is not None:
|
||||
|
|
Loading…
Reference in a new issue