diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index 50655623..0f85d543 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -645,7 +645,11 @@ class PlexAPI(): # Ping to check whether we need HTTPs or HTTP url = (self.getPMSProperty(ATV_udid, uuid_id, 'ip') + ':' + self.getPMSProperty(ATV_udid, uuid_id, 'port')) - if PMSHttpsEnabled(url): + https = PMSHttpsEnabled(url) + if https is None: + # Error contacting url + continue + elif https: self.updatePMSProperty(ATV_udid, uuid_id, 'scheme', 'https') else: self.updatePMSProperty(ATV_udid, uuid_id, 'scheme', 'http') diff --git a/resources/lib/PlexCompanion.py b/resources/lib/PlexCompanion.py index 203095f0..bd35daa1 100644 --- a/resources/lib/PlexCompanion.py +++ b/resources/lib/PlexCompanion.py @@ -63,22 +63,19 @@ class PlexCompanion(threading.Thread): message_count = 0 is_running = False while not self.threadStopped(): - while self.threadSuspended(): - if self.threadStopped(): - break - xbmc.sleep(3000) # If we are not authorized, sleep # Otherwise, we trigger a download which leads to a # re-authorizations - if window('emby_serverStatus'): - xbmc.sleep(3000) - continue + while self.threadSuspended() or window('emby_serverStatus'): + if self.threadStopped(): + break + xbmc.sleep(1000) try: httpd.handle_request() message_count += 1 - if message_count > 30: + if message_count > 100: if self.client.check_client_registration(): self.logMsg("Client is still registered", 1) else: @@ -96,7 +93,7 @@ class PlexCompanion(threading.Thread): xbmc.sleep(50) except: self.logMsg("Error in loop, continuing anyway", 1) - self.logMsg(traceback.print_exc(), 1) + self.logMsg(traceback.format_exc(), 1) xbmc.sleep(50) self.client.stop_all() diff --git a/resources/lib/PlexFunctions.py b/resources/lib/PlexFunctions.py index d00da0e7..6e048df3 100644 --- a/resources/lib/PlexFunctions.py +++ b/resources/lib/PlexFunctions.py @@ -4,12 +4,17 @@ from ast import literal_eval from urlparse import urlparse, parse_qs import re from copy import deepcopy +import requests from xbmcaddon import Addon import downloadutils from utils import logMsg, settings +# Disable requests logging +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + addonName = Addon().getAddonInfo('name') title = "%s %s" % (addonName, __name__) @@ -394,7 +399,8 @@ def getPlexRepeat(kodiRepeat): def PMSHttpsEnabled(url): """ - Returns True if the PMS wants to talk https, False otherwise + Returns True if the PMS wants to talk https, False otherwise. None if error + occured, e.g. the connection timed out With with e.g. url=192.168.0.1:32400 (NO http/https) @@ -403,17 +409,37 @@ def PMSHttpsEnabled(url): Prefers HTTPS over HTTP """ - xml = downloadutils.DownloadUtils().downloadUrl( - 'https://%s/identity' % url) + # True if https, False if http + answer = True try: - # received a valid XML - https connection is possible - xml.attrib - logMsg('PMSHttpsEnabled', 'PMS on %s talks HTTPS' % url, 1) - return True - except: - # couldn't get an xml - switch to http traffic - logMsg('PMSHttpsEnabled', 'PMS on %s talks HTTPS' % url, 1) - return False + # Don't use downloadutils here, otherwise we may get un-authorized! + res = requests.get('https://%s/identity' % url, + headers={}, + verify=False, + timeout=(3, 10)) + # Don't verify SSL since we can connect for sure then! + except requests.exceptions.ConnectionError as e: + # Might have SSL deactivated. Try with http + try: + res = requests.get('http://%s/identity' % url, + headers={}, + timeout=(3, 10)) + except requests.exceptions.ConnectionError as e: + logMsg("Server is offline or cannot be reached. Url: %s, " + "Error message: %s" % (url, e), -1) + return None + except requests.exceptions.ReadTimeout: + logMsg("Server timeout reached for Url %s" % url, -1) + return None + else: + answer = False + except requests.exceptions.ReadTimeout: + logMsg("Server timeout reached for Url %s" % url, -1) + return None + if res.status_code == requests.codes.ok: + return answer + else: + return None def scrobble(ratingKey, state): diff --git a/resources/lib/entrypoint.py b/resources/lib/entrypoint.py index 8d358e73..946b3345 100644 --- a/resources/lib/entrypoint.py +++ b/resources/lib/entrypoint.py @@ -81,13 +81,28 @@ def reConnect(): utils.logMsg("entrypoint reConnect", "Connection resets requested", 0) dialog = xbmcgui.Dialog() + # Resetting, please wait dialog.notification( heading=addonName, message=string(39207), icon="special://home/addons/plugin.video.plexkodiconnect/icon.png", + time=2000, sound=False) # Pause library sync thread - user needs to be auth in order to sync utils.window('suspend_LibraryThread', value='true') + # Wait max for 5 seconds for all lib scans to finish + counter = 0 + while utils.window('emby_dbScan') == 'true': + if counter > 500: + # Failed to reset PMS and plex.tv connects. Try to restart Kodi. + dialog.ok(heading=addonName, + message=string(39208)) + # Resuming threads, just in case + utils.window('suspend_LibraryThread', clear=True) + # Abort reConnection + return + counter += 1 + xbmc.sleep(50) # Delete plex credentials in settings utils.settings('myplexlogin', value="true") @@ -97,18 +112,13 @@ def reConnect(): utils.settings('plexHomeSize', value="1") utils.settings('plexAvatar', value="") - # Wait max for 5 seconds for all lib scans to finish - counter = 0 - while utils.window('emby_dbScan') == 'true': - if counter > 100: - dialog.ok(heading=addonName, - message=string(39208)) - # Resuming threads, just in case - utils.window('suspend_LibraryThread', clear=True) - # Abort reConnection - return - counter += 1 - xbmc.sleep(50) + # Reset connection details + utils.settings('plex_machineIdentifier', value="") + utils.settings('plex_servername', value="") + utils.settings('https', value="") + utils.settings('ipaddress', value="") + utils.settings('port', value="") + # Log out currently signed in user: utils.window('emby_serverStatus', value="401") diff --git a/resources/lib/librarysync.py b/resources/lib/librarysync.py index 1dc0cddd..9d13b1db 100644 --- a/resources/lib/librarysync.py +++ b/resources/lib/librarysync.py @@ -493,7 +493,7 @@ class LibrarySync(Thread): updatedAt=self.getPMSfromKodiTime(lastSync), containerSize=self.limitindex) # Just skip if something went wrong - if not items: + if items is None: continue # Get one itemtype, because they're the same in the PMS section try: @@ -528,7 +528,7 @@ class LibrarySync(Thread): view['id'], lastViewedAt=self.getPMSfromKodiTime(lastSync), containerSize=self.limitindex) - if not items: + if items is None: continue for item in items: itemId = item.attrib.get('ratingKey') @@ -1081,7 +1081,7 @@ class LibrarySync(Thread): viewName = view['name'] all_plexmovies = PlexFunctions.GetPlexSectionResults( viewId, args=None, containerSize=self.limitindex) - if not all_plexmovies: + if all_plexmovies is None: self.logMsg("Couldnt get section items, aborting for view.", 1) continue # Populate self.updatelist and self.allPlexElementsId diff --git a/resources/lib/plexbmchelper/plexgdm.py b/resources/lib/plexbmchelper/plexgdm.py index 52ef6d36..69621e40 100644 --- a/resources/lib/plexbmchelper/plexgdm.py +++ b/resources/lib/plexbmchelper/plexgdm.py @@ -32,6 +32,8 @@ import threading import time import urllib2 +import xbmc + import downloadutils from PlexFunctions import PMSHttpsEnabled from utils import window @@ -120,7 +122,7 @@ class plexgdm: self.__printDebug("Sending registration data: HTTP/1.0 200 OK\r\n%s" % (self.client_data), 3) self.client_registered = True - time.sleep(0.5) + xbmc.sleep(500) self.__printDebug("Client Update loop stopped",1) @@ -241,8 +243,12 @@ class plexgdm: update['class'] = each.split(':')[1].strip() # Quickly test if we need https - if PMSHttpsEnabled( - '%s:%s' % (update['server'], update['port'])): + https = PMSHttpsEnabled( + '%s:%s' % (update['server'], update['port'])) + if https is None: + # Error contacting server + continue + elif https: update['protocol'] = 'https' else: update['protocol'] = 'http' @@ -321,7 +327,7 @@ class plexgdm: if discovery_count > self.discovery_interval: self.discover() discovery_count=0 - time.sleep(1) + xbmc.sleep(1000) def start_discovery(self, daemon = False): if not self._discovery_is_running: @@ -355,8 +361,8 @@ if __name__ == '__main__': client.start_all() while not client.discovery_complete: print "Waiting for results" - time.sleep(1) - time.sleep(20) + xbmc.sleep(1000) + xbmc.sleep(20000) print client.getServerList() if client.check_client_registration(): print "Successfully registered" diff --git a/resources/lib/userclient.py b/resources/lib/userclient.py index 7a4e92b0..ea624fde 100644 --- a/resources/lib/userclient.py +++ b/resources/lib/userclient.py @@ -76,8 +76,8 @@ class UserClient(threading.Thread): settings = utils.settings # Original host - self.machineIdentifier = utils.settings('plex_machineIdentifier') - self.servername = utils.settings('plex_servername') + self.machineIdentifier = settings('plex_machineIdentifier') + self.servername = settings('plex_servername') HTTPS = settings('https') == "true" host = settings('ipaddress') port = settings('port') @@ -91,14 +91,11 @@ class UserClient(threading.Thread): # If https is true if prefix and HTTPS: server = "https://%s" % server - return server # If https is false elif prefix and not HTTPS: server = "http://%s" % server - return server - # If only the host:port is required - elif not prefix: - return server + self.logMsg('Returning active server: %s' % server) + return server def getSSLverify(self): # Verify host certificate @@ -410,6 +407,7 @@ class UserClient(threading.Thread): self.auth = False if self.authenticate(): # Successfully authenticated and loaded a user + log("Successfully authenticated!", 1) log("Current user: %s" % self.currUser, 1) log("Current userId: %s" % self.currUserId, 1) log("Current accessToken: xxxx", 1) diff --git a/service.py b/service.py index c3f6041a..4543bb29 100644 --- a/service.py +++ b/service.py @@ -135,12 +135,10 @@ class Service(): # 3. User has access to the server if window('emby_online') == "true": - # Emby server is online # Verify if user is set and has access to the server if (user.currUser is not None) and user.HasAccess: - - # If an item is playing + # If an item is playing if xplayer.isPlaying(): try: # Update and report progress @@ -189,14 +187,20 @@ class Service(): # Start the Websocket Client # if not self.websocket_running: + # log('Starting websocket thread', 1) # self.websocket_running = True # ws.start() # Start the syncing thread if not self.library_running: + log('Starting libary sync thread', 1) self.library_running = True library.start() + # Start the Plex Companion thread + if not self.plexCompanion_running and \ + self.runPlexCompanion == "true": + self.plexCompanion_running = True + plexCompanion.start() else: - if (user.currUser is None) and self.warn_auth: # Alert user is not authenticated and suppress future warning self.warn_auth = False @@ -216,6 +220,7 @@ class Service(): if monitor.waitForAbort(5): # Abort was requested while waiting. We should exit break + xbmc.sleep(50) else: # Wait until Emby server is online # or Kodi is shut down. @@ -238,9 +243,7 @@ class Service(): icon="special://home/addons/plugin.video." "plexkodiconnect/icon.png", sound=False) - self.server_online = False - else: # Server is online if not self.server_online: @@ -257,9 +260,8 @@ class Service(): "plexkodiconnect/icon.png", time=2000, sound=False) - self.server_online = True - log("Server is online and ready.", 1) + log("Server %s is online and ready." % server, 1) window('emby_online', value="true") # Start the userclient thread @@ -267,17 +269,14 @@ class Service(): self.userclient_running = True user.start() - # Start the Plex Companion thread - if not self.plexCompanion_running and \ - self.runPlexCompanion == "true": - self.plexCompanion_running = True - plexCompanion.start() + break if monitor.waitForAbort(1): # Abort was requested while waiting. break + xbmc.sleep(50) if monitor.waitForAbort(1): # Abort was requested while waiting. We should exit @@ -315,8 +314,8 @@ class Service(): delay = int(utils.settings('startupDelay')) xbmc.log("Delaying Plex startup by: %s sec..." % delay) -# Plex: add 3 seconds just for good measure -if delay and xbmc.Monitor().waitForAbort(delay+3): +# Plex: add 5 seconds just for good measure +if delay and xbmc.Monitor().waitForAbort(delay+5): # Start the service xbmc.log("Abort requested while waiting. Emby for kodi not started.") else: