Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions plexapi/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,13 @@ def add(self, name='', type='', agent='', scanner='', location='', language='en'

**Show Preferences**

* **agent** (str): com.plexapp.agents.none, com.plexapp.agents.thetvdb, com.plexapp.agents.themoviedb
* **agent** (str): com.plexapp.agents.none, com.plexapp.agents.thetvdb, com.plexapp.agents.themoviedb,
tv.plex.agent.series
* **enableBIFGeneration** (bool): Enable video preview thumbnails. Default value true.
* **episodeSort** (int): Episode order. Default -1 Possible options: 0:Oldest first, 1:Newest first.
* **flattenSeasons** (int): Seasons. Default value 0 Possible options: 0:Show,1:Hide.
* **includeInGlobal** (bool): Include in dashboard. Default value true.
* **scanner** (str): Plex Series Scanner
* **scanner** (str): Plex TV Series, Plex Series Scanner

**TheTVDB Show Options** (com.plexapp.agents.thetvdb)

Expand Down
46 changes: 46 additions & 0 deletions plexapi/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,25 +382,47 @@ class Show(Video, ArtMixin, BannerMixin, PosterMixin, SplitMergeMixin, UnmatchMa
Attributes:
TAG (str): 'Directory'
TYPE (str): 'show'
audienceRating (float): Audience rating (TMDB or TVDB).
audienceRatingImage (str): Key to audience rating image (tmdb://image.rating).
autoDeletionItemPolicyUnwatchedLibrary (int): Setting that indicates the number of unplayed
episodes to keep for the show (0 = All episodes, 5 = 5 latest episodes, 3 = 3 latest episodes,
1 = 1 latest episode, -3 = Episodes added in the past 3 days, -7 = Episodes added in the
past 7 days, -30 = Episodes added in the past 30 days).
autoDeletionItemPolicyWatchedLibrary (int): Setting that indicates if episodes are deleted
after being watched for the show (0 = Never, 1 = After a day, 7 = After a week,
100 = On next refresh).
banner (str): Key to banner artwork (/library/metadata/<ratingkey>/banner/<bannerid>).
childCount (int): Number of seasons in the show.
collections (List<:class:`~plexapi.media.Collection`>): List of collection objects.
contentRating (str) Content rating (PG-13; NR; TV-G).
duration (int): Typical duration of the show episodes in milliseconds.
episodeSort (int): Setting that indicates how episodes are sorted for the show
(-1 = Library default, 0 = Oldest first, 1 = Newest first).
flattenSeasons (int): Setting that indicates if seasons are set to hidden for the show
(-1 = Library default, 0 = Hide, 1 = Show).
genres (List<:class:`~plexapi.media.Genre`>): List of genre objects.
guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
index (int): Plex index number for the show.
key (str): API URL (/library/metadata/<ratingkey>).
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
languageOverride (str): Setting that indicates if a languge is used to override metadata
(eg. en-CA, None = Library default).
leafCount (int): Number of items in the show view.
locations (List<str>): List of folder paths where the show is found on disk.
network (str): The network that distributed the show.
originallyAvailableAt (datetime): Datetime the show was released.
originalTitle (str): The original title of the show.
rating (float): Show rating (7.9; 9.8; 8.1).
roles (List<:class:`~plexapi.media.Role`>): List of role objects.
showOrdering (str): Setting that indicates the episode ordering for the show
(None = Library default).
similar (List<:class:`~plexapi.media.Similar`>): List of Similar objects.
studio (str): Studio that created show (Di Bonaventura Pictures; 21 Laps Entertainment).
tagline (str): Show tag line.
theme (str): URL to theme resource (/library/metadata/<ratingkey>/theme/<themeid>).
useOriginalTitle (int): Setting that indicates if the original title is used for the show
(-1 = Library default, 0 = No, 1 = Yes).
userRating (float): User rating (2.0; 8.0).
viewedLeafCount (int): Number of items marked as played in the show view.
year (int): Year the show was released.
"""
Expand All @@ -411,25 +433,39 @@ class Show(Video, ArtMixin, BannerMixin, PosterMixin, SplitMergeMixin, UnmatchMa
def _loadData(self, data):
""" Load attribute values from Plex XML response. """
Video._loadData(self, data)
self.audienceRating = utils.cast(float, data.attrib.get('audienceRating'))
self.audienceRatingImage = data.attrib.get('audienceRatingImage')
self.autoDeletionItemPolicyUnwatchedLibrary = utils.cast(
int, data.attrib.get('autoDeletionItemPolicyUnwatchedLibrary', '0'))
self.autoDeletionItemPolicyWatchedLibrary = utils.cast(
int, data.attrib.get('autoDeletionItemPolicyWatchedLibrary', '0'))
self.banner = data.attrib.get('banner')
self.childCount = utils.cast(int, data.attrib.get('childCount'))
self.collections = self.findItems(data, media.Collection)
self.contentRating = data.attrib.get('contentRating')
self.duration = utils.cast(int, data.attrib.get('duration'))
self.episodeSort = utils.cast(int, data.attrib.get('episodeSort', '-1'))
self.flattenSeasons = utils.cast(int, data.attrib.get('flattenSeasons', '-1'))
self.genres = self.findItems(data, media.Genre)
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.languageOverride = data.attrib.get('languageOverride')
self.leafCount = utils.cast(int, data.attrib.get('leafCount'))
self.locations = self.listAttrs(data, 'path', etag='Location')
self.network = data.attrib.get('network')
self.originallyAvailableAt = utils.toDatetime(data.attrib.get('originallyAvailableAt'), '%Y-%m-%d')
self.originalTitle = data.attrib.get('originalTitle')
self.rating = utils.cast(float, data.attrib.get('rating'))
self.roles = self.findItems(data, media.Role)
self.showOrdering = data.attrib.get('showOrdering')
self.similar = self.findItems(data, media.Similar)
self.studio = data.attrib.get('studio')
self.tagline = data.attrib.get('tagline')
self.theme = data.attrib.get('theme')
self.useOriginalTitle = utils.cast(int, data.attrib.get('useOriginalTitle', '-1'))
self.userRating = utils.cast(float, data.attrib.get('userRating'))
self.viewedLeafCount = utils.cast(int, data.attrib.get('viewedLeafCount'))
self.year = utils.cast(int, data.attrib.get('year'))

Expand Down Expand Up @@ -584,6 +620,7 @@ class Season(Video, ArtMixin, PosterMixin):
Attributes:
TAG (str): 'Directory'
TYPE (str): 'season'
guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
index (int): Season number.
key (str): API URL (/library/metadata/<ratingkey>).
leafCount (int): Number of items in the season view.
Expand All @@ -603,6 +640,7 @@ class Season(Video, ArtMixin, PosterMixin):
def _loadData(self, data):
""" Load attribute values from Plex XML response. """
Video._loadData(self, data)
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.leafCount = utils.cast(int, data.attrib.get('leafCount'))
Expand Down Expand Up @@ -711,6 +749,8 @@ class Episode(Video, Playable, ArtMixin, PosterMixin,
Attributes:
TAG (str): 'Video'
TYPE (str): 'episode'
audienceRating (float): Audience rating (TMDB or TVDB).
audienceRatingImage (str): Key to audience rating image (tmdb://image.rating).
chapters (List<:class:`~plexapi.media.Chapter`>): List of Chapter objects.
chapterSource (str): Chapter source (agent; media; mixed).
contentRating (str) Content rating (PG-13; NR; TV-G).
Expand All @@ -723,6 +763,7 @@ class Episode(Video, Playable, ArtMixin, PosterMixin,
grandparentTheme (str): URL to show theme resource (/library/metadata/<grandparentRatingkey>/theme/<themeid>).
grandparentThumb (str): URL to show thumbnail image (/library/metadata/<grandparentRatingKey>/thumb/<thumbid>).
grandparentTitle (str): Name of the show for the episode.
guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
index (int): Episode number.
markers (List<:class:`~plexapi.media.Marker`>): List of marker objects.
media (List<:class:`~plexapi.media.Media`>): List of media objects.
Expand All @@ -735,6 +776,7 @@ class Episode(Video, Playable, ArtMixin, PosterMixin,
parentTitle (str): Name of the season for the episode.
rating (float): Episode rating (7.9; 9.8; 8.1).
skipParent (bool): True if the show's seasons are set to hidden.
userRating (float): User rating (2.0; 8.0).
viewOffset (int): View offset in milliseconds.
writers (List<:class:`~plexapi.media.Writer`>): List of writers objects.
year (int): Year episode was released.
Expand All @@ -748,6 +790,8 @@ def _loadData(self, data):
Video._loadData(self, data)
Playable._loadData(self, data)
self._seasonNumber = None # cached season number
self.audienceRating = utils.cast(float, data.attrib.get('audienceRating'))
self.audienceRatingImage = data.attrib.get('audienceRatingImage')
self.chapters = self.findItems(data, media.Chapter)
self.chapterSource = data.attrib.get('chapterSource')
self.contentRating = data.attrib.get('contentRating')
Expand All @@ -760,6 +804,7 @@ def _loadData(self, data):
self.grandparentTheme = data.attrib.get('grandparentTheme')
self.grandparentThumb = data.attrib.get('grandparentThumb')
self.grandparentTitle = data.attrib.get('grandparentTitle')
self.guids = self.findItems(data, media.Guid)
self.index = utils.cast(int, data.attrib.get('index'))
self.markers = self.findItems(data, media.Marker)
self.media = self.findItems(data, media.Media)
Expand All @@ -772,6 +817,7 @@ def _loadData(self, data):
self.parentTitle = data.attrib.get('parentTitle')
self.rating = utils.cast(float, data.attrib.get('rating'))
self.skipParent = utils.cast(bool, data.attrib.get('skipParent', '0'))
self.userRating = utils.cast(float, data.attrib.get('userRating'))
self.viewOffset = utils.cast(int, data.attrib.get('viewOffset', 0))
self.writers = self.findItems(data, media.Writer)
self.year = utils.cast(int, data.attrib.get('year'))
Expand Down
16 changes: 16 additions & 0 deletions tests/test_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,16 +559,25 @@ def test_video_Show_attrs(show):
# Check reloading the show loads the full list of genres
assert not {"Adventure", "Drama"} - {i.tag for i in show.genres}
show.reload()
assert show.audienceRating is None # TODO: Change when updating test to the Plex TV agent
assert show.audienceRatingImage is None # TODO: Change when updating test to the Plex TV agent
assert show.autoDeletionItemPolicyUnwatchedLibrary == 0
assert show.autoDeletionItemPolicyWatchedLibrary == 0
assert show.episodeSort == -1
assert show.flattenSeasons == -1
assert sorted([i.tag for i in show.genres]) == ["Adventure", "Drama", "Fantasy"]
assert show.guids == [] # TODO: Change when updating test to the Plex TV agent
# So the initkey should have changed because of the reload
assert utils.is_metadata(show._initpath)
assert utils.is_int(show.index)
assert utils.is_metadata(show.key)
assert show.languageOverride is None
assert utils.is_datetime(show.lastViewedAt)
assert utils.is_int(show.leafCount)
assert show.listType == "video"
assert len(show.locations) == 1
assert len(show.locations[0]) >= 10
assert show.network is None
assert utils.is_datetime(show.originallyAvailableAt)
assert show.originalTitle is None
assert show.rating >= 8.0
Expand All @@ -586,6 +595,7 @@ def test_video_Show_attrs(show):
"Alfie Allen",
] # noqa
assert show._server._baseurl == utils.SERVER_BASEURL
assert show.showOrdering in (None, 'aired')
assert show.studio == "HBO"
assert utils.is_string(show.summary, gte=100)
assert show.tagline is None
Expand All @@ -595,6 +605,8 @@ def test_video_Show_attrs(show):
assert show.title == "Game of Thrones"
assert show.titleSort == "Game of Thrones"
assert show.type == "show"
assert show.useOriginalTitle == -1
assert show.userRating is None
assert utils.is_datetime(show.updatedAt)
assert utils.is_int(show.viewCount, gte=0)
assert utils.is_int(show.viewedLeafCount, gte=0)
Expand Down Expand Up @@ -790,6 +802,8 @@ def test_video_Episode_attrs(episode):
assert utils.is_datetime(episode.addedAt)
if episode.art:
assert utils.is_art(episode.art)
assert episode.audienceRating is None # TODO: Change when updating test to the Plex TV agent
assert episode.audienceRatingImage is None # TODO: Change when updating test to the Plex TV agent
assert episode.contentRating in utils.CONTENTRATINGS
if len(episode.directors):
assert [i.tag for i in episode.directors] == ["Tim Van Patten"]
Expand All @@ -799,6 +813,7 @@ def test_video_Episode_attrs(episode):
if episode.grandparentThumb:
assert utils.is_thumb(episode.grandparentThumb)
assert episode.grandparentTitle == "Game of Thrones"
assert episode.guids == [] # TODO: Change when updating test to the Plex TV agent
assert episode.index == 1
assert utils.is_metadata(episode._initpath)
assert utils.is_metadata(episode.key)
Expand Down Expand Up @@ -913,6 +928,7 @@ def test_video_Season_attrs(show):
assert utils.is_datetime(season.addedAt)
if season.art:
assert utils.is_art(season.art)
assert season.guids == [] # TODO: Change when updating test to the Plex TV agent
assert season.index == 1
assert utils.is_metadata(season._initpath)
assert utils.is_metadata(season.key)
Expand Down