diff --git a/plexapi/audio.py b/plexapi/audio.py index 2cbd82d6..0bb04941 100644 --- a/plexapi/audio.py +++ b/plexapi/audio.py @@ -69,13 +69,17 @@ class Audio(PlexPartialObject): @property def thumbUrl(self): - """ Return url to for the thumbnail image. """ + """ Return the first first thumbnail url starting on + the most specific thumbnail for that item. + """ key = self.firstAttr('thumb', 'parentThumb', 'granparentThumb') return self._server.url(key, includeToken=True) if key else None @property def artUrl(self): - """ Return the first art url starting on the most specific for that item.""" + """ Return the first first art url starting on + the most specific art for that item. + """ art = self.firstAttr('art', 'grandparentArt') return self._server.url(art, includeToken=True) if art else None diff --git a/plexapi/video.py b/plexapi/video.py index 3ca41126..9d3b6a44 100644 --- a/plexapi/video.py +++ b/plexapi/video.py @@ -76,7 +76,9 @@ class Video(PlexPartialObject): @property def artUrl(self): - """ Return the first first art url starting on the most specific for that item.""" + """ Return the first first art url starting on + the most specific art for that item. + """ art = self.firstAttr('art', 'grandparentArt') return self._server.url(art, includeToken=True) if art else None @@ -458,6 +460,11 @@ class Show(Video, ArtMixin, BannerMixin, PosterMixin, SplitMergeMixin, UnmatchMa """ Returns True if the show is fully watched. """ return bool(self.viewedLeafCount == self.leafCount) + @property + def bannerUrl(self): + """ Return the banner url for the show.""" + return self._server.url(self.banner, includeToken=True) if self.banner else None + def preferences(self): """ Returns a list of :class:`~plexapi.settings.Preferences` objects. """ items = [] diff --git a/tests/conftest.py b/tests/conftest.py index 84e88eea..c0d8bf44 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -381,6 +381,10 @@ def is_art(key): return is_metadata(key, contains="/art/") +def is_banner(key): + return is_metadata(key, contains="/banner/") + + def is_thumb(key): return is_metadata(key, contains="/thumb/") @@ -389,6 +393,10 @@ def is_artUrl(url): return url.startswith(SERVER_BASEURL) and "/library/metadata/" in url and "/art/" in url +def is_bannerUrl(url): + return url.startswith(SERVER_BASEURL) and "/library/metadata/" in url and "/banner/" in url + + def is_thumbUrl(url): return url.startswith(SERVER_BASEURL) and "/library/metadata/" in url and "/thumb/" in url diff --git a/tests/test_audio.py b/tests/test_audio.py index 95b6844e..f854165f 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -179,8 +179,12 @@ def test_audio_Album_track(album, track=None): else: assert track.artUrl is None assert utils.is_int(track.duration) + if track.grandparentArt: + assert utils.is_art(track.grandparentArt) assert utils.is_metadata(track.grandparentKey) assert utils.is_int(track.grandparentRatingKey) + if track.grandparentThumb: + assert utils.is_thumb(track.grandparentThumb) assert track.grandparentTitle == "Broke For Free" assert int(track.index) == 1 assert utils.is_metadata(track._initpath) @@ -273,7 +277,8 @@ def test_audio_Track_attrs(album): assert track.artUrl is None assert track.chapterSource is None assert utils.is_int(track.duration) - assert track.grandparentArt is None + if track.grandparentArt: + assert utils.is_art(track.grandparengrandparentArt) assert utils.is_metadata(track.grandparentKey) assert utils.is_int(track.grandparentRatingKey) if track.grandparentThumb: diff --git a/tests/test_video.py b/tests/test_video.py index e9903952..8b25f87a 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -559,7 +559,11 @@ def test_video_Show_attrs(show): assert utils.is_artUrl(show.artUrl) else: assert show.artUrl is None - assert utils.is_metadata(show.banner, contains="/banner/") + if show.banner: + assert utils.is_banner(show.banner) + assert utils.is_bannerUrl(show.bannerUrl) + else: + assert show.bannerUrl is None assert utils.is_int(show.childCount) assert show.contentRating in utils.CONTENTRATINGS assert utils.is_int(show.duration, gte=1600000) @@ -800,6 +804,10 @@ def test_video_Episode_attrs(episode): if len(episode.directors): assert [i.tag for i in episode.directors] == ["Tim Van Patten"] assert utils.is_int(episode.duration, gte=120000) + if episode.grandparentArt: + assert utils.is_art(episode.grandparentArt) + if episode.grandparentThumb: + assert utils.is_thumb(episode.grandparentThumb) assert episode.grandparentTitle == "Game of Thrones" assert episode.index == 1 assert utils.is_metadata(episode._initpath) @@ -809,7 +817,8 @@ def test_video_Episode_attrs(episode): assert utils.is_int(episode.parentIndex) assert utils.is_metadata(episode.parentKey) assert utils.is_int(episode.parentRatingKey) - assert utils.is_metadata(episode.parentThumb, contains="/thumb/") + if episode.parentThumb: + assert utils.is_thumb(episode.parentThumb) assert episode.rating >= 7.7 assert utils.is_int(episode.ratingKey) assert episode._server._baseurl == utils.SERVER_BASEURL @@ -907,6 +916,8 @@ def test_video_Season_attrs(show): assert season.listType == "video" assert utils.is_metadata(season.parentKey) assert utils.is_int(season.parentRatingKey) + if season.parentThumb: + assert utils.is_thumb(season.parentThumb) assert season.parentTitle == "Game of Thrones" assert utils.is_int(season.ratingKey) assert season._server._baseurl == utils.SERVER_BASEURL