Skip to content

Commit 4d9e1d4

Browse files
authored
Add edition support for movies (#1010)
* Add editionTitle to Movie attributes * Add EditionTitleMixin to Movie * Add tests for movie editionTitle * Add `editions()` method to Movie * Add test for movie editions method
1 parent 02e3ddf commit 4d9e1d4

File tree

4 files changed

+43
-2
lines changed

4 files changed

+43
-2
lines changed

plexapi/mixins.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,19 @@ def editContentRating(self, contentRating, locked=True):
569569
return self.editField('contentRating', contentRating, locked=locked)
570570

571571

572+
class EditionTitleMixin(EditFieldMixin):
573+
""" Mixin for Plex objects that can have an edition title. """
574+
575+
def editEditionTitle(self, editionTitle, locked=True):
576+
""" Edit the edition title. Plex Pass is required to edit this field.
577+
578+
Parameters:
579+
editionTitle (str): The new value.
580+
locked (bool): True (default) to lock the field, False to unlock the field.
581+
"""
582+
return self.editField('editionTitle', editionTitle, locked=locked)
583+
584+
572585
class OriginallyAvailableMixin(EditFieldMixin):
573586
""" Mixin for Plex objects that can have an originally available date. """
574587

plexapi/video.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from plexapi.mixins import (
99
AdvancedSettingsMixin, SplitMergeMixin, UnmatchMatchMixin, ExtrasMixin, HubsMixin, PlayedUnplayedMixin, RatingMixin,
1010
ArtUrlMixin, ArtMixin, BannerMixin, PosterUrlMixin, PosterMixin, ThemeUrlMixin, ThemeMixin,
11-
ContentRatingMixin, OriginallyAvailableMixin, OriginalTitleMixin, SortTitleMixin, StudioMixin,
11+
ContentRatingMixin, EditionTitleMixin, OriginallyAvailableMixin, OriginalTitleMixin, SortTitleMixin, StudioMixin,
1212
SummaryMixin, TaglineMixin, TitleMixin,
1313
CollectionMixin, CountryMixin, DirectorMixin, GenreMixin, LabelMixin, ProducerMixin, WriterMixin,
1414
WatchlistMixin
@@ -291,7 +291,7 @@ class Movie(
291291
Video, Playable,
292292
AdvancedSettingsMixin, SplitMergeMixin, UnmatchMatchMixin, ExtrasMixin, HubsMixin, RatingMixin,
293293
ArtMixin, PosterMixin, ThemeMixin,
294-
ContentRatingMixin, OriginallyAvailableMixin, OriginalTitleMixin, SortTitleMixin, StudioMixin,
294+
ContentRatingMixin, EditionTitleMixin, OriginallyAvailableMixin, OriginalTitleMixin, SortTitleMixin, StudioMixin,
295295
SummaryMixin, TaglineMixin, TitleMixin,
296296
CollectionMixin, CountryMixin, DirectorMixin, GenreMixin, LabelMixin, ProducerMixin, WriterMixin,
297297
WatchlistMixin
@@ -310,6 +310,7 @@ class Movie(
310310
countries (List<:class:`~plexapi.media.Country`>): List of countries objects.
311311
directors (List<:class:`~plexapi.media.Director`>): List of director objects.
312312
duration (int): Duration of the movie in milliseconds.
313+
editionTitle (str): The edition title of the movie (e.g. Director's Cut, Extended Edition, etc.).
313314
genres (List<:class:`~plexapi.media.Genre`>): List of genre objects.
314315
guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
315316
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
@@ -350,6 +351,7 @@ def _loadData(self, data):
350351
self.countries = self.findItems(data, media.Country)
351352
self.directors = self.findItems(data, media.Director)
352353
self.duration = utils.cast(int, data.attrib.get('duration'))
354+
self.editionTitle = data.attrib.get('editionTitle')
353355
self.genres = self.findItems(data, media.Genre)
354356
self.guids = self.findItems(data, media.Guid)
355357
self.labels = self.findItems(data, media.Label)
@@ -400,6 +402,16 @@ def reviews(self):
400402
data = self._server.query(self._details_key)
401403
return self.findItems(data, media.Review, rtag='Video')
402404

405+
def editions(self):
406+
""" Returns a list of :class:`~plexapi.video.Movie` objects
407+
for other editions of the same movie.
408+
"""
409+
filters = {
410+
'guid': self.guid,
411+
'id!': self.ratingKey
412+
}
413+
return self.section().search(filters=filters)
414+
403415

404416
@utils.registerPlexObject
405417
class Show(

tests/test_mixins.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ def edit_content_rating(obj):
4646
_test_mixins_field(obj, "contentRating", "ContentRating")
4747

4848

49+
def edit_edition_title(obj):
50+
_test_mixins_field(obj, "editionTitle", "EditionTitle")
51+
52+
4953
def edit_originally_available(obj):
5054
_test_mixins_field(obj, "originallyAvailableAt", "OriginallyAvailable")
5155

tests/test_video.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def test_video_Movie_attrs(movies):
5656
assert movie.chapterSource is None
5757
assert not movie.collections
5858
assert movie.contentRating in utils.CONTENTRATINGS
59+
assert movie.editionTitle is None
5960
if movie.countries:
6061
assert "United States of America" in [i.tag for i in movie.countries]
6162
if movie.producers:
@@ -579,6 +580,10 @@ def test_video_Movie_reviews(movies):
579580
assert review.text
580581

581582

583+
def test_video_Movie_editions(movie):
584+
assert len(movie.editions()) == 0
585+
586+
582587
@pytest.mark.authenticated
583588
def test_video_Movie_extras(movies):
584589
movie = movies.get("Sita Sings The Blues")
@@ -660,6 +665,13 @@ def test_video_Movie_mixins_fields(movie):
660665
test_mixins.edit_summary(movie)
661666
test_mixins.edit_tagline(movie)
662667
test_mixins.edit_title(movie)
668+
with pytest.raises(BadRequest):
669+
test_mixins.edit_edition_title(movie)
670+
671+
672+
@pytest.mark.authenticated
673+
def test_video_Movie_mixins_fields(movie):
674+
test_mixins.edit_edition_title(movie)
663675

664676

665677
def test_video_Movie_mixins_tags(movie):

0 commit comments

Comments
 (0)