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
|
# add-on settings
|
||||||
|
|
||||||
msgctxt "#30500"
|
msgctxt "#30500"
|
||||||
msgid "Verify Host SSL Certificate (more secure)"
|
msgid "Verify SSL Certificate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgctxt "#30501"
|
msgctxt "#30501"
|
||||||
|
|
|
@ -175,36 +175,38 @@ class ConnectionManager(object):
|
||||||
"application/x-www-form-urlencoded")
|
"application/x-www-form-urlencoded")
|
||||||
|
|
||||||
def requestUrl(self, request):
|
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:
|
...and all the other requests settings
|
||||||
raise AttributeError("Request cannot be null")
|
"""
|
||||||
|
|
||||||
self._getHeaders(request)
|
self._getHeaders(request)
|
||||||
request['timeout'] = request.get('timeout') or self.default_timeout
|
request['timeout'] = request.get('timeout') or self.default_timeout
|
||||||
request['verify'] = request.get('ssl') or False
|
|
||||||
|
|
||||||
action = request['type']
|
action = request['type']
|
||||||
request.pop('type', None)
|
request.pop('type', None)
|
||||||
request.pop('ssl', None)
|
|
||||||
|
|
||||||
log.debug("ConnectionManager requesting %s" % request)
|
log.debug("Requesting %s" % request)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = self._requests(action, **request)
|
r = self._requests(action, **request)
|
||||||
log.info("ConnectionManager response status: %s" % r.status_code)
|
log.info("ConnectionManager response status: %s" % r.status_code)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
|
except Exception as e:
|
||||||
except Exception as e: # Elaborate on exceptions?
|
# Elaborate on exceptions?
|
||||||
log.error(e)
|
log.error(e)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
return etree.fromstring(r.content)
|
return etree.fromstring(r.content)
|
||||||
except etree.ParseError:
|
except etree.ParseError:
|
||||||
# Read response to release connection
|
# Read response to release connection
|
||||||
r.content
|
r.content
|
||||||
return
|
raise
|
||||||
|
|
||||||
def _requests(self, action, **kwargs):
|
def _requests(self, action, **kwargs):
|
||||||
|
|
||||||
|
@ -284,25 +286,12 @@ class ConnectionManager(object):
|
||||||
GDM.close()
|
GDM.close()
|
||||||
return servers
|
return servers
|
||||||
|
|
||||||
def _normalizeAddress(self, address):
|
def connectToAddress(self, address, options=None):
|
||||||
# Attempt to correct bad input
|
log.debug('connectToAddress %s with options %s' % (address, options))
|
||||||
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 _onFail():
|
def _onFail():
|
||||||
log.error("connectToAddress %s failed" % address)
|
log.error("connectToAddress %s failed with options %s" %
|
||||||
|
(address, options))
|
||||||
return self._resolveFailure()
|
return self._resolveFailure()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -310,10 +299,10 @@ class ConnectionManager(object):
|
||||||
except Exception:
|
except Exception:
|
||||||
return _onFail()
|
return _onFail()
|
||||||
else:
|
else:
|
||||||
log.info("connectToAddress %s succeeded" % address)
|
|
||||||
server = {
|
server = {
|
||||||
'ManualAddress': address,
|
'ManualAddress': address,
|
||||||
'LastCONNECTIONMODE': CONNECTIONMODE['Manual']
|
'LastCONNECTIONMODE': CONNECTIONMODE['Manual'],
|
||||||
|
'options': options
|
||||||
}
|
}
|
||||||
self._updateServerInfo(server, publicInfo)
|
self._updateServerInfo(server, publicInfo)
|
||||||
server = self.connectToServer(server, options)
|
server = self.connectToServer(server, options)
|
||||||
|
@ -342,15 +331,15 @@ class ConnectionManager(object):
|
||||||
self._saveUserInfoIntoCredentials(server, result['User'])
|
self._saveUserInfoIntoCredentials(server, result['User'])
|
||||||
self.credentialProvider.getCredentials(credentials)
|
self.credentialProvider.getCredentials(credentials)
|
||||||
|
|
||||||
def _tryConnect(self, url, timeout=None, options={}):
|
def _tryConnect(self, url, timeout=None, options=None):
|
||||||
url = '%s/identity' % url
|
request = {
|
||||||
log.debug("tryConnect url: %s" % url)
|
'type': 'GET',
|
||||||
return self.requestUrl({
|
'url': '%s/identity' % url,
|
||||||
'type': "GET",
|
'timeout': timeout
|
||||||
'url': url,
|
}
|
||||||
'timeout': timeout,
|
if options:
|
||||||
'ssl': options.get('ssl')
|
request.update(options)
|
||||||
})
|
return self.requestUrl(request)
|
||||||
|
|
||||||
def _addAppInfoToConnectRequest(self):
|
def _addAppInfoToConnectRequest(self):
|
||||||
return "%s/%s" % (self.appName, self.appVersion)
|
return "%s/%s" % (self.appName, self.appVersion)
|
||||||
|
@ -365,7 +354,7 @@ class ConnectionManager(object):
|
||||||
'type': 'GET',
|
'type': 'GET',
|
||||||
'headers': {'X-Plex-Token': self.plexToken},
|
'headers': {'X-Plex-Token': self.plexToken},
|
||||||
'timeout': 5.0,
|
'timeout': 5.0,
|
||||||
'ssl': True})
|
'verify': True})
|
||||||
try:
|
try:
|
||||||
xml.attrib
|
xml.attrib
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -528,7 +517,6 @@ class ConnectionManager(object):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def connectToServer(self, server, options={}):
|
def connectToServer(self, server, options={}):
|
||||||
|
|
||||||
log.info("begin connectToServer")
|
log.info("begin connectToServer")
|
||||||
|
|
||||||
tests = []
|
tests = []
|
||||||
|
|
|
@ -6,11 +6,10 @@ from os.path import join
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
|
|
||||||
import connect.connectionmanager as connectionmanager
|
import connect.connectionmanager as connectionmanager
|
||||||
from utils import language as lang, tryEncode
|
from utils import language as lang, tryEncode, tryDecode
|
||||||
import variables as v
|
import variables as v
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log = getLogger("PLEX."+__name__)
|
log = getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
CONN_STATE = connectionmanager.CONNECTIONSTATE
|
CONN_STATE = connectionmanager.CONNECTIONSTATE
|
||||||
|
@ -22,24 +21,51 @@ CANCEL = 201
|
||||||
ERROR_TOGGLE = 202
|
ERROR_TOGGLE = 202
|
||||||
ERROR_MSG = 203
|
ERROR_MSG = 203
|
||||||
VERIFY_SSL = 204
|
VERIFY_SSL = 204
|
||||||
|
HOST_SSL_PATH = 205
|
||||||
|
PMS_IP = 208
|
||||||
|
PMS_PORT = 209
|
||||||
ERROR = {
|
ERROR = {
|
||||||
'Invalid': 1,
|
'Invalid': 1,
|
||||||
'Empty': 2
|
'Empty': 2
|
||||||
}
|
}
|
||||||
|
|
||||||
MEDIA = tryEncode(join(v.ADDON_PATH, 'resources', 'skins', 'default', 'media'))
|
MEDIA = tryEncode(join(v.ADDON_PATH, 'resources', 'skins', 'default', 'media'))
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
class ServerManual(xbmcgui.WindowXMLDialog):
|
class ServerManual(xbmcgui.WindowXMLDialog):
|
||||||
|
|
||||||
_server = None
|
_server = None
|
||||||
error = 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):
|
def set_connect_manager(self, connect_manager):
|
||||||
self.connect_manager = connect_manager
|
self.connect_manager = connect_manager
|
||||||
|
@ -50,34 +76,8 @@ class ServerManual(xbmcgui.WindowXMLDialog):
|
||||||
def get_server(self):
|
def get_server(self):
|
||||||
return self._server
|
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):
|
def onClick(self, control):
|
||||||
|
|
||||||
if control == CONNECT:
|
if control == CONNECT:
|
||||||
# Sign in to emby connect
|
|
||||||
self._disable_error()
|
self._disable_error()
|
||||||
|
|
||||||
server = self.host_field.getText()
|
server = self.host_field.getText()
|
||||||
|
@ -90,56 +90,42 @@ class ServerManual(xbmcgui.WindowXMLDialog):
|
||||||
|
|
||||||
elif self._connect_to_server(server, port):
|
elif self._connect_to_server(server, port):
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
elif control == CANCEL:
|
elif control == CANCEL:
|
||||||
# Remind me later
|
|
||||||
self.close()
|
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):
|
def onAction(self, action):
|
||||||
|
if (self.error == ERROR['Empty'] and
|
||||||
if self.error == ERROR['Empty'] and self.host_field.getText() and self.port_field.getText():
|
self.host_field.getText() and self.port_field.getText()):
|
||||||
self._disable_error()
|
self._disable_error()
|
||||||
|
|
||||||
if action in (ACTION_BACK, ACTION_PARENT_DIR, ACTION_PREVIOUS_MENU):
|
if action in (ACTION_BACK, ACTION_PARENT_DIR, ACTION_PREVIOUS_MENU):
|
||||||
self.close()
|
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):
|
def _connect_to_server(self, server, port):
|
||||||
|
"""Returns True if we could connect, False otherwise"""
|
||||||
server_address = "%s:%s" % (server, port)
|
url = "%s:%s" % (server, port)
|
||||||
self._message("%s %s..." % (lang(30023), server_address))
|
self._message("%s %s..." % (lang(30023), url))
|
||||||
result = self.connect_manager.connectToAddress(server_address)
|
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']:
|
if result['State'] == CONN_STATE['Unavailable']:
|
||||||
self._message(lang(30204))
|
self._message(lang(30204))
|
||||||
return False
|
return False
|
||||||
|
@ -148,17 +134,17 @@ class ServerManual(xbmcgui.WindowXMLDialog):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _message(self, message):
|
def _message(self, message):
|
||||||
|
"""Displays a message popup just underneath the dialog"""
|
||||||
self.error_msg.setLabel(message)
|
self.error_msg.setLabel(message)
|
||||||
self.error_toggle.setVisibleCondition('True')
|
self.error_toggle.setVisibleCondition('True')
|
||||||
|
|
||||||
def _error(self, state, message):
|
def _error(self, state, message):
|
||||||
|
"""Displays an error message just underneath the dialog"""
|
||||||
self.error = state
|
self.error = state
|
||||||
self.error_msg.setLabel(message)
|
self.error_msg.setLabel(message)
|
||||||
self.error_toggle.setVisibleCondition('True')
|
self.error_toggle.setVisibleCondition('True')
|
||||||
|
|
||||||
def _disable_error(self):
|
def _disable_error(self):
|
||||||
|
"""Disables the message popup just underneath the dialog"""
|
||||||
self.error = None
|
self.error = None
|
||||||
self.error_toggle.setVisibleCondition('False')
|
self.error_toggle.setVisibleCondition('False')
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<centerleft>50%</centerleft>
|
<centerleft>50%</centerleft>
|
||||||
<centertop>50%</centertop>
|
<centertop>50%</centertop>
|
||||||
<width>560</width>
|
<width>560</width>
|
||||||
<height>560</height>
|
<height>656</height>
|
||||||
<textcolor>white</textcolor>
|
<textcolor>white</textcolor>
|
||||||
<control type="image">
|
<control type="image">
|
||||||
<top>-20</top>
|
<top>-20</top>
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
<description>Background box</description>
|
<description>Background box</description>
|
||||||
<texture colordiffuse="ff111111">white.png</texture>
|
<texture colordiffuse="ff111111">white.png</texture>
|
||||||
<width>600</width>
|
<width>600</width>
|
||||||
<height>600</height>
|
<height>636</height>
|
||||||
</control>
|
</control>
|
||||||
<control type="image">
|
<control type="image">
|
||||||
<description>Plex logo</description>
|
<description>Plex logo</description>
|
||||||
|
@ -43,47 +43,104 @@
|
||||||
<description>Container for spacing</description>
|
<description>Container for spacing</description>
|
||||||
<top>80</top>
|
<top>80</top>
|
||||||
<left>0</left>
|
<left>0</left>
|
||||||
<height>480</height>
|
<height>400</height>
|
||||||
<width>560</width>
|
<width>560</width>
|
||||||
<aligny>top</aligny>
|
<aligny>top</aligny>
|
||||||
<font>font6</font>
|
|
||||||
<control type="label">
|
<control type="label">
|
||||||
<height>50</height>
|
<height>50</height>
|
||||||
<width>560</width>
|
<width>560</width>
|
||||||
<description>PMS IP address or host name</description>
|
<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>
|
||||||
<control type="edit" id="1">
|
<control type="edit" id="208">
|
||||||
<height>50</height>
|
<height>50</height>
|
||||||
<width>560</width>
|
<width>560</width>
|
||||||
<font>font4</font>
|
|
||||||
<hinttext>https://192.168.1.2, https://myserver.com</hinttext>
|
<hinttext>https://192.168.1.2, https://myserver.com</hinttext>
|
||||||
|
<font>font10</font>
|
||||||
</control>
|
</control>
|
||||||
<control type="label">
|
<control type="label">
|
||||||
<height>50</height>
|
<height>50</height>
|
||||||
<width>560</width>
|
<width>560</width>
|
||||||
<description>Port Number</description>
|
<description>Port Number</description>
|
||||||
<label>$ADDON[plugin.video.plexkodiconnect 30030]</label>
|
<label>$ADDON[plugin.video.plexkodiconnect 30030]:</label>
|
||||||
|
<font>font10</font>
|
||||||
</control>
|
</control>
|
||||||
<control type="edit" id="2">
|
<control type="edit" id="209">
|
||||||
<height>50</height>
|
<height>50</height>
|
||||||
<width>560</width>
|
<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>
|
||||||
<control type="radiobutton" id="204">
|
<control type="radiobutton" id="204">
|
||||||
|
<description>Verify SSL Certificate</description>
|
||||||
<width>560</width>
|
<width>560</width>
|
||||||
<description>Verify Host SSL Certificate</description>
|
|
||||||
<label>$ADDON[plugin.video.plexkodiconnect 30500]</label>
|
<label>$ADDON[plugin.video.plexkodiconnect 30500]</label>
|
||||||
|
<font>font10</font>
|
||||||
</control>
|
</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">
|
<control type="button" id="200">
|
||||||
<description>Connect</description>
|
<description>Connect</description>
|
||||||
<label>$ADDON[plugin.video.plexkodiconnect 30020]</label>
|
<label>[UPPERCASE][B]$ADDON[plugin.video.plexkodiconnect 30020][/UPPERCASE][/B]</label>
|
||||||
<ondown>201</ondown>
|
<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="button" id="201">
|
<control type="button" id="201">
|
||||||
<description>Cancel</description>
|
<description>Cancel</description>
|
||||||
<label>$ADDON[plugin.video.plexkodiconnect 30602]</label>
|
<label>[UPPERCASE][B]$ADDON[plugin.video.plexkodiconnect 30602][/UPPERCASE][/B]</label>
|
||||||
<onup>200</onup>
|
<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>
|
</control>
|
||||||
</control>
|
</control>
|
||||||
|
|
|
@ -80,10 +80,10 @@
|
||||||
</control>
|
</control>
|
||||||
|
|
||||||
<control type="label">
|
<control type="label">
|
||||||
<description>Select server</description>
|
<description>Select Main PMS</description>
|
||||||
<textcolor>ffa6a6a6</textcolor>
|
<textcolor>ffa6a6a6</textcolor>
|
||||||
<label>$ADDON[plugin.video.plexkodiconnect 30607]</label>
|
<label>$ADDON[plugin.video.plexkodiconnect 30607]</label>
|
||||||
<font>font10</font>
|
<font>font12</font>
|
||||||
<align>center</align>
|
<align>center</align>
|
||||||
<aligny>top</aligny>
|
<aligny>top</aligny>
|
||||||
<top>170</top>
|
<top>170</top>
|
||||||
|
@ -205,7 +205,7 @@
|
||||||
<description>Toggle plex.tv sign-in</description>
|
<description>Toggle plex.tv sign-in</description>
|
||||||
<texturenofocus border="5" colordiffuse="ff464646">box.png</texturenofocus>
|
<texturenofocus border="5" colordiffuse="ff464646">box.png</texturenofocus>
|
||||||
<texturefocus border="5" colordiffuse="ff525252">box.png</texturefocus>
|
<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>
|
<font>font10</font>
|
||||||
<textcolor>ffa6a6a6</textcolor>
|
<textcolor>ffa6a6a6</textcolor>
|
||||||
<focusedcolor>white</focusedcolor>
|
<focusedcolor>white</focusedcolor>
|
||||||
|
@ -221,7 +221,7 @@
|
||||||
<description>Manually add server</description>
|
<description>Manually add server</description>
|
||||||
<texturenofocus border="5" colordiffuse="ff464646">box.png</texturenofocus>
|
<texturenofocus border="5" colordiffuse="ff464646">box.png</texturenofocus>
|
||||||
<texturefocus border="5" colordiffuse="ff525252">box.png</texturefocus>
|
<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>
|
<font>font10</font>
|
||||||
<textcolor>ffa6a6a6</textcolor>
|
<textcolor>ffa6a6a6</textcolor>
|
||||||
<focusedcolor>white</focusedcolor>
|
<focusedcolor>white</focusedcolor>
|
||||||
|
@ -239,7 +239,7 @@
|
||||||
<description>Cancel</description>
|
<description>Cancel</description>
|
||||||
<texturenofocus border="5" colordiffuse="ff464646">box.png</texturenofocus>
|
<texturenofocus border="5" colordiffuse="ff464646">box.png</texturenofocus>
|
||||||
<texturefocus border="5" colordiffuse="ff525252">box.png</texturefocus>
|
<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>
|
<font>font10</font>
|
||||||
<textcolor>ffa6a6a6</textcolor>
|
<textcolor>ffa6a6a6</textcolor>
|
||||||
<focusedcolor>white</focusedcolor>
|
<focusedcolor>white</focusedcolor>
|
||||||
|
|
Loading…
Reference in a new issue