def clients(self): """ Returns list of all :class:`~plexapi.client.PlexClient` objects connected to server. """ items = [] ports = None for elem in self.query('/clients'): port = elem.attrib.get('port') if not port: log.warn('%s did not advertise a port, checking plex.tv.', elem.attrib.get('name')) ports = self._myPlexClientPorts() if ports is None else ports port = ports.get(elem.attrib.get('machineIdentifier')) baseurl = 'http://%s:%s' % (elem.attrib['host'], port) items.append(PlexClient(baseurl=baseurl, server=self, data=elem, connect=False)) return items
def __getattribute__(self, attr): # Dragons inside.. :-/ value = utils.getattributeOrNone(PlexPartialObject, self, attr) # Check a few cases where we dont want to reload if attr == 'key' or attr.startswith('_'): return value if value not in (None, []): return value if self.isFullObject(): return value # Log warning that were reloading the object clsname = self.__class__.__name__ title = self.__dict__.get('title', self.__dict__.get('name')) objname = "%s '%s'" % (clsname, title) if title else clsname log.warn("Reloading %s for attr '%s'" % (objname, attr)) # Reload and return the value self.reload() return utils.getattributeOrNone(PlexPartialObject, self, attr)
def query(self, url, method=None, headers=None, **kwargs): method = method or self._session.get delim = '&' if '?' in url else '?' url = '%s%sX-Plex-Token=%s' % (url, delim, self._token) log.debug('%s %s', method.__name__.upper(), url) allheaders = BASE_HEADERS.copy() allheaders.update(headers or {}) response = method(url, headers=allheaders, timeout=TIMEOUT, **kwargs) if response.status_code not in (200, 201): codename = codes.get(response.status_code)[0] log.warn('BadRequest (%s) %s %s' % (response.status_code, codename, response.url)) raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data.strip() else None
def _myPlexClientPorts(self): """ Sometimes the PlexServer does not properly advertise port numbers required to connect. This attemps to look up device port number from plex.tv. See issue #126: Make PlexServer.clients() more user friendly. https://github.com/pkkid/python-plexapi/issues/126 """ try: ports = {} account = self.myPlexAccount() for device in account.devices(): if device.connections and ':' in device.connections[0][6:]: ports[device.clientIdentifier] = device.connections[0].split(':')[-1] return ports except Exception as err: log.warn('Unable to fetch client ports from myPlex: %s', err) return ports
def query(self, path, method=None, headers=None, timeout=None, **kwargs): """ Main method used to handle HTTPS requests to the Plex client. This method helps by encoding the response to utf-8 and parsing the returned XML into and ElementTree object. Returns None if no data exists in the response. """ url = self.url(path) method = method or self._session.get timeout = timeout or TIMEOUT log.debug('%s %s', method.__name__.upper(), url) headers = self._headers(**headers or {}) response = method(url, headers=headers, timeout=timeout, **kwargs) if response.status_code not in (200, 201): codename = codes.get(response.status_code)[0] log.warn('BadRequest (%s) %s %s' % (response.status_code, codename, response.url)) raise BadRequest('(%s) %s' % (response.status_code, codename)) data = response.text.encode('utf8') return ElementTree.fromstring(data) if data.strip() else None
def client(self, name): """ Returns the :class:`~plexapi.client.PlexClient` that matches the specified name. Parameters: name (str): Name of the client to return. Raises: :class:`~plexapi.exceptions.NotFound`: Unknown client name """ for elem in self.query('/clients'): if elem.attrib.get('name').lower() == name.lower(): port = elem.attrib.get('port') if not port: log.warn('%s did not advertise a port, checking plex.tv.', elem.attrib.get('name')) ports = self._myPlexClientPorts() port = ports.get(elem.attrib.get('machineIdentifier')) baseurl = 'http://%s:%s' % (elem.attrib['host'], port) return PlexClient(baseurl=baseurl, server=self, data=elem) raise NotFound('Unknown client name: %s' % name)