@@ -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