From 43e894ae1fc93e10b7d1be2e2d98130bcdbe9995 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Sat, 6 May 2017 19:05:18 +0200 Subject: [PATCH 01/27] Update German translation --- resources/language/resource.language.de_DE/strings.po | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/resources/language/resource.language.de_DE/strings.po b/resources/language/resource.language.de_DE/strings.po index 46e92b0d..7d42fee6 100644 --- a/resources/language/resource.language.de_DE/strings.po +++ b/resources/language/resource.language.de_DE/strings.po @@ -2068,3 +2068,13 @@ msgstr "Erzwungen" msgctxt "#39710" msgid "burn-in" msgstr "einbrennen" + +# Dialog text if PKC detected a new Music library and Kodi needs to be +# restarted +msgctxt "#39711" +msgid "" +"New Plex music library detected. Sorry, but we need to restart Kodi now due " +"to the changes made." +msgstr "" +"Neue Plex Musikbibliothek gefunden. Entschuldigung, aber Kodi muss nun " +"aufgrund der gemachten Änderungen neu gestartet werden." From acfb9d41287d8ba42903a6e03edefc1717ec159c Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Sun, 7 May 2017 13:42:46 +0200 Subject: [PATCH 02/27] Fix TypeError with AdvancedSettings.xml missing - Fixes #290 --- resources/lib/initialsetup.py | 9 +++++---- resources/lib/music.py | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/resources/lib/initialsetup.py b/resources/lib/initialsetup.py index 887c04a0..5d9eba95 100644 --- a/resources/lib/initialsetup.py +++ b/resources/lib/initialsetup.py @@ -401,12 +401,13 @@ class InitialSetup(): dialog = self.dialog # Get current Kodi video cache setting - cache, _ = advancedsettings_xml(['cache', 'memorysize']) - if cache is not None: - cache = str(cache.text) - else: + try: + cache, _ = advancedsettings_xml(['cache', 'memorysize']) + except TypeError: # Kodi default cache cache = '20971520' + else: + cache = str(cache.text) log.info('Current Kodi video memory cache in bytes: %s' % cache) settings('kodi_video_cache', value=cache) diff --git a/resources/lib/music.py b/resources/lib/music.py index 9ed2cb7b..3e967bbd 100644 --- a/resources/lib/music.py +++ b/resources/lib/music.py @@ -21,8 +21,9 @@ def get_current_music_folders(): excludefromscan music folders in the advancedsettings.xml """ paths = [] - root, _ = advancedsettings_xml(['audio', 'excludefromscan']) - if root is None: + try: + root, _ = advancedsettings_xml(['audio', 'excludefromscan']) + except TypeError: return paths for element in root: From d93850228a9f7f9b8eb75e0b770099a3bdb083fa Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Sun, 7 May 2017 13:46:38 +0200 Subject: [PATCH 03/27] Version bump --- README.md | 2 +- addon.xml | 7 +++++-- changelog.txt | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e398413f..caa2a4a9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![stable version](https://img.shields.io/badge/stable_version-1.7.7-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip) -[![beta version](https://img.shields.io/badge/beta_version-1.7.12-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) +[![beta version](https://img.shields.io/badge/beta_version-1.7.13-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) [![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation) [![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq) diff --git a/addon.xml b/addon.xml index 2476c915..e29b2883 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -44,7 +44,10 @@ Gebruik op eigen risico 使用風險由您自己承擔 Usar a su propio riesgo - version 1.7.12 (beta only) + version 1.7.13 (beta only) +- Fix TypeError with AdvancedSettings.xml missing + +version 1.7.12 (beta only) - Major music overhaul: Direct Paths should now work! Many thanks @Memesa for the pointers! Don't forget to reset your database - Some Plex Companion fixes - Fix UnicodeDecodeError on user switch diff --git a/changelog.txt b/changelog.txt index 03a188c2..6f7f0c10 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +version 1.7.13 (beta only) +- Fix TypeError with AdvancedSettings.xml missing + version 1.7.12 (beta only) - Major music overhaul: Direct Paths should now work! Many thanks @Memesa for the pointers! Don't forget to reset your database - Some Plex Companion fixes From 722c3c18212f7628b1126e9736627424d6bdfcce Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Sun, 7 May 2017 14:05:25 +0200 Subject: [PATCH 04/27] Fix TypeError, but for real now - Fixes #290 --- resources/lib/initialsetup.py | 5 ++--- resources/lib/librarysync.py | 19 ++++++++++--------- resources/lib/music.py | 5 ++--- resources/lib/utils.py | 8 +++++--- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/resources/lib/initialsetup.py b/resources/lib/initialsetup.py index 5d9eba95..54bd9940 100644 --- a/resources/lib/initialsetup.py +++ b/resources/lib/initialsetup.py @@ -401,9 +401,8 @@ class InitialSetup(): dialog = self.dialog # Get current Kodi video cache setting - try: - cache, _ = advancedsettings_xml(['cache', 'memorysize']) - except TypeError: + cache, _ = advancedsettings_xml(['cache', 'memorysize']) + if cache is None: # Kodi default cache cache = '20971520' else: diff --git a/resources/lib/librarysync.py b/resources/lib/librarysync.py index 75c4217b..d0e50cda 100644 --- a/resources/lib/librarysync.py +++ b/resources/lib/librarysync.py @@ -297,15 +297,6 @@ class LibrarySync(Thread): } if self.enableMusic: process['music'] = self.PlexMusic - if self.direct_paths is True: - if music.set_excludefromscan_music_folders() is True: - log.info('Detected new Music library - restarting now') - # 'New Plex music library detected. Sorry, but we need to - # restart Kodi now due to the changes made.' - dialog('ok', lang(29999), lang(39711)) - from xbmc import executebuiltin - executebuiltin('RestartApp') - return False # Do the processing for itemtype in process: @@ -483,6 +474,16 @@ class LibrarySync(Thread): """ Compare the views to Plex """ + if self.direct_paths is True: + if music.set_excludefromscan_music_folders() is True: + log.info('Detected new Music library - restarting now') + # 'New Plex music library detected. Sorry, but we need to + # restart Kodi now due to the changes made.' + dialog('ok', lang(29999), lang(39711)) + from xbmc import executebuiltin + executebuiltin('RestartApp') + return False + self.views = [] vnodes = self.vnodes diff --git a/resources/lib/music.py b/resources/lib/music.py index 3e967bbd..9ed2cb7b 100644 --- a/resources/lib/music.py +++ b/resources/lib/music.py @@ -21,9 +21,8 @@ def get_current_music_folders(): excludefromscan music folders in the advancedsettings.xml """ paths = [] - try: - root, _ = advancedsettings_xml(['audio', 'excludefromscan']) - except TypeError: + root, _ = advancedsettings_xml(['audio', 'excludefromscan']) + if root is None: return paths for element in root: diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 752801cf..f53759d3 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -542,8 +542,10 @@ def __setSubElement(element, subelement): def advancedsettings_xml(node_list, new_value=None, attrib=None, force_create=False): """ - Returns the etree element for nodelist (if it exists) and the tree. None if - not set + Returns + etree element, tree + or + None, None node_list is a list of node names starting from the outside, ignoring the outter advancedsettings. Example nodelist=['video', 'busydialogdelayms'] @@ -576,7 +578,7 @@ def advancedsettings_xml(node_list, new_value=None, attrib=None, # Document is blank or missing if new_value is None and attrib is None and force_create is False: log.debug('Could not parse advancedsettings.xml, returning None') - return + return None, None # Create topmost xml entry tree = etree.ElementTree(element=etree.Element('advancedsettings')) root = tree.getroot() From bd6dca73421ecb83c4466a822be13d88586eda39 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Sun, 7 May 2017 14:06:29 +0200 Subject: [PATCH 05/27] Version bump --- README.md | 2 +- addon.xml | 7 +++++-- changelog.txt | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index caa2a4a9..220af80c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![stable version](https://img.shields.io/badge/stable_version-1.7.7-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip) -[![beta version](https://img.shields.io/badge/beta_version-1.7.13-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) +[![beta version](https://img.shields.io/badge/beta_version-1.7.14-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) [![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation) [![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq) diff --git a/addon.xml b/addon.xml index e29b2883..1af024ab 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -44,7 +44,10 @@ Gebruik op eigen risico 使用風險由您自己承擔 Usar a su propio riesgo - version 1.7.13 (beta only) + version 1.7.14 (beta only) +- Fix TypeError, but for real now + +version 1.7.13 (beta only) - Fix TypeError with AdvancedSettings.xml missing version 1.7.12 (beta only) diff --git a/changelog.txt b/changelog.txt index 6f7f0c10..173fcd82 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +version 1.7.14 (beta only) +- Fix TypeError, but for real now + version 1.7.13 (beta only) - Fix TypeError with AdvancedSettings.xml missing From 543253e10e7014c215a9ecd12b0f1192414727ef Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Sun, 7 May 2017 15:02:45 +0200 Subject: [PATCH 06/27] Plex Companion: add itemType to playstate --- resources/lib/playlist_func.py | 15 ++++++++++----- resources/lib/plexbmchelper/subscribers.py | 15 +++++++++------ resources/lib/plexdb_functions.py | 5 +++-- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/resources/lib/playlist_func.py b/resources/lib/playlist_func.py index b3a9f143..2df5026c 100644 --- a/resources/lib/playlist_func.py +++ b/resources/lib/playlist_func.py @@ -75,6 +75,7 @@ class Playqueue_Object(Playlist_Object_Baseclase): class Playlist_Item(object): ID = None # Plex playlist/playqueue id, e.g. playQueueItemID plex_id = None # Plex unique item id, "ratingKey" + plex_type = None # Plex type, e.g. 'movie', 'clip' plex_UUID = None # Plex librarySectionUUID kodi_id = None # Kodi unique kodi id (unique only within type!) kodi_type = None # Kodi type: 'movie' @@ -102,20 +103,22 @@ def playlist_item_from_kodi(kodi_item): """ item = Playlist_Item() item.kodi_id = kodi_item.get('id') + item.kodi_type = kodi_item.get('type') if item.kodi_id: with plexdb.Get_Plex_DB() as plex_db: plex_dbitem = plex_db.getItem_byKodiId(kodi_item['id'], kodi_item['type']) try: item.plex_id = plex_dbitem[0] + item.plex_type = plex_dbitem[2] item.plex_UUID = plex_dbitem[0] # we dont need the uuid yet :-) except TypeError: pass item.file = kodi_item.get('file') - if item.file is not None and item.plex_id is None: - item.plex_id = dict( - parse_qsl(urlsplit(item.file).query)).get('plex_id') - item.kodi_type = kodi_item.get('type') + if item.plex_id is None and item.file is not None: + query = dict(parse_qsl(urlsplit(item.file).query)) + item.plex_id = query.get('plex_id') + item.plex_type = query.get('itemType') if item.plex_id is None: item.uri = 'library://whatever/item/%s' % quote(item.file, safe='') else: @@ -137,13 +140,14 @@ def playlist_item_from_plex(plex_id): with plexdb.Get_Plex_DB() as plex_db: plex_dbitem = plex_db.getItem_byId(plex_id) try: + item.plex_type = plex_dbitem[5] item.kodi_id = plex_dbitem[0] item.kodi_type = plex_dbitem[4] except: raise KeyError('Could not find plex_id %s in database' % plex_id) item.plex_UUID = plex_id item.uri = ('library://%s/item/library%%2Fmetadata%%2F%s' % - (item.plex_UUID, plex_id)) + (item.plex_UUID, plex_id)) log.debug('Made playlist item from plex: %s' % item) return item @@ -155,6 +159,7 @@ def playlist_item_from_xml(playlist, xml_video_element): item = Playlist_Item() api = API(xml_video_element) item.plex_id = api.getRatingKey() + item.plex_type = api.getType() item.ID = xml_video_element.attrib['%sItemID' % playlist.kind] item.guid = xml_video_element.attrib.get('guid') if item.guid is not None: diff --git a/resources/lib/plexbmchelper/subscribers.py b/resources/lib/plexbmchelper/subscribers.py index 22d77f64..fcdd2499 100644 --- a/resources/lib/plexbmchelper/subscribers.py +++ b/resources/lib/plexbmchelper/subscribers.py @@ -122,9 +122,11 @@ class SubscriptionManager: ret += ' shuffle="%s"' % info['shuffle'] ret += ' mute="%s"' % self.mute ret += ' repeat="%s"' % info['repeat'] + ret += ' itemType="%s"' % info['itemType'] # Might need an update in the future - ret += ' subtitleStreamID="-1"' - ret += ' audioStreamID="-1"' + if ptype == 'video': + ret += ' subtitleStreamID="-1"' + ret += ' audioStreamID="-1"' ret += '/>' return ret @@ -244,10 +246,11 @@ class SubscriptionManager: {"playerid": playerid, "properties": ["position"]})['position'] try: - info['playQueueItemID'] = playqueue.items[pos].ID - info['guid'] = playqueue.items[pos].guid - info['playQueueID'] = playqueue.ID - info['playQueueVersion'] = playqueue.version + info['playQueueItemID'] = playqueue.items[pos].ID or 'null' + info['guid'] = playqueue.items[pos].guid or 'null' + info['playQueueID'] = playqueue.ID or 'null' + info['playQueueVersion'] = playqueue.version or 'null' + info['itemType'] = playqueue.items[pos].plex_type or 'null' except: pass except: diff --git a/resources/lib/plexdb_functions.py b/resources/lib/plexdb_functions.py index 179518dc..1fdbe07d 100644 --- a/resources/lib/plexdb_functions.py +++ b/resources/lib/plexdb_functions.py @@ -258,10 +258,11 @@ class Plex_DB_Functions(): def getItem_byKodiId(self, kodi_id, kodi_type): """ - Returns the tuple (plex_id, parent_id) for kodi_id and kodi_type + Returns the tuple (plex_id, parent_id, plex_type) for kodi_id and + kodi_type """ query = ''' - SELECT plex_id, parent_id + SELECT plex_id, parent_id, plex_type FROM plex WHERE kodi_id = ? AND kodi_type = ? From b95ab225568f48dabbfb935cc351ccd2ac43a80b Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Sun, 7 May 2017 15:08:16 +0200 Subject: [PATCH 07/27] Change sleeping behavior for playqueue client --- resources/lib/playqueue.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/lib/playqueue.py b/resources/lib/playqueue.py index 551bd5f3..3559e0c6 100644 --- a/resources/lib/playqueue.py +++ b/resources/lib/playqueue.py @@ -206,5 +206,9 @@ class Playqueue(Thread): # compare old and new playqueue self._compare_playqueues(playqueue, kodi_playqueue) playqueue.old_kodi_pl = list(kodi_playqueue) - sleep(50) + # Still sleep a bit so Kodi does not become + # unresponsive + sleep(10) + continue + sleep(200) log.info("----===## PlayQueue client stopped ##===----") From 9378a8eb89e6b475b09c252dce3598ab3a794be6 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Sun, 7 May 2017 15:36:42 +0200 Subject: [PATCH 08/27] Less logging --- resources/lib/playlist_func.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/lib/playlist_func.py b/resources/lib/playlist_func.py index 2df5026c..3d0dc78b 100644 --- a/resources/lib/playlist_func.py +++ b/resources/lib/playlist_func.py @@ -319,8 +319,6 @@ def add_item_to_PMS_playlist(playlist, pos, plex_id=None, kodi_item=None): WILL ALSO UPDATE OUR PLAYLISTS """ - log.debug('Adding new item plex_id: %s, kodi_item: %s on the Plex side at ' - 'position %s for %s' % (plex_id, kodi_item, pos, playlist)) if plex_id: try: item = playlist_item_from_plex(plex_id) From 192c6e2e9aeda145439a093e10fd748d8f2e21d6 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Sun, 7 May 2017 16:21:19 +0200 Subject: [PATCH 09/27] Less logging --- resources/lib/PKC_listitem.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/resources/lib/PKC_listitem.py b/resources/lib/PKC_listitem.py index 4d9081a7..e34a0019 100644 --- a/resources/lib/PKC_listitem.py +++ b/resources/lib/PKC_listitem.py @@ -1,21 +1,13 @@ # -*- coding: utf-8 -*- ############################################################################### -import logging - from xbmcgui import ListItem -############################################################################### -log = logging.getLogger("PLEX."+__name__) - -############################################################################### - def convert_PKC_to_listitem(PKC_listitem): """ Insert a PKC_listitem and you will receive a valid XBMC listitem """ data = PKC_listitem.data - log.debug('data is: %s' % data) listitem = ListItem(label=data.get('label'), label2=data.get('label2'), path=data.get('path')) From 5adc032330c428122a83b04474d99c9999092268 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Sun, 7 May 2017 16:58:12 +0200 Subject: [PATCH 10/27] Fix companion for "Playback via PMS" --- resources/lib/playbackutils.py | 2 +- resources/lib/playlist_func.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/lib/playbackutils.py b/resources/lib/playbackutils.py index 56a45695..00fb5551 100644 --- a/resources/lib/playbackutils.py +++ b/resources/lib/playbackutils.py @@ -200,7 +200,7 @@ class PlaybackUtils(): playqueue, self.currentPosition+1, convert_PKC_to_listitem(listitem), - playurl, + file=playurl, kodi_item={'id': kodi_id, 'type': kodi_type}) else: # Full metadata$ diff --git a/resources/lib/playlist_func.py b/resources/lib/playlist_func.py index 3d0dc78b..fa439cde 100644 --- a/resources/lib/playlist_func.py +++ b/resources/lib/playlist_func.py @@ -535,9 +535,10 @@ def add_listitem_to_Kodi_playlist(playlist, pos, listitem, file, # We need to add this to our internal queue as well if xml_video_element is not None: item = playlist_item_from_xml(playlist, xml_video_element) - item.file = file else: item = playlist_item_from_kodi(kodi_item) + if file is not None: + item.file = file playlist.items.insert(pos, item) log.debug('Done inserting for %s' % playlist) From 353e1bee01aba2ae56f5c42abdff9c8af3766bf4 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Sun, 7 May 2017 17:07:01 +0200 Subject: [PATCH 11/27] Version bump --- README.md | 2 +- addon.xml | 10 ++++++++-- changelog.txt | 6 ++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 220af80c..37139a9f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![stable version](https://img.shields.io/badge/stable_version-1.7.7-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip) -[![beta version](https://img.shields.io/badge/beta_version-1.7.14-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) +[![beta version](https://img.shields.io/badge/beta_version-1.7.15-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) [![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation) [![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq) diff --git a/addon.xml b/addon.xml index 1af024ab..a6eff035 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -44,7 +44,13 @@ Gebruik op eigen risico 使用風險由您自己承擔 Usar a su propio riesgo - version 1.7.14 (beta only) + version 1.7.15 (beta only) +- Fix companion for "Playback via PMS" +- Change sleeping behavior for playqueue client +- Plex Companion: add itemType to playstate +- Less logging + +version 1.7.14 (beta only) - Fix TypeError, but for real now version 1.7.13 (beta only) diff --git a/changelog.txt b/changelog.txt index 173fcd82..db8a5a9e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,9 @@ +version 1.7.15 (beta only) +- Fix companion for "Playback via PMS" +- Change sleeping behavior for playqueue client +- Plex Companion: add itemType to playstate +- Less logging + version 1.7.14 (beta only) - Fix TypeError, but for real now From 21d13c6471ab4050f05e4ea1cf30d8ef49035eac Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 8 May 2017 19:15:50 +0200 Subject: [PATCH 12/27] Fix multiple subtitles per language not showing - Fixes #292 --- resources/lib/PlexAPI.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index 1c53396d..0d8c897e 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -2303,6 +2303,7 @@ class API(): except (TypeError, KeyError, IndexError): return kodiindex = 0 + fileindex = 0 for stream in mediastreams: # Since plex returns all possible tracks together, have to pull # only external subtitles - only for these a 'key' exists @@ -2318,8 +2319,10 @@ class API(): if stream.attrib.get('languageCode') is not None: path = self.download_external_subtitles( "{server}%s" % key, - "subtitle.%s.%s" % (stream.attrib['languageCode'], - stream.attrib['codec'])) + "subtitle%02d.%s.%s" % (fileindex, + stream.attrib['languageCode'], + stream.attrib['codec'])) + fileindex += 1 # We don't know the language - no need to download else: path = self.addPlexCredentialsToUrl( From 44af9a20e57d489d9edd42f5b570d14dab7dac9c Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 8 May 2017 19:28:34 +0200 Subject: [PATCH 13/27] Fix possible SQL injection vectors --- resources/lib/kodidb_functions.py | 5 ++--- resources/lib/utils.py | 8 ++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/resources/lib/kodidb_functions.py b/resources/lib/kodidb_functions.py index 2dd5ad90..9e595aab 100644 --- a/resources/lib/kodidb_functions.py +++ b/resources/lib/kodidb_functions.py @@ -1409,9 +1409,8 @@ class Kodidb_Functions(): ID = 'idEpisode' elif kodi_type == v.KODI_TYPE_SONG: ID = 'idSong' - query = ('''UPDATE %s SET userrating = ? WHERE %s = ?''' - % (kodi_type, ID)) - self.cursor.execute(query, (userrating, kodi_id)) + query = '''UPDATE ? SET userrating = ? WHERE ? = ?''' + self.cursor.execute(query, (kodi_type, userrating, ID, kodi_id)) def create_entry_uniqueid(self): self.cursor.execute( diff --git a/resources/lib/utils.py b/resources/lib/utils.py index f53759d3..d2a91f58 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -322,7 +322,7 @@ def reset(): for row in rows: tablename = row[0] if tablename != "version": - cursor.execute("DELETE FROM " + tablename) + cursor.execute("DELETE FROM ?", (tablename,)) connection.commit() cursor.close() @@ -335,7 +335,7 @@ def reset(): for row in rows: tablename = row[0] if tablename != "version": - cursor.execute("DELETE FROM " + tablename) + cursor.execute("DELETE FROM ?", (tablename, )) connection.commit() cursor.close() @@ -348,7 +348,7 @@ def reset(): for row in rows: tablename = row[0] if tablename != "version": - cursor.execute("DELETE FROM " + tablename) + cursor.execute("DELETE FROM ?", (tablename, )) cursor.execute('DROP table IF EXISTS plex') cursor.execute('DROP table IF EXISTS view') connection.commit() @@ -372,7 +372,7 @@ def reset(): for row in rows: tableName = row[0] if(tableName != "version"): - cursor.execute("DELETE FROM " + tableName) + cursor.execute("DELETE FROM ?", (tableName, )) connection.commit() cursor.close() From 51e2d87a2e3c3aac7d3fd609d88a991f39392e03 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 8 May 2017 19:29:52 +0200 Subject: [PATCH 14/27] Fix typo --- resources/lib/entrypoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/entrypoint.py b/resources/lib/entrypoint.py index dea40bfe..fe56d842 100644 --- a/resources/lib/entrypoint.py +++ b/resources/lib/entrypoint.py @@ -74,7 +74,7 @@ def togglePlexTV(): if settings('plexToken'): log.info('Reseting plex.tv credentials in settings') settings('plexLogin', value="") - settings('plexToken', value=""), + settings('plexToken', value="") settings('plexid', value="") settings('plexHomeSize', value="1") settings('plexAvatar', value="") From 2a8d288a5bb57eb9664c775d8ad508e4f8d29da0 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 8 May 2017 19:32:12 +0200 Subject: [PATCH 15/27] Fix else clauses in for loops --- resources/lib/itemtypes.py | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py index b7175530..92fb5d2e 100644 --- a/resources/lib/itemtypes.py +++ b/resources/lib/itemtypes.py @@ -1189,10 +1189,9 @@ class TVShows(Items): v.KODI_TYPE_SEASON) for season in seasons: self.removeSeason(season[1]) - else: - # Delete plex season entries - plex_db.removeItems_byParentId(showid, - v.KODI_TYPE_SEASON) + # Delete plex season entries + plex_db.removeItems_byParentId(showid, + v.KODI_TYPE_SEASON) self.removeShow(showid) plex_db.removeItem(show[0]) @@ -1208,14 +1207,12 @@ class TVShows(Items): seasonid, v.KODI_TYPE_EPISODE) for episode in season_episodes: self.removeEpisode(episode[1], episode[2]) - else: - # Remove plex episodes - plex_db.removeItems_byParentId(seasonid, - v.KODI_TYPE_EPISODE) - else: - # Remove plex seasons - plex_db.removeItems_byParentId(kodiid, - v.KODI_TYPE_SEASON) + # Remove plex episodes + plex_db.removeItems_byParentId(seasonid, + v.KODI_TYPE_EPISODE) + # Remove plex seasons + plex_db.removeItems_byParentId(kodiid, + v.KODI_TYPE_SEASON) # Remove tvshow self.removeShow(kodiid) @@ -1228,9 +1225,8 @@ class TVShows(Items): v.KODI_TYPE_EPISODE) for episode in season_episodes: self.removeEpisode(episode[1], episode[2]) - else: - # Remove plex episodes - plex_db.removeItems_byParentId(kodiid, v.KODI_TYPE_EPISODE) + # Remove plex episodes + plex_db.removeItems_byParentId(kodiid, v.KODI_TYPE_EPISODE) # Remove season self.removeSeason(kodiid) From c37961c600af95e26d8abf08eef5dac1dd214c72 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 8 May 2017 19:33:54 +0200 Subject: [PATCH 16/27] Fix too many arguments when marking 100% watched --- resources/lib/itemtypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py index 92fb5d2e..f0bac9a3 100644 --- a/resources/lib/itemtypes.py +++ b/resources/lib/itemtypes.py @@ -165,7 +165,7 @@ class Items(object): 'Mark item played at %s percent.' % (item['ratingKey'], str(complete), MARK_PLAYED_AT), 1) if complete >= MARK_PLAYED_AT: - log.info('Marking as completely watched in Kodi', 1) + log.info('Marking as completely watched in Kodi') sleep(500) try: item['viewCount'] += 1 From 5f7d8df6f7370a9ed7b26c99919983d9645b8816 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Tue, 9 May 2017 20:39:05 +0200 Subject: [PATCH 17/27] Fix PKC complaining about files not found --- resources/lib/PlexAPI.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index 0d8c897e..3dcc8696 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -2544,16 +2544,16 @@ class API(): # exist() needs a / or \ at the end to work for directories if folder is False: # files - check = exists(tryEncode(path)) == 1 + check = exists(tryEncode(path)) else: # directories - if "\\" in path: + if "\\" in path and not path.endswith('\\'): # Add the missing backslash - check = exists(tryEncode(path + "\\")) == 1 - else: - check = exists(tryEncode(path + "/")) == 1 + check = exists(tryEncode(path + "\\")) + elif "/" in path and not path.endswith('/'): + check = exists(tryEncode(path + "/")) - if check is False: + if not check: if forceCheck is False: # Validate the path is correct with user intervention if self.askToValidate(path): From f558b049fe00f0a7508b94c058583ef2d464bc31 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Tue, 9 May 2017 20:52:21 +0200 Subject: [PATCH 18/27] Update Czech translation --- resources/language/resource.language.cs_CZ/strings.po | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/resources/language/resource.language.cs_CZ/strings.po b/resources/language/resource.language.cs_CZ/strings.po index 5aa709c0..f00c289a 100644 --- a/resources/language/resource.language.cs_CZ/strings.po +++ b/resources/language/resource.language.cs_CZ/strings.po @@ -2041,3 +2041,13 @@ msgstr "Vynucené" msgctxt "#39710" msgid "burn-in" msgstr "Vpálit" + +# Dialog text if PKC detected a new Music library and Kodi needs to be +# restarted +msgctxt "#39711" +msgid "" +"New Plex music library detected. Sorry, but we need to restart Kodi now due " +"to the changes made." +msgstr "" +"Byla zjištěna nová hudební knihovna Plexu. Omlouváme se, ale pro provedení " +"změn budeme muset restartovat Kodi." From 4eb2e5a08ca4a9a562ef192189151ff579fab8f1 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Tue, 9 May 2017 20:54:16 +0200 Subject: [PATCH 19/27] Version bump --- README.md | 2 +- addon.xml | 11 +++++++++-- changelog.txt | 7 +++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 37139a9f..f4c0ca23 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![stable version](https://img.shields.io/badge/stable_version-1.7.7-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip) -[![beta version](https://img.shields.io/badge/beta_version-1.7.15-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) +[![beta version](https://img.shields.io/badge/beta_version-1.7.16-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) [![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation) [![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq) diff --git a/addon.xml b/addon.xml index a6eff035..737b21a7 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -44,7 +44,14 @@ Gebruik op eigen risico 使用風險由您自己承擔 Usar a su propio riesgo - version 1.7.15 (beta only) + version 1.7.16 (beta only) +- Fix PKC complaining about files not found +- Fix multiple subtitles per language not showing +- Update Czech translation +- Fix too many arguments when marking 100% watched +- More small fixes + +version 1.7.15 (beta only) - Fix companion for "Playback via PMS" - Change sleeping behavior for playqueue client - Plex Companion: add itemType to playstate diff --git a/changelog.txt b/changelog.txt index db8a5a9e..edb3f8dd 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,10 @@ +version 1.7.16 (beta only) +- Fix PKC complaining about files not found +- Fix multiple subtitles per language not showing +- Update Czech translation +- Fix too many arguments when marking 100% watched +- More small fixes + version 1.7.15 (beta only) - Fix companion for "Playback via PMS" - Change sleeping behavior for playqueue client From 216159d96cd6798aecd1ae0f9f5c58f88b74bd01 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Thu, 11 May 2017 17:51:14 +0200 Subject: [PATCH 20/27] Change to xbmcvfs mkdirs --- resources/lib/PlexAPI.py | 4 ++-- resources/lib/entrypoint.py | 5 +++-- resources/lib/utils.py | 7 ++++--- resources/lib/videonodes.py | 7 ++++--- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index 3dcc8696..ab96c6c4 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -40,10 +40,10 @@ from re import compile as re_compile, sub from json import dumps from urllib import urlencode, quote_plus, unquote from os.path import basename, join, exists -from os import makedirs import xbmcgui from xbmc import sleep, executebuiltin +from xbmcvfs import mkdirs import clientinfo as client from downloadutils import DownloadUtils @@ -2345,7 +2345,7 @@ class API(): Returns the path to the downloaded subtitle or None """ if not exists(v.EXTERNAL_SUBTITLE_TEMP_PATH): - makedirs(v.EXTERNAL_SUBTITLE_TEMP_PATH) + mkdirs(v.EXTERNAL_SUBTITLE_TEMP_PATH) path = join(v.EXTERNAL_SUBTITLE_TEMP_PATH, filename) r = DownloadUtils().downloadUrl(url, return_response=True) try: diff --git a/resources/lib/entrypoint.py b/resources/lib/entrypoint.py index fe56d842..dbac9e39 100644 --- a/resources/lib/entrypoint.py +++ b/resources/lib/entrypoint.py @@ -2,7 +2,7 @@ ############################################################################### import logging from shutil import copyfile -from os import walk, makedirs +from os import walk from os.path import basename, join, exists from sys import argv from urllib import urlencode @@ -10,6 +10,7 @@ from urllib import urlencode import xbmcplugin from xbmc import sleep, executebuiltin, translatePath from xbmcgui import ListItem +from xbmcvfs import mkdirs from utils import window, settings, language as lang, dialog, tryEncode, \ CatchExceptions, JSONRPC @@ -538,7 +539,7 @@ def getExtraFanArt(plexid, plexPath): fanartDir = translatePath("special://thumbnails/plex/%s/" % plexid) if not exists(fanartDir): # Download the images to the cache directory - makedirs(fanartDir) + mkdirs(fanartDir) xml = GetPlexMetadata(plexid) if xml is None: log.error('Could not download metadata for %s' % plexid) diff --git a/resources/lib/utils.py b/resources/lib/utils.py index d2a91f58..b040cdbd 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -13,14 +13,15 @@ from unicodedata import normalize import xml.etree.ElementTree as etree from functools import wraps from calendar import timegm -from os.path import exists, join -from os import remove, makedirs, walk +from os.path import join +from os import remove, walk from shutil import rmtree from urllib import quote_plus import xbmc import xbmcaddon import xbmcgui +from xbmcvfs import exists as kodi_exists, mkdirs from variables import DB_VIDEO_PATH, DB_MUSIC_PATH, DB_TEXTURE_PATH, \ DB_PLEX_PATH, KODI_PROFILE @@ -784,7 +785,7 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False): # Create the playlist directory if not exists(path): log.info("Creating directory: %s" % path) - makedirs(path) + mkdirs(path) # Only add the playlist if it doesn't already exists if exists(xsppath): diff --git a/resources/lib/videonodes.py b/resources/lib/videonodes.py index 4ffc91e7..1b200726 100644 --- a/resources/lib/videonodes.py +++ b/resources/lib/videonodes.py @@ -3,10 +3,11 @@ import logging from shutil import copytree import xml.etree.ElementTree as etree +from os import remove, listdir +from os.path import exists, isfile, join import xbmc -from os import remove, makedirs, listdir -from os.path import exists, isfile, join +from xbmcvfs import mkdirs from utils import window, settings, language as lang, tryEncode, indent, \ normalize_nodes @@ -84,7 +85,7 @@ class VideoNodes(object): if exists(nodepath) is False: # folder does not exist yet log.debug('Creating folder %s' % nodepath) - makedirs(nodepath) + mkdirs(nodepath) # Create index entry nodeXML = "%sindex.xml" % nodepath From fd84d97a462551503c278037d3b83518105f1a2e Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Thu, 11 May 2017 19:26:13 +0200 Subject: [PATCH 21/27] Use xbmcvfs exists instead of os.path.exists - Partially fixes #296 --- resources/lib/PlexAPI.py | 31 ++++++++++++++++++------------- resources/lib/artwork.py | 6 +++--- resources/lib/entrypoint.py | 9 +++++---- resources/lib/librarysync.py | 2 +- resources/lib/userclient.py | 2 +- resources/lib/utils.py | 28 ++++++++++++++++++++++++++-- resources/lib/videonodes.py | 12 ++++++------ 7 files changed, 60 insertions(+), 30 deletions(-) diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index ab96c6c4..07572f40 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -39,16 +39,16 @@ import xml.etree.ElementTree as etree from re import compile as re_compile, sub from json import dumps from urllib import urlencode, quote_plus, unquote -from os.path import basename, join, exists +from os.path import basename, join import xbmcgui from xbmc import sleep, executebuiltin -from xbmcvfs import mkdirs +from xbmcvfs import mkdirs, exists import clientinfo as client from downloadutils import DownloadUtils from utils import window, settings, language as lang, tryDecode, tryEncode, \ - DateToKodi + DateToKodi, exists_dir from PlexFunctions import PMSHttpsEnabled import plexdb_functions as plexdb import variables as v @@ -2117,10 +2117,9 @@ class API(): continue if fanartcount > maxfanarts: break - if exists(tryEncode(entry['url'])): - allartworks['Backdrop'].append( - entry['url'].replace(' ', '%20')) - fanartcount += 1 + allartworks['Backdrop'].append( + entry['url'].replace(' ', '%20')) + fanartcount += 1 return allartworks def getSetArtwork(self, parentInfo=False): @@ -2344,7 +2343,7 @@ class API(): Returns the path to the downloaded subtitle or None """ - if not exists(v.EXTERNAL_SUBTITLE_TEMP_PATH): + if not exists_dir(v.EXTERNAL_SUBTITLE_TEMP_PATH): mkdirs(v.EXTERNAL_SUBTITLE_TEMP_PATH) path = join(v.EXTERNAL_SUBTITLE_TEMP_PATH, filename) r = DownloadUtils().downloadUrl(url, return_response=True) @@ -2547,11 +2546,17 @@ class API(): check = exists(tryEncode(path)) else: # directories - if "\\" in path and not path.endswith('\\'): - # Add the missing backslash - check = exists(tryEncode(path + "\\")) - elif "/" in path and not path.endswith('/'): - check = exists(tryEncode(path + "/")) + if "\\" in path: + if not path.endswith('\\'): + # Add the missing backslash + check = exists_dir(tryEncode(path + "\\")) + else: + check = exists_dir(tryEncode(path)) + else: + if not path.endswith('/'): + check = exists_dir(tryEncode(path + "/")) + else: + check = exists_dir(tryEncode(path)) if not check: if forceCheck is False: diff --git a/resources/lib/artwork.py b/resources/lib/artwork.py index be076403..4efc05d4 100644 --- a/resources/lib/artwork.py +++ b/resources/lib/artwork.py @@ -4,16 +4,16 @@ import logging from json import dumps, loads import requests -from os.path import exists from shutil import rmtree from urllib import quote_plus, unquote from threading import Thread from Queue import Queue, Empty from xbmc import executeJSONRPC, sleep, translatePath +from xbmcvfs import exists from utils import window, settings, language as lang, kodiSQL, tryEncode, \ - ThreadMethods, ThreadMethodsAdditionalStop, dialog + ThreadMethods, ThreadMethodsAdditionalStop, dialog, exists_dir # Disable annoying requests warnings import requests.packages.urllib3 @@ -229,7 +229,7 @@ class Artwork(): log.info("Resetting all cache data first") # Remove all existing textures first path = translatePath("special://thumbnails/") - if exists(path): + if exists_dir(path): rmtree(path, ignore_errors=True) # remove all existing data from texture DB diff --git a/resources/lib/entrypoint.py b/resources/lib/entrypoint.py index dbac9e39..a7f14d23 100644 --- a/resources/lib/entrypoint.py +++ b/resources/lib/entrypoint.py @@ -3,7 +3,7 @@ import logging from shutil import copyfile from os import walk -from os.path import basename, join, exists +from os.path import basename, join from sys import argv from urllib import urlencode @@ -13,7 +13,7 @@ from xbmcgui import ListItem from xbmcvfs import mkdirs from utils import window, settings, language as lang, dialog, tryEncode, \ - CatchExceptions, JSONRPC + CatchExceptions, JSONRPC, exists_dir import downloadutils from PlexFunctions import GetPlexMetadata, GetPlexSectionResults, \ @@ -499,7 +499,7 @@ def getVideoFiles(plexId, params): path = path.replace('\\', '\\\\') # Directory only, get rid of filename path = path.replace(basename(path), '') - if exists(path): + if exists_dir(path): for root, dirs, files in walk(path): for directory in dirs: item_path = join(root, directory) @@ -514,6 +514,7 @@ def getVideoFiles(plexId, params): xbmcplugin.addDirectoryItem(handle=HANDLE, url=file, listitem=li) + break else: log.error('Kodi cannot access folder %s' % path) xbmcplugin.endOfDirectory(HANDLE) @@ -537,7 +538,7 @@ def getExtraFanArt(plexid, plexPath): # We need to store the images locally for this to work # because of the caching system in xbmc fanartDir = translatePath("special://thumbnails/plex/%s/" % plexid) - if not exists(fanartDir): + if not exists_dir(fanartDir): # Download the images to the cache directory mkdirs(fanartDir) xml = GetPlexMetadata(plexid) diff --git a/resources/lib/librarysync.py b/resources/lib/librarysync.py index d0e50cda..60e1a0e9 100644 --- a/resources/lib/librarysync.py +++ b/resources/lib/librarysync.py @@ -4,10 +4,10 @@ import logging from threading import Thread import Queue from random import shuffle -from os.path import exists import xbmc import xbmcgui +from xbmcvfs import exists from utils import window, settings, getUnixTimestamp, sourcesXML,\ ThreadMethods, ThreadMethodsAdditionalStop, LogTime, getScreensaver,\ diff --git a/resources/lib/userclient.py b/resources/lib/userclient.py index ebd790bd..339334a1 100644 --- a/resources/lib/userclient.py +++ b/resources/lib/userclient.py @@ -3,11 +3,11 @@ ############################################################################### import logging import threading -from os.path import exists import xbmc import xbmcgui import xbmcaddon +from xbmcvfs import exists from utils import window, settings, language as lang, ThreadMethods, \ diff --git a/resources/lib/utils.py b/resources/lib/utils.py index b040cdbd..7d17bd0c 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -21,10 +21,10 @@ from urllib import quote_plus import xbmc import xbmcaddon import xbmcgui -from xbmcvfs import exists as kodi_exists, mkdirs +from xbmcvfs import exists, mkdirs, delete from variables import DB_VIDEO_PATH, DB_MUSIC_PATH, DB_TEXTURE_PATH, \ - DB_PLEX_PATH, KODI_PROFILE + DB_PLEX_PATH, KODI_PROFILE, KODIVERSION ############################################################################### @@ -92,6 +92,30 @@ def settings(setting, value=None): return tryDecode(addon.getSetting(setting)) +def exists_dir(path): + """ + Safe way to check whether the directory path exists already (broken in Kodi + <17) + + Feed with encoded string + """ + if KODIVERSION >= 17: + answ = exists(path) + else: + dummyfile = join(path, 'dummyfile.txt') + try: + with open(dummyfile, 'w') as f: + f.write('text') + except IOError: + # folder does not exist yet + answ = 0 + else: + # Folder exists. Delete file again. + delete(dummyfile) + answ = 1 + return answ + + def language(stringid): # Central string retrieval return ADDON.getLocalizedString(stringid) diff --git a/resources/lib/videonodes.py b/resources/lib/videonodes.py index 1b200726..8e331a09 100644 --- a/resources/lib/videonodes.py +++ b/resources/lib/videonodes.py @@ -4,13 +4,13 @@ import logging from shutil import copytree import xml.etree.ElementTree as etree from os import remove, listdir -from os.path import exists, isfile, join +from os.path import isfile, join import xbmc -from xbmcvfs import mkdirs +from xbmcvfs import mkdirs, exists from utils import window, settings, language as lang, tryEncode, indent, \ - normalize_nodes + normalize_nodes, exists_dir import variables as v ############################################################################### @@ -75,14 +75,14 @@ class VideoNodes(object): return # Verify the video directory - if exists(path) is False: + if exists_dir(path) is False: copytree( src=xbmc.translatePath("special://xbmc/system/library/video"), dst=xbmc.translatePath("special://profile/library/video")) # Create the node directory if mediatype != "photos": - if exists(nodepath) is False: + if exists_dir(nodepath) is False: # folder does not exist yet log.debug('Creating folder %s' % nodepath) mkdirs(nodepath) @@ -388,7 +388,7 @@ class VideoNodes(object): windowpath = "ActivateWindow(Video,%s,return)" % path # Create the video node directory - if not exists(nodepath): + if not exists_dir(nodepath): # We need to copy over the default items copytree( src=xbmc.translatePath("special://xbmc/system/library/video"), From 03a1893bdb5396040948eaa95cab30825e258b81 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Thu, 11 May 2017 19:29:57 +0200 Subject: [PATCH 22/27] Fix WindowsError - Partially fixes #296 --- resources/lib/userclient.py | 3 +-- resources/lib/videonodes.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/resources/lib/userclient.py b/resources/lib/userclient.py index 339334a1..04f97d16 100644 --- a/resources/lib/userclient.py +++ b/resources/lib/userclient.py @@ -211,10 +211,9 @@ class UserClient(threading.Thread): # Get /profile/addon_data addondir = xbmc.translatePath(self.addon.getAddonInfo('profile')) - hasSettings = exists("%ssettings.xml" % addondir) # If there's no settings.xml - if not hasSettings: + if not exists("%ssettings.xml" % addondir): log.error("Error, no settings.xml found.") self.auth = False return False diff --git a/resources/lib/videonodes.py b/resources/lib/videonodes.py index 8e331a09..94fa9701 100644 --- a/resources/lib/videonodes.py +++ b/resources/lib/videonodes.py @@ -75,14 +75,14 @@ class VideoNodes(object): return # Verify the video directory - if exists_dir(path) is False: + if not exists_dir(path): copytree( src=xbmc.translatePath("special://xbmc/system/library/video"), dst=xbmc.translatePath("special://profile/library/video")) # Create the node directory if mediatype != "photos": - if exists_dir(nodepath) is False: + if not exists_dir(nodepath): # folder does not exist yet log.debug('Creating folder %s' % nodepath) mkdirs(nodepath) From 9138cdbb67af76a2c17288266d43c3a2202a5a38 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Thu, 11 May 2017 19:44:08 +0200 Subject: [PATCH 23/27] Repace Kodi mkdirs with os.makedirs - Partially fixes #296 --- resources/lib/PlexAPI.py | 5 +++-- resources/lib/entrypoint.py | 5 ++--- resources/lib/utils.py | 6 +++--- resources/lib/videonodes.py | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index 07572f40..fbd28e7c 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -40,10 +40,11 @@ from re import compile as re_compile, sub from json import dumps from urllib import urlencode, quote_plus, unquote from os.path import basename, join +from os import makedirs import xbmcgui from xbmc import sleep, executebuiltin -from xbmcvfs import mkdirs, exists +from xbmcvfs import exists import clientinfo as client from downloadutils import DownloadUtils @@ -2344,7 +2345,7 @@ class API(): Returns the path to the downloaded subtitle or None """ if not exists_dir(v.EXTERNAL_SUBTITLE_TEMP_PATH): - mkdirs(v.EXTERNAL_SUBTITLE_TEMP_PATH) + makedirs(v.EXTERNAL_SUBTITLE_TEMP_PATH) path = join(v.EXTERNAL_SUBTITLE_TEMP_PATH, filename) r = DownloadUtils().downloadUrl(url, return_response=True) try: diff --git a/resources/lib/entrypoint.py b/resources/lib/entrypoint.py index a7f14d23..8ab911cd 100644 --- a/resources/lib/entrypoint.py +++ b/resources/lib/entrypoint.py @@ -2,7 +2,7 @@ ############################################################################### import logging from shutil import copyfile -from os import walk +from os import walk, makedirs from os.path import basename, join from sys import argv from urllib import urlencode @@ -10,7 +10,6 @@ from urllib import urlencode import xbmcplugin from xbmc import sleep, executebuiltin, translatePath from xbmcgui import ListItem -from xbmcvfs import mkdirs from utils import window, settings, language as lang, dialog, tryEncode, \ CatchExceptions, JSONRPC, exists_dir @@ -540,7 +539,7 @@ def getExtraFanArt(plexid, plexPath): fanartDir = translatePath("special://thumbnails/plex/%s/" % plexid) if not exists_dir(fanartDir): # Download the images to the cache directory - mkdirs(fanartDir) + makedirs(fanartDir) xml = GetPlexMetadata(plexid) if xml is None: log.error('Could not download metadata for %s' % plexid) diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 7d17bd0c..e94f7555 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -14,14 +14,14 @@ import xml.etree.ElementTree as etree from functools import wraps from calendar import timegm from os.path import join -from os import remove, walk +from os import remove, walk, makedirs from shutil import rmtree from urllib import quote_plus import xbmc import xbmcaddon import xbmcgui -from xbmcvfs import exists, mkdirs, delete +from xbmcvfs import exists, delete from variables import DB_VIDEO_PATH, DB_MUSIC_PATH, DB_TEXTURE_PATH, \ DB_PLEX_PATH, KODI_PROFILE, KODIVERSION @@ -809,7 +809,7 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False): # Create the playlist directory if not exists(path): log.info("Creating directory: %s" % path) - mkdirs(path) + makedirs(path) # Only add the playlist if it doesn't already exists if exists(xsppath): diff --git a/resources/lib/videonodes.py b/resources/lib/videonodes.py index 94fa9701..f6561ad8 100644 --- a/resources/lib/videonodes.py +++ b/resources/lib/videonodes.py @@ -3,11 +3,11 @@ import logging from shutil import copytree import xml.etree.ElementTree as etree -from os import remove, listdir +from os import remove, listdir, makedirs from os.path import isfile, join import xbmc -from xbmcvfs import mkdirs, exists +from xbmcvfs import exists from utils import window, settings, language as lang, tryEncode, indent, \ normalize_nodes, exists_dir @@ -85,7 +85,7 @@ class VideoNodes(object): if not exists_dir(nodepath): # folder does not exist yet log.debug('Creating folder %s' % nodepath) - mkdirs(nodepath) + makedirs(nodepath) # Create index entry nodeXML = "%sindex.xml" % nodepath From 5c8c399b30676bf50146be024978122853a4acec Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Thu, 11 May 2017 19:58:21 +0200 Subject: [PATCH 24/27] Don't add media by other add-ons to queue - Fixes #295 --- resources/lib/playqueue.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/resources/lib/playqueue.py b/resources/lib/playqueue.py index 3559e0c6..a496574b 100644 --- a/resources/lib/playqueue.py +++ b/resources/lib/playqueue.py @@ -17,6 +17,7 @@ log = logging.getLogger("PLEX."+__name__) # Lock used for playqueue manipulations lock = RLock() +PLUGIN = 'plugin://%s' % v.ADDON_ID ############################################################################### @@ -147,11 +148,19 @@ class Playqueue(Thread): log.debug('Comparing new Kodi playqueue %s with our play queue %s' % (new, old)) for i, new_item in enumerate(new): + if (new_item['file'].startswith('plugin://') and + not new_item['file'].startswith(PLUGIN)): + # Ignore new media added by other addons + continue for j, old_item in enumerate(old): if self.threadStopped(): # Chances are that we got an empty Kodi playlist due to # Kodi exit return + if (old_item['file'].startswith('plugin://') and + not old_item['file'].startswith(PLUGIN)): + # Ignore media by other addons + continue if new_item.get('id') is None: identical = old_item.file == new_item['file'] else: From af55d75bf36d5f74327d0f1ed0671d8c274adac0 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Thu, 11 May 2017 20:07:23 +0200 Subject: [PATCH 25/27] Fix KeyError for Plex Companion --- resources/lib/plexbmchelper/subscribers.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/lib/plexbmchelper/subscribers.py b/resources/lib/plexbmchelper/subscribers.py index fcdd2499..b8f4e20b 100644 --- a/resources/lib/plexbmchelper/subscribers.py +++ b/resources/lib/plexbmchelper/subscribers.py @@ -227,7 +227,8 @@ class SubscriptionManager: props = self.js.jsonrpc( "Player.GetProperties", {"playerid": playerid, - "properties": ["time", + "properties": ["type", + "time", "totaltime", "speed", "shuffled", @@ -252,7 +253,7 @@ class SubscriptionManager: info['playQueueVersion'] = playqueue.version or 'null' info['itemType'] = playqueue.items[pos].plex_type or 'null' except: - pass + info['itemType'] = props.get('type') or 'null' except: import traceback log.error("Traceback:\n%s" % traceback.format_exc()) From 11077bccece953ab9a1fb8e2cd5919cf6e6e5049 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Thu, 11 May 2017 20:10:14 +0200 Subject: [PATCH 26/27] Version bump --- README.md | 2 +- addon.xml | 10 ++++++++-- changelog.txt | 6 ++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f4c0ca23..1c14e0e8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![stable version](https://img.shields.io/badge/stable_version-1.7.7-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip) -[![beta version](https://img.shields.io/badge/beta_version-1.7.16-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) +[![beta version](https://img.shields.io/badge/beta_version-1.7.17-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) [![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation) [![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq) diff --git a/addon.xml b/addon.xml index 737b21a7..c8b7d5eb 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -44,7 +44,13 @@ Gebruik op eigen risico 使用風險由您自己承擔 Usar a su propio riesgo - version 1.7.16 (beta only) + version 1.7.17 (beta only) +- Don't add media by other add-ons to queue +- Fix KeyError for Plex Companion +- Repace Kodi mkdirs with os.makedirs +- Use xbmcvfs exists instead of os.path.exists + +version 1.7.16 (beta only) - Fix PKC complaining about files not found - Fix multiple subtitles per language not showing - Update Czech translation diff --git a/changelog.txt b/changelog.txt index edb3f8dd..866eb44d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,9 @@ +version 1.7.17 (beta only) +- Don't add media by other add-ons to queue +- Fix KeyError for Plex Companion +- Repace Kodi mkdirs with os.makedirs +- Use xbmcvfs exists instead of os.path.exists + version 1.7.16 (beta only) - Fix PKC complaining about files not found - Fix multiple subtitles per language not showing From 56bd2d88b632adae80e83890a55a3cae8495078b Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Thu, 11 May 2017 20:16:19 +0200 Subject: [PATCH 27/27] Ability to translate sync progress dialog --- .../resource.language.en_gb/strings.po | 20 +++++++++++++++++++ resources/lib/library_sync/sync_info.py | 9 +++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index f88e31b5..e43dbf53 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -1899,3 +1899,23 @@ msgstr "" msgctxt "#39711" msgid "New Plex music library detected. Sorry, but we need to restart Kodi now due to the changes made." msgstr "" + +# Shown during sync process +msgctxt "#39712" +msgid "downloaded" +msgstr "" + +# Shown during sync process +msgctxt "#39713" +msgid "processed" +msgstr "" + +# Shown during sync process +msgctxt "#39714" +msgid "Sync" +msgstr "" + +# Shown during sync process +msgctxt "#39715" +msgid "items" +msgstr "" diff --git a/resources/lib/library_sync/sync_info.py b/resources/lib/library_sync/sync_info.py index df14e433..3be8f70b 100644 --- a/resources/lib/library_sync/sync_info.py +++ b/resources/lib/library_sync/sync_info.py @@ -54,9 +54,8 @@ class Threaded_Show_Sync_Info(Thread): total = self.total dialog = self.dialog threadStopped = self.threadStopped - dialog.create("%s: Sync %s: %s items" - % (lang(29999), self.item_type, str(total)), - "Starting") + dialog.create("%s %s: %s %s" + % (lang(39714), self.item_type, str(total), lang(39715))) total = 2 * total totalProgress = 0 @@ -71,9 +70,11 @@ class Threaded_Show_Sync_Info(Thread): except ZeroDivisionError: percentage = 0 dialog.update(percentage, - message="%s downloaded. %s processed: %s" + message="%s %s. %s %s: %s" % (get_progress, + lang(39712), process_progress, + lang(39713), viewName)) # Sleep for x milliseconds sleep(200)