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