mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-10 06:04:15 +00:00
Add LabelMixin to Season, Episode, Artist, and Track objects (#872)
* Add LabelMixin to Episode class * Add test_mixins.edit_label(episode) test * Add Label Mixin to Season, Artist,and Track * fix tests * Load manual FilteringFields for labels * Load manual FilteringFilters for labels Co-authored-by: Elan Ruusamäe <glen@pld-linux.org> Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>
This commit is contained in:
parent
158dd37e41
commit
2f101e3899
5 changed files with 78 additions and 14 deletions
|
@ -126,7 +126,7 @@ class Audio(PlexPartialObject):
|
|||
|
||||
@utils.registerPlexObject
|
||||
class Artist(Audio, AdvancedSettingsMixin, ArtMixin, PosterMixin, RatingMixin, SplitMergeMixin, UnmatchMatchMixin,
|
||||
CollectionMixin, CountryMixin, GenreMixin, MoodMixin, SimilarArtistMixin, StyleMixin):
|
||||
CollectionMixin, CountryMixin, GenreMixin, LabelMixin, MoodMixin, SimilarArtistMixin, StyleMixin):
|
||||
""" Represents a single Artist.
|
||||
|
||||
Attributes:
|
||||
|
@ -138,6 +138,7 @@ class Artist(Audio, AdvancedSettingsMixin, ArtMixin, PosterMixin, RatingMixin, S
|
|||
countries (List<:class:`~plexapi.media.Country`>): List country objects.
|
||||
genres (List<:class:`~plexapi.media.Genre`>): List of genre objects.
|
||||
key (str): API URL (/library/metadata/<ratingkey>).
|
||||
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
|
||||
locations (List<str>): List of folder paths where the artist is found on disk.
|
||||
similar (List<:class:`~plexapi.media.Similar`>): List of similar objects.
|
||||
styles (List<:class:`~plexapi.media.Style`>): List of style objects.
|
||||
|
@ -153,6 +154,7 @@ class Artist(Audio, AdvancedSettingsMixin, ArtMixin, PosterMixin, RatingMixin, S
|
|||
self.countries = self.findItems(data, media.Country)
|
||||
self.genres = self.findItems(data, media.Genre)
|
||||
self.key = self.key.replace('/children', '') # FIX_BUG_50
|
||||
self.labels = self.findItems(data, media.Label)
|
||||
self.locations = self.listAttrs(data, 'path', etag='Location')
|
||||
self.similar = self.findItems(data, media.Similar)
|
||||
self.styles = self.findItems(data, media.Style)
|
||||
|
@ -338,7 +340,7 @@ class Album(Audio, ArtMixin, PosterMixin, RatingMixin, UnmatchMatchMixin,
|
|||
|
||||
@utils.registerPlexObject
|
||||
class Track(Audio, Playable, ArtUrlMixin, PosterUrlMixin, RatingMixin,
|
||||
CollectionMixin, MoodMixin):
|
||||
CollectionMixin, LabelMixin, MoodMixin):
|
||||
""" Represents a single Track.
|
||||
|
||||
Attributes:
|
||||
|
@ -354,6 +356,7 @@ class Track(Audio, Playable, ArtUrlMixin, PosterUrlMixin, RatingMixin,
|
|||
grandparentThumb (str): URL to album artist thumbnail image
|
||||
(/library/metadata/<grandparentRatingKey>/thumb/<thumbid>).
|
||||
grandparentTitle (str): Name of the album artist for the track.
|
||||
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
|
||||
media (List<:class:`~plexapi.media.Media`>): List of media objects.
|
||||
originalTitle (str): The artist for the track.
|
||||
parentGuid (str): Plex GUID for the album (plex://album/5d07cd8e403c640290f180f9).
|
||||
|
@ -383,6 +386,7 @@ class Track(Audio, Playable, ArtUrlMixin, PosterUrlMixin, RatingMixin,
|
|||
self.grandparentRatingKey = utils.cast(int, data.attrib.get('grandparentRatingKey'))
|
||||
self.grandparentThumb = data.attrib.get('grandparentThumb')
|
||||
self.grandparentTitle = data.attrib.get('grandparentTitle')
|
||||
self.labels = self.findItems(data, media.Label)
|
||||
self.media = self.findItems(data, media.Media)
|
||||
self.originalTitle = data.attrib.get('originalTitle')
|
||||
self.parentGuid = data.attrib.get('parentGuid')
|
||||
|
|
|
@ -2236,16 +2236,57 @@ class FilteringType(PlexObject):
|
|||
self.title = data.attrib.get('title')
|
||||
self.type = data.attrib.get('type')
|
||||
|
||||
# Add additional manual sorts and fields which are available
|
||||
self._librarySectionID = self._parent().key
|
||||
|
||||
# Add additional manual filters, sorts, and fields which are available
|
||||
# but not exposed on the Plex server
|
||||
self.filters += self._manualFilters()
|
||||
self.sorts += self._manualSorts()
|
||||
self.fields += self._manualFields()
|
||||
|
||||
def _manualFilters(self):
|
||||
""" Manually add additional filters which are available
|
||||
but not exposed on the Plex server.
|
||||
"""
|
||||
# Filters: (filter, type, title)
|
||||
additionalFilters = [
|
||||
]
|
||||
|
||||
if self.type == 'season':
|
||||
additionalFilters.extend([
|
||||
('label', 'string', 'Labels')
|
||||
])
|
||||
elif self.type == 'episode':
|
||||
additionalFilters.extend([
|
||||
('label', 'string', 'Labels')
|
||||
])
|
||||
elif self.type == 'artist':
|
||||
additionalFilters.extend([
|
||||
('label', 'string', 'Labels')
|
||||
])
|
||||
elif self.type == 'track':
|
||||
additionalFilters.extend([
|
||||
('label', 'string', 'Labels')
|
||||
])
|
||||
|
||||
manualFilters = []
|
||||
for filterTag, filterType, filterTitle in additionalFilters:
|
||||
filterKey = '/library/sections/%s/%s?type=%s' % (
|
||||
self._librarySectionID, filterTag, utils.searchType(self.type)
|
||||
)
|
||||
filterXML = (
|
||||
'<Filter filter="%s" filterType="%s" key="%s" title="%s" type="filter" />'
|
||||
% (filterTag, filterType, filterKey, filterTitle)
|
||||
)
|
||||
manualFilters.append(self._manuallyLoadXML(filterXML, FilteringFilter))
|
||||
|
||||
return manualFilters
|
||||
|
||||
def _manualSorts(self):
|
||||
""" Manually add additional sorts which are available
|
||||
but not exposed on the Plex server.
|
||||
"""
|
||||
# Sorts: key, dir, title
|
||||
# Sorts: (key, dir, title)
|
||||
additionalSorts = [
|
||||
('guid', 'asc', 'Guid'),
|
||||
('id', 'asc', 'Rating Key'),
|
||||
|
@ -2275,8 +2316,10 @@ class FilteringType(PlexObject):
|
|||
|
||||
manualSorts = []
|
||||
for sortField, sortDir, sortTitle in additionalSorts:
|
||||
sortXML = ('<Sort defaultDirection="%s" descKey="%s:desc" key="%s" title="%s" />'
|
||||
% (sortDir, sortField, sortField, sortTitle))
|
||||
sortXML = (
|
||||
'<Sort defaultDirection="%s" descKey="%s:desc" key="%s" title="%s" />'
|
||||
% (sortDir, sortField, sortField, sortTitle)
|
||||
)
|
||||
manualSorts.append(self._manuallyLoadXML(sortXML, FilteringSort))
|
||||
|
||||
return manualSorts
|
||||
|
@ -2285,7 +2328,7 @@ class FilteringType(PlexObject):
|
|||
""" Manually add additional fields which are available
|
||||
but not exposed on the Plex server.
|
||||
"""
|
||||
# Fields: key, type, title
|
||||
# Fields: (key, type, title)
|
||||
additionalFields = [
|
||||
('guid', 'string', 'Guid'),
|
||||
('id', 'integer', 'Rating Key'),
|
||||
|
@ -2311,19 +2354,26 @@ class FilteringType(PlexObject):
|
|||
additionalFields.extend([
|
||||
('addedAt', 'date', 'Date Season Added'),
|
||||
('unviewedLeafCount', 'integer', 'Episode Unplayed Count'),
|
||||
('year', 'integer', 'Season Year')
|
||||
('year', 'integer', 'Season Year'),
|
||||
('label', 'tag', 'Label')
|
||||
])
|
||||
elif self.type == 'episode':
|
||||
additionalFields.extend([
|
||||
('audienceRating', 'integer', 'Audience Rating'),
|
||||
('duration', 'integer', 'Duration'),
|
||||
('rating', 'integer', 'Critic Rating'),
|
||||
('viewOffset', 'integer', 'View Offset')
|
||||
('viewOffset', 'integer', 'View Offset'),
|
||||
('label', 'tag', 'Label')
|
||||
])
|
||||
elif self.type == 'artist':
|
||||
additionalFields.extend([
|
||||
('label', 'tag', 'Label')
|
||||
])
|
||||
elif self.type == 'track':
|
||||
additionalFields.extend([
|
||||
('duration', 'integer', 'Duration'),
|
||||
('viewOffset', 'integer', 'View Offset')
|
||||
('viewOffset', 'integer', 'View Offset'),
|
||||
('label', 'tag', 'Label')
|
||||
])
|
||||
elif self.type == 'collection':
|
||||
additionalFields.extend([
|
||||
|
@ -2334,8 +2384,10 @@ class FilteringType(PlexObject):
|
|||
|
||||
manualFields = []
|
||||
for field, fieldType, fieldTitle in additionalFields:
|
||||
fieldXML = ('<Field key="%s%s" title="%s" type="%s"/>'
|
||||
% (prefix, field, fieldTitle, fieldType))
|
||||
fieldXML = (
|
||||
'<Field key="%s%s" title="%s" type="%s"/>'
|
||||
% (prefix, field, fieldTitle, fieldType)
|
||||
)
|
||||
manualFields.append(self._manuallyLoadXML(fieldXML, FilteringField))
|
||||
|
||||
return manualFields
|
||||
|
|
|
@ -574,7 +574,7 @@ class Show(Video, AdvancedSettingsMixin, ArtMixin, BannerMixin, PosterMixin, Rat
|
|||
|
||||
|
||||
@utils.registerPlexObject
|
||||
class Season(Video, ArtMixin, PosterMixin, RatingMixin, CollectionMixin):
|
||||
class Season(Video, ArtMixin, PosterMixin, RatingMixin, CollectionMixin, LabelMixin):
|
||||
""" Represents a single Show Season (including all episodes).
|
||||
|
||||
Attributes:
|
||||
|
@ -584,6 +584,7 @@ class Season(Video, ArtMixin, PosterMixin, RatingMixin, CollectionMixin):
|
|||
guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
|
||||
index (int): Season number.
|
||||
key (str): API URL (/library/metadata/<ratingkey>).
|
||||
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
|
||||
leafCount (int): Number of items in the season view.
|
||||
parentGuid (str): Plex GUID for the show (plex://show/5d9c086fe9d5a1001f4d9fe6).
|
||||
parentIndex (int): Plex index number for the show.
|
||||
|
@ -607,6 +608,7 @@ class Season(Video, ArtMixin, PosterMixin, RatingMixin, CollectionMixin):
|
|||
self.guids = self.findItems(data, media.Guid)
|
||||
self.index = utils.cast(int, data.attrib.get('index'))
|
||||
self.key = self.key.replace('/children', '') # FIX_BUG_50
|
||||
self.labels = self.findItems(data, media.Label)
|
||||
self.leafCount = utils.cast(int, data.attrib.get('leafCount'))
|
||||
self.parentGuid = data.attrib.get('parentGuid')
|
||||
self.parentIndex = utils.cast(int, data.attrib.get('parentIndex'))
|
||||
|
@ -710,7 +712,7 @@ class Season(Video, ArtMixin, PosterMixin, RatingMixin, CollectionMixin):
|
|||
|
||||
@utils.registerPlexObject
|
||||
class Episode(Video, Playable, ArtMixin, PosterMixin, RatingMixin,
|
||||
CollectionMixin, DirectorMixin, WriterMixin):
|
||||
CollectionMixin, DirectorMixin, LabelMixin, WriterMixin):
|
||||
""" Represents a single Shows Episode.
|
||||
|
||||
Attributes:
|
||||
|
@ -733,6 +735,7 @@ class Episode(Video, Playable, ArtMixin, PosterMixin, RatingMixin,
|
|||
grandparentTitle (str): Name of the show for the episode.
|
||||
guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
|
||||
index (int): Episode number.
|
||||
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
|
||||
markers (List<:class:`~plexapi.media.Marker`>): List of marker objects.
|
||||
media (List<:class:`~plexapi.media.Media`>): List of media objects.
|
||||
originallyAvailableAt (datetime): Datetime the episode was released.
|
||||
|
@ -777,6 +780,7 @@ class Episode(Video, Playable, ArtMixin, PosterMixin, RatingMixin,
|
|||
self.grandparentTitle = data.attrib.get('grandparentTitle')
|
||||
self.guids = self.findItems(data, media.Guid)
|
||||
self.index = utils.cast(int, data.attrib.get('index'))
|
||||
self.labels = self.findItems(data, media.Label)
|
||||
self.markers = self.findItems(data, media.Marker)
|
||||
self.media = self.findItems(data, media.Media)
|
||||
self.originallyAvailableAt = utils.toDatetime(data.attrib.get('originallyAvailableAt'), '%Y-%m-%d')
|
||||
|
|
|
@ -103,6 +103,7 @@ def test_audio_Artist_mixins_tags(artist):
|
|||
test_mixins.edit_collection(artist)
|
||||
test_mixins.edit_country(artist)
|
||||
test_mixins.edit_genre(artist)
|
||||
test_mixins.edit_label(artist)
|
||||
test_mixins.edit_mood(artist)
|
||||
test_mixins.edit_similar_artist(artist)
|
||||
test_mixins.edit_style(artist)
|
||||
|
@ -368,6 +369,7 @@ def test_audio_Track_mixins_rating(track):
|
|||
|
||||
def test_audio_Track_mixins_tags(track):
|
||||
test_mixins.edit_collection(track)
|
||||
test_mixins.edit_label(track)
|
||||
test_mixins.edit_mood(track)
|
||||
|
||||
|
||||
|
|
|
@ -938,6 +938,7 @@ def test_video_Season_mixins_rating(show):
|
|||
def test_video_Season_mixins_tags(show):
|
||||
season = show.season(season=1)
|
||||
test_mixins.edit_collection(season)
|
||||
test_mixins.edit_label(season)
|
||||
|
||||
|
||||
def test_video_Season_PlexWebURL(plex, season):
|
||||
|
@ -1149,6 +1150,7 @@ def test_video_Episode_mixins_tags(episode):
|
|||
test_mixins.edit_collection(episode)
|
||||
test_mixins.edit_director(episode)
|
||||
test_mixins.edit_writer(episode)
|
||||
test_mixins.edit_label(episode)
|
||||
|
||||
|
||||
def test_video_Episode_media_tags(episode):
|
||||
|
|
Loading…
Reference in a new issue