2014-05-04 17:26:43 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# vi:si:et:sw=4:sts=4:ts=4
|
|
|
|
from __future__ import division
|
|
|
|
|
|
|
|
from tornado.websocket import WebSocketHandler
|
|
|
|
from tornado.ioloop import IOLoop
|
|
|
|
from Queue import Queue
|
|
|
|
import json
|
|
|
|
from threading import Thread
|
|
|
|
|
|
|
|
from oxflask.shortcuts import json_dumps
|
|
|
|
|
|
|
|
import state
|
|
|
|
|
2014-05-18 03:01:24 +00:00
|
|
|
import logging
|
2014-05-17 14:26:59 +00:00
|
|
|
logger = logging.getLogger('oml.websocket')
|
|
|
|
|
2014-05-04 17:26:43 +00:00
|
|
|
class Background:
|
|
|
|
|
|
|
|
def __init__(self, handler):
|
|
|
|
self.handler = handler
|
|
|
|
self.q = Queue()
|
|
|
|
self.connected = True
|
2014-05-17 00:14:15 +00:00
|
|
|
self.main = IOLoop.instance()
|
2014-05-04 17:26:43 +00:00
|
|
|
|
|
|
|
def worker(self):
|
|
|
|
while self.connected:
|
|
|
|
message = self.q.get()
|
|
|
|
action, data = json.loads(message)
|
|
|
|
import item.scan
|
|
|
|
if action == 'ping':
|
|
|
|
self.post(['pong', data])
|
|
|
|
elif action == 'import':
|
2014-05-16 14:30:16 +00:00
|
|
|
item.scan.run_import(data)
|
2014-05-04 17:26:43 +00:00
|
|
|
elif action == 'scan':
|
|
|
|
item.scan.run_scan()
|
|
|
|
elif action == 'update':
|
|
|
|
self.post(['error', {'error': 'not implemented'}])
|
|
|
|
else:
|
|
|
|
self.post(['error', {'error': 'unknown action'}])
|
|
|
|
self.q.task_done()
|
|
|
|
|
|
|
|
def join(self):
|
|
|
|
self.q.join()
|
|
|
|
|
|
|
|
def put(self, data):
|
|
|
|
self.q.put(data)
|
|
|
|
|
|
|
|
def post(self, data):
|
|
|
|
if not isinstance(data, basestring):
|
|
|
|
data = json_dumps(data)
|
|
|
|
self.main.add_callback(lambda: self.handler.write_message(data))
|
|
|
|
|
|
|
|
|
|
|
|
class Handler(WebSocketHandler):
|
2014-05-14 09:57:11 +00:00
|
|
|
background = None
|
2014-05-04 17:26:43 +00:00
|
|
|
|
|
|
|
def open(self):
|
2014-05-14 09:57:11 +00:00
|
|
|
if self.request.host not in self.request.headers['origin']:
|
2014-05-17 14:26:59 +00:00
|
|
|
logger.debug('reject cross site attempt to open websocket %s', self.request)
|
2014-05-14 09:57:11 +00:00
|
|
|
self.close()
|
2014-05-04 17:26:43 +00:00
|
|
|
self.background = Background(self)
|
|
|
|
state.websockets.append(self.background)
|
|
|
|
self.t = Thread(target=self.background.worker)
|
|
|
|
self.t.daemon = True
|
|
|
|
self.t.start()
|
|
|
|
|
|
|
|
#websocket calls
|
|
|
|
def on_message(self, message):
|
|
|
|
self.background.put(message)
|
|
|
|
|
|
|
|
def on_close(self):
|
2014-05-14 09:57:11 +00:00
|
|
|
if self.background:
|
|
|
|
state.websockets.remove(self.background)
|
|
|
|
self.background.connected = False
|
2014-05-04 17:26:43 +00:00
|
|
|
|
|
|
|
def trigger_event(event, data):
|
|
|
|
if len(state.websockets):
|
2014-05-17 14:57:34 +00:00
|
|
|
logger.debug('trigger event %s %s %s', event, data, len(state.websockets))
|
2014-05-04 17:26:43 +00:00
|
|
|
for ws in state.websockets:
|
|
|
|
try:
|
|
|
|
ws.post([event, data])
|
|
|
|
except:
|
2014-05-18 03:01:24 +00:00
|
|
|
logger.debug('failed to send to ws %s %s %s', ws, event, data, exc_info=1)
|