From 0dbdff4b03248d8c89fbd7f5fe8e00538e6b4d50 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Fri, 5 Jun 2020 13:41:48 -0400 Subject: [PATCH 01/19] create editAdvanced method allow for editing a show's advanced settings using kwargs --- plexapi/video.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/plexapi/video.py b/plexapi/video.py index 5396d87fa..efd5b26f9 100644 --- a/plexapi/video.py +++ b/plexapi/video.py @@ -446,6 +446,22 @@ def preferences(self): return items + def editAdvanced(self, **kwargs): + data = {} + key = '%s/prefs?' % self.key + preferences = {pref.id: list(pref.enumValues.keys()) for pref in self.preferences()} + for settingID, value in kwargs.items(): + try: + enumValues = [int(x) for x in preferences.get(settingID)] + except ValueError: + enumValues = [x.decode() for x in preferences.get(settingID)] + if value in enumValues: + data[settingID] = value + else: + raise NotFound('%s not found in %s' % (value, enumValues)) + url = key + urlencode(data) + self._server.query(url, method=self._server._session.put) + def hubs(self): """ Returns a list of :class:`~plexapi.library.Hub` objects. """ data = self._server.query(self._details_key) From afe25d19acae5eddce545843dd8550d1610c9788 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Fri, 5 Jun 2020 13:48:34 -0400 Subject: [PATCH 02/19] create defaultAdvanced method allows for defaulting all advanced settings --- plexapi/video.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plexapi/video.py b/plexapi/video.py index efd5b26f9..01eb2da61 100644 --- a/plexapi/video.py +++ b/plexapi/video.py @@ -462,6 +462,14 @@ def editAdvanced(self, **kwargs): url = key + urlencode(data) self._server.query(url, method=self._server._session.put) + def defaultAdvanced(self): + data = {} + key = '%s/prefs?' % self.key + for preference in self.preferences(): + data[preference.id] = preference.default + url = key + urlencode(data) + self._server.query(url, method=self._server._session.put) + def hubs(self): """ Returns a list of :class:`~plexapi.library.Hub` objects. """ data = self._server.query(self._details_key) From 2c256f89c2264d193295dd357a0de446da1c0f6a Mon Sep 17 00:00:00 2001 From: blacktwin Date: Fri, 5 Jun 2020 14:12:30 -0400 Subject: [PATCH 03/19] add _initpath to Preferences atrributes --- plexapi/video.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plexapi/video.py b/plexapi/video.py index 01eb2da61..0cddc6c93 100644 --- a/plexapi/video.py +++ b/plexapi/video.py @@ -442,7 +442,9 @@ def preferences(self): data = self._server.query(self._details_key) for item in data.iter('Preferences'): for elem in item: - items.append(settings.Preferences(data=elem, server=self._server)) + setting = settings.Preferences(data=elem, server=self._server) + setting._initpath = self.key + items.append(setting) return items From 0b31454c0fe0ebd5744b4688d8f4545cdd63de41 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Fri, 5 Jun 2020 14:12:59 -0400 Subject: [PATCH 04/19] add _default method to Preferences class --- plexapi/settings.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plexapi/settings.py b/plexapi/settings.py index 88b8e4f68..4b2180aa0 100644 --- a/plexapi/settings.py +++ b/plexapi/settings.py @@ -167,3 +167,11 @@ class Preferences(Setting): """ TAG = 'Preferences' FILTER = 'preferences' + + def _default(self): + key = '%s/prefs?' % self._initpath + if self.type == 'int': + url = key + '%s=%s' % (self.id, self.default) + else: + url = key + '%s=%s' % (self.id, self.default.decode()) + self._server.query(url, method=self._server._session.put) From 0974b1e2b15350f30c3ad8b5a835ac9786672fe6 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Fri, 5 Jun 2020 14:18:35 -0400 Subject: [PATCH 05/19] _default docstring --- plexapi/settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plexapi/settings.py b/plexapi/settings.py index 4b2180aa0..aec215840 100644 --- a/plexapi/settings.py +++ b/plexapi/settings.py @@ -169,6 +169,7 @@ class Preferences(Setting): FILTER = 'preferences' def _default(self): + """ Set the default value for this setting.""" key = '%s/prefs?' % self._initpath if self.type == 'int': url = key + '%s=%s' % (self.id, self.default) From d0975a8a738bd931550d492d9c8b050fa43a0708 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Fri, 5 Jun 2020 14:20:39 -0400 Subject: [PATCH 06/19] docstrings for new methods. --- plexapi/video.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plexapi/video.py b/plexapi/video.py index 0cddc6c93..065348f0f 100644 --- a/plexapi/video.py +++ b/plexapi/video.py @@ -449,6 +449,7 @@ def preferences(self): return items def editAdvanced(self, **kwargs): + """ Edit a show's advanced settings. """ data = {} key = '%s/prefs?' % self.key preferences = {pref.id: list(pref.enumValues.keys()) for pref in self.preferences()} @@ -465,6 +466,7 @@ def editAdvanced(self, **kwargs): self._server.query(url, method=self._server._session.put) def defaultAdvanced(self): + """ Edit all of show's advanced settings to default. """ data = {} key = '%s/prefs?' % self.key for preference in self.preferences(): From 7474e7d28e4036e5cc3f55dc1c4f5615d065adef Mon Sep 17 00:00:00 2001 From: blacktwin Date: Tue, 9 Jun 2020 23:25:23 -0400 Subject: [PATCH 07/19] add editAdvanced method to library.LibrarySection addressing #450 --- plexapi/library.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/plexapi/library.py b/plexapi/library.py index 397f5c2ef..c562084d7 100644 --- a/plexapi/library.py +++ b/plexapi/library.py @@ -466,6 +466,31 @@ def settings(self): data = self._server.query(key) return self.findItems(data, cls=Setting) + def editAdvanced(self, **kwargs): + """ Edit a library's advanced settings. """ + data = {} + idEnums = {} + key = 'prefs[%s]' + + for setting in self.settings(): + if setting.type != 'bool': + idEnums[setting.id] = setting.enumValues + else: + idEnums[setting.id] = {0: False, 1: True} + + for settingID, value in kwargs.items(): + try: + enums = idEnums.get(settingID) + enumValues = [int(x) for x in enums] + except TypeError: + raise NotFound('%s not found in %s' % (value, list(idEnums.keys()))) + if value in enumValues: + data[key % settingID] = value + else: + raise NotFound('%s not found in %s' % (value, enums)) + + self.edit(**data) + def onDeck(self): """ Returns a list of media items on deck from this library section. """ key = '/library/sections/%s/onDeck' % self.key From 59fcdb4080c6acb675db6ee06ae2265fae099aa3 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Tue, 9 Jun 2020 23:32:22 -0400 Subject: [PATCH 08/19] add defaultAdvanced method to library.LibrarySection --- plexapi/library.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plexapi/library.py b/plexapi/library.py index c562084d7..bf1c85ab6 100644 --- a/plexapi/library.py +++ b/plexapi/library.py @@ -491,6 +491,15 @@ def editAdvanced(self, **kwargs): self.edit(**data) + def defaultAdvanced(self): + """ Edit all of library's advanced settings to default. """ + data = {} + key = 'prefs[%s]' + for setting in self.settings(): + data[key % setting.id] = setting.default + + self.edit(**data) + def onDeck(self): """ Returns a list of media items on deck from this library section. """ key = '/library/sections/%s/onDeck' % self.key From e93d957b2bef14f4e3a2abc5008a5fc684c5ec69 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Thu, 18 Jun 2020 09:47:22 -0400 Subject: [PATCH 09/19] add test for show preferences --- tests/test_video.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_video.py b/tests/test_video.py index 139031e09..3365ea7dd 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -558,6 +558,11 @@ def test_video_Show_location(plex): assert len(show.locations) >= 1 +def test_video_Show_settings(show): + preferences = show.preferences() + assert len(preferences) >= 1 + + def test_video_Show_reload(plex): show = plex.library.section("TV Shows").get("Game of Thrones") assert utils.is_metadata(show._initpath, prefix="/library/sections/") From fa54430a54691a487019827a14a0562a388c936e Mon Sep 17 00:00:00 2001 From: blacktwin Date: Thu, 18 Jun 2020 09:48:03 -0400 Subject: [PATCH 10/19] add test for editing show advanced setting then defaulting back --- tests/test_video.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/test_video.py b/tests/test_video.py index 3365ea7dd..44acca8da 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -563,6 +563,28 @@ def test_video_Show_settings(show): assert len(preferences) >= 1 +def test_video_Show_editAdvanced_default(show): + show.editAdvanced(episodeSort=0) + show.reload() + for pref in show.preferences(): + if pref.id == 'episodeSort': + assert int(pref.value) == 0 + + show.editAdvanced(flattenSeasons=1) + show.reload() + for pref in show.preferences(): + if pref.id == 'flattenSeasons': + assert int(pref.value) == 1 + + show.defaultAdvanced() + show.reload() + for pref in show.preferences(): + if pref.id == 'flattenSeasons': + assert int(pref.value) == int(pref.default) + if pref.id == 'episodeSort': + assert int(pref.value) == int(pref.default) + + def test_video_Show_reload(plex): show = plex.library.section("TV Shows").get("Game of Thrones") assert utils.is_metadata(show._initpath, prefix="/library/sections/") From 7caee834dabe0f9ee49d531d0cc14dcd9e8c51c6 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Thu, 18 Jun 2020 09:56:21 -0400 Subject: [PATCH 11/19] assert correction for defaulting show advanced settings --- tests/test_video.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/test_video.py b/tests/test_video.py index 44acca8da..319ec74f5 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -579,10 +579,7 @@ def test_video_Show_editAdvanced_default(show): show.defaultAdvanced() show.reload() for pref in show.preferences(): - if pref.id == 'flattenSeasons': - assert int(pref.value) == int(pref.default) - if pref.id == 'episodeSort': - assert int(pref.value) == int(pref.default) + assert int(pref.value) == int(pref.default) def test_video_Show_reload(plex): From c7baf7132311159747c7a2a4a6395a83b572f396 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Thu, 18 Jun 2020 09:57:04 -0400 Subject: [PATCH 12/19] add test for library settings --- tests/test_library.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_library.py b/tests/test_library.py index 17f8f54a0..2585cf3a2 100644 --- a/tests/test_library.py +++ b/tests/test_library.py @@ -218,6 +218,11 @@ def test_library_and_section_search_for_movie(plex): assert l_search == s_search +def test_library_settings(movies): + settings = movies.settings() + assert len(settings) >= 1 + + def test_library_Collection_modeUpdate(collection): mode_dict = {"default": "-2", "hide": "0", "hideItems": "1", "showItems": "2"} for key, value in mode_dict.items(): From 38b863b8daf670ed54c5b4532a82711bb8c23861 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Thu, 18 Jun 2020 10:03:47 -0400 Subject: [PATCH 13/19] correction for library.librarySection.defaultAdvanced method --- plexapi/library.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plexapi/library.py b/plexapi/library.py index bf1c85ab6..dd5f12562 100644 --- a/plexapi/library.py +++ b/plexapi/library.py @@ -496,7 +496,10 @@ def defaultAdvanced(self): data = {} key = 'prefs[%s]' for setting in self.settings(): - data[key % setting.id] = setting.default + if setting.type == 'bool': + data[key % setting.id] = int(setting.default) + else: + data[key % setting.id] = setting.default self.edit(**data) From ab41c1bdd5d42d2f18e010ba7959d4f16eb03679 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Thu, 18 Jun 2020 10:04:29 -0400 Subject: [PATCH 14/19] add test for editing library advanced setting then defaulting back. --- tests/test_library.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_library.py b/tests/test_library.py index 2585cf3a2..46fea865f 100644 --- a/tests/test_library.py +++ b/tests/test_library.py @@ -223,6 +223,23 @@ def test_library_settings(movies): assert len(settings) >= 1 +def test_library_editAdvanced_default(movies): + movies.editAdvanced(hidden=2) + for setting in movies.settings(): + if setting.id == 'hidden': + assert int(setting.value) == 2 + + movies.editAdvanced(collectionMode=0) + for setting in movies.settings(): + if setting.id == 'collectionMode': + assert int(setting.value) == 0 + + movies.reload() + movies.defaultAdvanced() + for setting in movies.settings(): + assert int(setting.value) == int(setting.default) + + def test_library_Collection_modeUpdate(collection): mode_dict = {"default": "-2", "hide": "0", "hideItems": "1", "showItems": "2"} for key, value in mode_dict.items(): From 337ad9d88cb40abc4c84a34eccd2feb52d365561 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Mon, 27 Jul 2020 15:54:54 -0400 Subject: [PATCH 15/19] correct assertion for default and value comparision. --- tests/test_video.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_video.py b/tests/test_video.py index 319ec74f5..0d3c48f3d 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -579,7 +579,7 @@ def test_video_Show_editAdvanced_default(show): show.defaultAdvanced() show.reload() for pref in show.preferences(): - assert int(pref.value) == int(pref.default) + assert pref.value == pref.default def test_video_Show_reload(plex): From 5045ddc04b118da4150d0657bf63089c5bd46660 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Tue, 28 Jul 2020 11:13:51 -0400 Subject: [PATCH 16/19] removed deprecated _str function as py2 support has been dropped update _str references to use builin str instead update settings.Preferences class for py2 drop --- plexapi/settings.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/plexapi/settings.py b/plexapi/settings.py index aec215840..a62460bdf 100644 --- a/plexapi/settings.py +++ b/plexapi/settings.py @@ -101,12 +101,11 @@ class Setting(PlexObject): """ _bool_cast = lambda x: True if x == 'true' or x == '1' else False _bool_str = lambda x: str(x).lower() - _str = lambda x: str(x).encode('utf-8') TYPES = { 'bool': {'type': bool, 'cast': _bool_cast, 'tostr': _bool_str}, - 'double': {'type': float, 'cast': float, 'tostr': _str}, - 'int': {'type': int, 'cast': int, 'tostr': _str}, - 'text': {'type': str, 'cast': _str, 'tostr': _str}, + 'double': {'type': float, 'cast': float, 'tostr': str}, + 'int': {'type': int, 'cast': int, 'tostr': str}, + 'text': {'type': str, 'cast': str, 'tostr': str}, } def _loadData(self, data): @@ -171,8 +170,5 @@ class Preferences(Setting): def _default(self): """ Set the default value for this setting.""" key = '%s/prefs?' % self._initpath - if self.type == 'int': - url = key + '%s=%s' % (self.id, self.default) - else: - url = key + '%s=%s' % (self.id, self.default.decode()) + url = key + '%s=%s' % (self.id, self.default) self._server.query(url, method=self._server._session.put) From 18973e2f2d7cf58933ef1bee2d6f1e7eb3b3a71f Mon Sep 17 00:00:00 2001 From: blacktwin Date: Tue, 28 Jul 2020 11:16:31 -0400 Subject: [PATCH 17/19] update editAdvanced method to work with py2 drop --- plexapi/video.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plexapi/video.py b/plexapi/video.py index 065348f0f..5e9c9aac6 100644 --- a/plexapi/video.py +++ b/plexapi/video.py @@ -454,10 +454,7 @@ def editAdvanced(self, **kwargs): key = '%s/prefs?' % self.key preferences = {pref.id: list(pref.enumValues.keys()) for pref in self.preferences()} for settingID, value in kwargs.items(): - try: - enumValues = [int(x) for x in preferences.get(settingID)] - except ValueError: - enumValues = [x.decode() for x in preferences.get(settingID)] + enumValues = preferences.get(settingID) if value in enumValues: data[settingID] = value else: From 620056a23458787833a46765485783462f5f2fa2 Mon Sep 17 00:00:00 2001 From: blacktwin Date: Tue, 28 Jul 2020 11:18:14 -0400 Subject: [PATCH 18/19] update test_video_Show_editAdvanced_default to use 1 str/text and 1 int/int based change --- tests/test_video.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_video.py b/tests/test_video.py index 0d3c48f3d..3c9a7b43e 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -564,17 +564,17 @@ def test_video_Show_settings(show): def test_video_Show_editAdvanced_default(show): - show.editAdvanced(episodeSort=0) + show.editAdvanced(showOrdering='absolute') show.reload() for pref in show.preferences(): - if pref.id == 'episodeSort': - assert int(pref.value) == 0 + if pref.id == 'showOrdering': + assert pref.value == 'absolute' show.editAdvanced(flattenSeasons=1) show.reload() for pref in show.preferences(): if pref.id == 'flattenSeasons': - assert int(pref.value) == 1 + assert pref.value == 1 show.defaultAdvanced() show.reload() From 01239046c7fb075313236fd01e7bfd32c2ca7bce Mon Sep 17 00:00:00 2001 From: blacktwin Date: Mon, 28 Sep 2020 13:58:07 -0400 Subject: [PATCH 19/19] cleaning up test_settings.test_settings_get test py2 support has been dropped. returning str instead of bytes now due to 5045ddc --- tests/test_settings.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/test_settings.py b/tests/test_settings.py index 3d3a0d9c1..b2edbcccc 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -3,12 +3,8 @@ def test_settings_group(plex): def test_settings_get(plex): - # This is the value since it we havnt set any friendlyname - # plex just default to computer name but it NOT in the settings. - # check this one. why is this bytes instead of string. value = plex.settings.get("FriendlyName").value - # Should not be bytes, fix this when py2 is dropped - assert isinstance(value, bytes) + assert isinstance(value, str) def test_settings_set(plex):