Skip to content

Commit a8136d2

Browse files
authored
Change LibrarySection.reload() to reload in-place (#855)
* Fix LibrarySection reload in-place to mimic PlexObject reload * Don't reload LibrarySection after edit * Also mimics PlexObject.edit() * Update library section edit test
1 parent 8815cda commit a8136d2

File tree

2 files changed

+47
-29
lines changed

2 files changed

+47
-29
lines changed

plexapi/library.py

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,47 +26,61 @@ class Library(PlexObject):
2626

2727
def _loadData(self, data):
2828
self._data = data
29-
self._sectionsByID = {} # cached Section UUIDs
3029
self.identifier = data.attrib.get('identifier')
3130
self.mediaTagVersion = data.attrib.get('mediaTagVersion')
3231
self.title1 = data.attrib.get('title1')
3332
self.title2 = data.attrib.get('title2')
33+
self._sectionsByID = {} # cached sections by key
34+
self._sectionsByTitle = {} # cached sections by title
3435

35-
def sections(self):
36-
""" Returns a list of all media sections in this library. Library sections may be any of
37-
:class:`~plexapi.library.MovieSection`, :class:`~plexapi.library.ShowSection`,
38-
:class:`~plexapi.library.MusicSection`, :class:`~plexapi.library.PhotoSection`.
39-
"""
36+
def _loadSections(self):
37+
""" Loads and caches all the library sections. """
4038
key = '/library/sections'
41-
sections = []
39+
self._sectionsByID = {}
40+
self._sectionsByTitle = {}
4241
for elem in self._server.query(key):
4342
for cls in (MovieSection, ShowSection, MusicSection, PhotoSection):
4443
if elem.attrib.get('type') == cls.TYPE:
4544
section = cls(self._server, elem, key)
4645
self._sectionsByID[section.key] = section
47-
sections.append(section)
48-
return sections
46+
self._sectionsByTitle[section.title.lower()] = section
47+
48+
def sections(self):
49+
""" Returns a list of all media sections in this library. Library sections may be any of
50+
:class:`~plexapi.library.MovieSection`, :class:`~plexapi.library.ShowSection`,
51+
:class:`~plexapi.library.MusicSection`, :class:`~plexapi.library.PhotoSection`.
52+
"""
53+
self._loadSections()
54+
return list(self._sectionsByID.values())
4955

50-
def section(self, title=None):
56+
def section(self, title):
5157
""" Returns the :class:`~plexapi.library.LibrarySection` that matches the specified title.
5258
5359
Parameters:
5460
title (str): Title of the section to return.
5561
"""
56-
for section in self.sections():
57-
if section.title.lower() == title.lower():
58-
return section
59-
raise NotFound('Invalid library section: %s' % title)
62+
if not self._sectionsByTitle or title not in self._sectionsByTitle:
63+
self._loadSections()
64+
try:
65+
return self._sectionsByTitle[title.lower()]
66+
except KeyError:
67+
raise NotFound('Invalid library section: %s' % title) from None
6068

6169
def sectionByID(self, sectionID):
6270
""" Returns the :class:`~plexapi.library.LibrarySection` that matches the specified sectionID.
6371
6472
Parameters:
6573
sectionID (int): ID of the section to return.
74+
75+
Raises:
76+
:exc:`~plexapi.exceptions.NotFound`: The library section ID is not found on the server.
6677
"""
6778
if not self._sectionsByID or sectionID not in self._sectionsByID:
68-
self.sections()
69-
return self._sectionsByID[sectionID]
79+
self._loadSections()
80+
try:
81+
return self._sectionsByID[sectionID]
82+
except KeyError:
83+
raise NotFound('Invalid library sectionID: %s' % sectionID) from None
7084

7185
def all(self, **kwargs):
7286
""" Returns a list of all media from all library sections.
@@ -464,8 +478,12 @@ def delete(self):
464478
log.error(msg)
465479
raise
466480

467-
def reload(self, key=None):
468-
return self._server.library.section(self.title)
481+
def reload(self):
482+
""" Reload the data for the library section. """
483+
self._server.library._loadSections()
484+
newLibrary = self._server.library.sectionByID(self.key)
485+
self.__dict__.update(newLibrary.__dict__)
486+
return self
469487

470488
def edit(self, agent=None, **kwargs):
471489
""" Edit a library (Note: agent is required). See :class:`~plexapi.library.Library` for example usage.
@@ -478,11 +496,6 @@ def edit(self, agent=None, **kwargs):
478496
part = '/library/sections/%s?agent=%s&%s' % (self.key, agent, urlencode(kwargs))
479497
self._server.query(part, method=self._server._session.put)
480498

481-
# Reload this way since the self.key dont have a full path, but is simply a id.
482-
for s in self._server.library.sections():
483-
if s.key == self.key:
484-
return s
485-
486499
def get(self, title):
487500
""" Returns the media item with the specified title.
488501

tests/test_library.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ def test_library_Library_section(plex):
1717
assert section_name.title == "TV Shows"
1818
with pytest.raises(NotFound):
1919
assert plex.library.section("cant-find-me")
20+
with pytest.raises(NotFound):
21+
assert plex.library.sectionByID(-1)
2022

2123

2224
def test_library_Library_sectionByID_is_equal_section(plex, movies):
@@ -129,12 +131,16 @@ def test_library_add_edit_delete(plex):
129131
scanner="Plex Movie Scanner",
130132
language="en",
131133
)
132-
assert plex.library.section(section_name)
133-
edited_library = plex.library.section(section_name).edit(
134-
name="a renamed lib", type="movie", agent="com.plexapp.agents.imdb"
134+
section = plex.library.section(section_name)
135+
assert section.title == section_name
136+
new_title = "a renamed lib"
137+
section.edit(
138+
name=new_title, type="movie", agent="com.plexapp.agents.imdb"
135139
)
136-
assert edited_library.title == "a renamed lib"
137-
plex.library.section("a renamed lib").delete()
140+
section.reload()
141+
assert section.title == new_title
142+
section.delete()
143+
assert section not in plex.library.sections()
138144

139145

140146
def test_library_Library_cleanBundle(plex):
@@ -372,7 +378,6 @@ def test_library_editAdvanced_default(movies):
372378
if setting.id == "collectionMode":
373379
assert int(setting.value) == 0
374380

375-
movies.reload()
376381
movies.defaultAdvanced()
377382
for setting in movies.settings():
378383
assert str(setting.value) == str(setting.default)

0 commit comments

Comments
 (0)