Skip to content

Commit

Permalink
Use cached_property decorator (#1065)
Browse files Browse the repository at this point in the history
* Use @cached_property in PlexSession.user

* Use @cached_property in PlexServer.library

* Use @cached_property in PlexServer.settings

* Tests: Update clearing plex.settings cache

* Use @cached_property in LibrarySection.totalSize

* Add backports.cached-property==1.0.2; python_version<="3.7" dependency

* Import cached_property from dist or backports

* Add backports.cached-property to requirements_dev.txt

* Remove version pin for backports.cached-property in requirements.txt

Co-authored-by: JonnyWong16 <[email protected]>

Co-authored-by: JonnyWong16 <[email protected]>
  • Loading branch information
glensc and JonnyWong16 authored Dec 21, 2022
1 parent ac41fbf commit 7580fc8
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 37 deletions.
16 changes: 7 additions & 9 deletions plexapi/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from plexapi import log, utils
from plexapi.exceptions import BadRequest, NotFound, UnknownType, Unsupported
from plexapi.utils import cached_property

USER_DONT_RELOAD_FOR_KEYS = set()
_DONT_RELOAD_FOR_KEYS = {'key'}
Expand Down Expand Up @@ -848,26 +849,23 @@ def _loadData(self, data):
user = data.find('User')
self._username = user.attrib.get('title')
self._userId = utils.cast(int, user.attrib.get('id'))
self._user = None # Cache for user object

# For backwards compatibility
self.players = [self.player] if self.player else []
self.sessions = [self.session] if self.session else []
self.transcodeSessions = [self.transcodeSession] if self.transcodeSession else []
self.usernames = [self._username] if self._username else []

@property
@cached_property
def user(self):
""" Returns the :class:`~plexapi.myplex.MyPlexAccount` object (for admin)
or :class:`~plexapi.myplex.MyPlexUser` object (for users) for this session.
"""
if self._user is None:
myPlexAccount = self._server.myPlexAccount()
if self._userId == 1:
self._user = myPlexAccount
else:
self._user = myPlexAccount.user(self._username)
return self._user
myPlexAccount = self._server.myPlexAccount()
if self._userId == 1:
return myPlexAccount

return myPlexAccount.user(self._username)

def reload(self):
""" Reload the data for the session.
Expand Down
9 changes: 3 additions & 6 deletions plexapi/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from plexapi.base import OPERATORS, PlexObject
from plexapi.exceptions import BadRequest, NotFound
from plexapi.settings import Setting
from plexapi.utils import deprecated
from plexapi.utils import cached_property, deprecated


class Library(PlexObject):
Expand Down Expand Up @@ -418,7 +418,6 @@ def _loadData(self, data):
self._filterTypes = None
self._fieldTypes = None
self._totalViewSize = None
self._totalSize = None
self._totalDuration = None
self._totalStorage = None

Expand Down Expand Up @@ -456,12 +455,10 @@ def fetchItems(self, ekey, cls=None, container_start=None, container_size=None,
item.librarySectionID = librarySectionID
return items

@property
@cached_property
def totalSize(self):
""" Returns the total number of items in the library for the default library type. """
if self._totalSize is None:
self._totalSize = self.totalViewSize(includeCollections=False)
return self._totalSize
return self.totalViewSize(includeCollections=False)

@property
def totalDuration(self):
Expand Down
33 changes: 13 additions & 20 deletions plexapi/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from plexapi.playlist import Playlist
from plexapi.playqueue import PlayQueue
from plexapi.settings import Settings
from plexapi.utils import deprecated
from plexapi.utils import cached_property, deprecated
from requests.status_codes import _codes as codes

# Need these imports to populate utils.PLEXOBJECTS
Expand Down Expand Up @@ -109,8 +109,6 @@ def __init__(self, baseurl=None, token=None, session=None, timeout=None):
self._showSecrets = CONFIG.get('log.show_secrets', '').lower() == 'true'
self._session = session or requests.Session()
self._timeout = timeout
self._library = None # cached library
self._settings = None # cached settings
self._myPlexAccount = None # cached myPlexAccount
self._systemAccounts = None # cached list of SystemAccount
self._systemDevices = None # cached list of SystemDevice
Expand Down Expand Up @@ -173,27 +171,22 @@ def _headers(self, **kwargs):
def _uriRoot(self):
return f'server://{self.machineIdentifier}/com.plexapp.plugins.library'

@property
@cached_property
def library(self):
""" Library to browse or search your media. """
if not self._library:
try:
data = self.query(Library.key)
self._library = Library(self, data)
except BadRequest:
data = self.query('/library/sections/')
# Only the owner has access to /library
# so just return the library without the data.
return Library(self, data)
return self._library

@property
try:
data = self.query(Library.key)
except BadRequest:
# Only the owner has access to /library
# so just return the library without the data.
data = self.query('/library/sections/')
return Library(self, data)

@cached_property
def settings(self):
""" Returns a list of all server settings. """
if not self._settings:
data = self.query(Settings.key)
self._settings = Settings(self, data)
return self._settings
data = self.query(Settings.key)
return Settings(self, data)

def account(self):
""" Returns the :class:`~plexapi.server.Account` object this server belongs to. """
Expand Down
5 changes: 5 additions & 0 deletions plexapi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
except ImportError:
tqdm = None

try:
from functools import cached_property
except ImportError:
from backports.cached_property import cached_property # noqa: F401

log = logging.getLogger('plexapi')

# Search Types - Plex uses these to filter specific media types when searching.
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
# pip install -r requirements.txt
#---------------------------------------------------------
requests
backports.cached-property; python_version<="3.7"
1 change: 1 addition & 0 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# PlexAPI requirements to run py.test.
# pip install -r requirements_dev.txt
#---------------------------------------------------------
backports.cached-property==1.0.2; python_version<="3.7"
coveralls==3.3.1
flake8==5.0.4
pillow==9.3.0
Expand Down
4 changes: 2 additions & 2 deletions tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_settings_set(plex):
new_value = not old_value
cd.set(new_value)
plex.settings.save()
plex._settings = None
del plex.__dict__['settings']
assert plex.settings.get("autoEmptyTrash").value == new_value


Expand All @@ -22,5 +22,5 @@ def test_settings_set_str(plex):
new_value = 99
cd.set(new_value)
plex.settings.save()
plex._settings = None
del plex.__dict__['settings']
assert plex.settings.get("OnDeckWindow").value == 99

0 comments on commit 7580fc8

Please sign in to comment.