Move xArgsDeviceInfo to clientinfo
This commit is contained in:
parent
9929ab2eb5
commit
12add3d369
3 changed files with 74 additions and 200 deletions
|
@ -67,21 +67,10 @@ class PlexAPI():
|
|||
# CONSTANTS
|
||||
# Timeout for POST/GET commands, I guess in seconds
|
||||
timeout = 10
|
||||
# VARIABLES
|
||||
|
||||
def __init__(self):
|
||||
self.__language__ = xbmcaddon.Addon().getLocalizedString
|
||||
self.g_PMS = {}
|
||||
client = clientinfo.ClientInfo()
|
||||
self.addonId = client.getAddonId()
|
||||
self.clientId = client.getDeviceId()
|
||||
self.deviceName = client.getDeviceName()
|
||||
self.plexversion = client.getVersion()
|
||||
self.platform = client.getPlatform()
|
||||
self.userId = utils.window('currUserId')
|
||||
self.token = utils.window('pms_token')
|
||||
self.server = utils.window('pms_server')
|
||||
|
||||
self.doUtils = downloadutils.DownloadUtils()
|
||||
|
||||
def GetPlexLoginFromSettings(self):
|
||||
|
@ -145,7 +134,8 @@ class PlexAPI():
|
|||
retrievedPlexLogin, authtoken = self.MyPlexSignIn(
|
||||
plexLogin,
|
||||
plexPassword,
|
||||
{'X-Plex-Client-Identifier': self.clientId})
|
||||
{'X-Plex-Client-Identifier':
|
||||
clientinfo.ClientInfo().getDeviceId()})
|
||||
self.logMsg("plex.tv username and token: %s, %s"
|
||||
% (plexLogin, authtoken), 1)
|
||||
if plexLogin == '':
|
||||
|
@ -345,7 +335,7 @@ class PlexAPI():
|
|||
"""
|
||||
# Add '/clients' to URL because then an authentication is necessary
|
||||
# If a plex.tv URL was passed, this does not work.
|
||||
header = self.getXArgsDeviceInfo()
|
||||
header = clientinfo.ClientInfo().getXArgsDeviceInfo()
|
||||
if token:
|
||||
header['X-Plex-Token'] = token
|
||||
sslverify = utils.settings('sslverify')
|
||||
|
@ -816,148 +806,6 @@ class PlexAPI():
|
|||
XML = self.getXMLFromPMS(PMS['baseURL'],PMS['path'],PMS['options'],PMS['token'])
|
||||
queue.put( (PMS['data'], XML) )
|
||||
|
||||
def getXArgsDeviceInfo(self, options={}):
|
||||
"""
|
||||
Returns a dictionary that can be used as headers for GET and POST
|
||||
requests. An authentication option is NOT yet added.
|
||||
|
||||
Inputs:
|
||||
options: dictionary of options that will override the
|
||||
standard header options otherwise set.
|
||||
Output:
|
||||
header dictionary
|
||||
"""
|
||||
# Get addon infos
|
||||
xargs = {
|
||||
'Accept': '*/*',
|
||||
'Connection': 'keep-alive',
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
# "Access-Control-Allow-Origin": "*",
|
||||
'X-Plex-Language': 'en',
|
||||
'X-Plex-Device': self.addonName,
|
||||
'X-Plex-Client-Platform': self.platform,
|
||||
'X-Plex-Device-Name': self.deviceName,
|
||||
'X-Plex-Platform': self.addonName,
|
||||
'X-Plex-Platform-Version': 'unknown',
|
||||
'X-Plex-Model': 'unknown',
|
||||
'X-Plex-Product': self.addonName,
|
||||
'X-Plex-Version': self.plexversion,
|
||||
'X-Plex-Client-Identifier': self.clientId,
|
||||
'X-Plex-Provides': 'player',
|
||||
}
|
||||
|
||||
if self.token:
|
||||
xargs['X-Plex-Token'] = self.token
|
||||
if options:
|
||||
xargs.update(options)
|
||||
return xargs
|
||||
|
||||
def getXMLFromMultiplePMS(self, ATV_udid, path, type, options={}):
|
||||
"""
|
||||
provide combined XML representation of local servers' XMLs, eg. /library/section
|
||||
|
||||
parameters:
|
||||
ATV_udid
|
||||
path
|
||||
type - owned <> shared (previously: local, myplex)
|
||||
options
|
||||
result:
|
||||
XML
|
||||
"""
|
||||
queue = Queue.Queue()
|
||||
threads = []
|
||||
|
||||
root = etree.Element("MediaConverter")
|
||||
root.set('friendlyName', type+' Servers')
|
||||
|
||||
for uuid in g_PMS.get(ATV_udid, {}):
|
||||
if (type=='all' and getPMSProperty(ATV_udid, uuid, 'name')!='plex.tv') or \
|
||||
(type=='owned' and getPMSProperty(ATV_udid, uuid, 'owned')=='1') or \
|
||||
(type=='shared' and getPMSProperty(ATV_udid, uuid, 'owned')=='0') or \
|
||||
(type=='local' and getPMSProperty(ATV_udid, uuid, 'local')=='1') or \
|
||||
(type=='remote' and getPMSProperty(ATV_udid, uuid, 'local')=='0'):
|
||||
Server = etree.SubElement(root, 'Server') # create "Server" node
|
||||
Server.set('name', getPMSProperty(ATV_udid, uuid, 'name'))
|
||||
Server.set('address', getPMSProperty(ATV_udid, uuid, 'ip'))
|
||||
Server.set('port', getPMSProperty(ATV_udid, uuid, 'port'))
|
||||
Server.set('baseURL', getPMSProperty(ATV_udid, uuid, 'baseURL'))
|
||||
Server.set('local', getPMSProperty(ATV_udid, uuid, 'local'))
|
||||
Server.set('owned', getPMSProperty(ATV_udid, uuid, 'owned'))
|
||||
|
||||
baseURL = getPMSProperty(ATV_udid, uuid, 'baseURL')
|
||||
token = getPMSProperty(ATV_udid, uuid, 'accesstoken')
|
||||
PMS_mark = 'PMS(' + getPMSProperty(ATV_udid, uuid, 'address') + ')'
|
||||
|
||||
Server.set('searchKey', PMS_mark + getURL('', '', '/Search/Entry.xml'))
|
||||
|
||||
# request XMLs, one thread for each
|
||||
PMS = { 'baseURL':baseURL, 'path':path, 'options':options, 'token':token, \
|
||||
'data': {'uuid': uuid, 'Server': Server} }
|
||||
t = Thread(target=getXMLFromPMSToQueue, args=(PMS, queue))
|
||||
t.start()
|
||||
threads.append(t)
|
||||
|
||||
# wait for requests being answered
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
# add new data to root XML, individual Server
|
||||
while not queue.empty():
|
||||
(data, XML) = queue.get()
|
||||
uuid = data['uuid']
|
||||
Server = data['Server']
|
||||
|
||||
baseURL = getPMSProperty(ATV_udid, uuid, 'baseURL')
|
||||
token = getPMSProperty(ATV_udid, uuid, 'accesstoken')
|
||||
PMS_mark = 'PMS(' + getPMSProperty(ATV_udid, uuid, 'address') + ')'
|
||||
|
||||
if XML==False:
|
||||
Server.set('size', '0')
|
||||
else:
|
||||
Server.set('size', XML.getroot().get('size', '0'))
|
||||
|
||||
for Dir in XML.getiterator('Directory'): # copy "Directory" content, add PMS to links
|
||||
key = Dir.get('key') # absolute path
|
||||
Dir.set('key', PMS_mark + getURL('', path, key))
|
||||
Dir.set('refreshKey', getURL(baseURL, path, key) + '/refresh')
|
||||
if 'thumb' in Dir.attrib:
|
||||
Dir.set('thumb', PMS_mark + getURL('', path, Dir.get('thumb')))
|
||||
if 'art' in Dir.attrib:
|
||||
Dir.set('art', PMS_mark + getURL('', path, Dir.get('art')))
|
||||
Server.append(Dir)
|
||||
|
||||
for Playlist in XML.getiterator('Playlist'): # copy "Playlist" content, add PMS to links
|
||||
key = Playlist.get('key') # absolute path
|
||||
Playlist.set('key', PMS_mark + getURL('', path, key))
|
||||
if 'composite' in Playlist.attrib:
|
||||
Playlist.set('composite', PMS_mark + getURL('', path, Playlist.get('composite')))
|
||||
Server.append(Playlist)
|
||||
|
||||
for Video in XML.getiterator('Video'): # copy "Video" content, add PMS to links
|
||||
key = Video.get('key') # absolute path
|
||||
Video.set('key', PMS_mark + getURL('', path, key))
|
||||
if 'thumb' in Video.attrib:
|
||||
Video.set('thumb', PMS_mark + getURL('', path, Video.get('thumb')))
|
||||
if 'parentKey' in Video.attrib:
|
||||
Video.set('parentKey', PMS_mark + getURL('', path, Video.get('parentKey')))
|
||||
if 'parentThumb' in Video.attrib:
|
||||
Video.set('parentThumb', PMS_mark + getURL('', path, Video.get('parentThumb')))
|
||||
if 'grandparentKey' in Video.attrib:
|
||||
Video.set('grandparentKey', PMS_mark + getURL('', path, Video.get('grandparentKey')))
|
||||
if 'grandparentThumb' in Video.attrib:
|
||||
Video.set('grandparentThumb', PMS_mark + getURL('', path, Video.get('grandparentThumb')))
|
||||
Server.append(Video)
|
||||
|
||||
root.set('size', str(len(root.findall('Server'))))
|
||||
|
||||
XML = etree.ElementTree(root)
|
||||
|
||||
dprint(__name__, 1, "====== Local Server/Sections XML ======")
|
||||
dprint(__name__, 1, XML.getroot())
|
||||
dprint(__name__, 1, "====== Local Server/Sections XML finished ======")
|
||||
|
||||
return XML # XML representation - created "just in time". Do we need to cache it?
|
||||
|
||||
def getURL(self, baseURL, path, key):
|
||||
if key.startswith('http://') or key.startswith('https://'): # external server
|
||||
URL = key
|
||||
|
@ -988,7 +836,7 @@ class PlexAPI():
|
|||
MyPlexURL = 'https://' + MyPlexHost + MyPlexSignInPath
|
||||
|
||||
# create POST request
|
||||
xargs = self.getXArgsDeviceInfo(options)
|
||||
xargs = clientinfo.ClientInfo().getXArgsDeviceInfo(options)
|
||||
self.logMsg("Header is: %s" % xargs, 1)
|
||||
request = urllib2.Request(MyPlexURL, None, xargs)
|
||||
request.get_method = lambda: 'POST'
|
||||
|
@ -1120,7 +968,7 @@ class PlexAPI():
|
|||
self.logMsg("No user selected.", 0)
|
||||
utils.settings('username', value='')
|
||||
xbmc.executebuiltin('Addon.OpenSettings(%s)'
|
||||
% self.addonId)
|
||||
% clientinfo.ClientInfo().getAddonId())
|
||||
return False
|
||||
# Only 1 user received, choose that one
|
||||
else:
|
||||
|
@ -1164,7 +1012,8 @@ class PlexAPI():
|
|||
|
||||
if not username:
|
||||
self.logMsg('Failed signing in a user to plex.tv', -1)
|
||||
xbmc.executebuiltin('Addon.OpenSettings(%s)' % self.addonId)
|
||||
xbmc.executebuiltin('Addon.OpenSettings(%s)'
|
||||
% clientinfo.ClientInfo().getAddonId())
|
||||
return False
|
||||
|
||||
return {
|
||||
|
@ -1385,7 +1234,7 @@ class PlexAPI():
|
|||
args['protocol'] = 'http'
|
||||
args['maxAudioBitrate'] = maxAudioBitrate
|
||||
|
||||
xargs = getXArgsDeviceInfo(options)
|
||||
xargs = clientinfo.ClientInfo().getXArgsDeviceInfo(options)
|
||||
if not AuthToken=='':
|
||||
xargs['X-Plex-Token'] = AuthToken
|
||||
|
||||
|
@ -1465,13 +1314,8 @@ class API():
|
|||
self.item = item
|
||||
# which media part in the XML response shall we look at?
|
||||
self.part = 0
|
||||
self.clientinfo = clientinfo.ClientInfo()
|
||||
self.clientId = self.clientinfo.getDeviceId()
|
||||
self.__language__ = xbmcaddon.Addon().getLocalizedString
|
||||
|
||||
self.userId = utils.window('currUserId')
|
||||
self.server = utils.window('pms_server')
|
||||
self.token = utils.window('pms_token')
|
||||
|
||||
def setPartNumber(self, number=None):
|
||||
"""
|
||||
|
@ -1888,7 +1732,7 @@ class API():
|
|||
|
||||
arguments overrule everything
|
||||
"""
|
||||
xargs = PlexAPI().getXArgsDeviceInfo()
|
||||
xargs = clientinfo.ClientInfo().getXArgsDeviceInfo()
|
||||
xargs.update(arguments)
|
||||
if '?' not in url:
|
||||
url = "%s?%s" % (url, urlencode(xargs))
|
||||
|
@ -1902,10 +1746,12 @@ class API():
|
|||
|
||||
url may or may not already contain a '?'
|
||||
"""
|
||||
if utils.window('pms_token') == '':
|
||||
return url
|
||||
if '?' not in url:
|
||||
url = "%s?X-Plex-Token=%s" % (url, self.token)
|
||||
url = "%s?X-Plex-Token=%s" % (url, utils.window('pms_token'))
|
||||
else:
|
||||
url = "%s&X-Plex-Token=%s" % (url, self.token)
|
||||
url = "%s&X-Plex-Token=%s" % (url, utils.window('pms_token'))
|
||||
return url
|
||||
|
||||
def GetPlayQueueItemID(self):
|
||||
|
@ -2176,7 +2022,7 @@ class API():
|
|||
TODO: mediaIndex
|
||||
"""
|
||||
|
||||
xargs = PlexAPI().getXArgsDeviceInfo()
|
||||
xargs = clientinfo.ClientInfo().getXArgsDeviceInfo()
|
||||
# For DirectPlay, path/key of PART is needed
|
||||
if action == "DirectPlay":
|
||||
path = self.item[0][self.part].attrib['key']
|
||||
|
|
|
@ -7,40 +7,72 @@ from uuid import uuid4
|
|||
import xbmc
|
||||
import xbmcaddon
|
||||
|
||||
import utils
|
||||
from utils import logging, window, settings
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
||||
@utils.logging
|
||||
@logging
|
||||
class ClientInfo():
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.addon = xbmcaddon.Addon()
|
||||
|
||||
def getXArgsDeviceInfo(self, options=None):
|
||||
"""
|
||||
Returns a dictionary that can be used as headers for GET and POST
|
||||
requests. An authentication option is NOT yet added.
|
||||
|
||||
Inputs:
|
||||
options: dictionary of options that will override the
|
||||
standard header options otherwise set.
|
||||
Output:
|
||||
header dictionary
|
||||
"""
|
||||
# Get addon infos
|
||||
xargs = {
|
||||
'Accept': '*/*',
|
||||
'Connection': 'keep-alive',
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
# "Access-Control-Allow-Origin": "*",
|
||||
# 'X-Plex-Language': 'en',
|
||||
'X-Plex-Device': self.getAddonName(),
|
||||
'X-Plex-Client-Platform': self.getPlatform(),
|
||||
'X-Plex-Device-Name': self.getDeviceName(),
|
||||
'X-Plex-Platform': self.getPlatform(),
|
||||
# 'X-Plex-Platform-Version': 'unknown',
|
||||
# 'X-Plex-Model': 'unknown',
|
||||
'X-Plex-Product': self.getAddonName(),
|
||||
'X-Plex-Version': self.getVersion(),
|
||||
'X-Plex-Client-Identifier': self.getDeviceId(),
|
||||
'X-Plex-Provides': 'player',
|
||||
}
|
||||
|
||||
if window('pms_token'):
|
||||
xargs['X-Plex-Token'] = window('pms_token')
|
||||
if options is not None:
|
||||
xargs.update(options)
|
||||
return xargs
|
||||
|
||||
def getAddonName(self):
|
||||
# Used for logging
|
||||
return self.addon.getAddonInfo('name')
|
||||
|
||||
def getAddonId(self):
|
||||
|
||||
return "plugin.video.plexkodiconnect"
|
||||
|
||||
def getVersion(self):
|
||||
|
||||
return self.addon.getAddonInfo('version')
|
||||
|
||||
def getDeviceName(self):
|
||||
|
||||
if utils.settings('deviceNameOpt') == "false":
|
||||
if settings('deviceNameOpt') == "false":
|
||||
# Use Kodi's deviceName
|
||||
deviceName = xbmc.getInfoLabel('System.FriendlyName').decode('utf-8')
|
||||
deviceName = xbmc.getInfoLabel(
|
||||
'System.FriendlyName').decode('utf-8')
|
||||
else:
|
||||
deviceName = utils.settings('deviceName')
|
||||
deviceName = settings('deviceName')
|
||||
deviceName = deviceName.replace("\"", "_")
|
||||
deviceName = deviceName.replace("/", "_")
|
||||
|
||||
return deviceName
|
||||
|
||||
def getPlatform(self):
|
||||
|
@ -69,25 +101,25 @@ class ClientInfo():
|
|||
|
||||
If id does not exist, create one and save in Kodi settings file.
|
||||
"""
|
||||
|
||||
if reset is True:
|
||||
utils.window('plex_client_Id', clear=True)
|
||||
utils.settings('plex_client_Id', value="")
|
||||
window('plex_client_Id', clear=True)
|
||||
settings('plex_client_Id', value="")
|
||||
|
||||
clientId = utils.window('plex_client_Id')
|
||||
clientId = window('plex_client_Id')
|
||||
if clientId:
|
||||
return clientId
|
||||
|
||||
clientId = utils.settings('plex_client_Id')
|
||||
clientId = settings('plex_client_Id')
|
||||
# Because Kodi appears to cache file settings!!
|
||||
if clientId != "" and reset is False:
|
||||
utils.window('plex_client_Id', value=clientId)
|
||||
self.logMsg("Unique device Id plex_client_Id loaded: %s" % clientId, 1)
|
||||
window('plex_client_Id', value=clientId)
|
||||
self.logMsg("Unique device Id plex_client_Id loaded: %s"
|
||||
% clientId, 1)
|
||||
return clientId
|
||||
|
||||
self.logMsg("Generating a new deviceid.", 0)
|
||||
clientId = str(uuid4())
|
||||
utils.settings('plex_client_Id', value=clientId)
|
||||
utils.window('plex_client_Id', value=clientId)
|
||||
settings('plex_client_Id', value=clientId)
|
||||
window('plex_client_Id', value=clientId)
|
||||
self.logMsg("Unique device Id plex_client_Id loaded: %s" % clientId, 1)
|
||||
return clientId
|
||||
|
|
|
@ -13,8 +13,6 @@ import xbmcgui
|
|||
import utils
|
||||
import clientinfo
|
||||
|
||||
import PlexAPI
|
||||
|
||||
###############################################################################
|
||||
|
||||
# Disable requests logging
|
||||
|
@ -30,16 +28,16 @@ class DownloadUtils():
|
|||
|
||||
# Borg - multiple instances, shared state
|
||||
_shared_state = {}
|
||||
clientInfo = clientinfo.ClientInfo()
|
||||
|
||||
# Requests session
|
||||
s = None
|
||||
timeout = 30
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.__dict__ = self._shared_state
|
||||
|
||||
self.clientInfo = clientinfo.ClientInfo()
|
||||
|
||||
def setUsername(self, username):
|
||||
# Reserved for userclient only
|
||||
self.username = username
|
||||
|
@ -175,17 +173,14 @@ class DownloadUtils():
|
|||
self.logMsg("Requests session could not be terminated.", 1)
|
||||
|
||||
def getHeader(self, authenticate=True, options={}):
|
||||
plx = PlexAPI.PlexAPI()
|
||||
if authenticate:
|
||||
header = plx.getXArgsDeviceInfo(options=options)
|
||||
header = self.clientInfo.getXArgsDeviceInfo(options=options)
|
||||
else:
|
||||
header = plx.getXArgsDeviceInfo(options=options)
|
||||
header = self.clientInfo.getXArgsDeviceInfo(options=options)
|
||||
return header
|
||||
|
||||
def downloadUrl(self, url, postBody=None, type="GET", parameters=None, authenticate=True, headerOptions={}):
|
||||
|
||||
# self.logMsg("=== ENTER downloadUrl ===", 2)
|
||||
|
||||
def downloadUrl(self, url, postBody=None, type="GET", parameters=None,
|
||||
authenticate=True, headerOptions={}):
|
||||
timeout = self.timeout
|
||||
default_link = ""
|
||||
|
||||
|
@ -276,7 +271,8 @@ class DownloadUtils():
|
|||
# If user is not authenticated
|
||||
elif not authenticate:
|
||||
|
||||
header = self.getHeader(authenticate=False, options=headerOptions)
|
||||
header = self.getHeader(authenticate=False,
|
||||
options=headerOptions)
|
||||
|
||||
# If user enables ssl verification
|
||||
try:
|
||||
|
@ -413,4 +409,4 @@ class DownloadUtils():
|
|||
self.logMsg("Unknown error connecting to: %s" % url, 0)
|
||||
self.logMsg(e, 1)
|
||||
|
||||
return default_link
|
||||
return default_link
|
||||
|
|
Loading…
Reference in a new issue