From 11e4a70e25fca62ccdf757d9da75d3f79d41281e Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Wed, 13 May 2015 23:48:35 -0500 Subject: [PATCH] Reworked the userclient with possibilities Revoked token was actually broken, handle access schedule better, restart/start properly. This is to stabilize things. --- resources/lib/DownloadUtils.py | 15 ++++++----- resources/lib/UserClient.py | 45 +++++++++++++++++++++++--------- resources/lib/WebSocketClient.py | 7 ++++- service.py | 5 +++- 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/resources/lib/DownloadUtils.py b/resources/lib/DownloadUtils.py index ba06efb4..dabef416 100644 --- a/resources/lib/DownloadUtils.py +++ b/resources/lib/DownloadUtils.py @@ -124,7 +124,6 @@ class DownloadUtils(): self.s.mount("https://", requests.adapters.HTTPAdapter(max_retries=1)) self.logMsg("Requests session started on: %s" % self.server) - self.postCapabilities(self.deviceId) def imageUrl(self, id, type, index, width, height): # To move to API.py @@ -279,13 +278,14 @@ class DownloadUtils(): # Unauthorized status = WINDOW.getProperty("Server_status") - if r.headers['X-Application-Error-Code'] == "ParentalControl": - # Parental control - access restricted - WINDOW.setProperty("Server_status", "restricted") - xbmcgui.Dialog().notification("Emby server", "Access restricted.", xbmcgui.NOTIFICATION_ERROR, time=5000) - return False + if 'x-application-error-code' in r.headers: + if r.headers['X-Application-Error-Code'] == "ParentalControl": + # Parental control - access restricted + WINDOW.setProperty("Server_status", "restricted") + xbmcgui.Dialog().notification("Emby server", "Access restricted.", xbmcgui.NOTIFICATION_ERROR, time=5000) + return False - elif (status == "401") or (status == "Auth"): + if (status == "401") or (status == "Auth"): pass else: @@ -293,6 +293,7 @@ class DownloadUtils(): WINDOW.setProperty("Server_status", "401") self.logMsg("HTTP Error: %s" % e, 0) xbmcgui.Dialog().notification("Error connecting", "Unauthorized.", xbmcgui.NOTIFICATION_ERROR) + return 401 elif (r.status_code == 301) or (r.status_code == 302): # Redirects diff --git a/resources/lib/UserClient.py b/resources/lib/UserClient.py index bb0f166a..0ce3c4bf 100644 --- a/resources/lib/UserClient.py +++ b/resources/lib/UserClient.py @@ -178,6 +178,9 @@ class UserClient(threading.Thread): self.logMsg("Access is restricted.") self.HasAccess = False return + elif self.WINDOW.getProperty('Server_online') != "true": + # Server connection failed + return if self.WINDOW.getProperty("Server_status") == "restricted": self.logMsg("Access is granted.") @@ -186,7 +189,7 @@ class UserClient(threading.Thread): xbmcgui.Dialog().notification("Emby server", "Access is enabled.") return - def loadCurrUser(self): + def loadCurrUser(self, authenticated=False): WINDOW = self.WINDOW doUtils = self.doUtils @@ -199,6 +202,17 @@ class UserClient(threading.Thread): self.ssl = self.getSSLverify() self.sslcert = self.getSSL() + # Test the validity of current token + if authenticated == False: + url = "%s/mediabrowser/Users/%s" % (self.currServer, self.currUserId) + WINDOW.setProperty("currUser", username) + WINDOW.setProperty("accessToken%s" % username, self.currToken) + result = doUtils.downloadUrl(url, type="POST") + if result == 401: + # Token is no longer valid + self.resetClient() + return False + # Set to windows property WINDOW.setProperty("currUser", username) WINDOW.setProperty("accessToken%s" % username, self.currToken) @@ -212,6 +226,8 @@ class UserClient(threading.Thread): doUtils.setServer(self.currServer) doUtils.setToken(self.currToken) doUtils.setSSL(self.ssl, self.sslcert) + # parental control - let's verify if access is restricted + self.hasAccess() # Start DownloadUtils session doUtils.startSession() @@ -239,13 +255,15 @@ class UserClient(threading.Thread): return # If there's a token if (self.getToken() != ""): - self.loadCurrUser() - self.logMsg("Current user: %s" % self.currUser, 0) - self.logMsg("Current userId: %s" % self.currUserId, 0) - self.logMsg("Current accessToken: %s" % self.currToken, 0) - # parental control - let's verify if access is restricted - self.hasAccess() - return + result = self.loadCurrUser() + + if result == False: + pass + else: + self.logMsg("Current user: %s" % self.currUser, 0) + self.logMsg("Current userId: %s" % self.currUserId, 0) + self.logMsg("Current accessToken: %s" % self.currToken, 0) + return users = self.getPublicUsers() password = "" @@ -292,11 +310,12 @@ class UserClient(threading.Thread): if (result != None and accessToken != None): self.currUser = username + xbmcgui.Dialog().notification("Emby server", "Welcome %s!" % self.currUser) userId = result[u'User'][u'Id'] addon.setSetting("accessToken", accessToken) addon.setSetting("userId%s" % username, userId) self.logMsg("User Authenticated: %s" % accessToken) - self.loadCurrUser() + self.loadCurrUser(authenticated=True) self.WINDOW.setProperty("Server_status", "") self.retry = 0 return @@ -318,17 +337,19 @@ class UserClient(threading.Thread): def resetClient(self): + username = self.getUsername() + self.logMsg("Reset UserClient authentication.", 1) if (self.currToken != None): # In case of 401, removed saved token - self.addon.setSetting("accessToken%s" % self.currUser, "") - self.WINDOW.setProperty("accessToken%s" % self.currUser, "") + self.addon.setSetting("accessToken", "") + self.WINDOW.setProperty("accessToken%s" % username, "") self.currToken = None self.logMsg("User token has been removed.", 1) self.auth = True self.currUser = None return - + def run(self): diff --git a/resources/lib/WebSocketClient.py b/resources/lib/WebSocketClient.py index a1c52d2a..1aeff13e 100644 --- a/resources/lib/WebSocketClient.py +++ b/resources/lib/WebSocketClient.py @@ -28,6 +28,7 @@ class WebSocketThread(threading.Thread): _shared_state = {} + doUtils = DownloadUtils() clientInfo = ClientInformation() KodiMonitor = KodiMonitor.Kodi_Monitor() addonName = clientInfo.getAddonName() @@ -258,10 +259,14 @@ class WebSocketThread(threading.Thread): on_close = self.on_close) self.client.on_open = self.on_open + self.doUtils.postCapabilities(deviceId) while not self.KodiMonitor.abortRequested(): - self.client.run_forever() + if WINDOW.getProperty("Server_online") == "true": + # Server came back online, repost capabilities + self.doUtils.postCapabilities(deviceId) + self.client.run_forever() if (self.keepRunning): # Server is not online diff --git a/service.py b/service.py index cff38680..206ece22 100644 --- a/service.py +++ b/service.py @@ -143,7 +143,6 @@ class Service(): if self.KodiMonitor.waitForAbort(1): # Abort was requested while waiting. We should exit break - #WebSocketThread().processPendingActions() else: if self.warn_auth: @@ -155,6 +154,10 @@ class Service(): WINDOW.setProperty("Emby_Service_Timestamp", str(int(time.time()))) user.hasAccess() + if WINDOW.getProperty('Server_online') != "true": + # Server went offline + break + if self.KodiMonitor.waitForAbort(5): # Abort was requested while waiting. We should exit break