From 06f9f6a7a50270547e7f1ef9152fa2f751c7ed58 Mon Sep 17 00:00:00 2001 From: Croneter Date: Wed, 30 May 2018 07:53:30 +0200 Subject: [PATCH 1/9] Fix PKC add-on setting user changes not saving --- resources/lib/artwork.py | 24 +++++++++++++----------- resources/lib/library_sync/fanart.py | 12 +++++++----- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/resources/lib/artwork.py b/resources/lib/artwork.py index f95d2b16..d778ad6e 100644 --- a/resources/lib/artwork.py +++ b/resources/lib/artwork.py @@ -9,7 +9,7 @@ from threading import Thread from os import makedirs import requests -from xbmc import sleep, translatePath +import xbmc from xbmcvfs import exists from utils import settings, language as lang, kodi_sql, try_encode, try_decode,\ @@ -64,16 +64,17 @@ class Image_Cache_Thread(Thread): # Abort was requested while waiting. We should exit LOG.info("---===### Stopped Image_Cache_Thread ###===---") return - sleep(1000) + xbmc.sleep(1000) try: url = queue.get(block=False) except Empty: - if not set_zero: + if not set_zero and not xbmc.getCondVisibility( + 'Window.IsVisible(DialogAddonSettings.xml)'): # Avoid saving '0' all the time set_zero = True settings('caching_artwork_count', value='0') - sleep(1000) + xbmc.sleep(1000) continue set_zero = False if isinstance(url, ArtworkSyncMessage): @@ -115,7 +116,7 @@ class Image_Cache_Thread(Thread): 'over-loaded. Sleep %s seconds before trying ' 'again to download %s', 2**sleeptime, double_urldecode(url)) - sleep((2**sleeptime) * 1000) + xbmc.sleep((2**sleeptime) * 1000) sleeptime += 1 continue except Exception as err: @@ -129,11 +130,12 @@ class Image_Cache_Thread(Thread): queue.task_done() # Update the caching state in the PKC settings. counter += 1 - if counter > 20: + if (counter > 20 and not xbmc.getCondVisibility( + 'Window.IsVisible(DialogAddonSettings.xml)')): counter = 0 settings('caching_artwork_count', value=str(queue.qsize())) # Sleep for a bit to reduce CPU strain - sleep(sleep_between) + xbmc.sleep(sleep_between) LOG.info("---===### Stopped Image_Cache_Thread ###===---") @@ -200,7 +202,7 @@ class Artwork(): if dialog('yesno', "Image Texture Cache", lang(39251)): LOG.info("Resetting all cache data first") # Remove all existing textures first - path = try_decode(translatePath("special://thumbnails/")) + path = try_decode(xbmc.translatePath("special://thumbnails/")) if exists_dir(path): rmtree(path, ignore_errors=True) self.restore_cache_directories() @@ -318,7 +320,7 @@ class Artwork(): pass else: # Delete thumbnail as well as the entry - path = translatePath("special://thumbnails/%s" % cachedurl) + path = xbmc.translatePath("special://thumbnails/%s" % cachedurl) LOG.debug("Deleting cached thumbnail: %s", path) if exists(path): rmtree(try_decode(path), ignore_errors=True) @@ -334,8 +336,8 @@ class Artwork(): "a", "b", "c", "d", "e", "f", "Video", "plex") for path in paths: - makedirs(try_decode(translatePath("special://thumbnails/%s" - % path))) + makedirs(try_decode(xbmc.translatePath("special://thumbnails/%s" + % path))) class ArtworkSyncMessage(object): diff --git a/resources/lib/library_sync/fanart.py b/resources/lib/library_sync/fanart.py index fddb6b82..05386527 100644 --- a/resources/lib/library_sync/fanart.py +++ b/resources/lib/library_sync/fanart.py @@ -3,7 +3,7 @@ from logging import getLogger from threading import Thread from Queue import Empty -from xbmc import sleep +import xbmc from utils import thread_methods, settings, language as lang, dialog import plexdb_functions as plexdb @@ -59,16 +59,17 @@ class ThreadedProcessFanart(Thread): # Abort was requested while waiting. We should exit LOG.info("---===### Stopped FanartSync ###===---") return - sleep(1000) + xbmc.sleep(1000) # grabs Plex item from queue try: item = queue.get(block=False) except Empty: - if not set_zero: + if not set_zero and not xbmc.getCondVisibility( + 'Window.IsVisible(DialogAddonSettings.xml)'):: # Avoid saving '0' all the time set_zero = True settings('fanarttv_lookups', value='0') - sleep(200) + xbmc.sleep(200) continue set_zero = False if isinstance(item, ArtworkSyncMessage): @@ -92,7 +93,8 @@ class ThreadedProcessFanart(Thread): plex_db.set_fanart_synched(item['plex_id']) # Update the caching state in the PKC settings. Avoid saving '0' counter += 1 - if counter > 10: + if (counter > 20 and not xbmc.getCondVisibility( + 'Window.IsVisible(DialogAddonSettings.xml)')): counter = 0 settings('fanarttv_lookups', value=str(queue.qsize())) queue.task_done() From 1f0977ec77ec49f3d81902f5da5778ff0c79969a Mon Sep 17 00:00:00 2001 From: Croneter Date: Wed, 30 May 2018 08:20:30 +0200 Subject: [PATCH 2/9] Fix Plex Companion failing leading to PMS connection loss --- resources/lib/websocket_client.py | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/resources/lib/websocket_client.py b/resources/lib/websocket_client.py index ff636c87..ce15f30e 100644 --- a/resources/lib/websocket_client.py +++ b/resources/lib/websocket_client.py @@ -57,7 +57,6 @@ class WebSocket(Thread): LOG.info("----===## Starting %s ##===----", self.__class__.__name__) counter = 0 - handshake_counter = 0 stopped = self.stopped suspended = self.suspended while not stopped(): @@ -94,9 +93,10 @@ class WebSocket(Thread): LOG.info("%s: Error connecting", self.__class__.__name__) self.ws = None counter += 1 - if counter > 3: - counter = 0 - self.IOError_response() + if counter >= 10: + LOG.info('%s: Repeated IOError detected. Stopping now', + self.__class__.__name__) + break sleep(1000) except websocket.WebSocketTimeoutException: LOG.info("%s: Timeout while connecting, trying again", @@ -106,10 +106,10 @@ class WebSocket(Thread): except websocket.WebSocketException as e: LOG.info('%s: WebSocketException: %s', self.__class__.__name__, e) - if ('Handshake Status 401' in e.args - or 'Handshake Status 403' in e.args): - handshake_counter += 1 - if handshake_counter >= 5: + if ('Handshake Status 401' in e.args or + 'Handshake Status 403' in e.args): + counter += 1 + if counter >= 5: LOG.info('%s: Error in handshake detected. ' 'Stopping now', self.__class__.__name__) break @@ -125,7 +125,6 @@ class WebSocket(Thread): sleep(1000) else: counter = 0 - handshake_counter = 0 except Exception as e: LOG.error("%s: Unknown exception encountered: %s", self.__class__.__name__, e) @@ -202,11 +201,6 @@ class PMS_Websocket(WebSocket): # Put PMS message on queue and let libsync take care of it state.WEBSOCKET_QUEUE.put(message) - def IOError_response(self): - LOG.warn("Repeatedly could not connect to PMS, " - "declaring the connection dead") - window('plex_online', value='false') - class Alexa_Websocket(WebSocket): """ @@ -252,9 +246,6 @@ class Alexa_Websocket(WebSocket): return process_command(message.attrib['path'][1:], message.attrib) - def IOError_response(self): - pass - # Path in thread_methods def stop(self): self.thread_stopped = True From 7c92c0104705c9748687da093a96baa55853a2a6 Mon Sep 17 00:00:00 2001 From: Croneter Date: Wed, 30 May 2018 08:29:33 +0200 Subject: [PATCH 3/9] Fix Typo --- resources/lib/library_sync/fanart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/library_sync/fanart.py b/resources/lib/library_sync/fanart.py index 05386527..a13aa956 100644 --- a/resources/lib/library_sync/fanart.py +++ b/resources/lib/library_sync/fanart.py @@ -65,7 +65,7 @@ class ThreadedProcessFanart(Thread): item = queue.get(block=False) except Empty: if not set_zero and not xbmc.getCondVisibility( - 'Window.IsVisible(DialogAddonSettings.xml)'):: + 'Window.IsVisible(DialogAddonSettings.xml)'): # Avoid saving '0' all the time set_zero = True settings('fanarttv_lookups', value='0') From b729cf542345d255f1fd41d4c930fdb1f108aa6f Mon Sep 17 00:00:00 2001 From: Croneter Date: Wed, 30 May 2018 10:40:58 +0200 Subject: [PATCH 4/9] Fix logging --- resources/lib/PlexFunctions.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/resources/lib/PlexFunctions.py b/resources/lib/PlexFunctions.py index 0fab1c47..8c60caf2 100644 --- a/resources/lib/PlexFunctions.py +++ b/resources/lib/PlexFunctions.py @@ -231,7 +231,12 @@ def discover_pms(token=None): pms['ip'], pms['port']) plex_pms_list.append(pms) - LOG.debug('Found the following PMS in total: %s', plex_pms_list) + + log_list = deepcopy(plex_pms_list) + for pms in log_list: + if pms.get('token') is not None: + pms['token'] = '%s...' % pms['token'][:5] + LOG.debug('Found the following PMS in total: %s', log_list) return plex_pms_list From 114895c183b99df01b62560a01d8828863c3ecd8 Mon Sep 17 00:00:00 2001 From: Croneter Date: Wed, 30 May 2018 11:24:51 +0200 Subject: [PATCH 5/9] Fix logging --- resources/lib/PlexFunctions.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/resources/lib/PlexFunctions.py b/resources/lib/PlexFunctions.py index 8c60caf2..7a127659 100644 --- a/resources/lib/PlexFunctions.py +++ b/resources/lib/PlexFunctions.py @@ -206,7 +206,7 @@ def discover_pms(token=None): if token: LOG.info('Checking with plex.tv for more PMS to connect to') plex_pms_list = _pms_list_from_plex_tv(token) - LOG.debug('PMS found on plex.tv: %s', plex_pms_list) + _log_pms(plex_pms_list) else: LOG.info('No plex token supplied, only checked LAN for available PMS') plex_pms_list = [] @@ -231,13 +231,16 @@ def discover_pms(token=None): pms['ip'], pms['port']) plex_pms_list.append(pms) + _log_pms(plex_pms_list) + return plex_pms_list - log_list = deepcopy(plex_pms_list) + +def _log_pms(pms_list): + log_list = deepcopy(pms_list) for pms in log_list: if pms.get('token') is not None: pms['token'] = '%s...' % pms['token'][:5] - LOG.debug('Found the following PMS in total: %s', log_list) - return plex_pms_list + LOG.debug('Found the following PMS: %s', log_list) def _plex_gdm(): From 7bf6d197087323304dba4874fd9d5277d9ee601f Mon Sep 17 00:00:00 2001 From: Croneter Date: Wed, 30 May 2018 13:10:54 +0200 Subject: [PATCH 6/9] Fix AttributeError --- resources/lib/userclient.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/lib/userclient.py b/resources/lib/userclient.py index c9458e85..cefa31b7 100644 --- a/resources/lib/userclient.py +++ b/resources/lib/userclient.py @@ -264,8 +264,10 @@ class UserClient(Thread): Reset all user settings """ LOG.debug("Reset UserClient authentication.") - self.do_utils.stopSession() - + try: + self.do_utils.stopSession() + except AttributeError: + pass window('plex_authenticated', clear=True) state.AUTHENTICATED = False window('pms_token', clear=True) From a6881a8a327c21fb48e0cad990afcc2c7146b971 Mon Sep 17 00:00:00 2001 From: Croneter Date: Fri, 1 Jun 2018 18:43:56 +0200 Subject: [PATCH 7/9] Fix KeyErrors if Kodi player does not return position - Partially fixes #481 --- resources/lib/PlexCompanion.py | 5 ++++- resources/lib/playback.py | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/resources/lib/PlexCompanion.py b/resources/lib/PlexCompanion.py index 0f9162fb..89d5a7a9 100644 --- a/resources/lib/PlexCompanion.py +++ b/resources/lib/PlexCompanion.py @@ -195,7 +195,10 @@ class PlexCompanion(Thread): elif task['action'] == 'refreshPlayQueue': self._process_refresh(data) elif task['action'] == 'setStreams': - self._process_streams(data) + try: + self._process_streams(data) + except KeyError: + pass def run(self): """ diff --git a/resources/lib/playback.py b/resources/lib/playback.py index 57f2377f..ea54923e 100644 --- a/resources/lib/playback.py +++ b/resources/lib/playback.py @@ -62,7 +62,11 @@ def playback_triage(plex_id=None, plex_type=None, path=None, resolve=True): return playqueue = PQ.get_playqueue_from_type( v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type]) - pos = js.get_position(playqueue.playlistid) + try: + pos = js.get_position(playqueue.playlistid) + except KeyError: + LOG.warning('No position returned from Kodi player! Assuming 0') + pos = 0 # Can return -1 (as in "no playlist") pos = pos if pos != -1 else 0 LOG.debug('playQueue position %s for %s', pos, playqueue) From a4273c6c6e896ec596eaacf98b23b9606e79f7e4 Mon Sep 17 00:00:00 2001 From: Croneter Date: Fri, 1 Jun 2018 18:48:45 +0200 Subject: [PATCH 8/9] Declare PMS connection dead on first failed connection --- resources/lib/downloadutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/downloadutils.py b/resources/lib/downloadutils.py index b4536c7e..6505702c 100644 --- a/resources/lib/downloadutils.py +++ b/resources/lib/downloadutils.py @@ -32,7 +32,7 @@ class DownloadUtils(): _shared_state = {} # How many failed attempts before declaring PMS dead? - connectionAttempts = 2 + connectionAttempts = 1 # How many 401 returns before declaring unauthorized? unauthorizedAttempts = 2 # How long should we wait for an answer from the From ff4217b4888915224f3fbc490ec8b75c6889df3f Mon Sep 17 00:00:00 2001 From: Croneter Date: Fri, 1 Jun 2018 18:49:43 +0200 Subject: [PATCH 9/9] Specify exception type --- resources/lib/downloadutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/downloadutils.py b/resources/lib/downloadutils.py index 6505702c..3c28ab11 100644 --- a/resources/lib/downloadutils.py +++ b/resources/lib/downloadutils.py @@ -318,7 +318,7 @@ class DownloadUtils(): LOG.warn('Failed to connect to %s too many times. ' 'Declare PMS dead', url) window('plex_online', value="false") - except: + except ValueError: # 'countError' not yet set pass return None