Skip to content

Commit c8854c6

Browse files
authored
Add return self to various methods to support chaining (#986)
* Add return self to various methods to support chaining * Fix runButlerTask test
1 parent f0ed19c commit c8854c6

File tree

10 files changed

+68
-15
lines changed

10 files changed

+68
-15
lines changed

plexapi/collection.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ def filterUserUpdate(self, user=None):
234234
key = user_dict.get(user)
235235
if key is None:
236236
raise BadRequest('Unknown collection filtering user: %s. Options %s' % (user, list(user_dict)))
237-
self.editAdvanced(collectionFilterBasedOnUser=key)
237+
return self.editAdvanced(collectionFilterBasedOnUser=key)
238238

239239
def modeUpdate(self, mode=None):
240240
""" Update the collection mode advanced setting.
@@ -261,7 +261,7 @@ def modeUpdate(self, mode=None):
261261
key = mode_dict.get(mode)
262262
if key is None:
263263
raise BadRequest('Unknown collection mode: %s. Options %s' % (mode, list(mode_dict)))
264-
self.editAdvanced(collectionMode=key)
264+
return self.editAdvanced(collectionMode=key)
265265

266266
def sortUpdate(self, sort=None):
267267
""" Update the collection order advanced setting.
@@ -289,7 +289,7 @@ def sortUpdate(self, sort=None):
289289
key = sort_dict.get(sort)
290290
if key is None:
291291
raise BadRequest('Unknown sort dir: %s. Options: %s' % (sort, list(sort_dict)))
292-
self.editAdvanced(collectionSort=key)
292+
return self.editAdvanced(collectionSort=key)
293293

294294
def addItems(self, items):
295295
""" Add items to the collection.
@@ -321,6 +321,7 @@ def addItems(self, items):
321321
'uri': uri
322322
}))
323323
self._server.query(key, method=self._server._session.put)
324+
return self
324325

325326
def removeItems(self, items):
326327
""" Remove items from the collection.
@@ -341,6 +342,7 @@ def removeItems(self, items):
341342
for item in items:
342343
key = '%s/items/%s' % (self.key, item.ratingKey)
343344
self._server.query(key, method=self._server._session.delete)
345+
return self
344346

345347
def moveItem(self, item, after=None):
346348
""" Move an item to a new position in the collection.
@@ -363,6 +365,7 @@ def moveItem(self, item, after=None):
363365
key += '?after=%s' % after.ratingKey
364366

365367
self._server.query(key, method=self._server._session.put)
368+
return self
366369

367370
def updateFilters(self, libtype=None, limit=None, sort=None, filters=None, **kwargs):
368371
""" Update the filters for a smart collection.
@@ -394,6 +397,7 @@ def updateFilters(self, libtype=None, limit=None, sort=None, filters=None, **kwa
394397
'uri': uri
395398
}))
396399
self._server.query(key, method=self._server._session.put)
400+
return self
397401

398402
@deprecated('use editTitle, editSortTitle, editContentRating, and editSummary instead')
399403
def edit(self, title=None, titleSort=None, contentRating=None, summary=None, **kwargs):

plexapi/library.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,40 +150,47 @@ def cleanBundles(self):
150150
"""
151151
# TODO: Should this check the response for success or the correct mediaprefix?
152152
self._server.query('/library/clean/bundles?async=1', method=self._server._session.put)
153+
return self
153154

154155
def emptyTrash(self):
155156
""" If a library has items in the Library Trash, use this option to empty the Trash. """
156157
for section in self.sections():
157158
section.emptyTrash()
159+
return self
158160

159161
def optimize(self):
160162
""" The Optimize option cleans up the server database from unused or fragmented data.
161163
For example, if you have deleted or added an entire library or many items in a
162164
library, you may like to optimize the database.
163165
"""
164166
self._server.query('/library/optimize?async=1', method=self._server._session.put)
167+
return self
165168

166169
def update(self):
167170
""" Scan this library for new items."""
168171
self._server.query('/library/sections/all/refresh')
172+
return self
169173

170174
def cancelUpdate(self):
171175
""" Cancel a library update. """
172176
key = '/library/sections/all/refresh'
173177
self._server.query(key, method=self._server._session.delete)
178+
return self
174179

175180
def refresh(self):
176181
""" Forces a download of fresh media information from the internet.
177182
This can take a long time. Any locked fields are not modified.
178183
"""
179184
self._server.query('/library/sections/all/refresh?force=1')
185+
return self
180186

181187
def deleteMediaPreviews(self):
182188
""" Delete the preview thumbnails for the all sections. This cannot be
183189
undone. Recreating media preview files can take hours or even days.
184190
"""
185191
for section in self.sections():
186192
section.deleteMediaPreviews()
193+
return self
187194

188195
def add(self, name='', type='', agent='', scanner='', location='', language='en', *args, **kwargs):
189196
""" Simplified add for the most common options.
@@ -549,6 +556,7 @@ def edit(self, agent=None, **kwargs):
549556

550557
part = '/library/sections/%s?agent=%s&%s' % (self.key, agent, urlencode(params, doseq=True))
551558
self._server.query(part, method=self._server._session.put)
559+
return self
552560

553561
def addLocations(self, location):
554562
""" Add a location to a library.
@@ -570,7 +578,7 @@ def addLocations(self, location):
570578
if not self._server.isBrowsable(path):
571579
raise BadRequest('Path: %s does not exist.' % path)
572580
locations.append(path)
573-
self.edit(location=locations)
581+
return self.edit(location=locations)
574582

575583
def removeLocations(self, location):
576584
""" Remove a location from a library.
@@ -595,7 +603,7 @@ def removeLocations(self, location):
595603
raise BadRequest('Path: %s does not exist in the library.' % location)
596604
if len(locations) == 0:
597605
raise BadRequest('You are unable to remove all locations from a library.')
598-
self.edit(location=locations)
606+
return self.edit(location=locations)
599607

600608
def get(self, title):
601609
""" Returns the media item with the specified title.
@@ -718,7 +726,7 @@ def editAdvanced(self, **kwargs):
718726
else:
719727
raise NotFound('%s not found in %s' % (value, enums))
720728

721-
self.edit(**data)
729+
return self.edit(**data)
722730

723731
def defaultAdvanced(self):
724732
""" Edit all of library's advanced settings to default. """
@@ -730,7 +738,7 @@ def defaultAdvanced(self):
730738
else:
731739
data[key % setting.id] = setting.default
732740

733-
self.edit(**data)
741+
return self.edit(**data)
734742

735743
def _lockUnlockAllField(self, field, libtype=None, locked=True):
736744
""" Lock or unlock a field for all items in the library. """
@@ -741,6 +749,7 @@ def _lockUnlockAllField(self, field, libtype=None, locked=True):
741749
}
742750
key = '/library/sections/%s/all%s' % (self.key, utils.joinArgs(args))
743751
self._server.query(key, method=self._server._session.put)
752+
return self
744753

745754
def lockAllField(self, field, libtype=None):
746755
""" Lock a field for all items in the library.
@@ -750,7 +759,7 @@ def lockAllField(self, field, libtype=None):
750759
libtype (str, optional): The library type to lock (movie, show, season, episode,
751760
artist, album, track, photoalbum, photo). Default is the main library type.
752761
"""
753-
self._lockUnlockAllField(field, libtype=libtype, locked=True)
762+
return self._lockUnlockAllField(field, libtype=libtype, locked=True)
754763

755764
def unlockAllField(self, field, libtype=None):
756765
""" Unlock a field for all items in the library.
@@ -760,7 +769,7 @@ def unlockAllField(self, field, libtype=None):
760769
libtype (str, optional): The library type to lock (movie, show, season, episode,
761770
artist, album, track, photoalbum, photo). Default is the main library type.
762771
"""
763-
self._lockUnlockAllField(field, libtype=libtype, locked=False)
772+
return self._lockUnlockAllField(field, libtype=libtype, locked=False)
764773

765774
def timeline(self):
766775
""" Returns a timeline query for this library section. """
@@ -794,11 +803,13 @@ def analyze(self):
794803
"""
795804
key = '/library/sections/%s/analyze' % self.key
796805
self._server.query(key, method=self._server._session.put)
806+
return self
797807

798808
def emptyTrash(self):
799809
""" If a section has items in the Trash, use this option to empty the Trash. """
800810
key = '/library/sections/%s/emptyTrash' % self.key
801811
self._server.query(key, method=self._server._session.put)
812+
return self
802813

803814
def update(self, path=None):
804815
""" Scan this section for new media.
@@ -810,25 +821,29 @@ def update(self, path=None):
810821
if path is not None:
811822
key += '?path=%s' % quote_plus(path)
812823
self._server.query(key)
824+
return self
813825

814826
def cancelUpdate(self):
815827
""" Cancel update of this Library Section. """
816828
key = '/library/sections/%s/refresh' % self.key
817829
self._server.query(key, method=self._server._session.delete)
830+
return self
818831

819832
def refresh(self):
820833
""" Forces a download of fresh media information from the internet.
821834
This can take a long time. Any locked fields are not modified.
822835
"""
823836
key = '/library/sections/%s/refresh?force=1' % self.key
824837
self._server.query(key)
838+
return self
825839

826840
def deleteMediaPreviews(self):
827841
""" Delete the preview thumbnails for items in this library. This cannot
828842
be undone. Recreating media preview files can take hours or even days.
829843
"""
830844
key = '/library/sections/%s/indexes' % self.key
831845
self._server.query(key, method=self._server._session.delete)
846+
return self
832847

833848
def _loadFilters(self):
834849
""" Retrieves and caches the list of :class:`~plexapi.library.FilteringType` and

plexapi/media.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ def setDefaultAudioStream(self, stream):
196196
else:
197197
key = "/library/parts/%d?audioStreamID=%d&allParts=1" % (self.id, stream)
198198
self._server.query(key, method=self._server._session.put)
199+
return self
199200

200201
def setDefaultSubtitleStream(self, stream):
201202
""" Set the default :class:`~plexapi.media.SubtitleStream` for this MediaPart.
@@ -208,11 +209,13 @@ def setDefaultSubtitleStream(self, stream):
208209
else:
209210
key = "/library/parts/%d?subtitleStreamID=%d&allParts=1" % (self.id, stream)
210211
self._server.query(key, method=self._server._session.put)
212+
return self
211213

212214
def resetDefaultSubtitleStream(self):
213215
""" Set default subtitle of this MediaPart to 'none'. """
214216
key = "/library/parts/%d?subtitleStreamID=0&allParts=1" % (self.id)
215217
self._server.query(key, method=self._server._session.put)
218+
return self
216219

217220

218221
class MediaPartStream(PlexObject):

plexapi/mixins.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def editAdvanced(self, **kwargs):
4949
raise NotFound('%s not found in %s' % (value, list(enumValues)))
5050
url = key + urlencode(data)
5151
self._server.query(url, method=self._server._session.put)
52+
return self
5253

5354
def defaultAdvanced(self):
5455
""" Edit all of a Plex object's advanced settings to default. """
@@ -58,6 +59,7 @@ def defaultAdvanced(self):
5859
data[preference.id] = preference.default
5960
url = key + urlencode(data)
6061
self._server.query(url, method=self._server._session.put)
62+
return self
6163

6264

6365
class SmartFilterMixin:
@@ -126,7 +128,8 @@ class SplitMergeMixin:
126128
def split(self):
127129
""" Split duplicated Plex object into separate objects. """
128130
key = f'{self.key}/split'
129-
return self._server.query(key, method=self._server._session.put)
131+
self._server.query(key, method=self._server._session.put)
132+
return self
130133

131134
def merge(self, ratingKeys):
132135
""" Merge other Plex objects into the current object.
@@ -138,7 +141,8 @@ def merge(self, ratingKeys):
138141
ratingKeys = str(ratingKeys).split(',')
139142

140143
key = '%s/merge?ids=%s' % (self.key, ','.join([str(r) for r in ratingKeys]))
141-
return self._server.query(key, method=self._server._session.put)
144+
self._server.query(key, method=self._server._session.put)
145+
return self
142146

143147

144148
class UnmatchMatchMixin:
@@ -232,6 +236,7 @@ def fixMatch(self, searchResult=None, auto=False, agent=None):
232236

233237
data = key + '?' + urlencode(params)
234238
self._server.query(data, method=self._server._session.put)
239+
return self
235240

236241

237242
class ExtrasMixin:
@@ -312,6 +317,7 @@ def rate(self, rating=None):
312317
raise BadRequest('Rating must be between 0 to 10.')
313318
key = '/:/rate?key=%s&identifier=com.plexapp.plugins.library&rating=%s' % (self.ratingKey, rating)
314319
self._server.query(key, method=self._server._session.put)
320+
return self
315321

316322

317323
class ArtUrlMixin:
@@ -345,6 +351,7 @@ def uploadArt(self, url=None, filepath=None):
345351
key = f'/library/metadata/{self.ratingKey}/arts'
346352
data = open(filepath, 'rb').read()
347353
self._server.query(key, method=self._server._session.post, data=data)
354+
return self
348355

349356
def setArt(self, art):
350357
""" Set the background artwork for a Plex object.
@@ -353,6 +360,7 @@ def setArt(self, art):
353360
art (:class:`~plexapi.media.Art`): The art object to select.
354361
"""
355362
art.select()
363+
return self
356364

357365
def lockArt(self):
358366
""" Lock the background artwork for a Plex object. """
@@ -394,6 +402,7 @@ def uploadBanner(self, url=None, filepath=None):
394402
key = f'/library/metadata/{self.ratingKey}/banners'
395403
data = open(filepath, 'rb').read()
396404
self._server.query(key, method=self._server._session.post, data=data)
405+
return self
397406

398407
def setBanner(self, banner):
399408
""" Set the banner for a Plex object.
@@ -402,6 +411,7 @@ def setBanner(self, banner):
402411
banner (:class:`~plexapi.media.Banner`): The banner object to select.
403412
"""
404413
banner.select()
414+
return self
405415

406416
def lockBanner(self):
407417
""" Lock the banner for a Plex object. """
@@ -448,6 +458,7 @@ def uploadPoster(self, url=None, filepath=None):
448458
key = f'/library/metadata/{self.ratingKey}/posters'
449459
data = open(filepath, 'rb').read()
450460
self._server.query(key, method=self._server._session.post, data=data)
461+
return self
451462

452463
def setPoster(self, poster):
453464
""" Set the poster for a Plex object.
@@ -456,6 +467,7 @@ def setPoster(self, poster):
456467
poster (:class:`~plexapi.media.Poster`): The poster object to select.
457468
"""
458469
poster.select()
470+
return self
459471

460472
def lockPoster(self):
461473
""" Lock the poster for a Plex object. """
@@ -499,6 +511,7 @@ def uploadTheme(self, url=None, filepath=None):
499511
key = f'/library/metadata/{self.ratingKey}/themes'
500512
data = open(filepath, 'rb').read()
501513
self._server.query(key, method=self._server._session.post, data=data)
514+
return self
502515

503516
def setTheme(self, theme):
504517
raise NotImplementedError(
@@ -508,11 +521,11 @@ def setTheme(self, theme):
508521

509522
def lockTheme(self):
510523
""" Lock the theme for a Plex object. """
511-
self._edit(**{'theme.locked': 1})
524+
return self._edit(**{'theme.locked': 1})
512525

513526
def unlockTheme(self):
514527
""" Unlock the theme for a Plex object. """
515-
self._edit(**{'theme.locked': 0})
528+
return self._edit(**{'theme.locked': 0})
516529

517530

518531
class EditFieldMixin:
@@ -1056,6 +1069,7 @@ def addToWatchlist(self, account=None):
10561069
except AttributeError:
10571070
account = self._server
10581071
account.addToWatchlist(self)
1072+
return self
10591073

10601074
def removeFromWatchlist(self, account=None):
10611075
""" Remove this item from the specified user's watchlist.
@@ -1070,6 +1084,7 @@ def removeFromWatchlist(self, account=None):
10701084
except AttributeError:
10711085
account = self._server
10721086
account.removeFromWatchlist(self)
1087+
return self
10731088

10741089
def streamingServices(self, account=None):
10751090
""" Return a list of :class:`~plexapi.media.Availability`

plexapi/myplex.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,7 @@ def addToWatchlist(self, items):
832832
raise BadRequest('"%s" is already on the watchlist' % item.title)
833833
ratingKey = item.guid.rsplit('/', 1)[-1]
834834
self.query(f'{self.METADATA}/actions/addToWatchlist?ratingKey={ratingKey}', method=self._session.put)
835+
return self
835836

836837
def removeFromWatchlist(self, items):
837838
""" Remove media items from the user's watchlist
@@ -852,6 +853,7 @@ def removeFromWatchlist(self, items):
852853
raise BadRequest('"%s" is not on the watchlist' % item.title)
853854
ratingKey = item.guid.rsplit('/', 1)[-1]
854855
self.query(f'{self.METADATA}/actions/removeFromWatchlist?ratingKey={ratingKey}', method=self._session.put)
856+
return self
855857

856858
def userState(self, item):
857859
""" Returns a :class:`~plexapi.myplex.UserState` object for the specified item.

0 commit comments

Comments
 (0)