mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-22 19:53:17 +00:00
Add support for credit markers (#1094)
* Add credit markers * Disable credit detection in bootstrap test server * Add `first` property for credits markers * Add credits detection setting attribute * Update tests for credits detection setting
This commit is contained in:
parent
6350e85ff9
commit
1e220eb311
4 changed files with 36 additions and 2 deletions
|
@ -1037,9 +1037,11 @@ class Marker(PlexObject):
|
||||||
Attributes:
|
Attributes:
|
||||||
TAG (str): 'Marker'
|
TAG (str): 'Marker'
|
||||||
end (int): The end time of the marker in milliseconds.
|
end (int): The end time of the marker in milliseconds.
|
||||||
|
final (bool): True if the marker is the final credits marker.
|
||||||
id (int): The ID of the marker.
|
id (int): The ID of the marker.
|
||||||
type (str): The type of marker.
|
type (str): The type of marker.
|
||||||
start (int): The start time of the marker in milliseconds.
|
start (int): The start time of the marker in milliseconds.
|
||||||
|
version (int): The Plex marker version.
|
||||||
"""
|
"""
|
||||||
TAG = 'Marker'
|
TAG = 'Marker'
|
||||||
|
|
||||||
|
@ -1053,10 +1055,25 @@ class Marker(PlexObject):
|
||||||
def _loadData(self, data):
|
def _loadData(self, data):
|
||||||
self._data = data
|
self._data = data
|
||||||
self.end = utils.cast(int, data.attrib.get('endTimeOffset'))
|
self.end = utils.cast(int, data.attrib.get('endTimeOffset'))
|
||||||
|
self.final = utils.cast(bool, data.attrib.get('final'))
|
||||||
self.id = utils.cast(int, data.attrib.get('id'))
|
self.id = utils.cast(int, data.attrib.get('id'))
|
||||||
self.type = data.attrib.get('type')
|
self.type = data.attrib.get('type')
|
||||||
self.start = utils.cast(int, data.attrib.get('startTimeOffset'))
|
self.start = utils.cast(int, data.attrib.get('startTimeOffset'))
|
||||||
|
|
||||||
|
attributes = data.find('Attributes')
|
||||||
|
self.version = attributes.attrib.get('version')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def first(self):
|
||||||
|
""" Returns True if the marker in the first credits marker. """
|
||||||
|
if self.type != 'credits':
|
||||||
|
return None
|
||||||
|
first = min(
|
||||||
|
(marker for marker in self._parent().markers if marker.type == 'credits'),
|
||||||
|
key=lambda m: m.start
|
||||||
|
)
|
||||||
|
return first == self
|
||||||
|
|
||||||
|
|
||||||
@utils.registerPlexObject
|
@utils.registerPlexObject
|
||||||
class Field(PlexObject):
|
class Field(PlexObject):
|
||||||
|
|
|
@ -311,6 +311,7 @@ class Movie(
|
||||||
directors (List<:class:`~plexapi.media.Director`>): List of director objects.
|
directors (List<:class:`~plexapi.media.Director`>): List of director objects.
|
||||||
duration (int): Duration of the movie in milliseconds.
|
duration (int): Duration of the movie in milliseconds.
|
||||||
editionTitle (str): The edition title of the movie (e.g. Director's Cut, Extended Edition, etc.).
|
editionTitle (str): The edition title of the movie (e.g. Director's Cut, Extended Edition, etc.).
|
||||||
|
enableCreditsMarkerGeneration (int): Setting that indicates if credits markers detection is enabled.
|
||||||
genres (List<:class:`~plexapi.media.Genre`>): List of genre objects.
|
genres (List<:class:`~plexapi.media.Genre`>): List of genre objects.
|
||||||
guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
|
guids (List<:class:`~plexapi.media.Guid`>): List of guid objects.
|
||||||
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
|
labels (List<:class:`~plexapi.media.Label`>): List of label objects.
|
||||||
|
@ -353,6 +354,7 @@ class Movie(
|
||||||
self.directors = self.findItems(data, media.Director)
|
self.directors = self.findItems(data, media.Director)
|
||||||
self.duration = utils.cast(int, data.attrib.get('duration'))
|
self.duration = utils.cast(int, data.attrib.get('duration'))
|
||||||
self.editionTitle = data.attrib.get('editionTitle')
|
self.editionTitle = data.attrib.get('editionTitle')
|
||||||
|
self.enableCreditsMarkerGeneration = utils.cast(int, data.attrib.get('enableCreditsMarkerGeneration', '-1'))
|
||||||
self.genres = self.findItems(data, media.Genre)
|
self.genres = self.findItems(data, media.Genre)
|
||||||
self.guids = self.findItems(data, media.Guid)
|
self.guids = self.findItems(data, media.Guid)
|
||||||
self.labels = self.findItems(data, media.Label)
|
self.labels = self.findItems(data, media.Label)
|
||||||
|
@ -390,6 +392,11 @@ class Movie(
|
||||||
"""
|
"""
|
||||||
return [part.file for part in self.iterParts() if part]
|
return [part.file for part in self.iterParts() if part]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hasCreditsMarker(self):
|
||||||
|
""" Returns True if the movie has a credits marker. """
|
||||||
|
return any(marker.type == 'credits' for marker in self.markers)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hasPreviewThumbnails(self):
|
def hasPreviewThumbnails(self):
|
||||||
""" Returns True if any of the media parts has generated preview (BIF) thumbnails. """
|
""" Returns True if any of the media parts has generated preview (BIF) thumbnails. """
|
||||||
|
@ -444,6 +451,7 @@ class Show(
|
||||||
collections (List<:class:`~plexapi.media.Collection`>): List of collection objects.
|
collections (List<:class:`~plexapi.media.Collection`>): List of collection objects.
|
||||||
contentRating (str) Content rating (PG-13; NR; TV-G).
|
contentRating (str) Content rating (PG-13; NR; TV-G).
|
||||||
duration (int): Typical duration of the show episodes in milliseconds.
|
duration (int): Typical duration of the show episodes in milliseconds.
|
||||||
|
enableCreditsMarkerGeneration (int): Setting that indicates if credits markers detection is enabled.
|
||||||
episodeSort (int): Setting that indicates how episodes are sorted for the show
|
episodeSort (int): Setting that indicates how episodes are sorted for the show
|
||||||
(-1 = Library default, 0 = Oldest first, 1 = Newest first).
|
(-1 = Library default, 0 = Oldest first, 1 = Newest first).
|
||||||
flattenSeasons (int): Setting that indicates if seasons are set to hidden for the show
|
flattenSeasons (int): Setting that indicates if seasons are set to hidden for the show
|
||||||
|
@ -493,6 +501,7 @@ class Show(
|
||||||
self.collections = self.findItems(data, media.Collection)
|
self.collections = self.findItems(data, media.Collection)
|
||||||
self.contentRating = data.attrib.get('contentRating')
|
self.contentRating = data.attrib.get('contentRating')
|
||||||
self.duration = utils.cast(int, data.attrib.get('duration'))
|
self.duration = utils.cast(int, data.attrib.get('duration'))
|
||||||
|
self.enableCreditsMarkerGeneration = utils.cast(int, data.attrib.get('enableCreditsMarkerGeneration', '-1'))
|
||||||
self.episodeSort = utils.cast(int, data.attrib.get('episodeSort', '-1'))
|
self.episodeSort = utils.cast(int, data.attrib.get('episodeSort', '-1'))
|
||||||
self.flattenSeasons = utils.cast(int, data.attrib.get('flattenSeasons', '-1'))
|
self.flattenSeasons = utils.cast(int, data.attrib.get('flattenSeasons', '-1'))
|
||||||
self.genres = self.findItems(data, media.Genre)
|
self.genres = self.findItems(data, media.Genre)
|
||||||
|
@ -920,14 +929,19 @@ class Episode(
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hasCommercialMarker(self):
|
def hasCommercialMarker(self):
|
||||||
""" Returns True if the episode has a commercial marker in the xml. """
|
""" Returns True if the episode has a commercial marker. """
|
||||||
return any(marker.type == 'commercial' for marker in self.markers)
|
return any(marker.type == 'commercial' for marker in self.markers)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hasIntroMarker(self):
|
def hasIntroMarker(self):
|
||||||
""" Returns True if the episode has an intro marker in the xml. """
|
""" Returns True if the episode has an intro marker. """
|
||||||
return any(marker.type == 'intro' for marker in self.markers)
|
return any(marker.type == 'intro' for marker in self.markers)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hasCreditsMarker(self):
|
||||||
|
""" Returns True if the episode has a credits marker. """
|
||||||
|
return any(marker.type == 'credits' for marker in self.markers)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hasPreviewThumbnails(self):
|
def hasPreviewThumbnails(self):
|
||||||
""" Returns True if any of the media parts has generated preview (BIF) thumbnails. """
|
""" Returns True if any of the media parts has generated preview (BIF) thumbnails. """
|
||||||
|
|
|
@ -59,6 +59,7 @@ def test_video_Movie_attrs(movies):
|
||||||
assert not movie.collections
|
assert not movie.collections
|
||||||
assert movie.contentRating in utils.CONTENTRATINGS
|
assert movie.contentRating in utils.CONTENTRATINGS
|
||||||
assert movie.editionTitle is None
|
assert movie.editionTitle is None
|
||||||
|
assert movie.enableCreditsMarkerGeneration == -1
|
||||||
if movie.countries:
|
if movie.countries:
|
||||||
assert "United States of America" in [i.tag for i in movie.countries]
|
assert "United States of America" in [i.tag for i in movie.countries]
|
||||||
if movie.producers:
|
if movie.producers:
|
||||||
|
@ -724,6 +725,7 @@ def test_video_Show_attrs(show):
|
||||||
assert show.audienceRatingImage == "themoviedb://image.rating"
|
assert show.audienceRatingImage == "themoviedb://image.rating"
|
||||||
assert show.autoDeletionItemPolicyUnwatchedLibrary == 0
|
assert show.autoDeletionItemPolicyUnwatchedLibrary == 0
|
||||||
assert show.autoDeletionItemPolicyWatchedLibrary == 0
|
assert show.autoDeletionItemPolicyWatchedLibrary == 0
|
||||||
|
assert show.enableCreditsMarkerGeneration == -1
|
||||||
assert show.episodeSort == -1
|
assert show.episodeSort == -1
|
||||||
assert show.flattenSeasons == -1
|
assert show.flattenSeasons == -1
|
||||||
assert "Drama" in [i.tag for i in show.genres]
|
assert "Drama" in [i.tag for i in show.genres]
|
||||||
|
|
|
@ -502,6 +502,7 @@ if __name__ == "__main__":
|
||||||
# These tasks won't work on the test server since we are using fake media files
|
# These tasks won't work on the test server since we are using fake media files
|
||||||
if not opts.unclaimed and account and account.subscriptionActive:
|
if not opts.unclaimed and account and account.subscriptionActive:
|
||||||
server.settings.get("GenerateIntroMarkerBehavior").set("never")
|
server.settings.get("GenerateIntroMarkerBehavior").set("never")
|
||||||
|
server.settings.get("GenerateCreditsMarkerBehavior").set("never")
|
||||||
server.settings.get("GenerateBIFBehavior").set("never")
|
server.settings.get("GenerateBIFBehavior").set("never")
|
||||||
server.settings.get("GenerateChapterThumbBehavior").set("never")
|
server.settings.get("GenerateChapterThumbBehavior").set("never")
|
||||||
server.settings.get("LoudnessAnalysisBehavior").set("never")
|
server.settings.get("LoudnessAnalysisBehavior").set("never")
|
||||||
|
|
Loading…
Reference in a new issue