diff --git a/plexapi/library.py b/plexapi/library.py index 6589ef84a..f6e10a117 100644 --- a/plexapi/library.py +++ b/plexapi/library.py @@ -466,6 +466,43 @@ 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 defaultAdvanced(self): + """ Edit all of library's advanced settings to default. """ + data = {} + key = 'prefs[%s]' + for setting in self.settings(): + if setting.type == 'bool': + data[key % setting.id] = int(setting.default) + else: + data[key % setting.id] = setting.default + + self.edit(**data) + def timeline(self): """ Returns a timeline query for this library section. """ key = '/library/sections/%s/timeline' % self.key diff --git a/plexapi/settings.py b/plexapi/settings.py index 88b8e4f68..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): @@ -167,3 +166,9 @@ class Preferences(Setting): """ TAG = 'Preferences' FILTER = 'preferences' + + def _default(self): + """ Set the default value for this setting.""" + key = '%s/prefs?' % self._initpath + url = key + '%s=%s' % (self.id, self.default) + self._server.query(url, method=self._server._session.put) diff --git a/plexapi/video.py b/plexapi/video.py index ef1a348ef..e2b542301 100644 --- a/plexapi/video.py +++ b/plexapi/video.py @@ -453,10 +453,35 @@ 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 + 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()} + for settingID, value in kwargs.items(): + enumValues = 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 defaultAdvanced(self): + """ Edit all of show's advanced settings to default. """ + 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) diff --git a/tests/test_library.py b/tests/test_library.py index 30d1d2b99..fabc3ff7a 100644 --- a/tests/test_library.py +++ b/tests/test_library.py @@ -219,6 +219,28 @@ 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_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(): 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): diff --git a/tests/test_video.py b/tests/test_video.py index c1ae4eca6..2c46a56c0 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -558,6 +558,30 @@ 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_editAdvanced_default(show): + show.editAdvanced(showOrdering='absolute') + show.reload() + for pref in show.preferences(): + if pref.id == 'showOrdering': + assert pref.value == 'absolute' + + show.editAdvanced(flattenSeasons=1) + show.reload() + for pref in show.preferences(): + if pref.id == 'flattenSeasons': + assert pref.value == 1 + + show.defaultAdvanced() + show.reload() + for pref in show.preferences(): + assert pref.value == 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/")