peerlink/example/server.py

141 lines
3.6 KiB
Python
Raw Normal View History

2014-08-28 12:52:31 +00:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from __future__ import division, print_function
2014-08-26 19:07:33 +00:00
import json
import os
2014-08-28 12:52:31 +00:00
import signal
2014-08-26 19:07:33 +00:00
import sys
2014-08-28 12:52:31 +00:00
import mimetypes
2014-08-26 19:07:33 +00:00
2014-08-28 12:52:31 +00:00
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop, PeriodicCallback
from tornado.web import Application
import tornado
2014-08-26 19:07:33 +00:00
2014-08-28 12:52:31 +00:00
import websocket
from websocket import trigger_event
import state
from tasks import Tasks
from utils import json_dumps
import link
2014-08-26 19:07:33 +00:00
2014-08-28 12:52:31 +00:00
import logging
logger = logging.getLogger('server')
2014-08-26 19:07:33 +00:00
2014-08-28 12:52:31 +00:00
root_dir = os.path.normpath(os.path.abspath(os.path.dirname(__file__)))
STATIC_PATH = os.path.join(root_dir, 'static')
2014-08-26 19:07:33 +00:00
2014-08-28 12:52:31 +00:00
class BaseHandler(tornado.web.RequestHandler):
2014-08-26 19:07:33 +00:00
2014-08-28 12:52:31 +00:00
def serve_static(self, path, mimetype=None, include_body=True):
if not mimetype:
mimetype = mimetypes.guess_type(path)[0]
logging.debug('serve %s', path)
2014-08-26 19:07:33 +00:00
if os.path.exists(path):
2014-08-28 12:52:31 +00:00
self.set_header('Content-Type', mimetype)
self.set_header('Content-Length', str(os.stat(path).st_size))
if include_body:
with open(path) as fd:
self.write(fd.read())
else:
self.set_status(404)
return
2014-08-26 19:07:33 +00:00
2014-08-28 12:52:31 +00:00
def render_json(self, response):
response = json_dumps(response)
self.set_header('Content-Type', 'application/json')
self.set_header('Content-Length', str(len(response)))
self.write(response)
self.finish()
class RemoteHandler(BaseHandler):
def post(self, action):
data = json.loads(self.request.body)
2014-08-26 19:07:33 +00:00
response = {}
2014-08-28 12:52:31 +00:00
print ('GOT remote request', action, data)
if action == 'info':
response = state.info
elif action == 'message':
data['from'] = self.request.headers['From']
trigger_event(action, data)
2014-08-26 19:07:33 +00:00
else:
2014-08-28 12:52:31 +00:00
response = {'error': 'unknown action'}
return self.render_json(response)
class MainHandler(BaseHandler):
def get(self, path):
path = path[1:]
if not path:
path = 'index.html'
path = os.path.join(STATIC_PATH, path)
self.serve_static(path)
def post(self, path):
action = path.split('/')[1]
data = json.loads(self.request.body)
response = {}
if action in ('info', 'ping'):
if 'id' in data:
id = data['id']
del data['id']
response = link.remote_json(id, action, data)
return self.render_json(response)
2014-08-26 19:07:33 +00:00
if __name__ == '__main__':
2014-08-28 12:52:31 +00:00
address = ''
port = 8000
if len(sys.argv) > 1:
2014-08-26 19:07:33 +00:00
port = int(sys.argv[1])
2014-08-28 12:52:31 +00:00
link.PEERLINK=sys.argv[2]
logging.basicConfig(level=logging.DEBUG)
options = {
'debug': True,
}
handlers = [
(r'/ws', websocket.Handler),
(r"/remote/(.*)", RemoteHandler),
(r"(.*)", MainHandler),
]
http_server = HTTPServer(Application(handlers, **options))
http_server.listen(port, address)
state.tasks = Tasks()
state.main = IOLoop.instance()
state._status = PeriodicCallback(lambda: state.info.update(link.post('info')), 60000)
state._status.start()
if ':' in address:
host = '[%s]' % address
elif not address:
host = '[::1]'
2014-08-26 19:07:33 +00:00
else:
2014-08-28 12:52:31 +00:00
host = address
url = 'http://%s:%s/' % (host, port)
link.add('chat', url + 'remote/')
state.info = link.post('info')
print('listening at %s' % url)
def shutdown():
state.tasks.join()
http_server.stop()
signal.signal(signal.SIGTERM, shutdown)
try:
state.main.start()
except:
print('shutting down...')
shutdown()