Merge pull request #619 from JonnyWong16/feature/object_parent

Add method to keep track of the parent PlexObject as children are built
This commit is contained in:
Steffen Fredriksen 2020-12-14 00:44:18 +01:00 committed by GitHub
commit b3f69010a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import re import re
import weakref
from urllib.parse import quote_plus, urlencode from urllib.parse import quote_plus, urlencode
from plexapi import log, utils from plexapi import log, utils
@ -35,15 +36,17 @@ class PlexObject(object):
server (:class:`~plexapi.server.PlexServer`): PlexServer this client is connected to (optional) server (:class:`~plexapi.server.PlexServer`): PlexServer this client is connected to (optional)
data (ElementTree): Response from PlexServer used to build this object (optional). data (ElementTree): Response from PlexServer used to build this object (optional).
initpath (str): Relative path requested when retrieving specified `data` (optional). initpath (str): Relative path requested when retrieving specified `data` (optional).
parent (:class:`~plexapi.base.PlexObject`): The parent object that this object is built from (optional).
""" """
TAG = None # xml element tag TAG = None # xml element tag
TYPE = None # xml element type TYPE = None # xml element type
key = None # plex relative url key = None # plex relative url
def __init__(self, server, data, initpath=None): def __init__(self, server, data, initpath=None, parent=None):
self._server = server self._server = server
self._data = data self._data = data
self._initpath = initpath or self.key self._initpath = initpath or self.key
self._parent = weakref.ref(parent) if parent else None
if data is not None: if data is not None:
self._loadData(data) self._loadData(data)
self._details_key = self._buildDetailsKey() self._details_key = self._buildDetailsKey()
@ -70,7 +73,7 @@ class PlexObject(object):
# cls is specified, build the object and return # cls is specified, build the object and return
initpath = initpath or self._initpath initpath = initpath or self._initpath
if cls is not None: if cls is not None:
return cls(self._server, elem, initpath) return cls(self._server, elem, initpath, parent=self)
# cls is not specified, try looking it up in PLEXOBJECTS # cls is not specified, try looking it up in PLEXOBJECTS
etype = elem.attrib.get('type', elem.attrib.get('streamType')) etype = elem.attrib.get('type', elem.attrib.get('streamType'))
ehash = '%s.%s' % (elem.tag, etype) if etype else elem.tag ehash = '%s.%s' % (elem.tag, etype) if etype else elem.tag
@ -105,6 +108,18 @@ class PlexObject(object):
details_key += '?' + urlencode(sorted(includes.items())) details_key += '?' + urlencode(sorted(includes.items()))
return details_key return details_key
def _isChildOf(self, cls):
""" Returns True if this object is a child of the given class.
Parameters:
cls: The parent :class:`~plexapi.base.PlexObject` to search for.
"""
obj = self
while obj._parent is not None:
if isinstance(obj._parent(), cls):
return True
obj = obj._parent()
def fetchItem(self, ekey, cls=None, **kwargs): def fetchItem(self, ekey, cls=None, **kwargs):
""" Load the specified key to find and build the first item with the """ Load the specified key to find and build the first item with the
specified tag and attrs. If no tag or attrs are specified then specified tag and attrs. If no tag or attrs are specified then