mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-22 03:33:08 +00:00
* Make test Plex Pass entitlements a subset * Fix create MyPlexDevice race condition * Rename to clientId to be consistent * Move link method to MyPlexAccount
This commit is contained in:
parent
5102201969
commit
9d23ec072e
4 changed files with 27 additions and 38 deletions
|
@ -76,6 +76,7 @@ class MyPlexAccount(PlexObject):
|
|||
REQUESTS = 'https://plex.tv/api/invites/requests' # get
|
||||
SIGNIN = 'https://plex.tv/users/sign_in.xml' # get with auth
|
||||
WEBHOOKS = 'https://plex.tv/api/v2/user/webhooks' # get, post with data
|
||||
LINK = 'https://plex.tv/api/v2/pins/link' # put
|
||||
# Hub sections
|
||||
VOD = 'https://vod.provider.plex.tv/' # get
|
||||
WEBSHOWS = 'https://webshows.provider.plex.tv/' # get
|
||||
|
@ -153,15 +154,15 @@ class MyPlexAccount(PlexObject):
|
|||
self.services = None
|
||||
self.joined_at = None
|
||||
|
||||
def device(self, name=None, clientIdentifier=None):
|
||||
def device(self, name=None, clientId=None):
|
||||
""" Returns the :class:`~plexapi.myplex.MyPlexDevice` that matches the name specified.
|
||||
|
||||
Parameters:
|
||||
name (str): Name to match against.
|
||||
clientIdentifier (str): clientIdentifier to match against.
|
||||
clientId (str): clientIdentifier to match against.
|
||||
"""
|
||||
for device in self.devices():
|
||||
if (name and device.name.lower() == name.lower() or device.clientIdentifier == clientIdentifier):
|
||||
if (name and device.name.lower() == name.lower() or device.clientIdentifier == clientId):
|
||||
return device
|
||||
raise NotFound('Unable to find device %s' % name)
|
||||
|
||||
|
@ -684,6 +685,19 @@ class MyPlexAccount(PlexObject):
|
|||
elem = ElementTree.fromstring(req.text)
|
||||
return self.findItems(elem)
|
||||
|
||||
def link(self, pin):
|
||||
""" Link a device to the account using a pin code.
|
||||
|
||||
Parameters:
|
||||
pin (str): The 4 digit link pin code.
|
||||
"""
|
||||
headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'X-Plex-Product': 'Plex SSO'
|
||||
}
|
||||
data = {'code': pin}
|
||||
self.query(self.LINK, self._session.put, headers=headers, data=data)
|
||||
|
||||
|
||||
class MyPlexUser(PlexObject):
|
||||
""" This object represents non-signed in users such as friends and linked
|
||||
|
@ -1110,7 +1124,6 @@ class MyPlexPinLogin(object):
|
|||
"""
|
||||
PINS = 'https://plex.tv/api/v2/pins' # get
|
||||
CHECKPINS = 'https://plex.tv/api/v2/pins/{pinid}' # get
|
||||
LINK = 'https://plex.tv/api/v2/pins/link' # put
|
||||
POLLINTERVAL = 1
|
||||
|
||||
def __init__(self, session=None, requestTimeout=None, headers=None):
|
||||
|
@ -1125,6 +1138,7 @@ class MyPlexPinLogin(object):
|
|||
self._abort = False
|
||||
self._id = None
|
||||
self._code = None
|
||||
self._getCode()
|
||||
|
||||
self.finished = False
|
||||
self.expired = False
|
||||
|
@ -1132,10 +1146,6 @@ class MyPlexPinLogin(object):
|
|||
|
||||
@property
|
||||
def pin(self):
|
||||
if self._code:
|
||||
return self._code
|
||||
|
||||
self._getCode()
|
||||
return self._code
|
||||
|
||||
def run(self, callback=None, timeout=None):
|
||||
|
@ -1199,24 +1209,6 @@ class MyPlexPinLogin(object):
|
|||
|
||||
return False
|
||||
|
||||
def link(self, code=None, token=None):
|
||||
if code is None:
|
||||
code = self.pin
|
||||
|
||||
url = self.LINK
|
||||
headers = BASE_HEADERS.copy()
|
||||
headers.update({
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'X-Plex-Product': 'Plex SSO',
|
||||
})
|
||||
|
||||
token = token or CONFIG.get('auth.server_token')
|
||||
if token:
|
||||
headers['X-Plex-Token'] = token
|
||||
|
||||
data = {'code': code}
|
||||
self._query(url, self._session.put, headers=headers, data=data)
|
||||
|
||||
def _getCode(self):
|
||||
url = self.PINS
|
||||
response = self._query(url, self._session.post)
|
||||
|
@ -1229,9 +1221,6 @@ class MyPlexPinLogin(object):
|
|||
return self._code
|
||||
|
||||
def _checkLogin(self):
|
||||
if not self._code:
|
||||
self._getCode()
|
||||
|
||||
if not self._id:
|
||||
return False
|
||||
|
||||
|
|
|
@ -382,12 +382,13 @@ def getMyPlexAccount(opts=None): # pragma: no cover
|
|||
return MyPlexAccount(username, password)
|
||||
|
||||
|
||||
def createMyPlexDevice(headers, timeout=None): # pragma: no cover
|
||||
def createMyPlexDevice(headers, account, timeout=10): # pragma: no cover
|
||||
""" Helper function to create a new MyPlexDevice.
|
||||
|
||||
Parameters:
|
||||
headers (dict): Provide the X-Plex- headers for the new device.
|
||||
A unique X-Plex-Client-Identifier is required.
|
||||
account (MyPlexAccount): The Plex account to create the device on.
|
||||
timeout (int): Timeout in seconds to wait for device login.
|
||||
"""
|
||||
from plexapi.myplex import MyPlexPinLogin
|
||||
|
@ -399,12 +400,10 @@ def createMyPlexDevice(headers, timeout=None): # pragma: no cover
|
|||
|
||||
pinlogin = MyPlexPinLogin(headers=headers)
|
||||
pinlogin.run(timeout=timeout)
|
||||
pinlogin.link()
|
||||
account.link(pinlogin.pin)
|
||||
pinlogin.waitForLogin()
|
||||
|
||||
account = getMyPlexAccount()
|
||||
device = account.device(clientIdentifier=clientIdentifier)
|
||||
return device
|
||||
return account.device(clientId=clientIdentifier)
|
||||
|
||||
|
||||
def choose(msg, items, attr): # pragma: no cover
|
||||
|
|
|
@ -160,14 +160,15 @@ def plex(request):
|
|||
return PlexServer(SERVER_BASEURL, token, session=session)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@pytest.fixture(scope="session")
|
||||
def sync_device(account_synctarget):
|
||||
try:
|
||||
device = account_synctarget.device(clientIdentifier=SYNC_DEVICE_IDENTIFIER)
|
||||
device = account_synctarget.device(clientId=SYNC_DEVICE_IDENTIFIER)
|
||||
except NotFound:
|
||||
device = createMyPlexDevice(SYNC_DEVICE_HEADERS, timeout=10)
|
||||
device = createMyPlexDevice(SYNC_DEVICE_HEADERS, account_synctarget)
|
||||
|
||||
assert device
|
||||
assert "sync-target" in device.provides
|
||||
return device
|
||||
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ def test_myplex_plexpass_attributes(account_plexpass):
|
|||
assert "sync" in account_plexpass.subscriptionFeatures
|
||||
assert "premium_music_metadata" in account_plexpass.subscriptionFeatures
|
||||
assert "plexpass" in account_plexpass.roles
|
||||
assert set(account_plexpass.entitlements) == utils.ENTITLEMENTS
|
||||
assert utils.ENTITLEMENTS <= set(account_plexpass.entitlements)
|
||||
|
||||
|
||||
def test_myplex_claimToken(account):
|
||||
|
|
Loading…
Reference in a new issue