Dialog: manual PMS entry, part 3
This commit is contained in:
parent
76ca66b38b
commit
c1098f22a4
5 changed files with 168 additions and 137 deletions
|
@ -997,7 +997,7 @@ msgstr ""
|
|||
# add-on settings
|
||||
|
||||
msgctxt "#30500"
|
||||
msgid "Verify Host SSL Certificate (more secure)"
|
||||
msgid "Verify SSL Certificate"
|
||||
msgstr ""
|
||||
|
||||
msgctxt "#30501"
|
||||
|
|
|
@ -175,36 +175,38 @@ class ConnectionManager(object):
|
|||
"application/x-www-form-urlencoded")
|
||||
|
||||
def requestUrl(self, request):
|
||||
"""
|
||||
request: dict with the following (optional) keys:
|
||||
type: GET, POST, ... (mandatory)
|
||||
url: (mandatory)
|
||||
timeout
|
||||
verify: set to False to disable SSL certificate check
|
||||
|
||||
if not request:
|
||||
raise AttributeError("Request cannot be null")
|
||||
|
||||
...and all the other requests settings
|
||||
"""
|
||||
self._getHeaders(request)
|
||||
request['timeout'] = request.get('timeout') or self.default_timeout
|
||||
request['verify'] = request.get('ssl') or False
|
||||
|
||||
action = request['type']
|
||||
request.pop('type', None)
|
||||
request.pop('ssl', None)
|
||||
|
||||
log.debug("ConnectionManager requesting %s" % request)
|
||||
log.debug("Requesting %s" % request)
|
||||
|
||||
try:
|
||||
r = self._requests(action, **request)
|
||||
log.info("ConnectionManager response status: %s" % r.status_code)
|
||||
r.raise_for_status()
|
||||
|
||||
except Exception as e: # Elaborate on exceptions?
|
||||
except Exception as e:
|
||||
# Elaborate on exceptions?
|
||||
log.error(e)
|
||||
raise
|
||||
|
||||
else:
|
||||
try:
|
||||
return etree.fromstring(r.content)
|
||||
except etree.ParseError:
|
||||
# Read response to release connection
|
||||
r.content
|
||||
return
|
||||
raise
|
||||
|
||||
def _requests(self, action, **kwargs):
|
||||
|
||||
|
@ -284,25 +286,12 @@ class ConnectionManager(object):
|
|||
GDM.close()
|
||||
return servers
|
||||
|
||||
def _normalizeAddress(self, address):
|
||||
# Attempt to correct bad input
|
||||
address = address.strip()
|
||||
address = address.lower()
|
||||
|
||||
if 'http' not in address:
|
||||
address = "http://%s" % address
|
||||
|
||||
return address
|
||||
|
||||
def connectToAddress(self, address, options={}):
|
||||
|
||||
if not address:
|
||||
return False
|
||||
|
||||
address = self._normalizeAddress(address)
|
||||
def connectToAddress(self, address, options=None):
|
||||
log.debug('connectToAddress %s with options %s' % (address, options))
|
||||
|
||||
def _onFail():
|
||||
log.error("connectToAddress %s failed" % address)
|
||||
log.error("connectToAddress %s failed with options %s" %
|
||||
(address, options))
|
||||
return self._resolveFailure()
|
||||
|
||||
try:
|
||||
|
@ -310,10 +299,10 @@ class ConnectionManager(object):
|
|||
except Exception:
|
||||
return _onFail()
|
||||
else:
|
||||
log.info("connectToAddress %s succeeded" % address)
|
||||
server = {
|
||||
'ManualAddress': address,
|
||||
'LastCONNECTIONMODE': CONNECTIONMODE['Manual']
|
||||
'LastCONNECTIONMODE': CONNECTIONMODE['Manual'],
|
||||
'options': options
|
||||
}
|
||||
self._updateServerInfo(server, publicInfo)
|
||||
server = self.connectToServer(server, options)
|
||||
|
@ -342,15 +331,15 @@ class ConnectionManager(object):
|
|||
self._saveUserInfoIntoCredentials(server, result['User'])
|
||||
self.credentialProvider.getCredentials(credentials)
|
||||
|
||||
def _tryConnect(self, url, timeout=None, options={}):
|
||||
url = '%s/identity' % url
|
||||
log.debug("tryConnect url: %s" % url)
|
||||
return self.requestUrl({
|
||||
'type': "GET",
|
||||
'url': url,
|
||||
'timeout': timeout,
|
||||
'ssl': options.get('ssl')
|
||||
})
|
||||
def _tryConnect(self, url, timeout=None, options=None):
|
||||
request = {
|
||||
'type': 'GET',
|
||||
'url': '%s/identity' % url,
|
||||
'timeout': timeout
|
||||
}
|
||||
if options:
|
||||
request.update(options)
|
||||
return self.requestUrl(request)
|
||||
|
||||
def _addAppInfoToConnectRequest(self):
|
||||
return "%s/%s" % (self.appName, self.appVersion)
|
||||
|
@ -365,7 +354,7 @@ class ConnectionManager(object):
|
|||
'type': 'GET',
|
||||
'headers': {'X-Plex-Token': self.plexToken},
|
||||
'timeout': 5.0,
|
||||
'ssl': True})
|
||||
'verify': True})
|
||||
try:
|
||||
xml.attrib
|
||||
except AttributeError:
|
||||
|
@ -528,7 +517,6 @@ class ConnectionManager(object):
|
|||
return 0
|
||||
|
||||
def connectToServer(self, server, options={}):
|
||||
|
||||
log.info("begin connectToServer")
|
||||
|
||||
tests = []
|
||||
|
|
|
@ -6,11 +6,10 @@ from os.path import join
|
|||
import xbmcgui
|
||||
|
||||
import connect.connectionmanager as connectionmanager
|
||||
from utils import language as lang, tryEncode
|
||||
from utils import language as lang, tryEncode, tryDecode
|
||||
import variables as v
|
||||
|
||||
###############################################################################
|
||||
|
||||
log = getLogger("PLEX."+__name__)
|
||||
|
||||
CONN_STATE = connectionmanager.CONNECTIONSTATE
|
||||
|
@ -22,24 +21,51 @@ CANCEL = 201
|
|||
ERROR_TOGGLE = 202
|
||||
ERROR_MSG = 203
|
||||
VERIFY_SSL = 204
|
||||
HOST_SSL_PATH = 205
|
||||
PMS_IP = 208
|
||||
PMS_PORT = 209
|
||||
ERROR = {
|
||||
'Invalid': 1,
|
||||
'Empty': 2
|
||||
}
|
||||
|
||||
MEDIA = tryEncode(join(v.ADDON_PATH, 'resources', 'skins', 'default', 'media'))
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
||||
class ServerManual(xbmcgui.WindowXMLDialog):
|
||||
|
||||
_server = None
|
||||
error = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
def onInit(self):
|
||||
self.connect_button = self.getControl(CONNECT)
|
||||
self.cancel_button = self.getControl(CANCEL)
|
||||
self.error_toggle = self.getControl(ERROR_TOGGLE)
|
||||
self.error_msg = self.getControl(ERROR_MSG)
|
||||
|
||||
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
|
||||
self.host_field = self.getControl(PMS_IP)
|
||||
self.port_field = self.getControl(PMS_PORT)
|
||||
self.verify_ssl_radio = self.getControl(VERIFY_SSL)
|
||||
self.host_ssl_path_radio = self.getControl(HOST_SSL_PATH)
|
||||
|
||||
self.port_field.setText('32400')
|
||||
self.setFocus(self.host_field)
|
||||
self.verify_ssl_radio.setSelected(True)
|
||||
self.host_ssl_path_radio.setSelected(False)
|
||||
self.host_ssl_path = None
|
||||
|
||||
self.host_field.controlUp(self.cancel_button)
|
||||
self.host_field.controlDown(self.port_field)
|
||||
self.port_field.controlUp(self.host_field)
|
||||
self.port_field.controlDown(self.verify_ssl_radio)
|
||||
self.verify_ssl_radio.controlUp(self.port_field)
|
||||
self.verify_ssl_radio.controlDown(self.host_ssl_path_radio)
|
||||
self.host_ssl_path_radio.controlUp(self.verify_ssl_radio)
|
||||
self.host_ssl_path_radio.controlDown(self.connect_button)
|
||||
self.connect_button.controlUp(self.host_ssl_path_radio)
|
||||
self.connect_button.controlDown(self.cancel_button)
|
||||
self.cancel_button.controlUp(self.connect_button)
|
||||
self.cancel_button.controlDown(self.host_field)
|
||||
|
||||
def set_connect_manager(self, connect_manager):
|
||||
self.connect_manager = connect_manager
|
||||
|
@ -50,34 +76,8 @@ class ServerManual(xbmcgui.WindowXMLDialog):
|
|||
def get_server(self):
|
||||
return self._server
|
||||
|
||||
def onInit(self):
|
||||
|
||||
self.connect_button = self.getControl(CONNECT)
|
||||
self.cancel_button = self.getControl(CANCEL)
|
||||
self.error_toggle = self.getControl(ERROR_TOGGLE)
|
||||
self.error_msg = self.getControl(ERROR_MSG)
|
||||
self.host_field = self._add_editcontrol(725, 325, 40, 500)
|
||||
self.port_field = self._add_editcontrol(725, 450, 40, 500)
|
||||
# self.ssl_field = self._add_radiobutton(725, 550, 50, 50)
|
||||
self.ssl_field = self.getControl(VERIFY_SSL)
|
||||
|
||||
self.port_field.setText('32400')
|
||||
self.setFocus(self.host_field)
|
||||
self.ssl_field.setSelected(True)
|
||||
|
||||
self.host_field.controlUp(self.cancel_button)
|
||||
self.host_field.controlDown(self.port_field)
|
||||
self.port_field.controlUp(self.host_field)
|
||||
self.port_field.controlDown(self.ssl_field)
|
||||
self.ssl_field.controlUp(self.port_field)
|
||||
self.ssl_field.controlDown(self.connect_button)
|
||||
self.connect_button.controlUp(self.ssl_field)
|
||||
self.cancel_button.controlDown(self.host_field)
|
||||
|
||||
def onClick(self, control):
|
||||
|
||||
if control == CONNECT:
|
||||
# Sign in to emby connect
|
||||
self._disable_error()
|
||||
|
||||
server = self.host_field.getText()
|
||||
|
@ -90,56 +90,42 @@ class ServerManual(xbmcgui.WindowXMLDialog):
|
|||
|
||||
elif self._connect_to_server(server, port):
|
||||
self.close()
|
||||
|
||||
elif control == CANCEL:
|
||||
# Remind me later
|
||||
self.close()
|
||||
elif control == HOST_SSL_PATH:
|
||||
if self.host_ssl_path_radio.isSelected():
|
||||
# Let the user choose path to the certificate (=file)
|
||||
self.host_ssl_path = xbmcgui.Dialog().browse(
|
||||
1, lang(29999), 'files', '', False, False, '', False)
|
||||
log.debug('Host SSL file path chosen: %s' % self.host_ssl_path)
|
||||
if not self.host_ssl_path:
|
||||
self.host_ssl_path_radio.setSelected(False)
|
||||
else:
|
||||
self.host_ssl_path = tryDecode(self.host_ssl_path)
|
||||
else:
|
||||
# User disabled
|
||||
# Ensure that we don't have a host certificate set
|
||||
self.host_ssl_path = None
|
||||
|
||||
def onAction(self, action):
|
||||
|
||||
if self.error == ERROR['Empty'] and self.host_field.getText() and self.port_field.getText():
|
||||
if (self.error == ERROR['Empty'] and
|
||||
self.host_field.getText() and self.port_field.getText()):
|
||||
self._disable_error()
|
||||
|
||||
if action in (ACTION_BACK, ACTION_PARENT_DIR, ACTION_PREVIOUS_MENU):
|
||||
self.close()
|
||||
|
||||
def _add_editcontrol(self, x, y, height, width):
|
||||
control = xbmcgui.ControlEdit(
|
||||
0, 0, 0, 0,
|
||||
label="User",
|
||||
font="font10",
|
||||
textColor="ffc2c2c2",
|
||||
focusTexture=join(MEDIA, "button-focus.png"),
|
||||
noFocusTexture=join(MEDIA, "button-focus.png"))
|
||||
control.setPosition(x, y)
|
||||
control.setHeight(height)
|
||||
control.setWidth(width)
|
||||
|
||||
self.addControl(control)
|
||||
return control
|
||||
|
||||
def _add_radiobutton(self, x, y, height, width):
|
||||
control = xbmcgui.ControlRadioButton(
|
||||
0, 0, 0, 0,
|
||||
label="",
|
||||
font="font10",
|
||||
textColor="ffc2c2c2",
|
||||
focusOnTexture=join(MEDIA, "radio-on.png"),
|
||||
noFocusOnTexture=join(MEDIA, "radio-on.png"),
|
||||
focusOffTexture=join(MEDIA, "radio-off.png"),
|
||||
noFocusOffTexture=join(MEDIA, "radio-off.png"))
|
||||
control.setPosition(x, y)
|
||||
control.setHeight(height)
|
||||
control.setWidth(width)
|
||||
|
||||
self.addControl(control)
|
||||
return control
|
||||
|
||||
def _connect_to_server(self, server, port):
|
||||
|
||||
server_address = "%s:%s" % (server, port)
|
||||
self._message("%s %s..." % (lang(30023), server_address))
|
||||
result = self.connect_manager.connectToAddress(server_address)
|
||||
|
||||
"""Returns True if we could connect, False otherwise"""
|
||||
url = "%s:%s" % (server, port)
|
||||
self._message("%s %s..." % (lang(30023), url))
|
||||
options = {
|
||||
'verify': True if self.verify_ssl_radio.isSelected() else False
|
||||
}
|
||||
if self.host_ssl_path:
|
||||
options['cert'] = self.host_ssl_path
|
||||
result = self.connect_manager.connectToAddress(url, options)
|
||||
log.debug('Received the following results: %s' % result)
|
||||
if result['State'] == CONN_STATE['Unavailable']:
|
||||
self._message(lang(30204))
|
||||
return False
|
||||
|
@ -148,17 +134,17 @@ class ServerManual(xbmcgui.WindowXMLDialog):
|
|||
return True
|
||||
|
||||
def _message(self, message):
|
||||
|
||||
"""Displays a message popup just underneath the dialog"""
|
||||
self.error_msg.setLabel(message)
|
||||
self.error_toggle.setVisibleCondition('True')
|
||||
|
||||
def _error(self, state, message):
|
||||
|
||||
"""Displays an error message just underneath the dialog"""
|
||||
self.error = state
|
||||
self.error_msg.setLabel(message)
|
||||
self.error_toggle.setVisibleCondition('True')
|
||||
|
||||
def _disable_error(self):
|
||||
|
||||
"""Disables the message popup just underneath the dialog"""
|
||||
self.error = None
|
||||
self.error_toggle.setVisibleCondition('False')
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<centerleft>50%</centerleft>
|
||||
<centertop>50%</centertop>
|
||||
<width>560</width>
|
||||
<height>560</height>
|
||||
<height>656</height>
|
||||
<textcolor>white</textcolor>
|
||||
<control type="image">
|
||||
<top>-20</top>
|
||||
|
@ -20,7 +20,7 @@
|
|||
<description>Background box</description>
|
||||
<texture colordiffuse="ff111111">white.png</texture>
|
||||
<width>600</width>
|
||||
<height>600</height>
|
||||
<height>636</height>
|
||||
</control>
|
||||
<control type="image">
|
||||
<description>Plex logo</description>
|
||||
|
@ -43,47 +43,104 @@
|
|||
<description>Container for spacing</description>
|
||||
<top>80</top>
|
||||
<left>0</left>
|
||||
<height>480</height>
|
||||
<height>400</height>
|
||||
<width>560</width>
|
||||
<aligny>top</aligny>
|
||||
<font>font6</font>
|
||||
<control type="label">
|
||||
<height>50</height>
|
||||
<width>560</width>
|
||||
<description>PMS IP address or host name</description>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30019]</label>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30019]:</label>
|
||||
<font>font10</font>
|
||||
</control>
|
||||
<control type="edit" id="1">
|
||||
<control type="edit" id="208">
|
||||
<height>50</height>
|
||||
<width>560</width>
|
||||
<font>font4</font>
|
||||
<hinttext>https://192.168.1.2, https://myserver.com</hinttext>
|
||||
<font>font10</font>
|
||||
</control>
|
||||
<control type="label">
|
||||
<height>50</height>
|
||||
<width>560</width>
|
||||
<description>Port Number</description>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30030]</label>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30030]:</label>
|
||||
<font>font10</font>
|
||||
</control>
|
||||
<control type="edit" id="2">
|
||||
<control type="edit" id="209">
|
||||
<height>50</height>
|
||||
<width>560</width>
|
||||
<font>font4</font>
|
||||
<font>font10</font>
|
||||
</control>
|
||||
<control type="label">
|
||||
<description>Advanced</description>
|
||||
<height>50</height>
|
||||
<width>560</width>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30022]:</label>
|
||||
<font>font10</font>
|
||||
</control>
|
||||
<control type="radiobutton" id="204">
|
||||
<description>Verify SSL Certificate</description>
|
||||
<width>560</width>
|
||||
<description>Verify Host SSL Certificate</description>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30500]</label>
|
||||
<font>font10</font>
|
||||
</control>
|
||||
<control type="radiobutton" id="205">
|
||||
<description>Client SSL certificate</description>
|
||||
<width>560</width>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30501]</label>
|
||||
<font>font10</font>
|
||||
</control>
|
||||
</control>
|
||||
<control type="group">
|
||||
<description>Buttons group</description>
|
||||
<top>480</top>
|
||||
<left>50</left>
|
||||
<width>460</width>
|
||||
<height>100</height>
|
||||
<control type="button" id="200">
|
||||
<description>Connect</description>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30020]</label>
|
||||
<ondown>201</ondown>
|
||||
<label>[UPPERCASE][B]$ADDON[plugin.video.plexkodiconnect 30020][/UPPERCASE][/B]</label>
|
||||
<height>50</height>
|
||||
<width>460</width>
|
||||
<font>font10</font>
|
||||
<texturenofocus border="5" colordiffuse="ff464646">box.png</texturenofocus>
|
||||
<texturefocus border="5" colordiffuse="ff525252">box.png</texturefocus>
|
||||
<textcolor>ffa6a6a6</textcolor>
|
||||
<focusedcolor>white</focusedcolor>
|
||||
<align>center</align>
|
||||
</control>
|
||||
<control type="button" id="201">
|
||||
<description>Cancel</description>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30602]</label>
|
||||
<onup>200</onup>
|
||||
<label>[UPPERCASE][B]$ADDON[plugin.video.plexkodiconnect 30602][/UPPERCASE][/B]</label>
|
||||
<top>55</top>
|
||||
<height>50</height>
|
||||
<width>460</width>
|
||||
<font>font10</font>
|
||||
<texturenofocus border="5" colordiffuse="ff464646">box.png</texturenofocus>
|
||||
<texturefocus border="5" colordiffuse="ff525252">box.png</texturefocus>
|
||||
<textcolor>ffa6a6a6</textcolor>
|
||||
<focusedcolor>white</focusedcolor>
|
||||
<align>center</align>
|
||||
</control>
|
||||
</control>
|
||||
<control type="group" id="202">
|
||||
<top>626</top>
|
||||
<left>-20</left>
|
||||
<width>600</width>
|
||||
<visible>False</visible>
|
||||
<control type="image">
|
||||
<description>Error box</description>
|
||||
<texture colordiffuse="ff222222">white.png</texture>
|
||||
<width>100%</width>
|
||||
<height>50</height>
|
||||
</control>
|
||||
<control type="label" id="203">
|
||||
<description>Error message</description>
|
||||
<textcolor>white</textcolor>
|
||||
<font>font10</font>
|
||||
<aligny>center</aligny>
|
||||
<align>center</align>
|
||||
<height>50</height>
|
||||
</control>
|
||||
</control>
|
||||
</control>
|
||||
|
|
|
@ -80,10 +80,10 @@
|
|||
</control>
|
||||
|
||||
<control type="label">
|
||||
<description>Select server</description>
|
||||
<description>Select Main PMS</description>
|
||||
<textcolor>ffa6a6a6</textcolor>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30607]</label>
|
||||
<font>font10</font>
|
||||
<font>font12</font>
|
||||
<align>center</align>
|
||||
<aligny>top</aligny>
|
||||
<top>170</top>
|
||||
|
@ -205,7 +205,7 @@
|
|||
<description>Toggle plex.tv sign-in</description>
|
||||
<texturenofocus border="5" colordiffuse="ff464646">box.png</texturenofocus>
|
||||
<texturefocus border="5" colordiffuse="ff525252">box.png</texturefocus>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30600]</label>
|
||||
<label>[UPPERCASE][B]$ADDON[plugin.video.plexkodiconnect 30600][/UPPERCASE][/B]</label>
|
||||
<font>font10</font>
|
||||
<textcolor>ffa6a6a6</textcolor>
|
||||
<focusedcolor>white</focusedcolor>
|
||||
|
@ -221,7 +221,7 @@
|
|||
<description>Manually add server</description>
|
||||
<texturenofocus border="5" colordiffuse="ff464646">box.png</texturenofocus>
|
||||
<texturefocus border="5" colordiffuse="ff525252">box.png</texturefocus>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30601]</label>
|
||||
<label>[UPPERCASE][B]$ADDON[plugin.video.plexkodiconnect 30601][/UPPERCASE][/B]</label>
|
||||
<font>font10</font>
|
||||
<textcolor>ffa6a6a6</textcolor>
|
||||
<focusedcolor>white</focusedcolor>
|
||||
|
@ -239,7 +239,7 @@
|
|||
<description>Cancel</description>
|
||||
<texturenofocus border="5" colordiffuse="ff464646">box.png</texturenofocus>
|
||||
<texturefocus border="5" colordiffuse="ff525252">box.png</texturefocus>
|
||||
<label>$ADDON[plugin.video.plexkodiconnect 30602]</label>
|
||||
<label>[UPPERCASE][B]$ADDON[plugin.video.plexkodiconnect 30602][/UPPERCASE][/B]</label>
|
||||
<font>font10</font>
|
||||
<textcolor>ffa6a6a6</textcolor>
|
||||
<focusedcolor>white</focusedcolor>
|
||||
|
|
Loading…
Reference in a new issue