From 82fca74b051affc8914a0ec645cab526618cfc06 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Mon, 8 Jan 2018 11:37:59 -0800 Subject: [PATCH] Use a chain of objects for getting a session --- example.py | 125 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 100 insertions(+), 25 deletions(-) diff --git a/example.py b/example.py index 649dbd4..c2841c7 100644 --- a/example.py +++ b/example.py @@ -28,39 +28,114 @@ def print_devices(devices): print(device['alias']) +class Gateway(object): + def __init__(self, oauth_base, api_root): + self.oauth_base = oauth_base + self.api_root = api_root + + @classmethod + def discover(cls): + gw = wideq.gateway_info() + return cls(gw['empUri'], gw['thinqUri']) + + @classmethod + def load(cls, data): + return cls(data['oauth_base'], data['api_root']) + + def dump(self): + return {'oauth_base': self.oauth_base, 'api_root': self.api_root} + + def oauth_url(self): + return wideq.oauth_url(self.oauth_base) + + +class Auth(object): + def __init__(self, gateway, access_token): + self.gateway = gateway + self.access_token = access_token + + def start_session(self): + """Start an API session for the logged-in user. Return the + Session object and the user's devices. + """ + + session_info = wideq.login(self.gateway.api_root, self.access_token) + session_id = session_info['jsessionId'] + return Session(self, session_id), session_info['item'] + + def dump(self): + return self.access_token + + @classmethod + def load(cls, gateway, data): + return cls(gateway, data) + + +class Session(object): + def __init__(self, auth, session_id): + self.auth = auth + self.session_id = session_id + + def get_devices(self): + return wideq.get_devices(self.auth.gateway.api_root, + self.auth.access_token, + self.session_id) + + def dump(self): + return self.session_id + + @classmethod + def load(cls, auth, data): + return cls(auth, data) + + +def authenticate(gateway): + login_url = gateway.oauth_url() + print('Log in here:') + print(login_url) + print('Then paste the URL where the browser is redirected:') + callback_url = input() + access_token = wideq.parse_oauth_callback(callback_url) + return Auth(gateway, access_token) + + def example(): state = load_state() - # Get the URLs for the API. - if 'oauth_base' not in state and 'api_root' not in state: - gw = wideq.gateway_info() - state['oauth_base'] = gw['empUri'] - state['api_root'] = gw['thinqUri'] - save_state(state) - oauth_base = state['oauth_base'] - api_root = state['api_root'] + # Get the gateway, which contains the base URLs and hostnames for + # accessing the API. + if 'gateway' in state: + gateway = Gateway.load(state['gateway']) + else: + gateway = Gateway.discover() - # If we don't have an access token, authenticate. - if 'access_token' not in state: - login_url = wideq.oauth_url(oauth_base) - print('Log in here:') - print(login_url) - print('Then paste the URL where the browser is redirected:') - callback_url = input() - state['access_token'] = wideq.parse_oauth_callback(callback_url) + state['gateway'] = gateway.dump() save_state(state) - access_token = state['access_token'] - # If we don't have a session, log in. - if 'session_id' not in state: - session_info = wideq.login(api_root, access_token) - state['session_id'] = session_info['jsessionId'] + # Authenticate the user. + if 'auth' in state: + auth = Auth.load(gateway, state['auth']) + else: + auth = authenticate(gateway) + + state['auth'] = auth.dump() save_state(state) - print_devices(session_info['item']) - session_id = state['session_id'] - # Request a list of devices. - devices = wideq.get_devices(api_root, access_token, session_id) + # Start a session. + if 'session' in state: + session = Session.load(auth, state['session']) + devices = None + else: + session, devices = auth.start_session() + + state['session'] = session.dump() + save_state(state) + + # Request a list of devices, if we didn't get them "for free" + # already by starting the session. + if not devices: + devices = session.get_devices() + print_devices(devices)