From 33ad095080075cd86bd1667833a55e1a18a68bce Mon Sep 17 00:00:00 2001 From: croneter Date: Fri, 24 Sep 2021 16:02:32 +0200 Subject: [PATCH 1/8] Fix download not always returning entire requests.response object --- resources/lib/downloadutils.py | 9 +++++---- resources/lib/plex_api/media.py | 15 +++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/resources/lib/downloadutils.py b/resources/lib/downloadutils.py index 4914016a..aec4efcd 100644 --- a/resources/lib/downloadutils.py +++ b/resources/lib/downloadutils.py @@ -223,7 +223,11 @@ class DownloadUtils(object): if r.status_code != 401: self.count_unauthorized = 0 - if r.status_code == 204: + if return_response is True: + # return the entire response object + return r + + elif r.status_code == 204: # No body in the response # But read (empty) content to release connection back to pool # (see requests: keep-alive documentation) @@ -257,9 +261,6 @@ class DownloadUtils(object): elif r.status_code in (200, 201): # 200: OK # 201: Created - if return_response is True: - # return the entire response object - return r try: # xml response r = utils.etree.fromstring(r.content) diff --git a/resources/lib/plex_api/media.py b/resources/lib/plex_api/media.py index 1a828dbd..1b3b7f35 100644 --- a/resources/lib/plex_api/media.py +++ b/resources/lib/plex_api/media.py @@ -357,16 +357,15 @@ class Media(object): filename, extension) response = DU().downloadUrl(url, return_response=True) - try: - response.status_code - except AttributeError: + if not response.ok: LOG.error('Could not temporarily download subtitle %s', url) + LOG.error('HTTP status: %s, message: %s', + response.status_code, response.text) return - else: - LOG.debug('Writing temp subtitle to %s', path) - with open(path, 'wb') as f: - f.write(response.content) - return path + LOG.debug('Writing temp subtitle to %s', path) + with open(path, 'wb') as f: + f.write(response.content) + return path def validate_playurl(self, path, typus, force_check=False, folder=False, omit_check=False): From 594ca9b667539048d638f4c38d77be2b267e2f0c Mon Sep 17 00:00:00 2001 From: croneter Date: Fri, 24 Sep 2021 16:24:57 +0200 Subject: [PATCH 2/8] Fix logging if fanart.tv lookup fails --- resources/lib/plex_api/artwork.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/resources/lib/plex_api/artwork.py b/resources/lib/plex_api/artwork.py index 8e354084..f8b351f8 100644 --- a/resources/lib/plex_api/artwork.py +++ b/resources/lib/plex_api/artwork.py @@ -220,12 +220,14 @@ class Artwork(object): else: # Not supported artwork return artworks - data = DU().downloadUrl(url, authenticate=False, timeout=15) - try: - data.get('test') - except AttributeError: - LOG.error('Could not download data from FanartTV') + data = DU().downloadUrl(url, + authenticate=False, + timeout=15, + return_response=True) + if not data.ok: + LOG.debug('Could not download data from FanartTV') return artworks + data = data.json() fanart_tv_types = list(v.FANART_TV_TO_KODI_TYPE) From fee6e23a234bc85f75631d5f74eddc29f51df890 Mon Sep 17 00:00:00 2001 From: croneter Date: Thu, 30 Sep 2021 12:13:29 +0200 Subject: [PATCH 3/8] Refactor and fix Kodi not activating subtitle when it should --- resources/lib/kodimonitor.py | 69 ++++------------------------------ resources/lib/playlist_func.py | 52 +++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 62 deletions(-) diff --git a/resources/lib/kodimonitor.py b/resources/lib/kodimonitor.py index de88a3c0..40633d46 100644 --- a/resources/lib/kodimonitor.py +++ b/resources/lib/kodimonitor.py @@ -382,72 +382,17 @@ class KodiMonitor(xbmc.Monitor): if not playerid == v.KODI_VIDEO_PLAYER_ID: # We're just messing with Kodi's videoplayer return - if not self._switched_to_plex_streams: - # We need to switch to the Plex streams ONCE upon playback start - # after onavchange has been fired - self.switch_to_plex_streams() - self._switched_to_plex_streams = True - else: - item = app.PLAYSTATE.item - if item is None: - # Player might've quit - return - kodi_audio_stream = js.get_current_audio_stream_index(playerid) - sub_enabled = js.get_subtitle_enabled(playerid) - kodi_sub_stream = js.get_current_subtitle_stream_index(playerid) - # Audio - if kodi_audio_stream != item.current_kodi_audio_stream: - item.on_kodi_audio_stream_change(kodi_audio_stream) - # Subtitles - CURRENTLY BROKEN ON THE KODI SIDE! - # current_kodi_sub_stream may also be zero - subs_off = (None, False) - if ((sub_enabled and item.current_kodi_sub_stream in subs_off) - or (not sub_enabled and item.current_kodi_sub_stream not in subs_off) - or (kodi_sub_stream is not None - and kodi_sub_stream != item.current_kodi_sub_stream)): - item.on_kodi_subtitle_stream_change(kodi_sub_stream, - sub_enabled) - - @staticmethod - def switch_to_plex_streams(): - """ - Override Kodi audio and subtitle streams with Plex PMS' selection - """ item = app.PLAYSTATE.item if item is None: # Player might've quit return - for typus in ('audio', 'subtitle'): - try: - plex_index, language_tag = item.active_plex_stream_index(typus) - except TypeError: - LOG.debug('Deactivating Kodi subtitles because the PMS ' - 'told us to not show any subtitles') - app.APP.player.showSubtitles(False) - item.current_kodi_sub_stream = False - continue - LOG.debug('The PMS wants to display %s stream with Plex id %s and ' - 'languageTag %s', - typus, plex_index, language_tag) - kodi_index = item.kodi_stream_index(plex_index, typus) - if kodi_index is None: - LOG.debug('Leaving Kodi %s stream settings untouched since we ' - 'could not parse Plex %s stream with id %s to a Kodi' - ' index', typus, typus, plex_index) - else: - LOG.debug('Switching to Kodi %s stream number %s because the ' - 'PMS told us to show stream with Plex id %s', - typus, kodi_index, plex_index) - # If we're choosing an "illegal" index, this function does - # need seem to fail nor log any errors - if typus == 'audio': - app.APP.player.setAudioStream(kodi_index) - else: - app.APP.player.setSubtitleStream(kodi_index) - if typus == 'audio': - item.current_kodi_audio_stream = kodi_index - else: - item.current_kodi_sub_stream = kodi_index + if not self._switched_to_plex_streams: + # We need to switch to the Plex streams ONCE upon playback start + # after onavchange has been fired + item.switch_to_plex_streams() + self._switched_to_plex_streams = True + else: + item.on_av_change(playerid) def _playback_cleanup(ended=False): diff --git a/resources/lib/playlist_func.py b/resources/lib/playlist_func.py index 153b0aed..c548dea0 100644 --- a/resources/lib/playlist_func.py +++ b/resources/lib/playlist_func.py @@ -324,6 +324,58 @@ class PlaylistItem(object): PF.change_audio_stream(plex_stream_index, self.api.part_id()) self.current_kodi_audio_stream = kodi_stream_index + def switch_to_plex_streams(self): + self.switch_to_plex_stream('audio') + self.switch_to_plex_stream('subtitle') + + def switch_to_plex_stream(self, typus): + try: + plex_index, language_tag = self.active_plex_stream_index(typus) + except TypeError: + LOG.debug('Deactivating Kodi subtitles because the PMS ' + 'told us to not show any subtitles') + app.APP.player.showSubtitles(False) + self.current_kodi_sub_stream = False + return + LOG.debug('The PMS wants to display %s stream with Plex id %s and ' + 'languageTag %s', typus, plex_index, language_tag) + kodi_index = self.kodi_stream_index(plex_index, typus) + if kodi_index is None: + LOG.debug('Leaving Kodi %s stream settings untouched since we ' + 'could not parse Plex %s stream with id %s to a Kodi' + ' index', typus, typus, plex_index) + else: + LOG.debug('Switching to Kodi %s stream number %s because the ' + 'PMS told us to show stream with Plex id %s', + typus, kodi_index, plex_index) + # If we're choosing an "illegal" index, this function does + # need seem to fail nor log any errors + if typus == 'audio': + app.APP.player.setAudioStream(kodi_index) + else: + app.APP.player.setSubtitleStream(kodi_index) + app.APP.player.showSubtitles(True) + if typus == 'audio': + self.current_kodi_audio_stream = kodi_index + else: + self.current_kodi_sub_stream = kodi_index + + def on_av_change(self, playerid): + kodi_audio_stream = js.get_current_audio_stream_index(playerid) + sub_enabled = js.get_subtitle_enabled(playerid) + kodi_sub_stream = js.get_current_subtitle_stream_index(playerid) + # Audio + if kodi_audio_stream != self.current_kodi_audio_stream: + self.on_kodi_audio_stream_change(kodi_audio_stream) + # Subtitles - CURRENTLY BROKEN ON THE KODI SIDE! + # current_kodi_sub_stream may also be zero + subs_off = (None, False) + if ((sub_enabled and self.current_kodi_sub_stream in subs_off) + or (not sub_enabled and self.current_kodi_sub_stream not in subs_off) + or (kodi_sub_stream is not None + and kodi_sub_stream != self.current_kodi_sub_stream)): + self.on_kodi_subtitle_stream_change(kodi_sub_stream, sub_enabled) + def playlist_item_from_kodi(kodi_item): """ From fa28ebfac1686dfa24697b23c188396366da7763 Mon Sep 17 00:00:00 2001 From: croneter Date: Thu, 30 Sep 2021 13:31:23 +0200 Subject: [PATCH 4/8] Fix whitespace --- resources/lib/plex_api/base.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/resources/lib/plex_api/base.py b/resources/lib/plex_api/base.py index c26d820f..a6837cad 100644 --- a/resources/lib/plex_api/base.py +++ b/resources/lib/plex_api/base.py @@ -16,12 +16,15 @@ METADATA_PROVIDERS = (('imdb', utils.REGEX_IMDB), ('tvdb', utils.REGEX_TVDB), ('tmdb', utils.REGEX_TMDB), ('anidb', utils.REGEX_ANIDB)) + + class Base(object): """ Processes a Plex media server's XML response xml: xml.etree.ElementTree element """ + def __init__(self, xml): self.xml = xml # which media part in the XML response shall we look at if several From 79e912e2bb67ff45ba5798a4b9e8f30c87a3aa57 Mon Sep 17 00:00:00 2001 From: croneter Date: Thu, 30 Sep 2021 14:17:52 +0200 Subject: [PATCH 5/8] Direct Paths: Fix TypeError: element indices must be integers for subtitles --- resources/lib/plex_api/base.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/resources/lib/plex_api/base.py b/resources/lib/plex_api/base.py index c26d820f..be76de56 100644 --- a/resources/lib/plex_api/base.py +++ b/resources/lib/plex_api/base.py @@ -260,13 +260,21 @@ class Base(object): Returns the media streams directly from the PMS xml. Mind to set self.mediastream and self.part before calling this method! """ - return self.xml[self.mediastream][self.part] + try: + return self.xml[self.mediastream][self.part] + except TypeError: + # Direct Paths when we don't set mediastream and part + return self.xml[0][0] def part_id(self): """ Returns the unique id of the currently active part [int] """ - return int(self.xml[self.mediastream][self.part].attrib['id']) + try: + return int(self.xml[self.mediastream][self.part].attrib['id']) + except TypeError: + # Direct Paths when we don't set mediastream and part + return int(self.xml[0][0].attrib['id']) def plot(self): """ From 3d535fe2bf71df30395c2e42bbbcb387f3f2b6dc Mon Sep 17 00:00:00 2001 From: croneter Date: Thu, 30 Sep 2021 14:33:43 +0200 Subject: [PATCH 6/8] Android: Fix broken Python multiprocessing module (a Kodi 19.2 bug) --- resources/lib/utils.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 3c663661..d7eea96a 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -23,6 +23,11 @@ import re import gc try: from multiprocessing.pool import ThreadPool + # Annyoing Kodi bug on Android, introduced with + # https://github.com/xbmc/xbmc/pull/20034 + # See https://github.com/croneter/PlexKodiConnect/issues/1641 + with ThreadPool(): + pass SUPPORTS_POOL = True except Exception: SUPPORTS_POOL = False @@ -867,13 +872,12 @@ def process_method_on_list(method_to_run, items): all_items = [] if SUPPORTS_POOL: pool = ThreadPool() - try: - all_items = pool.map(method_to_run, items) - except Exception: - # catch exception to prevent threadpool running forever - ERROR(notify=True) - pool.close() - pool.join() + with ThreadPool() as pool: + try: + all_items = pool.map(method_to_run, items) + except Exception: + # catch exception to prevent threadpool running forever + ERROR(notify=True) else: all_items = [method_to_run(item) for item in items] all_items = [_f for _f in all_items if _f] From 6e0c3c65677fe32aa2eedf4968d541b33051e71d Mon Sep 17 00:00:00 2001 From: croneter Date: Thu, 30 Sep 2021 14:55:42 +0200 Subject: [PATCH 7/8] Beta version bump 3.5.1 --- addon.xml | 10 ++++++++-- changelog.txt | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/addon.xml b/addon.xml index 21330134..cf055e1e 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -91,7 +91,13 @@ Plex를 Kodi에 기본 통합 Kodi를 Plex Media Server에 연결합니다. 이 플러그인은 Plex로 모든 비디오를 관리하고 Kodi로는 관리하지 않는다고 가정합니다. Kodi 비디오 및 음악 데이터베이스에 이미 저장된 데이터가 손실 될 수 있습니다 (이 플러그인이 직접 변경하므로). 자신의 책임하에 사용하십시오! 자신의 책임하에 사용 - version 3.5.0: + version 3.5.1 (beta only): +- Refactor stream code and fix Kodi not activating subtitle when it should +- Direct Paths: Fix TypeError: "element indices must be integers" on playback startup +- Android: Fix broken Python multiprocessing module (a Kodi 19.2 bug) +- Fix logging if fanart.tv lookup fails: be less verbose + +version 3.5.0: - versions 3.4.5-3.4.7 for everyone version 3.4.7 (beta only): diff --git a/changelog.txt b/changelog.txt index ba380ba2..2be0bc2a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,9 @@ +version 3.5.1 (beta only): +- Refactor stream code and fix Kodi not activating subtitle when it should +- Direct Paths: Fix TypeError: "element indices must be integers" on playback startup +- Android: Fix broken Python multiprocessing module (a Kodi 19.2 bug) +- Fix logging if fanart.tv lookup fails: be less verbose + version 3.5.0: - versions 3.4.5-3.4.7 for everyone From a7e4d49db1500d7d4b2101570b3e283cf8ac287d Mon Sep 17 00:00:00 2001 From: croneter Date: Mon, 4 Oct 2021 15:40:25 +0200 Subject: [PATCH 8/8] Stable and beta version bump 3.5.2 --- addon.xml | 7 +++++-- changelog.txt | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/addon.xml b/addon.xml index cf055e1e..d0846823 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -91,7 +91,10 @@ Plex를 Kodi에 기본 통합 Kodi를 Plex Media Server에 연결합니다. 이 플러그인은 Plex로 모든 비디오를 관리하고 Kodi로는 관리하지 않는다고 가정합니다. Kodi 비디오 및 음악 데이터베이스에 이미 저장된 데이터가 손실 될 수 있습니다 (이 플러그인이 직접 변경하므로). 자신의 책임하에 사용하십시오! 자신의 책임하에 사용 - version 3.5.1 (beta only): + version 3.5.2: +- version 3.5.1 for everyone + +version 3.5.1 (beta only): - Refactor stream code and fix Kodi not activating subtitle when it should - Direct Paths: Fix TypeError: "element indices must be integers" on playback startup - Android: Fix broken Python multiprocessing module (a Kodi 19.2 bug) diff --git a/changelog.txt b/changelog.txt index 2be0bc2a..b3db9478 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +version 3.5.2: +- version 3.5.1 for everyone + version 3.5.1 (beta only): - Refactor stream code and fix Kodi not activating subtitle when it should - Direct Paths: Fix TypeError: "element indices must be integers" on playback startup