Update plexapi==4.17.0

This commit is contained in:
JonnyWong16 2025-05-10 16:13:23 -07:00
parent 3cb71f94a3
commit f6bffe1850
No known key found for this signature in database
GPG key ID: B1F1F9807184697A
32 changed files with 1224 additions and 966 deletions

View file

@ -8,7 +8,7 @@ from urllib.parse import quote_plus
from typing import Any, Dict, List, Optional, TypeVar
from plexapi import media, utils
from plexapi.base import Playable, PlexPartialObject, PlexHistory, PlexSession
from plexapi.base import Playable, PlexPartialObject, PlexHistory, PlexSession, cached_data_property
from plexapi.exceptions import BadRequest
from plexapi.mixins import (
AdvancedSettingsMixin, SplitMergeMixin, UnmatchMatchMixin, ExtrasMixin, HubsMixin, PlayedUnplayedMixin, RatingMixin,
@ -59,14 +59,11 @@ class Audio(PlexPartialObject, PlayedUnplayedMixin):
def _loadData(self, data):
""" Load attribute values from Plex XML response. """
self._data = data
self.addedAt = utils.toDatetime(data.attrib.get('addedAt'))
self.art = data.attrib.get('art')
self.artBlurHash = data.attrib.get('artBlurHash')
self.distance = utils.cast(float, data.attrib.get('distance'))
self.fields = self.findItems(data, media.Field)
self.guid = data.attrib.get('guid')
self.images = self.findItems(data, media.Image)
self.index = utils.cast(int, data.attrib.get('index'))
self.key = data.attrib.get('key', '')
self.lastRatedAt = utils.toDatetime(data.attrib.get('lastRatedAt'))
@ -75,7 +72,6 @@ class Audio(PlexPartialObject, PlayedUnplayedMixin):
self.librarySectionKey = data.attrib.get('librarySectionKey')
self.librarySectionTitle = data.attrib.get('librarySectionTitle')
self.listType = 'audio'
self.moods = self.findItems(data, media.Mood)
self.musicAnalysisVersion = utils.cast(int, data.attrib.get('musicAnalysisVersion'))
self.ratingKey = utils.cast(int, data.attrib.get('ratingKey'))
self.summary = data.attrib.get('summary')
@ -88,6 +84,18 @@ class Audio(PlexPartialObject, PlayedUnplayedMixin):
self.userRating = utils.cast(float, data.attrib.get('userRating'))
self.viewCount = utils.cast(int, data.attrib.get('viewCount', 0))
@cached_data_property
def fields(self):
return self.findItems(self._data, media.Field)
@cached_data_property
def images(self):
return self.findItems(self._data, media.Image)
@cached_data_property
def moods(self):
return self.findItems(self._data, media.Mood)
def url(self, part):
""" Returns the full URL for the audio item. Typically used for getting a specific track. """
return self._server.url(part, includeToken=True) if part else None
@ -205,18 +213,45 @@ class Artist(
Audio._loadData(self, data)
self.albumSort = utils.cast(int, data.attrib.get('albumSort', '-1'))
self.audienceRating = utils.cast(float, data.attrib.get('audienceRating'))
self.collections = self.findItems(data, media.Collection)
self.countries = self.findItems(data, media.Country)
self.genres = self.findItems(data, media.Genre)
self.guids = self.findItems(data, media.Guid)
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.rating = utils.cast(float, data.attrib.get('rating'))
self.similar = self.findItems(data, media.Similar)
self.styles = self.findItems(data, media.Style)
self.theme = data.attrib.get('theme')
self.ultraBlurColors = self.findItem(data, media.UltraBlurColors)
@cached_data_property
def collections(self):
return self.findItems(self._data, media.Collection)
@cached_data_property
def countries(self):
return self.findItems(self._data, media.Country)
@cached_data_property
def genres(self):
return self.findItems(self._data, media.Genre)
@cached_data_property
def guids(self):
return self.findItems(self._data, media.Guid)
@cached_data_property
def labels(self):
return self.findItems(self._data, media.Label)
@cached_data_property
def locations(self):
return self.listAttrs(self._data, 'path', etag='Location')
@cached_data_property
def similar(self):
return self.findItems(self._data, media.Similar)
@cached_data_property
def styles(self):
return self.findItems(self._data, media.Style)
@cached_data_property
def ultraBlurColors(self):
return self.findItem(self._data, media.UltraBlurColors)
def __iter__(self):
for album in self.albums():
@ -355,12 +390,7 @@ class Album(
""" Load attribute values from Plex XML response. """
Audio._loadData(self, data)
self.audienceRating = utils.cast(float, data.attrib.get('audienceRating'))
self.collections = self.findItems(data, media.Collection)
self.formats = self.findItems(data, media.Format)
self.genres = self.findItems(data, media.Genre)
self.guids = self.findItems(data, media.Guid)
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.loudnessAnalysisVersion = utils.cast(int, data.attrib.get('loudnessAnalysisVersion'))
self.originallyAvailableAt = utils.toDatetime(data.attrib.get('originallyAvailableAt'), '%Y-%m-%d')
@ -372,12 +402,41 @@ class Album(
self.parentTitle = data.attrib.get('parentTitle')
self.rating = utils.cast(float, data.attrib.get('rating'))
self.studio = data.attrib.get('studio')
self.styles = self.findItems(data, media.Style)
self.subformats = self.findItems(data, media.Subformat)
self.ultraBlurColors = self.findItem(data, media.UltraBlurColors)
self.viewedLeafCount = utils.cast(int, data.attrib.get('viewedLeafCount'))
self.year = utils.cast(int, data.attrib.get('year'))
@cached_data_property
def collections(self):
return self.findItems(self._data, media.Collection)
@cached_data_property
def formats(self):
return self.findItems(self._data, media.Format)
@cached_data_property
def genres(self):
return self.findItems(self._data, media.Genre)
@cached_data_property
def guids(self):
return self.findItems(self._data, media.Guid)
@cached_data_property
def labels(self):
return self.findItems(self._data, media.Label)
@cached_data_property
def styles(self):
return self.findItems(self._data, media.Style)
@cached_data_property
def subformats(self):
return self.findItems(self._data, media.Subformat)
@cached_data_property
def ultraBlurColors(self):
return self.findItem(self._data, media.UltraBlurColors)
def __iter__(self):
for track in self.tracks():
yield track
@ -495,11 +554,8 @@ class Track(
Audio._loadData(self, data)
Playable._loadData(self, data)
self.audienceRating = utils.cast(float, data.attrib.get('audienceRating'))
self.chapters = self.findItems(data, media.Chapter)
self.chapterSource = data.attrib.get('chapterSource')
self.collections = self.findItems(data, media.Collection)
self.duration = utils.cast(int, data.attrib.get('duration'))
self.genres = self.findItems(data, media.Genre)
self.grandparentArt = data.attrib.get('grandparentArt')
self.grandparentGuid = data.attrib.get('grandparentGuid')
self.grandparentKey = data.attrib.get('grandparentKey')
@ -507,9 +563,6 @@ class Track(
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.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')
self.parentIndex = utils.cast(int, data.attrib.get('parentIndex'))
@ -525,6 +578,30 @@ class Track(
self.viewOffset = utils.cast(int, data.attrib.get('viewOffset', 0))
self.year = utils.cast(int, data.attrib.get('year'))
@cached_data_property
def chapters(self):
return self.findItems(self._data, media.Chapter)
@cached_data_property
def collections(self):
return self.findItems(self._data, media.Collection)
@cached_data_property
def genres(self):
return self.findItems(self._data, media.Genre)
@cached_data_property
def guids(self):
return self.findItems(self._data, media.Guid)
@cached_data_property
def labels(self):
return self.findItems(self._data, media.Label)
@cached_data_property
def media(self):
return self.findItems(self._data, media.Media)
@property
def locations(self):
""" This does not exist in plex xml response but is added to have a common