diff --git a/addon.xml b/addon.xml index 16aa485d..bb1cca2c 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,7 @@ diff --git a/resources/language/English/strings.xml b/resources/language/English/strings.xml index 5a458fef..727f4019 100644 --- a/resources/language/English/strings.xml +++ b/resources/language/English/strings.xml @@ -276,6 +276,15 @@ Remove from Emby favorites Set custom song rating Emby addon settings - Delete item from the server + Delete item from the server + + + Welcome + Error connecting + Server is unreachable + Server is online + items added to playlist + items queued to playlist + Server is restarting diff --git a/resources/lib/api.py b/resources/lib/api.py index 552c55b9..55deeada 100644 --- a/resources/lib/api.py +++ b/resources/lib/api.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- +# Read an api response and convert more complex cases + ################################################################################################## import clientinfo @@ -11,8 +13,9 @@ import utils class API(): def __init__(self, item): - + # item is the api response self.item = item + self.clientinfo = clientinfo.ClientInfo() self.addonName = self.clientinfo.getAddonName() @@ -377,7 +380,7 @@ class API(): # Specific format modification if 'Dvd'in videotype: filepath = "%s/VIDEO_TS/VIDEO_TS.IFO" % filepath - elif 'Bluray' in videotype: + elif 'BluRay' in videotype: filepath = "%s/BDMV/index.bdmv" % filepath if "\\" in filepath: @@ -388,6 +391,7 @@ class API(): def updateUserRating(self, itemid, like=None, favourite=None, deletelike=False): #updates the userrating to Emby + # This should be moved to read_embyserver.py import downloadutils doUtils = downloadutils.DownloadUtils() diff --git a/resources/lib/playlist.py b/resources/lib/playlist.py index afc6dc43..bafe71ac 100644 --- a/resources/lib/playlist.py +++ b/resources/lib/playlist.py @@ -32,7 +32,7 @@ class Playlist(): emby_db = embydb.Embydb_Functions(embycursor) self.logMsg("---*** PLAY ALL ***---", 1) - self.logMsg("Items: %s" % itemids) + self.logMsg("Items: %s and start at: %s" % (itemids, startat)) player = xbmc.Player() playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) @@ -50,6 +50,7 @@ class Playlist(): mediatype = embydb_item[4] except TypeError: # Item is not found in our database, add item manually + self.logMsg("Item was not found in the database, manually adding item.", 1) item = self.emby.getItem(itemid) self.addtoPlaylist_xbmc(playlist, item) else: @@ -66,6 +67,7 @@ class Playlist(): # Seek to the starting position seektime = startat / 10000000.0 player.seekTime(seektime) + self.logMsg("Seeking to: %s" % seektime, 1) self.verifyPlaylist() embycursor.close() diff --git a/resources/lib/websocket.py b/resources/lib/websocket.py index 98b7902e..3d777a97 100644 --- a/resources/lib/websocket.py +++ b/resources/lib/websocket.py @@ -853,6 +853,7 @@ class WebSocketApp(object): if self.sock: raise WebSocketException("socket is already opened") thread = None + self.keep_running = True try: self.sock = WebSocket(self.get_mask_key, sockopt=sockopt, sslopt=sslopt) diff --git a/resources/lib/websocket_client.py b/resources/lib/websocket_client.py index d657b631..85fae535 100644 --- a/resources/lib/websocket_client.py +++ b/resources/lib/websocket_client.py @@ -44,7 +44,10 @@ class WebSocket_Client(threading.Thread): threading.Thread.__init__(self) def sendProgressUpdate(self, data): - self.logMsg("sendProgressUpdate", 2) + + log = self.logMsg + + log("sendProgressUpdate", 2) try: messageData = { @@ -53,20 +56,24 @@ class WebSocket_Client(threading.Thread): } messageString = json.dumps(messageData) self.client.send(messageString) - self.logMsg("Message data: %s" % messageString, 2) + log("Message data: %s" % messageString, 2) except Exception as e: - self.logMsg("Exception: %s" % e, 1) + log("Exception: %s" % e, 1) def on_message(self, ws, message): + log = self.logMsg + window = utils.window + lang = utils.language + result = json.loads(message) messageType = result['MessageType'] data = result['Data'] if messageType not in ('SessionEnded'): # Mute certain events - self.logMsg("Message: %s" % message, 1) + log("Message: %s" % message, 1) if messageType == "Play": # A remote control play command has been sent from the server. @@ -75,12 +82,11 @@ class WebSocket_Client(threading.Thread): pl = playlist.Playlist() dialog = xbmcgui.Dialog() - dialog.notification("Emby for Kodi", "Adding %s items to playlist." % len(itemIds)) if command == "PlayNow": dialog.notification( heading="Emby for Kodi", - message="Adding %s items to playlist." % len(itemIds), + message="%s %s" % (len(itemIds), lang(33004)), icon="special://home/addons/plugin.video.plexkodiconnect/icon.png", sound=False) startat = data.get('StartPositionTicks', 0) @@ -89,7 +95,7 @@ class WebSocket_Client(threading.Thread): elif command == "PlayNext": dialog.notification( heading="Emby for Kodi", - message="Queueing %s items to playlist." % len(itemIds), + message="%s %s" % (len(itemIds), lang(33005)), icon="special://home/addons/plugin.video.plexkodiconnect/icon.png", sound=False) newplaylist = pl.modifyPlaylist(itemIds) @@ -117,12 +123,12 @@ class WebSocket_Client(threading.Thread): seekto = data['SeekPositionTicks'] seektime = seekto / 10000000.0 action(seektime) - self.logMsg("Seek to %s." % seektime, 1) + log("Seek to %s." % seektime, 1) else: action() - self.logMsg("Command: %s completed." % command, 1) + log("Command: %s completed." % command, 1) - utils.window('emby_command', value="true") + window('emby_command', value="true") elif messageType == "UserDataChanged": # A user changed their personal rating for an item, or their playstate was updated @@ -165,7 +171,7 @@ class WebSocket_Client(threading.Thread): embyindex = int(arguments['Index']) currentFile = player.getPlayingFile() - mapping = utils.window('emby_%s.indexMapping' % currentFile) + mapping = window('emby_%s.indexMapping' % currentFile) if mapping: externalIndex = json.loads(mapping) # If there's external subtitles added via playbackutils @@ -184,7 +190,7 @@ class WebSocket_Client(threading.Thread): player.setSubtitleStream(index - audioTracks - 1) # Let service know - utils.window('emby_command', value="true") + window('emby_command', value="true") elif command == "DisplayMessage": @@ -243,8 +249,8 @@ class WebSocket_Client(threading.Thread): elif messageType == "ServerRestarting": if utils.settings('supressRestartMsg') == "true": xbmcgui.Dialog().notification( - heading="Emby server", - message="Server is restarting.", + heading="Emby for Kodi", + message=lang(33006), icon="special://home/addons/plugin.video.plexkodiconnect/icon.png") elif messageType == "UserConfigurationUpdated": @@ -267,13 +273,16 @@ class WebSocket_Client(threading.Thread): def run(self): + log = self.logMsg + window = utils.window monitor = self.monitor - loglevel = int(utils.window('emby_logLevel')) + + loglevel = int(window('emby_logLevel')) # websocket.enableTrace(True) - userId = utils.window('emby_currUser') - server = utils.window('emby_server%s' % userId) - token = utils.window('emby_accessToken%s' % userId) + userId = window('emby_currUser') + server = window('emby_server%s' % userId) + token = window('emby_accessToken%s' % userId) deviceId = self.deviceId # Get the appropriate prefix for the websocket @@ -284,7 +293,7 @@ class WebSocket_Client(threading.Thread): #EDIT: realized the ws url is at: ws://server.local:32400/:/websockets/notifications websocket_url = "" # websocket_url = "%s/:/websockets/notifications/?X-Plex-Token=%s" % (server, token) - self.logMsg("websocket url: %s" % websocket_url, 1) + log("websocket url: %s" % websocket_url, 1) self.client = websocket.WebSocketApp(websocket_url, on_message=self.on_message, @@ -292,11 +301,11 @@ class WebSocket_Client(threading.Thread): on_close=self.on_close) self.client.on_open = self.on_open - self.logMsg("----===## Starting WebSocketClient ##===----", 0) + log("----===## Starting WebSocketClient ##===----", 0) while not monitor.abortRequested(): - self.client.run_forever(ping_interval = 10) + self.client.run_forever(ping_interval=10) if self.stopWebsocket: break @@ -304,7 +313,7 @@ class WebSocket_Client(threading.Thread): # Abort was requested, exit break - self.logMsg("##===---- WebSocketClient Stopped ----===##", 0) + log("##===---- WebSocketClient Stopped ----===##", 0) def stopClient(self): diff --git a/service.py b/service.py index 55e8a18b..b26e7984 100644 --- a/service.py +++ b/service.py @@ -53,23 +53,26 @@ class Service(): def __init__(self): + log = self.logMsg + window = utils.window + self.clientInfo = clientinfo.ClientInfo() logLevel = userclient.UserClient().getLogLevel() self.monitor = xbmc.Monitor() - utils.window('emby_logLevel', value=str(logLevel)) - utils.window('emby_kodiProfile', value=xbmc.translatePath("special://profile")) - utils.window('emby_pluginpath', value=utils.settings('useDirectPaths')) + window('emby_logLevel', value=str(logLevel)) + window('emby_kodiProfile', value=xbmc.translatePath("special://profile")) + window('emby_pluginpath', value=utils.settings('useDirectPaths')) self.runPlexCompanion = utils.settings('plexCompanion') # Initial logging - self.logMsg("======== START %s ========" % self.addonName, 0) - self.logMsg("Platform: %s" % (self.clientInfo.getPlatform()), 0) - self.logMsg("KODI Version: %s" % xbmc.getInfoLabel('System.BuildVersion'), 0) - self.logMsg("%s Version: %s" % (self.addonName, self.clientInfo.getVersion()), 0) - self.logMsg("Using plugin paths: %s" % (utils.settings('useDirectPaths') != "true"), 0) - self.logMsg("Log Level: %s" % logLevel, 0) + log("======== START %s ========" % self.addonName, 0) + log("Platform: %s" % (self.clientInfo.getPlatform()), 0) + log("KODI Version: %s" % xbmc.getInfoLabel('System.BuildVersion'), 0) + log("%s Version: %s" % (self.addonName, self.clientInfo.getVersion()), 0) + log("Using plugin paths: %s" % (utils.settings('useDirectPaths') != "true"), 0) + log("Log Level: %s" % logLevel, 0) # Reset window props for profile switch properties = [ @@ -81,15 +84,20 @@ class Service(): "plex_runLibScan" ] for prop in properties: - utils.window(prop, clear=True) + window(prop, clear=True) # Clear video nodes properties videonodes.VideoNodes().clearProperties() # Set the minimum database version - utils.window('emby_minDBVersion', value="1.1.63") + window('emby_minDBVersion', value="1.1.63") def ServiceEntryPoint(self): + + log = self.logMsg + window = utils.window + lang = utils.language + # Important: Threads depending on abortRequest will not trigger # if profile switch happens more than once. monitor = self.monitor @@ -111,10 +119,9 @@ class Service(): while not monitor.abortRequested(): - if utils.window('emby_kodiProfile') != kodiProfile: + if window('emby_kodiProfile') != kodiProfile: # Profile change happened, terminate this thread and others - self.logMsg( - "Kodi profile was: %s and changed to: %s. Terminating old Emby thread." + log("Kodi profile was: %s and changed to: %s. Terminating old Emby thread." % (kodiProfile, utils.window('emby_kodiProfile')), 1) break @@ -124,7 +131,7 @@ class Service(): # 2. User is set # 3. User has access to the server - if utils.window('emby_online') == "true": + if window('emby_online') == "true": # Emby server is online # Verify if user is set and has access to the server @@ -150,15 +157,15 @@ class Service(): kplayer.reportPlayback() lastProgressUpdate = datetime.today() - elif utils.window('emby_command') == "true": + elif window('emby_command') == "true": # Received a remote control command that # requires updating immediately - utils.window('emby_command', clear=True) + window('emby_command', clear=True) kplayer.reportPlayback() lastProgressUpdate = datetime.today() except Exception as e: - self.logMsg("Exception in Playback Monitor Service: %s" % e, 1) + log("Exception in Playback Monitor Service: %s" % e, 1) pass else: # Start up events @@ -174,8 +181,8 @@ class Service(): add = "" xbmcgui.Dialog().notification( heading=self.addonName, - message="Welcome %s%s" - % (user.currUser, add), + message="%s %s%s!" + % (lang(33000), user.currUser, add), icon="special://home/addons/plugin.video." "plexkodiconnect/icon.png", time=2000, @@ -198,7 +205,7 @@ class Service(): if (user.currUser is None) and self.warn_auth: # Alert user is not authenticated and suppress future warning self.warn_auth = False - self.logMsg("Not authenticated yet.", 1) + log("Not authenticated yet.", 1) # User access is restricted. # Keep verifying until access is granted @@ -207,7 +214,7 @@ class Service(): # Verify access with an API call user.hasAccess() - if utils.window('emby_online') != "true": + if window('emby_online') != "true": # Server went offline break @@ -229,13 +236,12 @@ class Service(): # Server is offline. # Alert the user and suppress future warning if self.server_online: - self.logMsg("Server is offline.", 1) - utils.window('emby_online', value="false") + log("Server is offline.", 1) + window('emby_online', value="false") xbmcgui.Dialog().notification( - heading="Error connecting", - message="%s Server is unreachable." - % self.addonName, + heading=lang(33001), + message="%s %s" % (self.addonName, lang(33002)), icon="special://home/addons/plugin.video." "plexkodiconnect/icon.png", sound=False) @@ -253,15 +259,15 @@ class Service(): # Alert the user that server is online. xbmcgui.Dialog().notification( heading=self.addonName, - message="Server is online.", + message=lang(33003), icon="special://home/addons/plugin.video." "plexkodiconnect/icon.png", time=2000, sound=False) self.server_online = True - self.logMsg("Server is online and ready.", 1) - utils.window('emby_online', value="true") + log("Server is online and ready.", 1) + window('emby_online', value="true") # Start the userclient thread if not self.userclient_running: @@ -298,7 +304,7 @@ class Service(): if self.userclient_running: user.stopThread() - self.logMsg("======== STOP %s ========" % self.addonName, 0) + log("======== STOP %s ========" % self.addonName, 0) # Delay option delay = int(utils.settings('startupDelay'))