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/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 236a9ca..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__) @@ -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 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 + + + +