Merge pull request #159 from mcarlton00/quick-connect
Add quick connect authentication
This commit is contained in:
@@ -1087,3 +1087,11 @@ msgstr "Use cached widget data"
|
||||
msgctxt "#30442"
|
||||
msgid "Simple new content check"
|
||||
msgstr "Simple new content check"
|
||||
|
||||
msgctxt "#30443"
|
||||
msgid "Quick Connect"
|
||||
msgstr "Quick Connect"
|
||||
|
||||
msgctxt "#30444"
|
||||
msgid "Login using Quick Connect"
|
||||
msgstr "Login using Quick Connect"
|
||||
|
||||
@@ -203,3 +203,43 @@ class PlayNextDialog(xbmcgui.WindowXMLDialog):
|
||||
|
||||
def get_play_called(self):
|
||||
return self.play_called
|
||||
|
||||
|
||||
class QuickConnectDialog(xbmcgui.WindowXMLDialog):
|
||||
connect_method = -1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
|
||||
log.debug("QuickConnectDialog INITIALISED")
|
||||
|
||||
self.code = ''
|
||||
|
||||
def onInit(self):
|
||||
self.action_exitkeys_id = [10, 13]
|
||||
|
||||
message_control = self.getControl(3)
|
||||
message_control.setText(self.code)
|
||||
|
||||
message_control = self.getControl(4)
|
||||
message_control.setLabel(translate_string(30443))
|
||||
|
||||
self.getControl(3010).setLabel(translate_string(30444))
|
||||
self.getControl(3011).setLabel(translate_string(30365))
|
||||
|
||||
def onFocus(self, controlId):
|
||||
pass
|
||||
|
||||
def doAction(self, actionID):
|
||||
pass
|
||||
|
||||
def onClick(self, controlID):
|
||||
|
||||
if controlID == 3010:
|
||||
self.connect_method = 1
|
||||
self.close()
|
||||
if controlID == 3011:
|
||||
self.connect_method = 0
|
||||
self.close()
|
||||
|
||||
def getConnectMethod(self):
|
||||
return self.connect_method
|
||||
|
||||
@@ -14,6 +14,7 @@ from .kodi_utils import HomeWindow
|
||||
from .jellyfin import API
|
||||
from .lazylogger import LazyLogger
|
||||
from .utils import datetime_from_string, translate_string, save_user_details, load_user_details
|
||||
from .dialogs import QuickConnectDialog
|
||||
|
||||
log = LazyLogger(__name__)
|
||||
|
||||
@@ -209,9 +210,17 @@ def check_server(force=False, change_user=False, notify=False):
|
||||
# stop playback when switching users
|
||||
xbmc.Player().stop()
|
||||
|
||||
users, user_selection = user_select(api, current_username)
|
||||
auth = quick_connect(api)
|
||||
|
||||
if user_selection > -1:
|
||||
if auth:
|
||||
users = []
|
||||
user_selection = -1
|
||||
selected_user_name = auth.get('User', {}).get('Name')
|
||||
something_changed = True
|
||||
else:
|
||||
users, user_selection = user_select(api, current_username)
|
||||
|
||||
if not auth and user_selection > -1:
|
||||
|
||||
something_changed = True
|
||||
selected_user = users[user_selection]
|
||||
@@ -247,13 +256,14 @@ def check_server(force=False, change_user=False, notify=False):
|
||||
if kb.isConfirmed():
|
||||
password = kb.getText()
|
||||
|
||||
auth_payload = {'username': selected_user_name, 'pw': password}
|
||||
auth = api.authenticate(auth_payload)
|
||||
|
||||
if something_changed:
|
||||
home_window = HomeWindow()
|
||||
home_window.clear_property("jellycon_widget_reload")
|
||||
auth_payload = {'username': selected_user_name, 'pw': password}
|
||||
user = api.authenticate(auth_payload)
|
||||
token = user.get('AccessToken')
|
||||
user_id = user.get('User').get('Id')
|
||||
token = auth.get('AccessToken')
|
||||
user_id = auth.get('User').get('Id')
|
||||
save_user_details(selected_user_name, user_id, token)
|
||||
xbmc.executebuiltin("ActivateWindow(Home)")
|
||||
if "estuary_jellycon" in xbmc.getSkinDir():
|
||||
@@ -261,6 +271,54 @@ def check_server(force=False, change_user=False, notify=False):
|
||||
xbmc.executebuiltin("ReloadSkin()")
|
||||
|
||||
|
||||
def quick_connect(api):
|
||||
'''
|
||||
Log in using quick connect funcion
|
||||
'''
|
||||
settings = xbmcaddon.Addon()
|
||||
addon_path = settings.getAddonInfo('path')
|
||||
|
||||
result = api.get('/QuickConnect/Initiate')
|
||||
|
||||
if not isinstance(result, dict):
|
||||
log.debug('Quick connect is disabled on the server')
|
||||
return {}
|
||||
|
||||
code = result.get('Code')
|
||||
secret = result.get('Secret')
|
||||
|
||||
# Open Quick Connect dialog, ask to proceed
|
||||
qc_dialog = QuickConnectDialog("QuickConnectDialog.xml", addon_path, "default", "720p")
|
||||
qc_dialog.code = code
|
||||
qc_dialog.doModal()
|
||||
connect_method = qc_dialog.getConnectMethod()
|
||||
del qc_dialog
|
||||
|
||||
if connect_method < 1:
|
||||
# User backed out or selected manual login
|
||||
return {}
|
||||
|
||||
count = 0
|
||||
while count < 15:
|
||||
# Check the server to see if the auth request has been completed
|
||||
log.debug('Checking for quick connect auth: attempt {}'.format(count))
|
||||
check = api.get('/QuickConnect/Connect?secret={}'.format(secret))
|
||||
if check.get('Authenticated'):
|
||||
break
|
||||
count += 1
|
||||
xbmc.sleep(1000)
|
||||
|
||||
if not check.get('Authenticated'):
|
||||
log.info('Quick connect not authorized in 15 seconds, defaulting to manual authentication')
|
||||
return {}
|
||||
|
||||
# Retrieve authentication information
|
||||
auth = api.post('/Users/AuthenticateWithQuickConnect',
|
||||
{'secret': secret})
|
||||
|
||||
return auth
|
||||
|
||||
|
||||
def user_select(api, current_username):
|
||||
'''
|
||||
Display user selection screen
|
||||
|
||||
68
resources/skins/default/720p/QuickConnectDialog.xml
Normal file
68
resources/skins/default/720p/QuickConnectDialog.xml
Normal file
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<window id="3301" type="dialog">
|
||||
<defaultcontrol always="true">3010</defaultcontrol>
|
||||
<zorder>2</zorder>
|
||||
<coordinates>
|
||||
<system>1</system>
|
||||
<left>450</left>
|
||||
<top>200</top>
|
||||
</coordinates>
|
||||
<controls>
|
||||
|
||||
<control type="image">
|
||||
<left>0</left>
|
||||
<top>0</top>
|
||||
<width>400</width>
|
||||
<height>270</height>
|
||||
<texture border="40">bg.png</texture>
|
||||
</control>
|
||||
|
||||
<control type="label" id="4">
|
||||
<left>20</left>
|
||||
<top>5</top>
|
||||
<width>360</width>
|
||||
<height>50</height>
|
||||
<label>Heading</label>
|
||||
<font>font45_title</font>
|
||||
<align>center</align>
|
||||
</control>
|
||||
|
||||
<control type="textbox" id="3">
|
||||
<left>20</left>
|
||||
<top>65</top>
|
||||
<width>360</width>
|
||||
<height>50</height>
|
||||
<font>font45</font>
|
||||
<align>center</align>
|
||||
</control>
|
||||
|
||||
<control type="button" id="3010">
|
||||
<texturenofocus border="1" colordiffuse="ff161616">white.png</texturenofocus>
|
||||
<texturefocus border="1" colordiffuse="ff525252">white.png</texturefocus>
|
||||
<left>20</left>
|
||||
<top>135</top>
|
||||
<width>360</width>
|
||||
<height>40</height>
|
||||
<label></label>
|
||||
<onup></onup>
|
||||
<ondown>3011</ondown>
|
||||
<font>font14</font>
|
||||
<align>center</align>
|
||||
</control>
|
||||
|
||||
<control type="button" id="3011">
|
||||
<texturenofocus border="1" colordiffuse="ff161616">white.png</texturenofocus>
|
||||
<texturefocus border="1" colordiffuse="ff525252">white.png</texturefocus>
|
||||
<left>20</left>
|
||||
<top>195</top>
|
||||
<width>360</width>
|
||||
<height>40</height>
|
||||
<label></label>
|
||||
<onup>3010</onup>
|
||||
<ondown>3012</ondown>
|
||||
<font>font14</font>
|
||||
<align>center</align>
|
||||
</control>
|
||||
|
||||
</controls>
|
||||
</window>
|
||||
Reference in New Issue
Block a user