Re-wired connection manager
This commit is contained in:
parent
67755d6a23
commit
ae34b63de9
3 changed files with 151 additions and 114 deletions
|
@ -508,24 +508,33 @@ class PlexAPI():
|
|||
self.g_PMS dict set
|
||||
"""
|
||||
self.g_PMS = {}
|
||||
# "Searching for Plex Server"
|
||||
xbmcgui.Dialog().notification(
|
||||
heading=self.addonName,
|
||||
message=self.__language__(39055),
|
||||
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
||||
time=3000,
|
||||
time=4000,
|
||||
sound=False)
|
||||
|
||||
# Look first for local PMS in the LAN
|
||||
pmsList = self.PlexGDM()
|
||||
self.logMsg('pmslist: %s' % pmsList, 1)
|
||||
self.logMsg('PMS found in the local LAN via GDM: %s' % pmsList, 2)
|
||||
|
||||
# Get PMS from plex.tv
|
||||
if plexToken:
|
||||
self.logMsg('Checking with plex.tv for more PMS to connect to', 1)
|
||||
self.getPMSListFromMyPlex(plexToken)
|
||||
else:
|
||||
self.logMsg('No plex token supplied, only checked LAN for PMS', 1)
|
||||
|
||||
for uuid in pmsList:
|
||||
PMS = pmsList[uuid]
|
||||
if PMS['uuid'] in self.g_PMS:
|
||||
continue
|
||||
self.declarePMS(PMS['uuid'], PMS['serverName'], 'http',
|
||||
PMS['ip'], PMS['port'])
|
||||
self.updatePMSProperty(PMS['uuid'], 'owned', '-')
|
||||
# Ping to check whether we need HTTPs or HTTP
|
||||
url = '%s:%s' % (PMS['ip'], PMS['port'])
|
||||
https = PMSHttpsEnabled(url)
|
||||
https = PMSHttpsEnabled('%s:%s' % (PMS['ip'], PMS['port']))
|
||||
if https is None:
|
||||
# Error contacting url. Skip for now
|
||||
continue
|
||||
|
@ -539,10 +548,6 @@ class PlexAPI():
|
|||
# Already declared with http
|
||||
pass
|
||||
|
||||
if not plexToken:
|
||||
self.logMsg('No plex.tv token supplied, checked LAN for PMS', 0)
|
||||
return
|
||||
|
||||
# install plex.tv "virtual" PMS - for myPlex, PlexHome
|
||||
# self.declarePMS('plex.tv', 'plex.tv', 'https', 'plex.tv', '443')
|
||||
# self.updatePMSProperty('plex.tv', 'local', '-')
|
||||
|
@ -551,9 +556,6 @@ class PlexAPI():
|
|||
# 'plex.tv', 'accesstoken', plexToken)
|
||||
# (remote and local) servers from plex.tv
|
||||
|
||||
# Get PMS from plex.tv. This will overwrite any PMS we already found
|
||||
self.getPMSListFromMyPlex(plexToken)
|
||||
|
||||
def getPMSListFromMyPlex(self, token):
|
||||
"""
|
||||
getPMSListFromMyPlex
|
||||
|
@ -566,7 +568,7 @@ class PlexAPI():
|
|||
headerOptions={'X-Plex-Token': token})
|
||||
try:
|
||||
xml.attrib
|
||||
except:
|
||||
except AttributeError:
|
||||
self.logMsg('Could not get list of PMS from plex.tv', -1)
|
||||
return
|
||||
|
||||
|
@ -574,105 +576,110 @@ class PlexAPI():
|
|||
queue = Queue.Queue()
|
||||
threads = []
|
||||
|
||||
maxAgeSeconds = 2*60*60*24
|
||||
for Dir in xml.findall('Device'):
|
||||
if "server" in Dir.get('provides'):
|
||||
if Dir.find('Connection') is None:
|
||||
# no valid connection - skip
|
||||
continue
|
||||
if 'server' not in Dir.get('provides'):
|
||||
# No PMS - skip
|
||||
continue
|
||||
if Dir.find('Connection') is None:
|
||||
# no valid connection - skip
|
||||
continue
|
||||
|
||||
# check MyPlex data age - skip if >2 days
|
||||
PMS = {}
|
||||
PMS['name'] = Dir.get('name')
|
||||
infoAge = time.time() - int(Dir.get('lastSeenAt'))
|
||||
oneDayInSec = 60 * 60 * 24
|
||||
if infoAge > 2 * oneDayInSec:
|
||||
self.logMsg("Server %s not seen for 2 days - "
|
||||
"skipping." % PMS['name'], 0)
|
||||
continue
|
||||
# check MyPlex data age - skip if >2 days
|
||||
PMS = {}
|
||||
PMS['name'] = Dir.get('name')
|
||||
infoAge = time.time() - int(Dir.get('lastSeenAt'))
|
||||
if infoAge > maxAgeSeconds:
|
||||
self.logMsg("Server %s not seen for 2 days - skipping."
|
||||
% PMS['name'], 1)
|
||||
continue
|
||||
|
||||
PMS['uuid'] = Dir.get('clientIdentifier')
|
||||
PMS['token'] = Dir.get('accessToken', token)
|
||||
PMS['owned'] = Dir.get('owned', '0')
|
||||
PMS['local'] = Dir.get('publicAddressMatches')
|
||||
PMS['ownername'] = Dir.get('sourceTitle', '')
|
||||
PMS['path'] = '/'
|
||||
PMS['options'] = None
|
||||
PMS['uuid'] = Dir.get('clientIdentifier')
|
||||
PMS['token'] = Dir.get('accessToken', token)
|
||||
PMS['owned'] = Dir.get('owned', '1')
|
||||
PMS['local'] = Dir.get('publicAddressMatches')
|
||||
PMS['ownername'] = Dir.get('sourceTitle', '')
|
||||
PMS['path'] = '/'
|
||||
PMS['options'] = None
|
||||
|
||||
# If PMS seems (!!) local, try a local connection first
|
||||
# Backup to remote connection, if that failes
|
||||
PMS['baseURL'] = ''
|
||||
for Con in Dir.findall('Connection'):
|
||||
localConn = Con.get('local')
|
||||
if ((PMS['local'] == '1' and localConn == '1') or
|
||||
(PMS['local'] == '0' and localConn == '0')):
|
||||
# Either both local or both remote
|
||||
PMS['protocol'] = Con.get('protocol')
|
||||
PMS['ip'] = Con.get('address')
|
||||
PMS['port'] = Con.get('port')
|
||||
PMS['baseURL'] = Con.get('uri')
|
||||
elif PMS['local'] == '1' and localConn == '0':
|
||||
# Backup connection if local one did not work
|
||||
PMS['backup'] = {}
|
||||
PMS['backup']['protocol'] = Con.get('protocol')
|
||||
PMS['backup']['ip'] = Con.get('address')
|
||||
PMS['backup']['port'] = Con.get('port')
|
||||
PMS['backup']['baseURL'] = Con.get('uri')
|
||||
# Try a local connection first
|
||||
# Backup to remote connection, if that failes
|
||||
PMS['connections'] = []
|
||||
for Con in Dir.findall('Connection'):
|
||||
if Con.get('local') == '1':
|
||||
PMS['connections'].append(Con)
|
||||
# Append non-local
|
||||
for Con in Dir.findall('Connection'):
|
||||
if Con.get('local') != '1':
|
||||
PMS['connections'].append(Con)
|
||||
|
||||
# poke PMS, own thread for each poke
|
||||
t = Thread(target=self.pokePMS,
|
||||
args=(PMS, queue))
|
||||
t.start()
|
||||
threads.append(t)
|
||||
# poke PMS, own thread for each poke
|
||||
t = Thread(target=self.pokePMS,
|
||||
args=(PMS, queue))
|
||||
t.start()
|
||||
threads.append(t)
|
||||
|
||||
# wait for requests being answered
|
||||
for t in threads:
|
||||
t.join()
|
||||
# wait for requests being answered
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
# declare new PMSs
|
||||
while not queue.empty():
|
||||
PMS = queue.get()
|
||||
self.declarePMS(PMS['uuid'], PMS['name'],
|
||||
PMS['protocol'], PMS['ip'], PMS['port'])
|
||||
# dflt: token='', local, owned - updated later
|
||||
self.updatePMSProperty(
|
||||
PMS['uuid'], 'accesstoken', PMS['token'])
|
||||
self.updatePMSProperty(
|
||||
PMS['uuid'], 'owned', PMS['owned'])
|
||||
self.updatePMSProperty(
|
||||
PMS['uuid'], 'local', PMS['local'])
|
||||
# set in declarePMS, overwrite for https encryption
|
||||
self.updatePMSProperty(
|
||||
PMS['uuid'], 'baseURL', PMS['baseURL'])
|
||||
self.updatePMSProperty(
|
||||
PMS['uuid'], 'ownername', PMS['ownername'])
|
||||
queue.task_done()
|
||||
# declare new PMSs
|
||||
while not queue.empty():
|
||||
PMS = queue.get()
|
||||
self.declarePMS(PMS['uuid'], PMS['name'],
|
||||
PMS['protocol'], PMS['ip'], PMS['port'])
|
||||
# dflt: token='', local, owned - updated later
|
||||
self.updatePMSProperty(
|
||||
PMS['uuid'], 'accesstoken', PMS['token'])
|
||||
self.updatePMSProperty(
|
||||
PMS['uuid'], 'owned', PMS['owned'])
|
||||
self.updatePMSProperty(
|
||||
PMS['uuid'], 'local', PMS['local'])
|
||||
# set in declarePMS, overwrite for https encryption
|
||||
self.updatePMSProperty(
|
||||
PMS['uuid'], 'baseURL', PMS['baseURL'])
|
||||
self.updatePMSProperty(
|
||||
PMS['uuid'], 'ownername', PMS['ownername'])
|
||||
queue.task_done()
|
||||
|
||||
def pokePMS(self, PMS, queue):
|
||||
# Ignore SSL certificates for now
|
||||
xml = self.doUtils(PMS['baseURL'],
|
||||
if PMS['connections'][0].get('local') == '1':
|
||||
protocol = PMS['connections'][0].get('protocol')
|
||||
address = PMS['connections'][0].get('address')
|
||||
port = PMS['connections'][0].get('port')
|
||||
url = '%s://%s:%s' % (protocol, address, port)
|
||||
else:
|
||||
url = PMS['connections'][0].get('uri')
|
||||
protocol, address, port = url.split(':')
|
||||
address = address.replace('/', '')
|
||||
|
||||
xml = self.doUtils('%s/identity' % url,
|
||||
authenticate=False,
|
||||
headerOptions={'X-Plex-Token': PMS['token']},
|
||||
verifySSL=False)
|
||||
verifySSL=False,
|
||||
timeout=3)
|
||||
try:
|
||||
xml.attrib
|
||||
except:
|
||||
# Connection failed
|
||||
# retry with remote connection if we just tested local one.
|
||||
if PMS['local'] == '1' and PMS.get('backup'):
|
||||
self.logMsg('Couldnt talk to local PMS locally.'
|
||||
'Trying again remotely.', 0)
|
||||
PMS['protocol'] = PMS['backup']['protocol']
|
||||
PMS['ip'] = PMS['backup']['ip']
|
||||
PMS['port'] = PMS['backup']['port']
|
||||
PMS['baseURL'] = PMS['backup']['baseURL']
|
||||
PMS['local'] = '0'
|
||||
# Try again
|
||||
self.pokePMS(PMS, queue)
|
||||
else:
|
||||
return
|
||||
except AttributeError:
|
||||
# No connection, delete the one we just tested
|
||||
del PMS['connections'][0]
|
||||
if len(PMS['connections']) > 0:
|
||||
# Still got connections left, try them
|
||||
return self.pokePMS(PMS, queue)
|
||||
return
|
||||
else:
|
||||
# Connection successful, process later
|
||||
queue.put(PMS)
|
||||
# Connection successful - correct PMS?
|
||||
if xml.get('machineIdentifier') == PMS['uuid']:
|
||||
# process later
|
||||
PMS['baseURL'] = url
|
||||
PMS['protocol'] = protocol
|
||||
PMS['ip'] = address
|
||||
PMS['port'] = port
|
||||
queue.put(PMS)
|
||||
return
|
||||
self.logMsg('Found a PMS at %s, but the expected machineIdentifier of '
|
||||
'%s did not match the one we found: %s'
|
||||
% (url, PMS['uuid'], xml.get('machineIdentifier')), -1)
|
||||
|
||||
def MyPlexSignIn(self, username, password, options):
|
||||
"""
|
||||
|
|
|
@ -424,14 +424,14 @@ def PMSHttpsEnabled(url):
|
|||
verifySSL=False)
|
||||
try:
|
||||
res.attrib
|
||||
except:
|
||||
except AttributeError:
|
||||
# Might have SSL deactivated. Try with http
|
||||
res = doUtils('http://%s/identity' % url,
|
||||
authenticate=False,
|
||||
verifySSL=False)
|
||||
try:
|
||||
res.attrib
|
||||
except:
|
||||
except AttributeError:
|
||||
logMsg(title, "Could not contact PMS %s" % url, -1)
|
||||
return None
|
||||
else:
|
||||
|
@ -448,15 +448,16 @@ def GetMachineIdentifier(url):
|
|||
|
||||
Returns None if something went wrong
|
||||
"""
|
||||
xml = downloadutils.DownloadUtils().downloadUrl(url + '/identity')
|
||||
xml = downloadutils.DownloadUtils().downloadUrl('%s/identity' % url,
|
||||
authenticate=False,
|
||||
verifySSL=False)
|
||||
try:
|
||||
xml.attrib
|
||||
except:
|
||||
machineIdentifier = xml.attrib['machineIdentifier']
|
||||
except (AttributeError, KeyError):
|
||||
logMsg(title, 'Could not get the PMS machineIdentifier for %s'
|
||||
% url, -1)
|
||||
return None
|
||||
machineIdentifier = xml.attrib.get('machineIdentifier')
|
||||
logMsg(title, 'Found machineIdentifier %s for %s'
|
||||
logMsg(title, 'Found machineIdentifier %s for the PMS %s'
|
||||
% (machineIdentifier, url), 1)
|
||||
return machineIdentifier
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import downloadutils
|
|||
import userclient
|
||||
|
||||
import PlexAPI
|
||||
from PlexFunctions import GetMachineIdentifier
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
@ -26,6 +27,11 @@ class InitialSetup():
|
|||
self.userClient = userclient.UserClient()
|
||||
self.plx = PlexAPI.PlexAPI()
|
||||
|
||||
def PlexTvSignIn(self):
|
||||
"""
|
||||
Checks existing connection to plex.tv. If not, triggers sign in
|
||||
"""
|
||||
|
||||
def setup(self, forcePlexTV=False, chooseServer=False):
|
||||
"""
|
||||
Initial setup. Run once upon startup.
|
||||
|
@ -44,7 +50,7 @@ class InitialSetup():
|
|||
plexToken = plexdict['plexToken']
|
||||
plexid = plexdict['plexid']
|
||||
if plexToken:
|
||||
self.logMsg('Found plex.tv token in settings', 0)
|
||||
self.logMsg('Found a plex.tv token in the settings', 0)
|
||||
|
||||
dialog = xbmcgui.Dialog()
|
||||
|
||||
|
@ -79,11 +85,10 @@ class InitialSetup():
|
|||
authenticate=False,
|
||||
headerOptions={'X-Plex-Token': plexToken})
|
||||
try:
|
||||
xml.attrib
|
||||
except:
|
||||
plexLogin = xml.attrib['title']
|
||||
except (AttributeError, KeyError):
|
||||
self.logMsg('Failed to update Plex info from plex.tv', -1)
|
||||
else:
|
||||
plexLogin = xml.attrib.get('title')
|
||||
utils.settings('plexLogin', value=plexLogin)
|
||||
home = 'true' if xml.attrib.get('home') == '1' else 'false'
|
||||
utils.settings('plexhome', value=home)
|
||||
|
@ -92,12 +97,36 @@ class InitialSetup():
|
|||
'plexHomeSize', value=xml.attrib.get('homeSize', '1'))
|
||||
self.logMsg('Updated Plex info from plex.tv', 0)
|
||||
|
||||
# If a Plex server IP has already been set, return.
|
||||
# If a Plex server IP has already been set
|
||||
# return only if the right machine identifier is found
|
||||
getNewPMS = False
|
||||
if server and forcePlexTV is False and chooseServer is False:
|
||||
self.logMsg("Server is already set.", 0)
|
||||
self.logMsg("url: %s, Plex machineIdentifier: %s"
|
||||
% (server, serverid), 0)
|
||||
return
|
||||
self.logMsg("PMS is already set: %s. Checking now..." % server, 0)
|
||||
chk = self.plx.CheckConnection(server, verifySSL=False)
|
||||
if chk is False:
|
||||
self.logMsg('Could not reach PMS %s' % server, -1)
|
||||
getNewPMS = True
|
||||
if getNewPMS is False and not serverid:
|
||||
self.logMsg('No PMS machineIdentifier found for %s. Trying to '
|
||||
'get the PMS unique ID' % server, 1)
|
||||
serverid = GetMachineIdentifier(server)
|
||||
if serverid is None:
|
||||
self.logMsg('Could not retrieve machineIdentifier', -1)
|
||||
getNewPMS = True
|
||||
else:
|
||||
utils.settings('plex_machineIdentifier', value=serverid)
|
||||
elif getNewPMS is False:
|
||||
tempServerid = GetMachineIdentifier(server)
|
||||
if tempServerid != serverid:
|
||||
self.logMsg('The current PMS %s was expected to have a '
|
||||
'unique machineIdentifier of %s. But we got '
|
||||
'%s. Pick a new server to be sure'
|
||||
% (server, serverid, tempServerid), 1)
|
||||
getNewPMS = True
|
||||
if getNewPMS is False:
|
||||
self.logMsg("Using PMS %s with machineIdentifier %s"
|
||||
% (server, serverid), 0)
|
||||
return
|
||||
|
||||
# If not already retrieved myplex info, optionally let user sign in
|
||||
# to plex.tv. This DOES get called on very first install run
|
||||
|
|
Loading…
Reference in a new issue