Source

Cherry NAO / server.py

#from __future__ import print_function
import os
import json

import cherrypy
try:
	import naoqi
except ImportError:
	# mock the naoqi module so we can test this on a platform without naoqi
	import mock
	naoqi = mock.Mock(
		ALProxy=mock.Mock(
			return_value=mock.Mock(
				getRunningBehaviors=mock.Mock(
					return_value=[],
				),
				getInstalledBehaviors=mock.Mock(
					return_value=[],
				),
			)))

class BaseHandler(object):
	exposed = True

def load_al_module(name):
	"""
	Add a proxy to the AL Module named by `name` to the CherryPy request.
	"""
	cherrypy.serving.request.module = naoqi.ALProxy(name, 'localhost', 9559)

# install the AL Module Loader as a CherryPy tool.
cherrypy.tools.al_module_loader = cherrypy.Tool('before_handler', load_al_module)

class Behavior(BaseHandler):
	def GET(self):
		req = cherrypy.request
		name = req.behavior_name
		if not name in req.module.getInstalledBehaviors():
			raise cherrypy.NotFound()
		return name

	def PUT(self):
		"Install a new behavior"
		behavior_crg = cherrypy.request.body
		raise NotImplementedError()

class InstalledBehaviors(BaseHandler):
	def GET(self):
		req = cherrypy.request
		resp = cherrypy.response
		resp.headers['Content-Type'] = 'application/json'
		return json.dumps(req.module.getInstalledBehaviors())

class RunningBehaviors(BaseHandler):
	def GET(self):
		req = cherrypy.request
		resp = cherrypy.response
		resp.headers['Content-Type'] = 'application/json'
		return json.dumps(req.module.getRunningBehaviors())

	def POST(self):
		req = cherrypy.request
		name = req.body.read()
		req.module.post.runBehavior(name)

	def DELETE(self, name):
		req = cherrypy.request
		req.module.stopBehavior(name)

class Behaviors(BaseHandler):
	_cp_config = {
		'tools.al_module_loader.on': True,
		'tools.al_module_loader.name': 'ALBehaviorManager',
	}
	installed = InstalledBehaviors()
	running = RunningBehaviors()

	def GET(self):
		req = cherrypy.request
		req.headers['Content-Type'] = 'application/json'
		return json.dumps(req.module.getInstalledBehaviors())

	def _cp_dispatch(self, vpath):
		cherrypy.serving.request.behavior_name = vpath.pop(0)
		return Behavior()

class AudioVolume(BaseHandler):
	def GET(self):
		req = cherrypy.request
		req.headers['Content-Type'] = 'application/json'
		return json.dumps(req.module.getOutputVolume())

	def PUT(self):
		req = cherrypy.request
		req.module.setOutputVolume(int(req.body.read()))

class AudioDevice(BaseHandler):
	"A base handler for the ALAudioDevice"

	_cp_config = {
		'tools.al_module_loader.on': True,
		'tools.al_module_loader.name': 'ALAudioDevice',
	}

	volume = AudioVolume()

class TextToSpeech(BaseHandler):
	"A handler for ALTextToSpeech"

	_cp_config = {
		'tools.al_module_loader.on': True,
		'tools.al_module_loader.name': 'ALTextToSpeech',
	}

	def POST(self):
		req = cherrypy.request
		text = req.body.read()
		req.module.say(text)

class Memory(BaseHandler):
	_cp_config = {
		'tools.al_module_loader.on': True,
		'tools.al_module_loader.name': 'ALMemory',
	}

	def GET(self, name):
		cherrypy.response.headers['Content-Type'] = 'application/json'
		return json.dumps(cherrypy.request.module.getData(name))

class Root(BaseHandler):
	behaviors = Behaviors()
	audio = AudioDevice()
	speech = TextToSpeech()
	memory = Memory()

	def GET(self):
		"Provide a simple link to the controller"
		return 'Welcome to <a href="controller">NAO</a>'

this_dir = os.path.dirname(__file__)

def start():
	config = {
		'global': {
			'server.socket_host': '0.0.0.0',
			'server.socket_port': 8080,
			'engine.autoreload.on': False,
		},
		'/': {
			'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
			'tools.trailing_slash.status': 307,
		},
		'/controller': {
			'tools.staticfile.on': True,
			'tools.staticfile.filename': os.path.join(this_dir,
				'controller.xhtml')
		},
		'/assets': {
			'tools.staticdir.on': True,
			'tools.staticdir.dir': os.path.join(this_dir, 'assets'),
		},
		# okapi is a tool for working with RESTful web services
		'/okapi': {
			'tools.staticfile.on': True,
			'tools.staticfile.filename': os.path.join(this_dir, 'okapi.html')
		},
		'/okapibg.png': {
			'tools.staticfile.on': True,
			'tools.staticfile.filename': os.path.join(this_dir, 'okapibg.png')
		},
	}
	if hasattr(cherrypy.engine, 'signal_handler'):
		cherrypy.engine.signal_handler.subscribe()
	if hasattr(cherrypy.engine, 'console_control_handler'):
		cherrypy.engine.console_control_handler.subscribe()
	cherrypy.config.update(config)
	cherrypy.tree.mount(Root(), config=config)
	cherrypy.engine.start()

def stop():
	cherrypy.engine.exit()

if __name__ == '__main__':
	start()
	cherrypy.engine.block()
	stop()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.