From d25c7b351ed5ad5f5ba47e3dfcd0aa43002e8a8e Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 28 May 2022 19:27:51 -0400 Subject: [PATCH 1/2] Default to using quick connect to log into server --- .../resource.language.en_gb/strings.po | 8 +++ resources/lib/server_detect.py | 49 ++++++++++++++++--- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index b0d978c..c118339 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -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" diff --git a/resources/lib/server_detect.py b/resources/lib/server_detect.py index 236a9ca..94c8dab 100644 --- a/resources/lib/server_detect.py +++ b/resources/lib/server_detect.py @@ -209,9 +209,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 +255,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 +270,34 @@ def check_server(force=False, change_user=False, notify=False): xbmc.executebuiltin("ReloadSkin()") +def quick_connect(api): + ''' + Log in using quick connect funcion + ''' + 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') + heading = "Quick Connect" + message = "Log in with the Jellyfin app: {}".format(code) + + response = xbmcgui.Dialog().ok(heading, message) + + while True: + check = api.get('/QuickConnect/Connect?secret={}'.format(secret)) + if check.get('Authenticated'): + break + + auth = api.post('/Users/AuthenticateWithQuickConnect', + {'secret': secret}) + + return auth + + def user_select(api, current_username): ''' Display user selection screen From b7c31fa7a0ff82d917978c6ed1ea8ddf215112f8 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 30 May 2022 15:27:35 -0400 Subject: [PATCH 2/2] Add custom dialog for quick connect --- resources/lib/dialogs.py | 40 +++++++++++ resources/lib/server_detect.py | 29 ++++++-- .../skins/default/720p/QuickConnectDialog.xml | 68 +++++++++++++++++++ 3 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 resources/skins/default/720p/QuickConnectDialog.xml diff --git a/resources/lib/dialogs.py b/resources/lib/dialogs.py index 6c7eae0..5018780 100644 --- a/resources/lib/dialogs.py +++ b/resources/lib/dialogs.py @@ -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 diff --git a/resources/lib/server_detect.py b/resources/lib/server_detect.py index 94c8dab..fa60c00 100644 --- a/resources/lib/server_detect.py +++ b/resources/lib/server_detect.py @@ -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__) @@ -274,6 +275,9 @@ 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): @@ -282,16 +286,33 @@ def quick_connect(api): code = result.get('Code') secret = result.get('Secret') - heading = "Quick Connect" - message = "Log in with the Jellyfin app: {}".format(code) - response = xbmcgui.Dialog().ok(heading, message) + # 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 - while True: + 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}) diff --git a/resources/skins/default/720p/QuickConnectDialog.xml b/resources/skins/default/720p/QuickConnectDialog.xml new file mode 100644 index 0000000..402739a --- /dev/null +++ b/resources/skins/default/720p/QuickConnectDialog.xml @@ -0,0 +1,68 @@ + + + 3010 + 2 + + 1 + 450 + 200 + + + + + 0 + 0 + 400 + 270 + bg.png + + + + 20 + 5 + 360 + 50 + + font45_title + center + + + + 20 + 65 + 360 + 50 + font45 + center + + + + white.png + white.png + 20 + 135 + 360 + 40 + + + 3011 + font14 + center + + + + white.png + white.png + 20 + 195 + 360 + 40 + + 3010 + 3012 + font14 + center + + + +