Skip to content

Commit ef12e64

Browse files
authored
Add support for using MediaTag objects when editing tags (#994)
* Support using MediaTag objects when editing tags * Update tests for editing tags with MediaTag objects
1 parent d121172 commit ef12e64

File tree

3 files changed

+56
-34
lines changed

3 files changed

+56
-34
lines changed

plexapi/media.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,10 @@ class MediaTag(PlexObject):
676676
thumb (str): URL to thumbnail image for :class:`~plexapi.media.Role` only.
677677
"""
678678

679+
def __str__(self):
680+
""" Returns the tag name. """
681+
return self.tag
682+
679683
def _loadData(self, data):
680684
""" Load attribute values from Plex XML response. """
681685
self._data = data

plexapi/mixins.py

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -549,8 +549,8 @@ def editField(self, field, value, locked=True, **kwargs):
549549
550550
"""
551551
edits = {
552-
'%s.value' % field: value or '',
553-
'%s.locked' % field: 1 if locked else 0
552+
f'{field}.value': value or '',
553+
f'{field}.locked': 1 if locked else 0
554554
}
555555
edits.update(kwargs)
556556
return self._edit(**edits)
@@ -733,7 +733,7 @@ def editTags(self, tag, items, locked=True, remove=False, **kwargs):
733733
734734
Parameters:
735735
tag (str): Name of the tag to edit.
736-
items (List<str>): List of tags to add or remove.
736+
items (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags to add or remove.
737737
locked (bool): True (default) to lock the tags, False to unlock the tags.
738738
remove (bool): True to remove the tags in items.
739739
@@ -748,9 +748,11 @@ def editTags(self, tag, items, locked=True, remove=False, **kwargs):
748748
if not isinstance(items, list):
749749
items = [items]
750750

751-
value = getattr(self, self._tagPlural(tag))
752-
existing_tags = [t.tag for t in value if t and remove is False]
753-
edits = self._tagHelper(self._tagSingular(tag), existing_tags + items, locked, remove)
751+
if not remove:
752+
tags = getattr(self, self._tagPlural(tag))
753+
items = tags + items
754+
755+
edits = self._tagHelper(self._tagSingular(tag), items, locked, remove)
754756
edits.update(kwargs)
755757
return self._edit(**edits)
756758

@@ -783,15 +785,15 @@ def _tagHelper(tag, items, locked=True, remove=False):
783785
items = [items]
784786

785787
data = {
786-
'%s.locked' % tag: 1 if locked else 0
788+
f'{tag}.locked': 1 if locked else 0
787789
}
788790

789791
if remove:
790-
tagname = '%s[].tag.tag-' % tag
791-
data[tagname] = ','.join(items)
792+
tagname = f'{tag}[].tag.tag-'
793+
data[tagname] = ','.join([str(t) for t in items])
792794
else:
793795
for i, item in enumerate(items):
794-
tagname = '%s[%s].tag.tag' % (tag, i)
796+
tagname = f'{str(tag)}[{i}].tag.tag'
795797
data[tagname] = item
796798

797799
return data
@@ -804,7 +806,7 @@ def addCollection(self, collections, locked=True):
804806
""" Add a collection tag(s).
805807
806808
Parameters:
807-
collections (list): List of strings.
809+
collections (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
808810
locked (bool): True (default) to lock the field, False to unlock the field.
809811
"""
810812
return self.editTags('collection', collections, locked=locked)
@@ -813,7 +815,7 @@ def removeCollection(self, collections, locked=True):
813815
""" Remove a collection tag(s).
814816
815817
Parameters:
816-
collections (list): List of strings.
818+
collections (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
817819
locked (bool): True (default) to lock the field, False to unlock the field.
818820
"""
819821
return self.editTags('collection', collections, locked=locked, remove=True)
@@ -826,7 +828,7 @@ def addCountry(self, countries, locked=True):
826828
""" Add a country tag(s).
827829
828830
Parameters:
829-
countries (list): List of strings.
831+
countries (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
830832
locked (bool): True (default) to lock the field, False to unlock the field.
831833
"""
832834
return self.editTags('country', countries, locked=locked)
@@ -835,7 +837,7 @@ def removeCountry(self, countries, locked=True):
835837
""" Remove a country tag(s).
836838
837839
Parameters:
838-
countries (list): List of strings.
840+
countries (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
839841
locked (bool): True (default) to lock the field, False to unlock the field.
840842
"""
841843
return self.editTags('country', countries, locked=locked, remove=True)
@@ -848,7 +850,7 @@ def addDirector(self, directors, locked=True):
848850
""" Add a director tag(s).
849851
850852
Parameters:
851-
directors (list): List of strings.
853+
directors (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
852854
locked (bool): True (default) to lock the field, False to unlock the field.
853855
"""
854856
return self.editTags('director', directors, locked=locked)
@@ -857,7 +859,7 @@ def removeDirector(self, directors, locked=True):
857859
""" Remove a director tag(s).
858860
859861
Parameters:
860-
directors (list): List of strings.
862+
directors (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
861863
locked (bool): True (default) to lock the field, False to unlock the field.
862864
"""
863865
return self.editTags('director', directors, locked=locked, remove=True)
@@ -870,7 +872,7 @@ def addGenre(self, genres, locked=True):
870872
""" Add a genre tag(s).
871873
872874
Parameters:
873-
genres (list): List of strings.
875+
genres (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
874876
locked (bool): True (default) to lock the field, False to unlock the field.
875877
"""
876878
return self.editTags('genre', genres, locked=locked)
@@ -879,7 +881,7 @@ def removeGenre(self, genres, locked=True):
879881
""" Remove a genre tag(s).
880882
881883
Parameters:
882-
genres (list): List of strings.
884+
genres (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
883885
locked (bool): True (default) to lock the field, False to unlock the field.
884886
"""
885887
return self.editTags('genre', genres, locked=locked, remove=True)
@@ -892,7 +894,7 @@ def addLabel(self, labels, locked=True):
892894
""" Add a label tag(s).
893895
894896
Parameters:
895-
labels (list): List of strings.
897+
labels (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
896898
locked (bool): True (default) to lock the field, False to unlock the field.
897899
"""
898900
return self.editTags('label', labels, locked=locked)
@@ -901,7 +903,7 @@ def removeLabel(self, labels, locked=True):
901903
""" Remove a label tag(s).
902904
903905
Parameters:
904-
labels (list): List of strings.
906+
labels (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
905907
locked (bool): True (default) to lock the field, False to unlock the field.
906908
"""
907909
return self.editTags('label', labels, locked=locked, remove=True)
@@ -914,7 +916,7 @@ def addMood(self, moods, locked=True):
914916
""" Add a mood tag(s).
915917
916918
Parameters:
917-
moods (list): List of strings.
919+
moods (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
918920
locked (bool): True (default) to lock the field, False to unlock the field.
919921
"""
920922
return self.editTags('mood', moods, locked=locked)
@@ -923,7 +925,7 @@ def removeMood(self, moods, locked=True):
923925
""" Remove a mood tag(s).
924926
925927
Parameters:
926-
moods (list): List of strings.
928+
moods (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
927929
locked (bool): True (default) to lock the field, False to unlock the field.
928930
"""
929931
return self.editTags('mood', moods, locked=locked, remove=True)
@@ -936,7 +938,7 @@ def addProducer(self, producers, locked=True):
936938
""" Add a producer tag(s).
937939
938940
Parameters:
939-
producers (list): List of strings.
941+
producers (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
940942
locked (bool): True (default) to lock the field, False to unlock the field.
941943
"""
942944
return self.editTags('producer', producers, locked=locked)
@@ -945,7 +947,7 @@ def removeProducer(self, producers, locked=True):
945947
""" Remove a producer tag(s).
946948
947949
Parameters:
948-
producers (list): List of strings.
950+
producers (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
949951
locked (bool): True (default) to lock the field, False to unlock the field.
950952
"""
951953
return self.editTags('producer', producers, locked=locked, remove=True)
@@ -958,7 +960,7 @@ def addSimilarArtist(self, artists, locked=True):
958960
""" Add a similar artist tag(s).
959961
960962
Parameters:
961-
artists (list): List of strings.
963+
artists (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
962964
locked (bool): True (default) to lock the field, False to unlock the field.
963965
"""
964966
return self.editTags('similar', artists, locked=locked)
@@ -967,7 +969,7 @@ def removeSimilarArtist(self, artists, locked=True):
967969
""" Remove a similar artist tag(s).
968970
969971
Parameters:
970-
artists (list): List of strings.
972+
artists (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
971973
locked (bool): True (default) to lock the field, False to unlock the field.
972974
"""
973975
return self.editTags('similar', artists, locked=locked, remove=True)
@@ -980,7 +982,7 @@ def addStyle(self, styles, locked=True):
980982
""" Add a style tag(s).
981983
982984
Parameters:
983-
styles (list): List of strings.
985+
styles (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
984986
locked (bool): True (default) to lock the field, False to unlock the field.
985987
"""
986988
return self.editTags('style', styles, locked=locked)
@@ -989,7 +991,7 @@ def removeStyle(self, styles, locked=True):
989991
""" Remove a style tag(s).
990992
991993
Parameters:
992-
styles (list): List of strings.
994+
styles (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
993995
locked (bool): True (default) to lock the field, False to unlock the field.
994996
"""
995997
return self.editTags('style', styles, locked=locked, remove=True)
@@ -1002,7 +1004,7 @@ def addTag(self, tags, locked=True):
10021004
""" Add a tag(s).
10031005
10041006
Parameters:
1005-
tags (list): List of strings.
1007+
tags (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
10061008
locked (bool): True (default) to lock the field, False to unlock the field.
10071009
"""
10081010
return self.editTags('tag', tags, locked=locked)
@@ -1011,7 +1013,7 @@ def removeTag(self, tags, locked=True):
10111013
""" Remove a tag(s).
10121014
10131015
Parameters:
1014-
tags (list): List of strings.
1016+
tags (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
10151017
locked (bool): True (default) to lock the field, False to unlock the field.
10161018
"""
10171019
return self.editTags('tag', tags, locked=locked, remove=True)
@@ -1024,7 +1026,7 @@ def addWriter(self, writers, locked=True):
10241026
""" Add a writer tag(s).
10251027
10261028
Parameters:
1027-
writers (list): List of strings.
1029+
writers (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
10281030
locked (bool): True (default) to lock the field, False to unlock the field.
10291031
"""
10301032
return self.editTags('writer', writers, locked=locked)
@@ -1033,7 +1035,7 @@ def removeWriter(self, writers, locked=True):
10331035
""" Remove a writer tag(s).
10341036
10351037
Parameters:
1036-
writers (list): List of strings.
1038+
writers (List<str> or List<:class:`~plexapi.media.MediaTag`>): List of tags.
10371039
locked (bool): True (default) to lock the field, False to unlock the field.
10381040
"""
10391041
return self.editTags('writer', writers, locked=locked, remove=True)

tests/test_mixins.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,33 @@ def _test_mixins_tag(obj, attr, tag_method):
9696
field_name = obj._tagSingular(attr)
9797
_tags = lambda: [t.tag for t in getattr(obj, attr)]
9898
_fields = lambda: [f for f in obj.fields if f.name == field_name]
99+
99100
# Check tag is not present to begin with
100101
tags = _tags()
101102
assert TEST_MIXIN_TAG not in tags
102-
# Add tag and lock the field
103+
104+
# Add tag string and lock the field
103105
add_tag_method(TEST_MIXIN_TAG)
104106
obj.reload()
105107
tags = _tags()
106108
fields = _fields()
107109
assert TEST_MIXIN_TAG in tags
108110
assert fields and fields[0].locked
109-
# Remove tag and unlock to field to restore the clean state
111+
112+
# Remove MediaTag object
113+
mediaTag = next(t for t in getattr(obj, attr) if t.tag == TEST_MIXIN_TAG)
114+
remove_tag_method(mediaTag)
115+
obj.reload()
116+
tags = _tags()
117+
assert TEST_MIXIN_TAG not in tags
118+
119+
# Add MediaTag object
120+
add_tag_method(mediaTag)
121+
obj.reload()
122+
tags = _tags()
123+
assert TEST_MIXIN_TAG in tags
124+
125+
# Remove tag string and unlock to field to restore the clean state
110126
remove_tag_method(TEST_MIXIN_TAG, locked=False)
111127
obj.reload()
112128
tags = _tags()

0 commit comments

Comments
 (0)