Skip to content

Commit acff7b9

Browse files
authored
Add ability to select/lock/unlock logos and delete resources (#1558)
* Add ability to select, lock, and unlock logos * Add ability to delete resources * Add tests for logos and deleting * Add tests for music, photos, collections, and playlists
1 parent bc74728 commit acff7b9

File tree

7 files changed

+65
-9
lines changed

7 files changed

+65
-9
lines changed

plexapi/mixins.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,12 @@ def setArt(self, art):
402402
art.select()
403403
return self
404404

405+
def deleteArt(self):
406+
""" Delete the art from a Plex object. """
407+
key = f'/library/metadata/{self.ratingKey}/art'
408+
self._server.query(key, method=self._server._session.delete)
409+
return self
410+
405411

406412
class LogoUrlMixin:
407413
""" Mixin for Plex objects that can have a logo url. """
@@ -422,11 +428,11 @@ class LogoLockMixin:
422428

423429
def lockLogo(self):
424430
""" Lock the logo for a Plex object. """
425-
raise NotImplementedError('Logo cannot be locked through the API.')
431+
return self._edit(**{'clearLogo.locked': 1})
426432

427433
def unlockLogo(self):
428434
""" Unlock the logo for a Plex object. """
429-
raise NotImplementedError('Logo cannot be unlocked through the API.')
435+
return self._edit(**{'clearLogo.locked': 0})
430436

431437

432438
class LogoMixin(LogoUrlMixin, LogoLockMixin):
@@ -455,13 +461,17 @@ def uploadLogo(self, url=None, filepath=None):
455461
def setLogo(self, logo):
456462
""" Set the logo for a Plex object.
457463
458-
Raises:
459-
:exc:`~plexapi.exceptions.NotImplementedError`: Logo cannot be set through the API.
464+
Parameters:
465+
logo (:class:`~plexapi.media.Logo`): The logo object to select.
460466
"""
461-
raise NotImplementedError(
462-
'Logo cannot be set through the API. '
463-
'Re-upload the logo using "uploadLogo" to set it.'
464-
)
467+
logo.select()
468+
return self
469+
470+
def deleteLogo(self):
471+
""" Delete the logo from a Plex object. """
472+
key = f'/library/metadata/{self.ratingKey}/clearLogo'
473+
self._server.query(key, method=self._server._session.delete)
474+
return self
465475

466476

467477
class PosterUrlMixin:
@@ -523,6 +533,12 @@ def setPoster(self, poster):
523533
poster.select()
524534
return self
525535

536+
def deletePoster(self):
537+
""" Delete the poster from a Plex object. """
538+
key = f'/library/metadata/{self.ratingKey}/thumb'
539+
self._server.query(key, method=self._server._session.delete)
540+
return self
541+
526542

527543
class SquareArtUrlMixin:
528544
""" Mixin for Plex objects that can have a square art url. """
@@ -649,6 +665,12 @@ def setTheme(self, theme):
649665
'Re-upload the theme using "uploadTheme" to set it.'
650666
)
651667

668+
def deleteTheme(self):
669+
""" Delete the theme from a Plex object. """
670+
key = f'/library/metadata/{self.ratingKey}/theme'
671+
self._server.query(key, method=self._server._session.delete)
672+
return self
673+
652674

653675
class EditFieldMixin:
654676
""" Mixin for editing Plex object fields. """

tests/test_audio.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,11 @@ def test_audio_Artist_mixins_edit_advanced_settings(artist):
103103
@pytest.mark.xfail(reason="Changing images fails randomly")
104104
def test_audio_Artist_mixins_images(artist):
105105
test_mixins.lock_art(artist)
106+
test_mixins.lock_logo(artist)
106107
test_mixins.lock_poster(artist)
107108
test_mixins.lock_squareArt(artist)
108109
test_mixins.edit_art(artist)
110+
test_mixins.edit_logo(artist)
109111
test_mixins.edit_poster(artist)
110112
test_mixins.edit_squareArt(artist)
111113
test_mixins.attr_artUrl(artist)
@@ -237,9 +239,11 @@ def test_audio_Album_artist(album):
237239
@pytest.mark.xfail(reason="Changing images fails randomly")
238240
def test_audio_Album_mixins_images(album):
239241
test_mixins.lock_art(album)
242+
test_mixins.lock_logo(album)
240243
test_mixins.lock_poster(album)
241244
test_mixins.lock_squareArt(album)
242245
test_mixins.edit_art(album)
246+
test_mixins.edit_logo(album)
243247
test_mixins.edit_poster(album)
244248
test_mixins.edit_squareArt(album)
245249
test_mixins.attr_artUrl(album)

tests/test_collection.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,11 @@ def test_Collection_art(collection):
352352
@pytest.mark.xfail(reason="Changing images fails randomly")
353353
def test_Collection_mixins_images(collection):
354354
test_mixins.lock_art(collection)
355+
test_mixins.lock_logo(collection)
355356
test_mixins.lock_poster(collection)
356357
test_mixins.lock_squareArt(collection)
357358
test_mixins.edit_art(collection)
359+
test_mixins.edit_logo(collection)
358360
test_mixins.edit_poster(collection)
359361
test_mixins.edit_squareArt(collection)
360362
test_mixins.attr_artUrl(collection)

tests/test_mixins.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ def lock_art(obj):
219219
_test_mixins_lock_image(obj, "arts")
220220

221221

222+
def lock_logo(obj):
223+
_test_mixins_lock_image(obj, "logos")
224+
225+
222226
def lock_poster(obj):
223227
_test_mixins_lock_image(obj, "posters")
224228

@@ -294,6 +298,10 @@ def edit_art(obj):
294298
_test_mixins_edit_image(obj, "arts")
295299

296300

301+
def edit_logo(obj):
302+
_test_mixins_edit_image(obj, "logos")
303+
304+
297305
def edit_poster(obj):
298306
_test_mixins_edit_image(obj, "posters")
299307

@@ -353,9 +361,17 @@ def _test_mixins_edit_theme(obj):
353361
obj.lockTheme()
354362
obj.reload()
355363
assert "theme" in _fields()
364+
365+
# Set the theme
356366
with pytest.raises(NotImplementedError):
357367
obj.setTheme(themes[0])
358368

369+
# Delete the theme
370+
obj.deleteTheme()
371+
obj.reload()
372+
selected_theme = next((t for t in obj.themes() if t.selected), None)
373+
assert selected_theme is None
374+
359375

360376
def edit_theme(obj):
361377
_test_mixins_edit_theme(obj)

tests/test_photo.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ def test_photo_Photoalbum(photoalbum):
1818
@pytest.mark.xfail(reason="Changing images fails randomly")
1919
def test_photo_Photoalbum_mixins_images(photoalbum):
2020
test_mixins.edit_art(photoalbum)
21+
test_mixins.edit_logo(photoalbum)
2122
test_mixins.edit_poster(photoalbum)
2223
test_mixins.edit_squareArt(photoalbum)
2324
test_mixins.lock_art(photoalbum)
25+
test_mixins.lock_logo(photoalbum)
2426
test_mixins.lock_poster(photoalbum)
2527
test_mixins.lock_squareArt(photoalbum)
2628
test_mixins.attr_artUrl(photoalbum)

tests/test_playlist.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,11 @@ def test_Playlist_PlexWebURL(plex, show):
327327
@pytest.mark.xfail(reason="Changing images fails randomly")
328328
def test_Playlist_mixins_images(playlist):
329329
test_mixins.lock_art(playlist)
330+
test_mixins.lock_logo(playlist)
330331
test_mixins.lock_poster(playlist)
331332
test_mixins.lock_squareArt(playlist)
332333
test_mixins.edit_art(playlist)
334+
test_mixins.edit_logo(playlist)
333335
test_mixins.edit_poster(playlist)
334336
test_mixins.edit_squareArt(playlist)
335337
test_mixins.attr_artUrl(playlist)

tests/test_video.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,9 +694,11 @@ def test_video_Movie_mixins_edit_advanced_settings(movie):
694694
@pytest.mark.xfail(reason="Changing images fails randomly")
695695
def test_video_Movie_mixins_images(movie):
696696
test_mixins.lock_art(movie)
697+
test_mixins.lock_logo(movie)
697698
test_mixins.lock_poster(movie)
698699
test_mixins.lock_squareArt(movie)
699700
test_mixins.edit_art(movie)
701+
test_mixins.edit_logo(movie)
700702
test_mixins.edit_poster(movie)
701703
test_mixins.edit_squareArt(movie)
702704
test_mixins.attr_artUrl(movie)
@@ -967,9 +969,11 @@ def test_video_Show_mixins_edit_advanced_settings(show):
967969
@pytest.mark.xfail(reason="Changing images fails randomly")
968970
def test_video_Show_mixins_images(show):
969971
test_mixins.lock_art(show)
972+
test_mixins.lock_logo(show)
970973
test_mixins.lock_poster(show)
971974
test_mixins.lock_squareArt(show)
972975
test_mixins.edit_art(show)
976+
test_mixins.edit_logo(show)
973977
test_mixins.edit_poster(show)
974978
test_mixins.edit_squareArt(show)
975979
test_mixins.attr_artUrl(show)
@@ -1175,9 +1179,11 @@ def test_video_Season_episodes(show):
11751179
def test_video_Season_mixins_images(show):
11761180
season = show.season(season=1)
11771181
test_mixins.lock_art(season)
1182+
test_mixins.lock_logo(season)
11781183
test_mixins.lock_poster(season)
11791184
test_mixins.lock_squareArt(season)
11801185
test_mixins.edit_art(season)
1186+
test_mixins.edit_logo(season)
11811187
test_mixins.edit_poster(season)
11821188
test_mixins.edit_squareArt(season)
11831189
test_mixins.attr_artUrl(season)
@@ -1397,9 +1403,11 @@ def test_video_Episode_unwatched(tvshows):
13971403
@pytest.mark.xfail(reason="Changing images fails randomly")
13981404
def test_video_Episode_mixins_images(episode):
13991405
test_mixins.lock_art(episode)
1406+
test_mixins.lock_logo(episode)
14001407
test_mixins.lock_poster(episode)
1401-
test_mixins.lock_squareArt(episode)
1408+
test_mixins.lock_square_art(episode)
14021409
test_mixins.edit_art(episode)
1410+
test_mixins.edit_logo(episode)
14031411
test_mixins.edit_poster(episode)
14041412
test_mixins.edit_squareArt(episode)
14051413
test_mixins.attr_artUrl(episode)

0 commit comments

Comments
 (0)