Skip to content

Instantly share code, notes, and snippets.

@jrlucier
Last active March 15, 2018 02:06
Show Gist options
  • Save jrlucier/90d0db3c46d81e42c0854603dd07d316 to your computer and use it in GitHub Desktop.
Save jrlucier/90d0db3c46d81e42c0854603dd07d316 to your computer and use it in GitHub Desktop.
import re
import json
import requests
from argparse import ArgumentParser
from abc import abstractproperty
__version__ = "0.0.1"
__all__ = ['ClientException', 'Eero', 'SessionStorage', '__version__']
'''
This can be deleted, but I'm keeping it here for debug
'''
def print_json(data):
print(json.dumps(data, indent=4))
class Eero(object):
def __init__(self, session):
# type(SessionStorage) -> ()
self.session = session
self.client = Client()
@property
def _cookie_dict(self):
if self.needs_login():
return dict()
else:
return dict(s=self.session.cookie)
def needs_login(self):
return self.session.cookie is None
def login(self, identifier):
# type(string) -> string
params = dict(login=identifier)
data = self.client.post('login', params=params)
return data['user_token']
def login_verify(self, verification_code, user_token):
params = dict(code=verification_code)
response = self.client.post('login/verify', params=params,
cookies=dict(s=user_token))
self.session.cookie = user_token
return response
def refreshed(self, func):
try:
return func()
except ClientException as exception:
if (exception.status == 401
and exception.error_message == 'error.session.refresh'):
self.login_refresh()
return func()
else:
raise
def login_refresh(self):
response = self.client.post('login/refresh', cookies=self._cookie_dict)
self.session.cookie = response['user_token']
def account(self):
return self.refreshed(lambda: self.client.get(
'account',
cookies=self._cookie_dict))
def id_from_url(self, id_or_url):
match = re.search('^[0-9]+$', id_or_url)
if match:
return match.group(0)
match = re.search(r'\/([0-9]+)$', id_or_url)
if match:
return match.group(1)
def devices(self, network_id):
return self.refreshed(lambda: self.client.get(
'networks/{}/devices'.format(
self.id_from_url(network_id)),
cookies=self._cookie_dict))
class SessionStorage(object):
@abstractproperty
def cookie(self):
pass
class ClientException(Exception):
def __init__(self, status, error_message):
super(ClientException, self).__init__()
self.status = status
self.error_message = error_message
class Client(object):
API_ENDPOINT = 'https://api-user.e2ro.com/2.2/{}'
def _parse_response(self, response):
data = json.loads(response.text)
if data['meta']['code'] is not 200 and data['meta']['code'] is not 201:
raise ClientException(data['meta']['code'],
data['meta'].get('error', ""))
return data.get('data', "")
def post(self, action, **kwargs):
response = requests.post(self.API_ENDPOINT.format(action), **kwargs)
return self._parse_response(response)
def get(self, action, **kwargs):
response = requests.get(self.API_ENDPOINT.format(action), **kwargs)
return self._parse_response(response)
class CookieStore(SessionStorage):
def __init__(self, cookie_file):
from os import path
self.cookie_file = path.abspath(cookie_file)
try:
with open(self.cookie_file, 'r') as f:
self.__cookie = f.read()
except IOError:
self.__cookie = None
@property
def cookie(self):
return self.__cookie
@cookie.setter
def cookie(self, cookie):
self.__cookie = cookie
with open(self.cookie_file, 'w+') as f:
f.write(self.__cookie)
session = CookieStore('session.cookie')
eero = Eero(session)
if __name__ == '__main__':
if eero.needs_login():
parser = ArgumentParser()
parser.add_argument("-l", help="your eero login (phone number)")
args = parser.parse_args()
if args.l:
phone_number = args.l
else:
phone_number = raw_input('your eero login (phone number): ')
user_token = eero.login(phone_number)
verification_code = raw_input('verification key from SMS: ')
eero.login_verify(verification_code, user_token)
print('Login successful. Rerun this command to get some output')
else:
account = eero.account()
for network in account['networks']['data']:
devices = eero.devices(network['url'])
json_obj = json.loads(json.dumps(devices, indent=4))
for device in json_obj:
if device['wireless'] and device['connected']:
print("{}, {}, {}".format(device['nickname'], device['hostname'], device['mac']))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment