diff --git a/plexapi/mixins.py b/plexapi/mixins.py index b9710e43c..f27ab71ec 100644 --- a/plexapi/mixins.py +++ b/plexapi/mixins.py @@ -402,6 +402,12 @@ def setArt(self, art): art.select() return self + def deleteArt(self): + """ Delete the art from a Plex object. """ + key = f'/library/metadata/{self.ratingKey}/art' + self._server.query(key, method=self._server._session.delete) + return self + class LogoUrlMixin: """ Mixin for Plex objects that can have a logo url. """ @@ -422,11 +428,11 @@ class LogoLockMixin: def lockLogo(self): """ Lock the logo for a Plex object. """ - raise NotImplementedError('Logo cannot be locked through the API.') + return self._edit(**{'clearLogo.locked': 1}) def unlockLogo(self): """ Unlock the logo for a Plex object. """ - raise NotImplementedError('Logo cannot be unlocked through the API.') + return self._edit(**{'clearLogo.locked': 0}) class LogoMixin(LogoUrlMixin, LogoLockMixin): @@ -455,13 +461,17 @@ def uploadLogo(self, url=None, filepath=None): def setLogo(self, logo): """ Set the logo for a Plex object. - Raises: - :exc:`~plexapi.exceptions.NotImplementedError`: Logo cannot be set through the API. + Parameters: + logo (:class:`~plexapi.media.Logo`): The logo object to select. """ - raise NotImplementedError( - 'Logo cannot be set through the API. ' - 'Re-upload the logo using "uploadLogo" to set it.' - ) + logo.select() + return self + + def deleteLogo(self): + """ Delete the logo from a Plex object. """ + key = f'/library/metadata/{self.ratingKey}/clearLogo' + self._server.query(key, method=self._server._session.delete) + return self class PosterUrlMixin: @@ -523,6 +533,12 @@ def setPoster(self, poster): poster.select() return self + def deletePoster(self): + """ Delete the poster from a Plex object. """ + key = f'/library/metadata/{self.ratingKey}/thumb' + self._server.query(key, method=self._server._session.delete) + return self + class SquareArtUrlMixin: """ Mixin for Plex objects that can have a square art url. """ @@ -649,6 +665,12 @@ def setTheme(self, theme): 'Re-upload the theme using "uploadTheme" to set it.' ) + def deleteTheme(self): + """ Delete the theme from a Plex object. """ + key = f'/library/metadata/{self.ratingKey}/theme' + self._server.query(key, method=self._server._session.delete) + return self + class EditFieldMixin: """ Mixin for editing Plex object fields. """ diff --git a/tests/test_audio.py b/tests/test_audio.py index 91be580ec..60510d31b 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -103,9 +103,11 @@ def test_audio_Artist_mixins_edit_advanced_settings(artist): @pytest.mark.xfail(reason="Changing images fails randomly") def test_audio_Artist_mixins_images(artist): test_mixins.lock_art(artist) + test_mixins.lock_logo(artist) test_mixins.lock_poster(artist) test_mixins.lock_squareArt(artist) test_mixins.edit_art(artist) + test_mixins.edit_logo(artist) test_mixins.edit_poster(artist) test_mixins.edit_squareArt(artist) test_mixins.attr_artUrl(artist) @@ -237,9 +239,11 @@ def test_audio_Album_artist(album): @pytest.mark.xfail(reason="Changing images fails randomly") def test_audio_Album_mixins_images(album): test_mixins.lock_art(album) + test_mixins.lock_logo(album) test_mixins.lock_poster(album) test_mixins.lock_squareArt(album) test_mixins.edit_art(album) + test_mixins.edit_logo(album) test_mixins.edit_poster(album) test_mixins.edit_squareArt(album) test_mixins.attr_artUrl(album) diff --git a/tests/test_collection.py b/tests/test_collection.py index 03632530c..0b18179a1 100644 --- a/tests/test_collection.py +++ b/tests/test_collection.py @@ -352,9 +352,11 @@ def test_Collection_art(collection): @pytest.mark.xfail(reason="Changing images fails randomly") def test_Collection_mixins_images(collection): test_mixins.lock_art(collection) + test_mixins.lock_logo(collection) test_mixins.lock_poster(collection) test_mixins.lock_squareArt(collection) test_mixins.edit_art(collection) + test_mixins.edit_logo(collection) test_mixins.edit_poster(collection) test_mixins.edit_squareArt(collection) test_mixins.attr_artUrl(collection) diff --git a/tests/test_mixins.py b/tests/test_mixins.py index f80fa5479..2aceff56f 100644 --- a/tests/test_mixins.py +++ b/tests/test_mixins.py @@ -219,6 +219,10 @@ def lock_art(obj): _test_mixins_lock_image(obj, "arts") +def lock_logo(obj): + _test_mixins_lock_image(obj, "logos") + + def lock_poster(obj): _test_mixins_lock_image(obj, "posters") @@ -294,6 +298,10 @@ def edit_art(obj): _test_mixins_edit_image(obj, "arts") +def edit_logo(obj): + _test_mixins_edit_image(obj, "logos") + + def edit_poster(obj): _test_mixins_edit_image(obj, "posters") @@ -353,9 +361,17 @@ def _test_mixins_edit_theme(obj): obj.lockTheme() obj.reload() assert "theme" in _fields() + + # Set the theme with pytest.raises(NotImplementedError): obj.setTheme(themes[0]) + # Delete the theme + obj.deleteTheme() + obj.reload() + selected_theme = next((t for t in obj.themes() if t.selected), None) + assert selected_theme is None + def edit_theme(obj): _test_mixins_edit_theme(obj) diff --git a/tests/test_photo.py b/tests/test_photo.py index 96fa7b389..487c3f91a 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -18,9 +18,11 @@ def test_photo_Photoalbum(photoalbum): @pytest.mark.xfail(reason="Changing images fails randomly") def test_photo_Photoalbum_mixins_images(photoalbum): test_mixins.edit_art(photoalbum) + test_mixins.edit_logo(photoalbum) test_mixins.edit_poster(photoalbum) test_mixins.edit_squareArt(photoalbum) test_mixins.lock_art(photoalbum) + test_mixins.lock_logo(photoalbum) test_mixins.lock_poster(photoalbum) test_mixins.lock_squareArt(photoalbum) test_mixins.attr_artUrl(photoalbum) diff --git a/tests/test_playlist.py b/tests/test_playlist.py index f1c2f5f13..6e608d022 100644 --- a/tests/test_playlist.py +++ b/tests/test_playlist.py @@ -327,9 +327,11 @@ def test_Playlist_PlexWebURL(plex, show): @pytest.mark.xfail(reason="Changing images fails randomly") def test_Playlist_mixins_images(playlist): test_mixins.lock_art(playlist) + test_mixins.lock_logo(playlist) test_mixins.lock_poster(playlist) test_mixins.lock_squareArt(playlist) test_mixins.edit_art(playlist) + test_mixins.edit_logo(playlist) test_mixins.edit_poster(playlist) test_mixins.edit_squareArt(playlist) test_mixins.attr_artUrl(playlist) diff --git a/tests/test_video.py b/tests/test_video.py index 0c8ff6e93..539d4d5f9 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -694,9 +694,11 @@ def test_video_Movie_mixins_edit_advanced_settings(movie): @pytest.mark.xfail(reason="Changing images fails randomly") def test_video_Movie_mixins_images(movie): test_mixins.lock_art(movie) + test_mixins.lock_logo(movie) test_mixins.lock_poster(movie) test_mixins.lock_squareArt(movie) test_mixins.edit_art(movie) + test_mixins.edit_logo(movie) test_mixins.edit_poster(movie) test_mixins.edit_squareArt(movie) test_mixins.attr_artUrl(movie) @@ -967,9 +969,11 @@ def test_video_Show_mixins_edit_advanced_settings(show): @pytest.mark.xfail(reason="Changing images fails randomly") def test_video_Show_mixins_images(show): test_mixins.lock_art(show) + test_mixins.lock_logo(show) test_mixins.lock_poster(show) test_mixins.lock_squareArt(show) test_mixins.edit_art(show) + test_mixins.edit_logo(show) test_mixins.edit_poster(show) test_mixins.edit_squareArt(show) test_mixins.attr_artUrl(show) @@ -1175,9 +1179,11 @@ def test_video_Season_episodes(show): def test_video_Season_mixins_images(show): season = show.season(season=1) test_mixins.lock_art(season) + test_mixins.lock_logo(season) test_mixins.lock_poster(season) test_mixins.lock_squareArt(season) test_mixins.edit_art(season) + test_mixins.edit_logo(season) test_mixins.edit_poster(season) test_mixins.edit_squareArt(season) test_mixins.attr_artUrl(season) @@ -1397,9 +1403,11 @@ def test_video_Episode_unwatched(tvshows): @pytest.mark.xfail(reason="Changing images fails randomly") def test_video_Episode_mixins_images(episode): test_mixins.lock_art(episode) + test_mixins.lock_logo(episode) test_mixins.lock_poster(episode) - test_mixins.lock_squareArt(episode) + test_mixins.lock_square_art(episode) test_mixins.edit_art(episode) + test_mixins.edit_logo(episode) test_mixins.edit_poster(episode) test_mixins.edit_squareArt(episode) test_mixins.attr_artUrl(episode)