Index: components/cloud_devices/tools/prototype/prototype.py |
diff --git a/components/cloud_devices/tools/prototype/prototype.py b/components/cloud_devices/tools/prototype/prototype.py |
index 851b54d482c4585d9bc71a36cdada8be63f01c16..2e2d92330545759d14f6a623078be9a74557b131 100755 |
--- a/components/cloud_devices/tools/prototype/prototype.py |
+++ b/components/cloud_devices/tools/prototype/prototype.py |
@@ -6,74 +6,75 @@ |
# This prototype has tons of flaws, not the least of which being that it |
# occasionally will block while waiting for commands to finish. However, this is |
# a quick sketch. |
+# Script requires following components: |
+# sudo apt-get install python-tornado |
+# sudo apt-get install python-pip |
+# sudo pip install google-api-python-client |
-import subprocess |
-import json |
-import tornado.httpserver |
-import tornado.ioloop |
-import time |
import atexit |
-import apiclient.errors |
-from apiclient.discovery import build_from_document |
-from oauth2client.client import OAuth2WebServerFlow |
-from oauth2client.file import Storage |
-import oauth2client.client |
+import base64 |
import datetime |
import httplib2 |
+import json |
import os |
+import subprocess |
+import time |
import traceback |
-import urlparse |
-import base64 |
+ |
+from apiclient.discovery import build_from_document |
+from apiclient.errors import HttpError |
+from oauth2client.client import AccessTokenRefreshError |
+from oauth2client.client import OAuth2WebServerFlow |
+from oauth2client.file import Storage |
+from tornado.httpserver import HTTPServer |
+from tornado.ioloop import IOLoop |
_OAUTH_SCOPE = 'https://www.googleapis.com/auth/clouddevices' |
+_API_CLIENT_FILE = 'config.json' |
+_API_DISCOVERY_FILE = 'discovery.json' |
+ |
DEVICE_DRAFT = { |
- "systemName": "LEDFlasher", |
- "deviceKind": "vendor", |
- "displayName": "LED Flasher", |
- "channel": |
- { |
- "supportedType": "xmpp" |
- }, |
- "commands": |
- { |
- "base": |
- { |
- "vendorCommands": |
- [ |
- { |
- "name": "flashLED", |
- "parameter" : [{ |
- "name": "times", |
- "type": "string" |
- }] |
- } |
- ] |
- } |
+ 'systemName': 'LEDFlasher', |
+ 'deviceKind': 'vendor', |
+ 'displayName': 'LED Flasher', |
+ 'channel': { |
+ 'supportedType': 'xmpp' |
+ }, |
+ 'commands': { |
+ 'base': { |
+ 'vendorCommands': [{ |
+ 'name': 'flashLED', |
+ 'parameter' : [{ |
+ 'name': 'times', |
+ 'type': 'string' |
+ }] |
+ }] |
} |
} |
- |
-wpa_supplicant_cmd = "wpa_supplicant -Dwext -iwlan0 -cwpa_supplicant.conf" |
-ifconfig_cmd = "ifconfig wlan0 192.168.0.3" |
-hostapd_cmd = "hostapd hostapd-min.conf" |
-dhclient_release = "dhclient -r wlan0" |
-dhclient_renew = "dhclient wlan0" |
-dhcpd_cmd = "udhcpd -f /etc/udhcpd.conf" |
- |
- |
-wpa_supplicant_conf = "wpa_supplicant.conf" |
- |
-wpa_supplicant_template = """network={ |
- ssid="%s" |
- scan_ssid=1 |
- proto=WPA RSN |
- key_mgmt=WPA-PSK |
- pairwise=CCMP TKIP |
- group=CCMP TKIP |
- psk="%s" |
+} |
+ |
+wpa_supplicant_cmd = 'wpa_supplicant -Dwext -iwlan0 -cwpa_supplicant.conf' |
+ifconfig_cmd = 'ifconfig wlan0 192.168.0.3' |
+hostapd_cmd = 'hostapd hostapd-min.conf' |
+dhclient_release = 'dhclient -r wlan0' |
+dhclient_renew = 'dhclient wlan0' |
+dhcpd_cmd = 'udhcpd -f /etc/udhcpd.conf' |
+ |
+wpa_supplicant_conf = 'wpa_supplicant.conf' |
+ |
+wpa_supplicant_template = """ |
+network={ |
+ ssid="%s" |
+ scan_ssid=1 |
+ proto=WPA RSN |
+ key_mgmt=WPA-PSK |
+ pairwise=CCMP TKIP |
+ group=CCMP TKIP |
+ psk="%s" |
}""" |
-led_path = "/sys/class/leds/ath9k_htc-phy0/" |
+led_path = '/sys/class/leds/ath9k_htc-phy0/' |
class DeviceUnregisteredError(Exception): |
pass |
@@ -83,7 +84,7 @@ def ignore_errors(func): |
try: |
func(*args, **kwargs) |
except: |
- print "Got error in unsafe function:" |
+ print 'Got error in unsafe function:' |
traceback.print_exc() |
return inner |
@@ -107,31 +108,31 @@ class CommandWrapperFake(object): |
def __init__(self, cmd): |
self.cmd = cmd |
def start(self): |
- print "Start: ", self.cmd |
+ print 'Start: ', self.cmd |
def wait(self): |
- print "Wait: ", self.cmd |
+ print 'Wait: ', self.cmd |
def end(self): |
- print "End: ", self.cmd |
+ print 'End: ', self.cmd |
class CloudCommandHandlerFake(object): |
def __init__(self, ioloop): |
pass |
def handle_command(self, command_name, args): |
- if command_name == "flashLED": |
+ if command_name == 'flashLED': |
times = 1 |
- if "times" in args: |
- times = int(args["times"]) |
- print "Flashing LED %d times" % times |
+ if 'times' in args: |
+ times = int(args['times']) |
+ print 'Flashing LED %d times' % times |
class CloudCommandHandlerReal(object): |
def __init__(self, ioloop): |
self.ioloop = ioloop |
def handle_command(self, command_name, args): |
- if command_name == "flashLED": |
+ if command_name == 'flashLED': |
times = 1 |
- if "times" in args: |
- times = int(args["times"]) |
- print "Really flashing LED %d times" % times |
+ if 'times' in args: |
+ times = int(args['times']) |
+ print 'Really flashing LED %d times' % times |
self.flash_led(times) |
@ignore_errors |
def flash_led(self, times): |
@@ -140,12 +141,12 @@ class CloudCommandHandlerReal(object): |
if not times: |
return |
- file_trigger = open(os.path.join(led_path, "brightness"), "w") |
+ file_trigger = open(os.path.join(led_path, 'brightness'), 'w') |
if value: |
- file_trigger.write("1") |
+ file_trigger.write('1') |
else: |
- file_trigger.write("0") |
+ file_trigger.write('0') |
file_trigger.close() |
@@ -156,16 +157,16 @@ class WifiHandler(object): |
class Delegate: |
# Token is optional, and all delegates should support it being None |
def on_wifi_connected(self, token): |
- raise Exception("Unhandled condition: WiFi connected") |
+ raise Exception('Unhandled condition: WiFi connected') |
def __init__(self, ioloop, state, delegate): |
self.ioloop = ioloop |
self.state = state |
self.delegate = delegate |
def start(self): |
- raise Exception("Start not implemented!") |
+ raise Exception('Start not implemented!') |
def get_ssid(self): |
- raise Exception("Get SSID not implemented!") |
+ raise Exception('Get SSID not implemented!') |
# Note that by using CommandWrapperFake, you can run WifiHandlerReal on fake |
# devices for testing the wifi-specific logic |
@@ -190,7 +191,7 @@ class WifiHandlerReal(WifiHandler): |
self.dhcpd.start() |
def switch_to_wifi(self, ssid, passwd, token): |
try: |
- wpa_config = open(wpa_supplicant_conf, "w") |
+ wpa_config = open(wpa_supplicant_conf, 'w') |
wpa_config.write(wpa_supplicant_template % (ssid, passwd)) |
wpa_config.close() |
self.hostapd.end() |
@@ -219,20 +220,20 @@ class WifiHandlerPassthrough(WifiHandler): |
def start(self): |
self.delegate.on_wifi_connected(None) |
def switch_to_wifi(self, ssid, passwd, token): |
- raise Exception("Should not be reached") |
+ raise Exception('Should not be reached') |
def get_ssid(self): |
- return "dummy" |
+ return 'dummy' |
def setup_fake(): |
- print "Called setup" |
+ print 'Called setup' |
def setup_real(): |
- file_trigger = open(os.path.join(led_path, "trigger"), "w") |
- file_trigger.write("none") |
+ file_trigger = open(os.path.join(led_path, 'trigger'), 'w') |
+ file_trigger.write('none') |
file_trigger.close() |
-if os.path.exists("on_real_device"): |
+if os.path.exists('on_real_device'): |
CommandWrapper = CommandWrapperReal |
CommandWrapperMDns = CommandWrapperReal |
CloudCommandHandler = CloudCommandHandlerReal |
@@ -253,36 +254,36 @@ class State: |
self.credentials_ = None |
self.has_credentials_ = False |
self.has_wifi_ = False |
- self.ssid_ = "" |
- self.password_ = "" |
- self.device_id_ = "" |
+ self.ssid_ = '' |
+ self.password_ = '' |
+ self.device_id_ = '' |
def reset(self): |
self.clear() |
self.dump() |
def dump(self): |
json_obj = { |
- "has_credentials": self.has_credentials_, |
- "has_wifi": self.has_wifi_, |
- "ssid": self.ssid_, |
- "password": self.password_, |
- "device_id": self.device_id_ } |
- statefile = open("device_state.json", "w") |
+ 'has_credentials': self.has_credentials_, |
+ 'has_wifi': self.has_wifi_, |
+ 'ssid': self.ssid_, |
+ 'password': self.password_, |
+ 'device_id': self.device_id_ } |
+ statefile = open('device_state.json', 'w') |
json.dump(json_obj, statefile) |
statefile.close() |
if self.has_credentials_: |
self.oauth_storage_.put(self.credentials_) |
def load(self): |
- if os.path.exists("device_state.json"): |
- statefile = open("device_state.json", "r") |
+ if os.path.exists('device_state.json'): |
+ statefile = open('device_state.json', 'r') |
json_obj = json.load(statefile) |
statefile.close() |
- self.has_credentials_ = json_obj["has_credentials"] |
- self.has_wifi_ = json_obj["has_wifi"] |
- self.ssid_ = json_obj["ssid"] |
- self.password_ = json_obj["password"] |
- self.device_id_ = json_obj["device_id"] |
+ self.has_credentials_ = json_obj['has_credentials'] |
+ self.has_wifi_ = json_obj['has_wifi'] |
+ self.ssid_ = json_obj['ssid'] |
+ self.password_ = json_obj['password'] |
+ self.device_id_ = json_obj['device_id'] |
if self.has_credentials_: |
self.credentials_ = self.oauth_storage_.get() |
@@ -318,17 +319,17 @@ class MDnsWrapper: |
def __init__(self): |
self.avahi_wrapper = None |
self.setup_name = None |
- self.device_id = "" |
+ self.device_id = '' |
self.started = False |
def start(self): |
self.started = True |
self.run_command() |
def get_command(self): |
- cmd = ["avahi-publish", "-s", "Raspberry Pi" , "_privet._tcp", "8080", |
- "txtvers=2", "type=wifi", "ty=Raspberry Pi", |
- "id=" + self.device_id] |
+ cmd = ['avahi-publish', '-s', 'Raspberry Pi' , '_privet._tcp', '8080', |
+ 'txtvers=2', 'type=wifi', 'ty=Raspberry Pi', |
+ 'id=' + self.device_id] |
if self.setup_name: |
- cmd.append("setup=" + self.setup_name) |
+ cmd.append('setup=' + self.setup_name) |
return cmd |
def run_command(self): |
if self.avahi_wrapper: |
@@ -349,22 +350,36 @@ class MDnsWrapper: |
class CloudDevice: |
class Delegate: |
def on_device_started(self): |
- raise Exception("Not implemented: Device started") |
+ raise Exception('Not implemented: Device started') |
def on_device_stopped(self): |
- raise Exception("Not implemented: Device stopped") |
+ raise Exception('Not implemented: Device stopped') |
def __init__(self, ioloop, state, delegate): |
self.state = state |
self.http = httplib2.Http() |
+ if not os.path.isfile(_API_CLIENT_FILE): |
+ credentials = { |
+ 'oauth_client_id' : '', |
+ 'oauth_secret' : '', |
+ 'api_key' : '' |
+ } |
+ credentials_f = open(_API_CLIENT_FILE + '.samlpe', 'w') |
+ credentials_f.write(json.dumps(credentials)); |
+ credentials_f.close() |
+ raise Exception('Missing ' + _API_CLIENT_FILE); |
- credentials_f = open("api_client.json") |
+ credentials_f = open(_API_CLIENT_FILE) |
credentials = json.load(credentials_f) |
credentials_f.close() |
- self.oauth_client_id = credentials["oauth_client_id"] |
- self.oauth_secret = credentials["oauth_secret"] |
- self.api_key = credentials["api_key"] |
+ self.oauth_client_id = credentials['oauth_client_id'] |
+ self.oauth_secret = credentials['oauth_secret'] |
+ self.api_key = credentials['api_key'] |
+ |
+ if not os.path.isfile(_API_DISCOVERY_FILE): |
+ raise Exception('Download https://developers.google.com/' |
+ 'cloud-devices/v1/discovery.json'); |
- f = open("clouddevices.json") |
+ f = open('discovery.json') |
discovery = f.read() |
f.close() |
self.gcd = build_from_document( |
@@ -384,8 +399,8 @@ class CloudDevice: |
elif token: |
self.register(token) |
else: |
- print "Device not registered and has no credentials." |
- print "Waiting for registration." |
+ print 'Device not registered and has no credentials.' |
+ print 'Waiting for registration.' |
def register(self, token): |
resource = { |
'deviceDraft': DEVICE_DRAFT, |
@@ -405,7 +420,7 @@ class CloudDevice: |
self.credentials = flow.step2_exchange(authorization_code) |
self.device_id = finalTicket['deviceDraft']['id'] |
self.state.set_credentials(self.credentials, self.device_id) |
- print "Registered with device_id ", self.device_id |
+ print 'Registered with device_id ', self.device_id |
self.run_device() |
def run_device(self): |
@@ -413,11 +428,11 @@ class CloudDevice: |
try: |
dev=self.gcd.devices().get(deviceId=self.device_id).execute() |
- except apiclient.errors.HttpError, e: |
+ except HttpError, e: |
# Pretty good indication the device was deleted |
if e.resp.status == 404: |
raise DeviceUnregisteredError() |
- except oauth2client.client.AccessTokenRefreshError: |
+ except AccessTokenRefreshError: |
raise DeviceUnregisteredError() |
self.check_commands() |
@@ -426,29 +441,29 @@ class CloudDevice: |
if not self.active: |
return |
- print "Checking commands..." |
+ print 'Checking commands...' |
commands = self.gcd.commands().list(deviceId=self.device_id, |
- state="queued").execute() |
+ state='queued').execute() |
- if "commands" in commands: |
- print "Found ", len(commands["commands"]), " commands" |
+ if 'commands' in commands: |
+ print 'Found ', len(commands['commands']), ' commands' |
args = {} |
vendorCommandName = None |
- for command in commands["commands"]: |
+ for command in commands['commands']: |
try: |
- if command["name"].startswith("base._"): |
- vendorCommandName = command["name"][ |
- len("base._"):] |
- if "parameters" in command: |
- parameters = command["parameters"] |
+ if command['name'].startswith('base._'): |
+ vendorCommandName = command['name'][ |
+ len('base._'):] |
+ if 'parameters' in command: |
+ parameters = command['parameters'] |
else: |
parameters = {} |
else: |
vendorCommandName = None |
except KeyError: |
- print "Could not parse vendor command ", |
+ print 'Could not parse vendor command ', |
print repr(command) |
vendorCommandName = None |
@@ -457,10 +472,10 @@ class CloudDevice: |
vendorCommandName, |
parameters) |
- self.gcd.commands().patch(commandId = command["id"], |
- body={"state": "done"}).execute() |
+ self.gcd.commands().patch(commandId = command['id'], |
+ body={'state': 'done'}).execute() |
else: |
- print "Found no commands" |
+ print 'Found no commands' |
self.ioloop.add_timeout(datetime.timedelta(milliseconds=1000), |
self.check_commands) |
@@ -471,14 +486,14 @@ class CloudDevice: |
def get_only(f): |
def inner(self, request, response_func, *args): |
- if request.method != "GET": |
+ if request.method != 'GET': |
return False |
return f(self, request, response_func, *args) |
return inner |
def post_only(f): |
def inner(self, request, response_func, *args): |
- if request.method != "POST": |
+ if request.method != 'POST': |
return False |
return f(self, request, response_func, *args) |
return inner |
@@ -500,15 +515,15 @@ def post_provisioning(f): |
def extract_encryption_params(f): |
def inner(self, request, response_func, *args): |
try: |
- client_id = request.headers["X-Privet-Client-ID"] |
- if "X-Privet-Encrypted" in request.headers: |
- encrypted = (request.headers["X-Privet-Encrypted"].lower() |
- == "true") |
+ client_id = request.headers['X-Privet-Client-ID'] |
+ if 'X-Privet-Encrypted' in request.headers: |
+ encrypted = (request.headers['X-Privet-Encrypted'].lower() |
+ == 'true') |
else: |
encrypted = False |
except (KeyError, TypeError): |
- print "Missing client parameters in headers" |
- response_func(400, { "error": "missing_client_parameters" }) |
+ print 'Missing client parameters in headers' |
+ response_func(400, { 'error': 'missing_client_parameters' }) |
return True |
return f(self, request, response_func, client_id, encrypted, *args) |
@@ -560,7 +575,7 @@ class DummySession: |
def get_client_id(self): |
return client_id |
def get_stype(self): |
- return "dummy" |
+ return 'dummy' |
class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate): |
def __init__(self, ioloop, state): |
@@ -572,15 +587,15 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate): |
self.in_session = False |
self.ioloop = ioloop |
self.handlers = { |
- "/internal/ping": self.do_ping, |
- "/privet/info": self.do_info, |
- "/deprecated/wifi/switch": self.do_wifi_switch, |
- "/privet/v2/session/handshake": self.do_session_handshake, |
- "/privet/v2/session/cancel": self.do_session_cancel, |
- "/privet/v2/session/api": self.do_session_api, |
- "/privet/v2/setup/start": self.get_insecure_api_handler( |
+ '/internal/ping': self.do_ping, |
+ '/privet/info': self.do_info, |
+ '/deprecated/wifi/switch': self.do_wifi_switch, |
+ '/privet/v2/session/handshake': self.do_session_handshake, |
+ '/privet/v2/session/cancel': self.do_session_cancel, |
+ '/privet/v2/session/api': self.do_session_api, |
+ '/privet/v2/setup/start': self.get_insecure_api_handler( |
self.do_secure_setup), |
- "/privet/v2/setup/status": self.get_insecure_api_handler( |
+ '/privet/v2/setup/status': self.get_insecure_api_handler( |
self.do_secure_status), |
} |
@@ -588,27 +603,27 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate): |
self.current_session = None |
self.session_cancel_callback = None |
self.session_handlers = { |
- "dummy" : DummySession |
+ 'dummy' : DummySession |
} |
self.secure_handlers = { |
- "/privet/v2/setup/start" : self.do_secure_setup, |
- "/privet/v2/setup/status" : self.do_secure_status |
+ '/privet/v2/setup/start' : self.do_secure_setup, |
+ '/privet/v2/setup/status' : self.do_secure_status |
} |
def start(self): |
self.wifi_handler.start() |
- self.mdns_wrapper.set_setup_name("RaspberryPi.camera.privet") |
+ self.mdns_wrapper.set_setup_name('RaspberryPi.camera.privet') |
self.mdns_wrapper.start() |
@get_only |
def do_ping(self, request, response_func): |
- response_func(200, "{ \"pong\": true }") |
+ response_func(200, '{ "pong": true }') |
return True |
@get_only |
def do_public_info(self, request, response_func): |
info = merge_dictionary( |
self.get_common_info(), |
{ |
- "stype" : self.session_handlers.keys() |
+ 'stype' : self.session_handlers.keys() |
}) |
self.real_send_response( |
@@ -617,7 +632,7 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate): |
@get_only |
def do_info(self, request, response_func): |
specific_info = { |
- "x-privet-token": "sample", |
+ 'x-privet-token': 'sample', |
} |
info = merge_dictionary( |
@@ -632,16 +647,16 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate): |
def do_wifi_switch(self, request, response_func): |
data = json.loads(request.body) |
try: |
- ssid = data["ssid"] |
- passw = data["passw"] |
+ ssid = data['ssid'] |
+ passw = data['passw'] |
except KeyError: |
- print "Malformed content: " + repr(data) |
+ print 'Malformed content: ' + repr(data) |
self.real_send_response( |
- request, 400, { "error": "invalid_params" }) |
+ request, 400, { 'error': 'invalid_params' }) |
traceback.print_exc() |
return True |
- response_func(200, { "ssid": ssid } ) |
+ response_func(200, { 'ssid': ssid } ) |
self.wifi_handler.switch_to_wifi(ssid, passw, None) |
# TODO: Return to normal wifi after timeout (cancelable) |
return True |
@@ -652,29 +667,29 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate): |
encrypted): |
data = json.loads(request.body) |
try: |
- stype = data["stype"] |
- step = data["step"] |
- package = base64.b64decode(data["package"]) |
+ stype = data['stype'] |
+ step = data['step'] |
+ package = base64.b64decode(data['package']) |
except (KeyError, TypeError): |
traceback.print_exc() |
- print "Malformed content: " + repr(data) |
+ print 'Malformed content: ' + repr(data) |
self.real_send_response( |
- request, 400, { "error": "invalid_params" }) |
+ request, 400, { 'error': 'invalid_params' }) |
return True |
if self.current_session: |
if client_id != self.current_session.get_client_id(): |
self.real_send_response( |
- request, 500, { "error": "in_session" }) |
+ request, 500, { 'error': 'in_session' }) |
return True |
if stype != self.current_session.get_stype(): |
self.real_send_response( |
- request, 500, { "error": "invalid_stype" }) |
+ request, 500, { 'error': 'invalid_stype' }) |
return True |
else: |
if stype not in self.session_handlers: |
self.real_send_response( |
- request, 500, { "error": "invalid_stype" }) |
+ request, 500, { 'error': 'invalid_stype' }) |
return True |
self.current_session = self.session_handlers[stype](client_id) |
@@ -682,17 +697,17 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate): |
output_package = self.current_session.do_step(step, package) |
except InvalidStepError: |
self.real_send_response( |
- request, 500, { "error": "invalid_step" }) |
+ request, 500, { 'error': 'invalid_step' }) |
return True |
except InvalidPackageError: |
self.real_send_response( |
- request, 500, { "error": "invalid_step" }) |
+ request, 500, { 'error': 'invalid_step' }) |
return True |
return_obj = { |
- "stype" : stype, |
- "step" : step, |
- "package": base64.b64encode(output_package)} |
+ 'stype' : stype, |
+ 'step' : step, |
+ 'package': base64.b64encode(output_package)} |
self.real_send_response( |
request, 200, json.dumps(return_obj)) |
@@ -710,48 +725,48 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate): |
self.session_cancel_callback.cancel() |
else: |
self.real_send_response( |
- request, 400, { "error": "invalid_client_id" }) |
+ request, 400, { 'error': 'invalid_client_id' }) |
return True |
@extract_encryption_params |
@post_only |
@wifi_provisioning |
def do_session_api(self, request, response_func, client_id, encrypted): |
if not encrypted: |
- response_func(400, { "error": "encryption_required" }) |
+ response_func(400, { 'error': 'encryption_required' }) |
return True |
if (not self.current_session or |
client_id != self.current_session.client_id): |
- response_func(405, { "error": "invalid_client_id" }) |
+ response_func(405, { 'error': 'invalid_client_id' }) |
return True |
try: |
decrypted = self.current_session.decrypt(request.body) |
except EncryptionError: |
- response_func(415, { "error": "decryption_failed" }) |
+ response_func(415, { 'error': 'decryption_failed' }) |
return True |
def encrypted_response_func(code, data): |
- if "error" in data: |
+ if 'error' in data: |
self.encrypted_send_response(request, code, data) |
else: |
self.encrypted_send_response(request, code, { |
- "api": decrypted["api"], |
- "response": data}) |
+ 'api': decrypted['api'], |
+ 'response': data}) |
- if ("api" not in decrypted or "request" not in decrypted |
- or type(decrypted["request"]) != dict): |
- print "Invalid params in API stage" |
- encrypted_response_func(400, { "error": "invalid_params" }) |
+ if ('api' not in decrypted or 'request' not in decrypted |
+ or type(decrypted['request']) != dict): |
+ print 'Invalid params in API stage' |
+ encrypted_response_func(400, { 'error': 'invalid_params' }) |
return True |
- if decrypted["api"] in self.secure_handlers: |
- self.secure_handlers[decrypted["api"]](request, |
+ if decrypted['api'] in self.secure_handlers: |
+ self.secure_handlers[decrypted['api']](request, |
encrypted_response_func, |
- decrypted["request"]) |
+ decrypted['request']) |
else: |
- encrypted_response_func(400, { "error": "unknown_api" }) |
+ encrypted_response_func(400, { 'error': 'unknown_api' }) |
self.post_session_cancel() |
return True |
@@ -765,63 +780,63 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate): |
return True |
def do_secure_setup(self, request, response_func, params): |
setup_handlers = { |
- "start": self.do_setup_start, |
- "cancel": self.do_setup_cancel } |
+ 'start': self.do_setup_start, |
+ 'cancel': self.do_setup_cancel } |
- if not "action" in params: |
- response_func(400, { "error": "invalid_params" }) |
+ if not 'action' in params: |
+ response_func(400, { 'error': 'invalid_params' }) |
return |
- if params["action"] not in setup: |
- response_func(400, { "error": "invalid_action" }) |
+ if params['action'] not in setup: |
+ response_func(400, { 'error': 'invalid_action' }) |
return |
- setup[params["action"]](request, response_func, params) |
+ setup[params['action']](request, response_func, params) |
def do_secure_status(self, request, response_func, params): |
setup = { |
- "registration" : { |
- "required" : True |
+ 'registration' : { |
+ 'required' : True |
}, |
- "wifi" : { |
- "required" : True |
+ 'wifi' : { |
+ 'required' : True |
} |
} |
if self.on_wifi: |
- setup["wifi"]["status"] = "complete" |
- setup["wifi"]["ssid"] = "" # TODO(noamsml): Add SSID to status |
+ setup['wifi']['status'] = 'complete' |
+ setup['wifi']['ssid'] = '' # TODO(noamsml): Add SSID to status |
else: |
- setup["wifi"]["status"] = "available" |
+ setup['wifi']['status'] = 'available' |
if self.cloud_device.get_device_id(): |
- setup["registration"]["status"] = "complete" |
- setup["registration"]["id"] = self.cloud_device.get_device_id() |
+ setup['registration']['status'] = 'complete' |
+ setup['registration']['id'] = self.cloud_device.get_device_id() |
else: |
- specific_info["setup"]["registration"] = "available" |
+ specific_info['setup']['registration'] = 'available' |
def do_setup_start(self, request, response_func, params): |
has_wifi = False |
token = None |
try: |
- if "wifi" in params: |
+ if 'wifi' in params: |
has_wifi = True |
- ssid = params["wifi"]["ssid"] |
- passw = params["wifi"]["passphrase"] |
+ ssid = params['wifi']['ssid'] |
+ passw = params['wifi']['passphrase'] |
- if "registration" in params: |
- token = params["registration"]["ticketID"] |
+ if 'registration' in params: |
+ token = params['registration']['ticketID'] |
except KeyError: |
- print "Invalid params in bootstrap stage" |
- response_func(400, { "error": "invalid_params" }) |
+ print 'Invalid params in bootstrap stage' |
+ response_func(400, { 'error': 'invalid_params' }) |
return |
- response_func(200, { "ssid" : ssid }) |
+ response_func(200, { 'ssid' : ssid }) |
if has_wifi: |
self.wifi_handler.switch_to_wifi(ssid, passw, token) |
elif token: |
self.cloud_device.register(token) |
else: |
- response_func(400, { "error": "invalid_params" }) |
+ response_func(400, { 'error': 'invalid_params' }) |
def do_setup_cancel(self, request, response_func, params): |
pass |
def handle_request(self, request): |
@@ -834,24 +849,24 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate): |
if not handled: |
self.real_send_response(request, 404, |
- { "error": "Not found" }) |
+ { 'error': 'Not found' }) |
def encrypted_send_response(self, request, code, json): |
self.real_send_response(request, code, |
self.current_session.encrypt(json)) |
def real_send_response(self, request, code, data): |
- request.write("HTTP/1.1 %d Maybe OK\n" % code) |
- request.write("Content-Type: application/json\n") |
- request.write("Content-Length: %d\n" % len(data)) |
- write_data = "\n%s" % data |
+ request.write('HTTP/1.1 %d Maybe OK\n' % code) |
+ request.write('Content-Type: application/json\n') |
+ request.write('Content-Length: %d\n' % len(data)) |
+ write_data = '\n%s' % data |
request.write(str(write_data)); |
request.finish() |
def device_state(self): |
- return "idle" |
+ return 'idle' |
def get_common_info(self): |
- return { "version" : "2.0", |
- "name" : "Sample Device", |
- "device_state" : self.device_state() } |
+ return { 'version' : '2.0', |
+ 'name' : 'Sample Device', |
+ 'device_state' : self.device_state() } |
def post_session_cancel(self): |
if self.session_cancel_callback: |
self.session_cancel_callback.cancel() |
@@ -876,7 +891,7 @@ class WebRequestHandler(WifiHandler.Delegate, CloudDevice.Delegate): |
state = State() |
state.load() |
-ioloop = tornado.ioloop.IOLoop.instance() |
+ioloop = IOLoop.instance() |
handler = WebRequestHandler(ioloop, state) |
@@ -887,6 +902,6 @@ def logic_stop(): |
atexit.register(logic_stop) |
-server = tornado.httpserver.HTTPServer(handler.handle_request) |
+server = HTTPServer(handler.handle_request) |
server.listen(8080) |
ioloop.start() |