Ability to get a MyPlexAccount object from the plexServer object A(using same token). Review code to lookup port if not available on the client listing (fixed a few bugs in it).

This commit is contained in:
Michael Shepanski 2017-05-18 23:04:57 -04:00
parent 1315f4f3c3
commit a79bc44b7a
3 changed files with 42 additions and 20 deletions

View file

@ -55,8 +55,8 @@ class PlexClient(PlexObject):
TAG = 'Player' TAG = 'Player'
key = '/resources' key = '/resources'
def __init__(self, server=None, data=None, initpath=None, baseurl=None, token=None, def __init__(self, server=None, data=None, initpath=None, baseurl=None,
connect=True, session=None, timeout=None): token=None, connect=True, session=None, timeout=None):
super(PlexClient, self).__init__(server, data, initpath) super(PlexClient, self).__init__(server, data, initpath)
self._baseurl = baseurl.strip('/') if baseurl else None self._baseurl = baseurl.strip('/') if baseurl else None
self._token = logfilter.add_secret(token) self._token = logfilter.add_secret(token)

View file

@ -59,13 +59,19 @@ class MyPlexAccount(PlexObject):
WEBHOOKS = 'https://plex.tv/api/v2/user/webhooks' WEBHOOKS = 'https://plex.tv/api/v2/user/webhooks'
key = 'https://plex.tv/users/account' key = 'https://plex.tv/users/account'
def __init__(self, username=None, password=None, session=None, timeout=None): def __init__(self, username=None, password=None, token=None, session=None, timeout=None):
self._token = token
self._session = session or requests.Session() self._session = session or requests.Session()
self._token = None data, initpath = self._signin(username, password, timeout)
super(MyPlexAccount, self).__init__(self, data, initpath)
def _signin(self, username, password, timeout):
if self._token:
return self.query(self.key), self.key
username = username or CONFIG.get('auth.myplex_username') username = username or CONFIG.get('auth.myplex_username')
password = password or CONFIG.get('auth.myplex_password') password = password or CONFIG.get('auth.myplex_password')
data = self.query(self.SIGNIN, method=self._session.post, auth=(username, password), timeout=timeout) data = self.query(self.SIGNIN, method=self._session.post, auth=(username, password), timeout=timeout)
super(MyPlexAccount, self).__init__(self, data, self.SIGNIN) return data, self.SIGNIN
def _loadData(self, data): def _loadData(self, data):
""" Load attribute values from Plex XML response. """ """ Load attribute values from Plex XML response. """

View file

@ -174,25 +174,36 @@ class PlexServer(PlexObject):
data = self.query(Account.key) data = self.query(Account.key)
return Account(self, data) return Account(self, data)
def myPlexAccount(self):
""" Returns a :class:`~plexapi.myplex.MyPlexAccount` object using the same
token to access this server. If you are not the owner of this PlexServer
you're likley to recieve an authentication error calling this.
"""
from plexapi.myplex import MyPlexAccount
return MyPlexAccount(token=self._token)
def _myPlexClientPorts(self):
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 clients(self): def clients(self):
""" Returns list of all :class:`~plexapi.client.PlexClient` objects connected to server. """ """ Returns list of all :class:`~plexapi.client.PlexClient` objects connected to server. """
items = [] items = []
cache_resource = None ports = None
from plexapi.myplex import MyPlexResource
for elem in self.query('/clients'): for elem in self.query('/clients'):
# Some shitty clients dont include a port..
port = elem.attrib.get('port') port = elem.attrib.get('port')
if port is None: if not port:
log.debug("%s didn't provide a port. Checking https://plex.tv/devices.xml" % elem.attrib.get('name')) log.warn('%s did not advertise a port, checking plex.tv.', elem.attrib.get('name'))
data = cache_resource or self._server._session.get('https://plex.tv/devices.xml?X-Plex-Token=%s' % self.token) # noqa ports = self._myPlexClientPorts() if ports is None else ports
cache_resource = data port = ports.get(elem.attrib.get('machineIdentifier'))
resources = MyPlexResource(self, data)
for resource in resources:
if resource.clientIdentifier == elem.attrib.get('machineIdentifier'):
for conn in resource.connection:
if conn.local is True:
port = conn.port
break
baseurl = 'http://%s:%s' % (elem.attrib['host'], port) baseurl = 'http://%s:%s' % (elem.attrib['host'], port)
items.append(PlexClient(baseurl=baseurl, server=self, data=elem, connect=False)) items.append(PlexClient(baseurl=baseurl, server=self, data=elem, connect=False))
return items return items
@ -208,7 +219,12 @@ class PlexServer(PlexObject):
""" """
for elem in self.query('/clients'): for elem in self.query('/clients'):
if elem.attrib.get('name').lower() == name.lower(): if elem.attrib.get('name').lower() == name.lower():
baseurl = 'http://%s:%s' % (elem.attrib['host'], elem.attrib['port']) 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) return PlexClient(baseurl=baseurl, server=self, data=elem)
raise NotFound('Unknown client name: %s' % name) raise NotFound('Unknown client name: %s' % name)