Skip to content

Commit cf56d9a

Browse files
committed
Update photo attributes
1 parent 1c59429 commit cf56d9a

File tree

1 file changed

+86
-39
lines changed

1 file changed

+86
-39
lines changed

plexapi/photo.py

Lines changed: 86 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,31 @@ class Photoalbum(PlexPartialObject):
1313
Attributes:
1414
TAG (str): 'Directory'
1515
TYPE (str): 'photo'
16-
addedAt (datetime): Datetime this item was added to the library.
17-
art (str): Photo art (/library/metadata/<ratingkey>/art/<artid>)
18-
composite (str): Unknown
19-
fields (list): List of :class:`~plexapi.media.Field`.
20-
guid (str): Unknown (unique ID)
21-
index (sting): Index number of this album.
16+
addedAt (datetime): Datetime the photo album was added to the library.
17+
art (str): URL to artwork image (/library/metadata/<ratingKey>/art/<artid>).
18+
composite (str): URL to composite image (/library/metadata/<ratingKey>/composite/<compositeid>)
19+
fields (List<:class:`~plexapi.media.Field`>): List of field objects.
20+
guid (str): Plex GUID for the photo album (local://229674).
21+
index (sting): Plex index number for the photo album.
2222
key (str): API URL (/library/metadata/<ratingkey>).
2323
librarySectionID (int): :class:`~plexapi.library.LibrarySection` ID.
24+
librarySectionKey (str): :class:`~plexapi.library.LibrarySection` key.
25+
librarySectionTitle (str): :class:`~plexapi.library.LibrarySection` title.
2426
listType (str): Hardcoded as 'photo' (useful for search filters).
25-
ratingKey (int): Unique key identifying this item.
27+
ratingKey (int): Unique key identifying the photo album.
2628
summary (str): Summary of the photoalbum.
27-
thumb (str): URL to thumbnail image.
28-
title (str): Photoalbum title. (Trip to Disney World)
29-
type (str): Unknown
30-
updatedAt (datatime): Datetime this item was updated.
29+
thumb (str): URL to thumbnail image (/library/metadata/<ratingKey>/thumb/<thumbid>).
30+
title (str): Name of the photo album. (Trip to Disney World)
31+
titleSort (str): Title to use when sorting (defaults to title).
32+
type (str): 'photo'
33+
updatedAt (datatime): Datetime the photo album was updated.
34+
userRating (float): Rating of the photoalbum (0.0 - 10.0) equaling (0 stars - 5 stars).
3135
"""
3236
TAG = 'Directory'
3337
TYPE = 'photo'
3438

3539
def _loadData(self, data):
3640
""" Load attribute values from Plex XML response. """
37-
self.listType = 'photo'
3841
self.addedAt = utils.toDatetime(data.attrib.get('addedAt'))
3942
self.art = data.attrib.get('art')
4043
self.composite = data.attrib.get('composite')
@@ -43,15 +46,20 @@ def _loadData(self, data):
4346
self.index = utils.cast(int, data.attrib.get('index'))
4447
self.key = data.attrib.get('key')
4548
self.librarySectionID = data.attrib.get('librarySectionID')
46-
self.ratingKey = data.attrib.get('ratingKey')
49+
self.librarySectionKey = data.attrib.get('librarySectionKey')
50+
self.librarySectionTitle = data.attrib.get('librarySectionTitle')
51+
self.listType = 'photo'
52+
self.ratingKey = utils.cast(int, data.attrib.get('ratingKey'))
4753
self.summary = data.attrib.get('summary')
4854
self.thumb = data.attrib.get('thumb')
4955
self.title = data.attrib.get('title')
56+
self.titleSort = data.attrib.get('titleSort', self.title)
5057
self.type = data.attrib.get('type')
5158
self.updatedAt = utils.toDatetime(data.attrib.get('updatedAt'))
59+
self.userRating = utils.cast(float, data.attrib.get('userRating', 0))
5260

5361
def albums(self, **kwargs):
54-
""" Returns a list of :class:`~plexapi.photo.Photoalbum` objects in this album. """
62+
""" Returns a list of :class:`~plexapi.photo.Photoalbum` objects in the album. """
5563
key = '/library/metadata/%s/children' % self.ratingKey
5664
return self.fetchItems(key, etag='Directory', **kwargs)
5765

@@ -63,7 +71,7 @@ def album(self, title):
6371
raise NotFound('Unable to find album: %s' % title)
6472

6573
def photos(self, **kwargs):
66-
""" Returns a list of :class:`~plexapi.photo.Photo` objects in this album. """
74+
""" Returns a list of :class:`~plexapi.photo.Photo` objects in the album. """
6775
key = '/library/metadata/%s/children' % self.ratingKey
6876
return self.fetchItems(key, etag='Photo', **kwargs)
6977

@@ -74,8 +82,20 @@ def photo(self, title):
7482
return photo
7583
raise NotFound('Unable to find photo: %s' % title)
7684

85+
def clips(self, **kwargs):
86+
""" Returns a list of :class:`~plexapi.video.Clip` objects in the album. """
87+
key = '/library/metadata/%s/children' % self.ratingKey
88+
return self.fetchItems(key, etag='Video', **kwargs)
89+
90+
def clip(self, title):
91+
""" Returns the :class:`~plexapi.video.Clip` that matches the specified title. """
92+
for clip in self.clips():
93+
if clip.title.lower() == title.lower():
94+
return clip
95+
raise NotFound('Unable to find clip: %s' % title)
96+
7797
def iterParts(self):
78-
""" Iterates over the parts of this media item. """
98+
""" Iterates over the parts of the media item. """
7999
for album in self.albums():
80100
for photo in album.photos():
81101
for part in photo.iterParts():
@@ -112,23 +132,34 @@ class Photo(PlexPartialObject, Playable):
112132
Attributes:
113133
TAG (str): 'Photo'
114134
TYPE (str): 'photo'
115-
addedAt (datetime): Datetime this item was added to the library.
135+
addedAt (datetime): Datetime the photo was added to the library.
136+
createdAtAccuracy (str): Unknown (local).
137+
createdAtTZOffset (int): Unknown (-25200).
116138
fields (list): List of :class:`~plexapi.media.Field`.
117-
index (sting): Index number of this photo.
139+
guid (str): Plex GUID for the photo (com.plexapp.agents.none://231714?lang=xn).
140+
index (sting): Plex index number for the photo.
118141
key (str): API URL (/library/metadata/<ratingkey>).
119142
librarySectionID (int): :class:`~plexapi.library.LibrarySection` ID.
143+
librarySectionKey (str): :class:`~plexapi.library.LibrarySection` key.
144+
librarySectionTitle (str): :class:`~plexapi.library.LibrarySection` title.
120145
listType (str): Hardcoded as 'photo' (useful for search filters).
121-
media (TYPE): Unknown
122-
originallyAvailableAt (datetime): Datetime this photo was added to Plex.
123-
parentKey (str): Photoalbum API URL.
124-
parentRatingKey (int): Unique key identifying the photoalbum.
125-
ratingKey (int): Unique key identifying this item.
146+
media (List<:class:`~plexapi.media.Media`>): List of media objects.
147+
originallyAvailableAt (datetime): Datetime the photo was added to Plex.
148+
parentGuid (str): Plex GUID for the photo album (local://229674).
149+
parentIndex (int): Plex index number for the photo album.
150+
parentKey (str): API URL of the photo album (/library/metadata/<parentRatingKey>).
151+
parentRatingKey (int): Unique key identifying the photo album.
152+
parentThumb (str): URL to photo album thumbnail image (/library/metadata/<parentRatingKey>/thumb/<thumbid>).
153+
parentTitle (str): Name of the photo album for the photo.
154+
ratingKey (int): Unique key identifying the photo.
126155
summary (str): Summary of the photo.
127-
thumb (str): URL to thumbnail image.
128-
title (str): Photo title.
129-
type (str): Unknown
130-
updatedAt (datatime): Datetime this item was updated.
131-
year (int): Year this photo was taken.
156+
tag (List<:class:`~plexapi.media.Tag`>): List of tag objects.
157+
thumb (str): URL to thumbnail image (/library/metadata/<ratingKey>/thumb/<thumbid>).
158+
title (str): Name of the photo.
159+
titleSort (str): Title to use when sorting (defaults to title).
160+
type (str): 'photo'
161+
updatedAt (datatime): Datetime the photo was updated.
162+
year (int): Year the photo was taken.
132163
"""
133164
TAG = 'Photo'
134165
TYPE = 'photo'
@@ -137,25 +168,34 @@ class Photo(PlexPartialObject, Playable):
137168
def _loadData(self, data):
138169
""" Load attribute values from Plex XML response. """
139170
Playable._loadData(self, data)
140-
self.listType = 'photo'
141171
self.addedAt = utils.toDatetime(data.attrib.get('addedAt'))
142-
self.fields = self.findItems(data, etag='Field')
172+
self.createdAtAccuracy = data.attrib.get('createdAtAccuracy')
173+
self.createdAtTZOffset = utils.cast(int, data.attrib.get('createdAtTZOffset'))
174+
self.fields = self.findItems(data, media.Field)
175+
self.guid = data.attrib.get('guid')
143176
self.index = utils.cast(int, data.attrib.get('index'))
144177
self.key = data.attrib.get('key')
145178
self.librarySectionID = data.attrib.get('librarySectionID')
146-
self.originallyAvailableAt = utils.toDatetime(
147-
data.attrib.get('originallyAvailableAt'), '%Y-%m-%d')
179+
self.librarySectionKey = data.attrib.get('librarySectionKey')
180+
self.librarySectionTitle = data.attrib.get('librarySectionTitle')
181+
self.listType = 'photo'
182+
self.media = self.findItems(data, media.Media)
183+
self.originallyAvailableAt = utils.toDatetime(data.attrib.get('originallyAvailableAt'), '%Y-%m-%d')
184+
self.parentGuid = data.attrib.get('parentGuid')
185+
self.parentIndex = utils.cast(int, data.attrib.get('parentIndex'))
148186
self.parentKey = data.attrib.get('parentKey')
149-
self.parentRatingKey = data.attrib.get('parentRatingKey')
150-
self.ratingKey = data.attrib.get('ratingKey')
187+
self.parentRatingKey = utils.cast(int, data.attrib.get('parentRatingKey'))
188+
self.parentThumb = data.attrib.get('parentThumb')
189+
self.parentTitle = data.attrib.get('parentTitle')
190+
self.ratingKey = utils.cast(int, data.attrib.get('ratingKey'))
151191
self.summary = data.attrib.get('summary')
192+
self.tag = self.findItems(data, media.Tag)
152193
self.thumb = data.attrib.get('thumb')
153194
self.title = data.attrib.get('title')
195+
self.titleSort = data.attrib.get('titleSort', self.title)
154196
self.type = data.attrib.get('type')
155197
self.updatedAt = utils.toDatetime(data.attrib.get('updatedAt'))
156198
self.year = utils.cast(int, data.attrib.get('year'))
157-
self.media = self.findItems(data, media.Media)
158-
self.tag = self.findItems(data, media.Tag)
159199

160200
@property
161201
def thumbUrl(self):
@@ -164,20 +204,27 @@ def thumbUrl(self):
164204
return self._server.url(key, includeToken=True) if key else None
165205

166206
def photoalbum(self):
167-
""" Return this photo's :class:`~plexapi.photo.Photoalbum`. """
207+
""" Return the photo's :class:`~plexapi.photo.Photoalbum`. """
168208
return self.fetchItem(self.parentKey)
169209

170210
def section(self):
171-
""" Returns the :class:`~plexapi.library.LibrarySection` this item belongs to. """
211+
""" Returns the :class:`~plexapi.library.LibrarySection` the item belongs to. """
172212
if hasattr(self, 'librarySectionID'):
173213
return self._server.library.sectionByID(self.librarySectionID)
174214
elif self.parentKey:
175215
return self._server.library.sectionByID(self.photoalbum().librarySectionID)
176216
else:
177217
raise BadRequest('Unable to get section for photo, can`t find librarySectionID')
178218

219+
@property
220+
def locations(self):
221+
""" This does not exist in plex xml response but is added to have a common
222+
interface to get the locations of the photo.
223+
"""
224+
return [part.file for item in self.media for part in item.parts if part]
225+
179226
def iterParts(self):
180-
""" Iterates over the parts of this media item. """
227+
""" Iterates over the parts of the media item. """
181228
for item in self.media:
182229
for part in item.parts:
183230
yield part

0 commit comments

Comments
 (0)