import json
import logging
-from tornado.web import RequestHandler, HTTPError
+from tornado.web import RequestHandler, HTTPError, asynchronous
import config
import mjpgclient
else:
raise HTTPError(400, 'unknown operation')
+ @asynchronous
def get_config(self, camera_id):
if camera_id:
logging.debug('getting config for camera %(id)s' % {'id': camera_id})
camera_config = config.get_camera(camera_id)
if camera_config['@proto'] != 'v4l2':
- try:
- remote_ui_config = remote.get_config(
- camera_config.get('@host'),
- camera_config.get('@port'),
- camera_config.get('@username'),
- camera_config.get('@password'),
- camera_config.get('@remote_camera_id'))
+ def on_response(remote_ui_config):
+ if remote_ui_config is None:
+ return self.finish_json({'error': True})
- except Exception as e:
- return self.finish_json({'error': unicode(e)})
-
- local_data = camera_config
- camera_config = self._camera_ui_to_dict(remote_ui_config)
- camera_config.update(local_data)
+ tmp_config = self._camera_ui_to_dict(remote_ui_config)
+ tmp_config.update(camera_config)
+ ui_config = self._camera_dict_to_ui(tmp_config)
+ ui_config['available_resolutions'] = remote_ui_config['available_resolutions']
+
+ self.finish_json(ui_config)
- ui_config = self._camera_dict_to_ui(camera_config)
+ remote.get_config(
+ camera_config.get('@host'),
+ camera_config.get('@port'),
+ camera_config.get('@username'),
+ camera_config.get('@password'),
+ camera_config.get('@remote_camera_id'), on_response)
- if camera_config['@proto'] == 'v4l2':
+ else:
+ ui_config = self._camera_dict_to_ui(camera_config)
+
resolutions = v4l2ctl.list_resolutions(camera_config['videodevice'])
resolutions = [(str(w) + 'x' + str(h)) for (w, h) in resolutions]
ui_config['available_resolutions'] = resolutions
-
- else:
- ui_config['available_resolutions'] = remote_ui_config['available_resolutions']
-
- self.finish_json(ui_config)
+
+ self.finish_json(ui_config)
else:
logging.debug('getting main config')
motionctl.restart()
+ @asynchronous
def set_preview(self, camera_id):
try:
controls = json.loads(self.request.body)
logging.debug('setting hue to %(value)s...' % {'value': value})
v4l2ctl.set_hue(device, value)
+
+ self.finish_json({})
else:
- try:
- remote.set_preview(
- camera_config['@host'],
- camera_config['@port'],
- camera_config['@username'],
- camera_config['@password'],
- camera_config['@remote_camera_id'],
- controls)
-
- except Exception as e:
- self.finish_json({'error': unicode(e)})
-
+ def on_response(response):
+ if response is None:
+ self.finish_json({'error': True})
+
+ else:
+ self.finish_json({})
+
+ remote.set_preview(
+ camera_config['@host'],
+ camera_config['@port'],
+ camera_config['@username'],
+ camera_config['@password'],
+ camera_config['@remote_camera_id'],
+ controls, on_response)
+
+ @asynchronous
def list_cameras(self):
logging.debug('listing cameras')
password = self.get_argument('password', None)
if host: # remote listing
- try:
- cameras = remote.list_cameras(host, port, username, password)
+ def on_response(cameras):
+ if cameras is None:
+ self.finish_json({'error': True})
+
+ else:
+ self.finish_json({'cameras': cameras})
+
+ cameras = remote.list_cameras(host, port, username, password, on_response)
- except Exception as e:
- return self.finish_json({'error': unicode(e)})
-
- else:
+ else: # local listing
cameras = []
+
+ length = [len(config.get_camera_ids())]
+ def check_finished():
+ if len(cameras) == length[0]:
+ self.finish_json({'cameras': cameras})
+
+ def on_response_builder(camera_id, camera_config):
+ def on_response(remote_ui_config):
+ if remote_ui_config is None:
+ length[0] -= 1
+
+ else:
+ remote_ui_config['id'] = camera_id
+ remote_ui_config['enabled'] = camera_config['@enabled'] # override the enabled status
+ cameras.append(remote_ui_config)
+
+ check_finished()
+
+ return on_response
+
for camera_id in config.get_camera_ids():
camera_config = config.get_camera(camera_id)
if camera_config['@proto'] == 'v4l2':
ui_config = self._camera_dict_to_ui(camera_config)
+ cameras.append(ui_config)
+ check_finished()
else: # remote camera
- try:
- remote_ui_config = remote.get_config(
- camera_config.get('@host'),
- camera_config.get('@port'),
- camera_config.get('@username'),
- camera_config.get('@password'),
- camera_config.get('@remote_camera_id'))
-
- except:
- continue
-
- ui_config = remote_ui_config
- ui_config['id'] = camera_id
- ui_config['enabled'] = camera_config['@enabled'] # override the enabled status
-
- cameras.append(ui_config)
+ remote.get_config(
+ camera_config.get('@host'),
+ camera_config.get('@port'),
+ camera_config.get('@username'),
+ camera_config.get('@password'),
+ camera_config.get('@remote_camera_id'), on_response_builder(camera_id, camera_config))
+
+ if length[0] == 0:
+ self.finish_json({'cameras': []})
- self.finish_json({'cameras': cameras})
-
def list_devices(self):
logging.debug('listing devices')
self.finish_json({'devices': devices})
+ @asynchronous
def add_camera(self):
logging.debug('adding new camera')
break
camera_id, camera_config = config.add_camera(device_details)
+ camera_config['@id'] = camera_id
if proto == 'v4l2':
motionctl.restart()
-
- else:
- try:
- remote_ui_config = remote.get_config(
- device_details.get('host'),
- device_details.get('port'),
- device_details.get('username'),
- device_details.get('password'),
- device_details.get('remote_camera_id'))
-
- except Exception as e:
- return self.finish_json({'error': unicode(e)})
-
- local_data = camera_config
- camera_config = self._camera_ui_to_dict(remote_ui_config)
- camera_config.update(local_data)
-
- camera_config['@id'] = camera_id
-
- ui_config = self._camera_dict_to_ui(camera_config)
-
- if camera_config['@proto'] == 'v4l2':
+
+ ui_config = self._camera_dict_to_ui(camera_config)
resolutions = v4l2ctl.list_resolutions(camera_config['videodevice'])
resolutions = [(str(w) + 'x' + str(h)) for (w, h) in resolutions]
ui_config['available_resolutions'] = resolutions
+ self.finish_json(ui_config)
+
else:
- ui_config['available_resolutions'] = remote_ui_config['available_resolutions']
+ def on_response(remote_ui_config):
+ if remote_ui_config is None:
+ self.finish_json({'error': True})
+
+ tmp_config = self._camera_ui_to_dict(remote_ui_config)
+ tmp_config.update(camera_config)
+ ui_config = self._camera_dict_to_ui(tmp_config)
+ ui_config['available_resolutions'] = remote_ui_config['available_resolutions']
+
+ self.finish_json(ui_config)
+
+ remote.get_config(
+ device_details.get('host'),
+ device_details.get('port'),
+ device_details.get('username'),
+ device_details.get('password'),
+ device_details.get('remote_camera_id'), on_response)
- self.finish_json(ui_config)
-
def rem_camera(self, camera_id):
logging.debug('removing camera %(id)s' % {'id': camera_id})
else:
raise HTTPError(400, 'unknown operation')
+ @asynchronous
def current(self, camera_id):
camera_config = config.get_camera(camera_id)
if camera_config['@proto'] == 'v4l2':
self.finish(jpg)
else:
- try:
- jpg = remote.current_snapshot(
- camera_config['@host'],
- camera_config['@port'],
- camera_config['@username'],
- camera_config['@password'],
- camera_config['@remote_camera_id'])
+ def on_response(jpg):
+ if jpg is None:
+ self.finish({})
+
+ else:
+ self.set_header('Content-Type', 'image/jpeg')
+ self.finish(jpg)
+
+ remote.current_snapshot(
+ camera_config['@host'],
+ camera_config['@port'],
+ camera_config['@username'],
+ camera_config['@password'],
+ camera_config['@remote_camera_id'], on_response)
- except:
- return self.finish()
-
- self.set_header('Content-Type', 'image/jpeg')
- self.finish(jpg)
-
def list(self, camera_id):
logging.debug('listing snapshots for camera %(id)s' % {'id': camera_id})
import json
import logging
-import urllib2
+
+from tornado.httpclient import AsyncHTTPClient, HTTPClient, HTTPRequest
def _compose_url(host, port, username, password, uri, query=None):
return url
-def list_cameras(host, port, username, password):
+def list_cameras(host, port, username, password, callback):
logging.debug('listing remote cameras on %(host)s:%(port)s' % {
'host': host,
'port': port})
url = _compose_url(host, port, username, password, '/config/list/')
- request = urllib2.Request(url)
-
- try:
- response = urllib2.urlopen(request)
- except Exception as e:
- logging.error('failed to list remote cameras on %(host)s:%(port)s: %(msg)s' % {
- 'host': host,
- 'port': port,
- 'msg': unicode(e)})
+ def on_response(response):
+ if response.error:
+ logging.error('failed to list remote cameras on %(host)s:%(port)s: %(msg)s' % {
+ 'host': host,
+ 'port': port,
+ 'msg': unicode(response.error)})
+
+ return callback(None)
- raise
-
- try:
- response = json.load(response)
-
- except Exception as e:
- logging.error('failed to decode json answer from %(host)s:%(port)s: %(msg)s' % {
- 'host': host,
- 'port': port,
- 'msg': unicode(e)})
+ try:
+ response = json.loads(response.body)
+
+ except Exception as e:
+ logging.error('failed to decode json answer from %(host)s:%(port)s: %(msg)s' % {
+ 'host': host,
+ 'port': port,
+ 'msg': unicode(e)})
+
+ return callback(None)
- raise
+ return callback(response['cameras'])
+
+ http_client = AsyncHTTPClient()
+ http_client.fetch(url, on_response)
- return response['cameras']
-
-def get_config(host, port, username, password, camera_id):
+def get_config(host, port, username, password, camera_id, callback):
logging.debug('getting config for remote camera %(id)s on %(host)s:%(port)s' % {
'id': camera_id,
'host': host,
'port': port})
url = _compose_url(host, port, username, password, '/config/%(id)s/get/' % {'id': camera_id})
- request = urllib2.Request(url)
-
- try:
- response = urllib2.urlopen(request)
-
- except Exception as e:
- logging.error('failed to get config for remote camera %(id)s on %(host)s:%(port)s: %(msg)s' % {
- 'id': camera_id,
- 'host': host,
- 'port': port,
- 'msg': unicode(e)})
-
- raise
- try:
- response = json.load(response)
-
- except Exception as e:
- logging.error('failed to decode json answer from %(host)s:%(port)s: %(msg)s' % {
- 'host': host,
- 'port': port,
- 'msg': unicode(e)})
+ def on_response(response):
+ if response.error:
+ logging.error('failed to get config for remote camera %(id)s on %(host)s:%(port)s: %(msg)s' % {
+ 'id': camera_id,
+ 'host': host,
+ 'port': port,
+ 'msg': unicode(response.error)})
+
+ return callback(None)
+
+ try:
+ response = json.loads(response.body)
- raise
+ except Exception as e:
+ logging.error('failed to decode json answer from %(host)s:%(port)s: %(msg)s' % {
+ 'host': host,
+ 'port': port,
+ 'msg': unicode(e)})
+
+ return callback(None)
+
+ callback(response)
+
+ http_client = AsyncHTTPClient()
+ http_client.fetch(url, on_response)
- return response
-
def set_config(host, port, username, password, camera_id, data):
logging.debug('setting config for remote camera %(id)s on %(host)s:%(port)s' % {
data = json.dumps(data)
url = _compose_url(host, port, username, password, '/config/%(id)s/set/' % {'id': camera_id})
- request = urllib2.Request(url, data=data)
+ request = HTTPRequest(url, method='POST', body=data)
try:
- urllib2.urlopen(request)
+ http_client = HTTPClient()
+ response = http_client.fetch(request)
+ if response.error:
+ raise Exception(unicode(response.error))
except Exception as e:
logging.error('failed to set config for remote camera %(id)s on %(host)s:%(port)s: %(msg)s' % {
raise
-def set_preview(host, port, username, password, camera_id, controls):
+def set_preview(host, port, username, password, camera_id, controls, callback):
logging.debug('setting preview for remote camera %(id)s on %(host)s:%(port)s' % {
'id': camera_id,
'host': host,
controls = json.dumps(controls)
url = _compose_url(host, port, username, password, '/config/%(id)s/set_preview/' % {'id': camera_id})
- request = urllib2.Request(url, data=controls)
-
- try:
- urllib2.urlopen(request)
-
- except Exception as e:
- logging.error('failed to set preview for remote camera %(id)s on %(host)s:%(port)s: %(msg)s' % {
- 'id': camera_id,
- 'host': host,
- 'port': port,
- 'msg': unicode(e)})
+
+ def on_response(response):
+ if response.error:
+ logging.error('failed to set preview for remote camera %(id)s on %(host)s:%(port)s: %(msg)s' % {
+ 'id': camera_id,
+ 'host': host,
+ 'port': port,
+ 'msg': unicode(response.error)})
- raise
+ return callback(None)
+
+ callback('')
+
+ http_client = AsyncHTTPClient()
+ http_client.fetch(url, on_response)
-def current_snapshot(host, port, username, password, camera_id):
+def current_snapshot(host, port, username, password, camera_id, callback):
logging.debug('getting current snapshot for remote camera %(id)s on %(host)s:%(port)s' % {
'id': camera_id,
'host': host,
'port': port})
url = _compose_url(host, port, username, password, '/snapshot/%(id)s/current/' % {'id': camera_id})
- request = urllib2.Request(url)
-
- try:
- response = urllib2.urlopen(request)
- except Exception as e:
- logging.error('failed to get current snapshot for remote camera %(id)s on %(host)s:%(port)s: %(msg)s' % {
- 'id': camera_id,
- 'host': host,
- 'port': port,
- 'msg': unicode(e)})
+ def on_response(response):
+ if response.error:
+ logging.error('failed to get current snapshot for remote camera %(id)s on %(host)s:%(port)s: %(msg)s' % {
+ 'id': camera_id,
+ 'host': host,
+ 'port': port,
+ 'msg': unicode(response.error)})
+
+ return callback(None)
- raise
+ callback(response.body)
- return response.read()
+ http_client = AsyncHTTPClient()
+ http_client.fetch(url, on_response)