Added server online check

This commit is contained in:
angelblue05 2015-04-26 15:41:39 -05:00
parent 6ec92da158
commit 9020c1c908
4 changed files with 193 additions and 129 deletions

View file

@ -71,7 +71,7 @@ class DownloadUtils():
url = "{server}/mediabrowser/Sessions?DeviceId=%s&format=json" % deviceId url = "{server}/mediabrowser/Sessions?DeviceId=%s&format=json" % deviceId
result = self.downloadUrl(url) result = self.downloadUrl(url)
# sessionId result # sessionId result
self.logMsg("Session result: %s" % result, 1) self.logMsg("Session result: %s" % result, 2)
self.sessionId = result[0][u'Id'] self.sessionId = result[0][u'Id']
# Settings for capabilities # Settings for capabilities
@ -152,52 +152,51 @@ class DownloadUtils():
timeout = self.timeout timeout = self.timeout
default_link = "" default_link = ""
# If user is authenticated
if (authenticate):
# Get requests session
s = self.s
# Replace for the real values and append api_key
url = url.replace("{server}", self.server, 1)
url = url.replace("{UserId}", self.userId, 1)
url = "%s&api_key=%s" % (url, self.token)
self.logMsg("URL: %s" % url, 2)
# Prepare request
if type == "GET":
r = s.get(url, params=postBody, timeout=timeout)
elif type == "POST":
r = s.post(url, params=postBody, timeout=timeout)
elif type == "DELETE":
r = s.delete(url, params=postBody, timeout=timeout)
# If user is not authenticated
elif not authenticate:
self.logMsg("URL: %s" % url, 1)
header = self.getHeader(authenticate=False)
verifyssl = False
# If user enables ssl verification
try:
verifyssl = self.sslverify
except AttributeError:
pass
# Prepare request
if type == "GET":
r = requests.get(url, params=postBody, headers=header, timeout=timeout, verify=verifyssl)
elif type == "POST":
r = requests.post(url, params=postBody, headers=header, timeout=timeout, verify=verifyssl)
# Process the response
try: try:
r.raise_for_status()
# If user is authenticated
if (authenticate):
# Get requests session
s = self.s
# Replace for the real values and append api_key
url = url.replace("{server}", self.server, 1)
url = url.replace("{UserId}", self.userId, 1)
url = "%s&api_key=%s" % (url, self.token)
self.logMsg("URL: %s" % url, 2)
# Prepare request
if type == "GET":
r = s.get(url, params=postBody, timeout=timeout)
elif type == "POST":
r = s.post(url, params=postBody, timeout=timeout)
elif type == "DELETE":
r = s.delete(url, params=postBody, timeout=timeout)
# If user is not authenticated
elif not authenticate:
self.logMsg("URL: %s" % url, 2)
header = self.getHeader(authenticate=False)
verifyssl = False
# If user enables ssl verification
try:
verifyssl = self.sslverify
except AttributeError:
pass
# Prepare request
if type == "GET":
r = requests.get(url, params=postBody, headers=header, timeout=timeout, verify=verifyssl)
elif type == "POST":
r = requests.post(url, params=postBody, headers=header, timeout=timeout, verify=verifyssl)
# Process the response
if r.status_code == 204: if r.status_code == 204:
# No response in body # No body in the response
self.logMsg("====== 204 Success ======", 2) self.logMsg("====== 204 Success ======", 2)
return default_link return default_link
# Response code 200
elif r.status_code == requests.codes.ok: elif r.status_code == requests.codes.ok:
try: try:
# UTF-8 - JSON object # UTF-8 - JSON object
@ -206,21 +205,35 @@ class DownloadUtils():
return r return r
except: except:
self.logMsg("Unable to convert the response for: %s" % url, 1) self.logMsg("Unable to convert the response for: %s" % url, 1)
else:
r.raise_for_status()
return default_link return default_link
# TO REVIEW EXCEPTIONS # TO REVIEW EXCEPTIONS
except requests.exceptions.ConnectionError as e: except requests.exceptions.ConnectionError as e:
self.logMsg("Server unreachable at: %s" % url, 0) # Addon is already aware of status
self.logMsg(e, 1) if WINDOW.getProperty("Server_online") == "true":
self.logMsg("Server unreachable at: %s" % url, 0)
self.logMsg(e, 2)
WINDOW.setProperty("Server_online", "false")
pass
except requests.exceptions.ConnectTimeout as e: except requests.exceptions.ConnectTimeout as e:
self.logMsg("Server timeout at: %s" % url, 0) self.logMsg("Server timeout at: %s" % url, 0)
self.logMsg(e, 1) self.logMsg(e, 2)
except requests.exceptions.HTTPError as e: except requests.exceptions.HTTPError as e:
if r.status_code == 401: if (r.status_code == 301) or (r.status_code == 302):
# Redirects
pass
elif (r.status_code == 400):
# Bad requests
pass
elif (r.status_code == 401):
# Unauthorized # Unauthorized
status = WINDOW.getProperty("Server_status") status = WINDOW.getProperty("Server_status")
if (status == "401") or (status == "Auth"): if (status == "401") or (status == "Auth"):
@ -230,19 +243,16 @@ class DownloadUtils():
WINDOW.setProperty("Server_status", "401") WINDOW.setProperty("Server_status", "401")
self.logMsg("HTTP Error: %s" % e, 0) self.logMsg("HTTP Error: %s" % e, 0)
elif (r.status_code == 301) or (r.status_code == 302): elif (r.status_code == 500):
# Redirects # Out of memory
pass
elif r.status_code == 400:
# Bad requests
pass pass
except requests.exceptions.SSLError as e: except requests.exceptions.SSLError as e:
self.logMsg("Invalid SSL certificate for: %s" % url, 0) self.logMsg("Invalid SSL certificate for: %s" % url, 0)
self.logMsg(e, 1) self.logMsg(e, 2)
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
self.logMsg("Unknown error connecting to: %s" % url, 0) self.logMsg("Unknown error connecting to: %s" % url, 0)
self.logMsg(e, 1) self.logMsg(e, 2)
return default_link return default_link

View file

@ -46,6 +46,7 @@ class UserClient(threading.Thread):
self.__dict__ = self._shared_state self.__dict__ = self._shared_state
self.className = self.__class__.__name__ self.className = self.__class__.__name__
self.__language__ = self.addon.getLocalizedString
threading.Thread.__init__(self, *args) threading.Thread.__init__(self, *args)
@ -161,6 +162,9 @@ class UserClient(threading.Thread):
if (result != ""): if (result != ""):
users = result users = result
else:
# Server connection failed
return False
return users return users
@ -225,10 +229,7 @@ class UserClient(threading.Thread):
users = self.getPublicUsers() users = self.getPublicUsers()
password = "" password = ""
'''if users == "":
self.WINDOW.setProperty("Server_status", "Stop")
return'''
# Find user in list # Find user in list
for user in users: for user in users:
name = user[u'Name'] name = user[u'Name']

View file

@ -18,6 +18,7 @@ from DownloadUtils import DownloadUtils
from PlaybackUtils import PlaybackUtils from PlaybackUtils import PlaybackUtils
from LibrarySync import LibrarySync from LibrarySync import LibrarySync
from WriteKodiDB import WriteKodiDB from WriteKodiDB import WriteKodiDB
from UserClient import UserClient
import Utils as utils import Utils as utils
pendingUserDataList = [] pendingUserDataList = []
@ -30,6 +31,8 @@ class WebSocketThread(threading.Thread):
logLevel = 0 logLevel = 0
client = None client = None
keepRunning = True keepRunning = True
uc = UserClient()
def __init__(self, *args): def __init__(self, *args):
@ -246,7 +249,7 @@ class WebSocketThread(threading.Thread):
LibrarySync().updatePlayCount(itemId) LibrarySync().updatePlayCount(itemId)
def on_error(self, ws, error): def on_error(self, ws, error):
self.logMsg("Error : " + str(error)) self.logMsg("Error : " + str(error), 2)
#raise #raise
def on_close(self, ws): def on_close(self, ws):
@ -298,7 +301,7 @@ class WebSocketThread(threading.Thread):
username = WINDOW.getProperty('currUser') username = WINDOW.getProperty('currUser')
server = WINDOW.getProperty('server%s' % username) server = WINDOW.getProperty('server%s' % username)
host = WINDOW.getProperty('server_%s' % username) host = WINDOW.getProperty('server_%s' % username)
if(self.logLevel >= 1): if(self.logLevel >= 1):
websocket.enableTrace(True) websocket.enableTrace(True)
''' '''
@ -323,12 +326,19 @@ class WebSocketThread(threading.Thread):
self.client.on_open = self.on_open self.client.on_open = self.on_open
while not self.KodiMonitor.abortRequested(): while not self.KodiMonitor.abortRequested():
self.logMsg("Client Starting")
self.client.run_forever() self.client.run_forever()
if(self.keepRunning):
self.logMsg("Client Needs To Restart") if (self.keepRunning):
# Server is not online, suppress future warning
if WINDOW.getProperty("Server_online") == "true":
self.logMsg("Server is unreachable.", 1)
WINDOW.setProperty("Server_online", "false")
xbmcgui.Dialog().notification("Error connecting", "Server is unreachable.")
if self.KodiMonitor.waitForAbort(5): if self.KodiMonitor.waitForAbort(5):
break break
self.logMsg("Thread Exited") self.logMsg("Thread Exited")

View file

@ -1,6 +1,7 @@
import xbmcaddon import xbmcaddon
import xbmc import xbmc
import xbmcgui import xbmcgui
import os import os
import threading import threading
import json import json
@ -30,25 +31,28 @@ class Service():
clientInfo = ClientInformation() clientInfo = ClientInformation()
addonName = clientInfo.getAddonName() addonName = clientInfo.getAddonName()
className = None WINDOW = xbmcgui.Window(10000)
warn_auth = True
server_online = True
def __init__(self, *args ): def __init__(self, *args ):
self.KodiMonitor = KodiMonitor.Kodi_Monitor() self.KodiMonitor = KodiMonitor.Kodi_Monitor()
addonName = self.addonName
self.className = self.__class__.__name__ self.className = self.__class__.__name__
addonName = self.addonName
self.logMsg("Starting Monitor", 0) self.logMsg("Starting Monitor", 0)
self.logMsg("======== START %s ========" % addonName, 0) self.logMsg("======== START %s ========" % addonName, 0)
self.logMsg("KODI Version: %s" % xbmc.getInfoLabel("System.BuildVersion"), 0) self.logMsg("KODI Version: %s" % xbmc.getInfoLabel("System.BuildVersion"), 0)
self.logMsg("%s Version: %s" % (addonName, self.clientInfo.getVersion()), 0) self.logMsg("%s Version: %s" % (addonName, self.clientInfo.getVersion()), 0)
pass
def logMsg(self, msg, lvl=1): def logMsg(self, msg, lvl=1):
utils.logMsg("%s %s" % (self.addonName, self.className), str(msg), int(lvl)) utils.logMsg("%s %s" % (self.addonName, self.className), msg, int(lvl))
def ServiceEntryPoint(self): def ServiceEntryPoint(self):
WINDOW = self.WINDOW
ConnectionManager().checkServer() ConnectionManager().checkServer()
lastProgressUpdate = datetime.today() lastProgressUpdate = datetime.today()
@ -65,77 +69,116 @@ class Service():
ws = WebSocketThread() ws = WebSocketThread()
lastFile = None lastFile = None
# Main program
while not self.KodiMonitor.abortRequested(): while not self.KodiMonitor.abortRequested():
if self.KodiMonitor.waitForAbort(1): if self.KodiMonitor.waitForAbort(1):
# Abort was requested while waiting. We should exit # Abort was requested while waiting. We should exit
break break
if xbmc.Player().isPlaying():
try:
playTime = xbmc.Player().getTime()
totalTime = xbmc.Player().getTotalTime()
currentFile = xbmc.Player().getPlayingFile()
if(player.played_information.get(currentFile) != None):
player.played_information[currentFile]["currentPosition"] = playTime
# send update
td = datetime.today() - lastProgressUpdate
secDiff = td.seconds
if(secDiff > 10):
try:
player.reportPlayback()
except Exception, msg:
xbmc.log("MB3 Sync Service -> Exception reporting progress : " + msg)
pass
lastProgressUpdate = datetime.today()
# only try autoplay when there's 20 seconds or less remaining and only once!
if (totalTime - playTime <= 20 and (lastFile==None or lastFile!=currentFile)):
lastFile = currentFile
player.autoPlayPlayback()
except Exception, e:
xbmc.log("MB3 Sync Service -> Exception in Playback Monitor Service : " + str(e))
pass
else:
if (self.newUserClient == None):
self.newUserClient = "Started"
user.start()
# background worker for database sync
if (user.currUser != None):
# Correctly launch the websocket, if user manually launches the add-on
if (self.newWebSocketThread == None):
self.newWebSocketThread = "Started"
ws.start()
#full sync
if(startupComplete == False):
xbmc.log("Doing_Db_Sync: syncDatabase (Started)")
libSync = librarySync.syncDatabase()
xbmc.log("Doing_Db_Sync: syncDatabase (Finished) " + str(libSync))
countSync = librarySync.updatePlayCounts()
xbmc.log("Doing_Db_Sync: updatePlayCounts (Finished) " + str(countSync))
# Force refresh newly set thumbnails if (self.newUserClient == None):
xbmc.executebuiltin("UpdateLibrary(video)") self.newUserClient = "Started"
if(libSync and countSync): user.start()
startupComplete = True
else: # isServerOnline verification
if self.KodiMonitor.waitForAbort(10): if WINDOW.getProperty("Server_online") == "true":
# Abort was requested while waiting. We should exit # Server is online, proceed.
break
WebSocketThread().processPendingActions() if xbmc.Player().isPlaying():
try:
playTime = xbmc.Player().getTime()
totalTime = xbmc.Player().getTotalTime()
currentFile = xbmc.Player().getPlayingFile()
if(player.played_information.get(currentFile) != None):
player.played_information[currentFile]["currentPosition"] = playTime
# send update
td = datetime.today() - lastProgressUpdate
secDiff = td.seconds
if(secDiff > 10):
try:
player.reportPlayback()
except Exception, msg:
self.logMsg("Exception reporting progress: %s" % msg, 1)
pass
lastProgressUpdate = datetime.today()
# only try autoplay when there's 20 seconds or less remaining and only once!
if (totalTime - playTime <= 20 and (lastFile==None or lastFile!=currentFile)):
lastFile = currentFile
player.autoPlayPlayback()
except Exception, e:
self.logMsg("Exception in Playback Monitor Service : " + str(e), 1)
pass
else: else:
xbmc.log("Not authenticated yet") # background worker for database sync
if (user.currUser != None):
# Correctly launch the websocket, if user manually launches the add-on
if (self.newWebSocketThread == None):
self.newWebSocketThread = "Started"
ws.start()
#full sync
if (startupComplete == False):
self.logMsg("Doing_Db_Sync: syncDatabase (Started)", 1)
libSync = librarySync.syncDatabase()
self.logMsg("Doing_Db_Sync: syncDatabase (Finished) " + str(libSync), 1)
countSync = librarySync.updatePlayCounts()
self.logMsg("Doing_Db_Sync: updatePlayCounts (Finished) " + str(countSync), 1)
# Force refresh newly set thumbnails
xbmc.executebuiltin("UpdateLibrary(video)")
if (libSync and countSync):
startupComplete = True
else:
if self.KodiMonitor.waitForAbort(10):
# Abort was requested while waiting. We should exit
break
WebSocketThread().processPendingActions()
else:
# Supress future warnings
if self.warn_auth:
self.logMsg("Not authenticated yet.", 1)
self.warn_auth = False
else:
# Wait until server becomes online or shut down is requested
while not self.KodiMonitor.abortRequested():
if user.getServer() == "":
# Server information missing
pass
# Make a simple api call to server
elif not user.getPublicUsers():
self.server_online = False
# Server is not online, suppress future warning
if WINDOW.getProperty("Server_online") != "false":
WINDOW.setProperty("Server_online", "false")
self.logMsg("Server is offline.", 1)
xbmcgui.Dialog().notification("Error connecting", "%s Server is unreachable." % self.addonName)
else:
# Server is online
if not self.server_online:
# Server was not online when Kodi started.
# Wait for server to be fully established.
if self.KodiMonitor.waitForAbort(10):
# Abort was requested while waiting.
break
self.logMsg("Server is online and ready.", 1)
xbmcgui.Dialog().notification("Connection successful", "%s Server is online." % self.addonName, time=2000)
WINDOW.setProperty("Server_online", "true")
break
utils.logMsg("MB3 Sync Service", "stopping Service",0) if self.KodiMonitor.waitForAbort(1):
# Abort was requested while waiting.
break
self.logMsg("======== STOP %s ========" % self.addonName, 0)
# If user reset library database. # If user reset library database.
WINDOW = xbmcgui.Window(10000)
if WINDOW.getProperty("SyncInstallRunDone") == "false": if WINDOW.getProperty("SyncInstallRunDone") == "false":
addon = xbmcaddon.Addon('plugin.video.emby') addon = xbmcaddon.Addon('plugin.video.emby')
addon.setSetting("SyncInstallRunDone", "false") addon.setSetting("SyncInstallRunDone", "false")
@ -147,5 +190,5 @@ class Service():
user.stopClient() user.stopClient()
#start the service # Start the service
Service().ServiceEntryPoint() Service().ServiceEntryPoint()