parent
34d08d9255
commit
d5ee60abf8
@ -0,0 +1,127 @@ |
||||
|
||||
# Copyright 2017, 2018 Max H. Parke KA1RBI |
||||
# |
||||
# This file is part of OP25 |
||||
# |
||||
# OP25 is free software; you can redistribute it and/or modify it |
||||
# under the terms of the GNU General Public License as published by |
||||
# the Free Software Foundation; either version 3, or (at your option) |
||||
# any later version. |
||||
# |
||||
# OP25 is distributed in the hope that it will be useful, but WITHOUT |
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
||||
# License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with OP25; see the file COPYING. If not, write to the Free |
||||
# Software Foundation, Inc., 51 Franklin Street, Boston, MA |
||||
# 02110-1301, USA. |
||||
|
||||
import sys |
||||
import os |
||||
import time |
||||
import re |
||||
import json |
||||
import socket |
||||
import traceback |
||||
|
||||
from gnuradio import gr |
||||
from waitress.server import create_server |
||||
|
||||
my_input_q = None |
||||
my_output_q = None |
||||
my_port = None |
||||
|
||||
""" |
||||
fake http and ajax server module |
||||
TODO: make less fake |
||||
""" |
||||
|
||||
def static_file(environ, start_response): |
||||
content_types = { 'png': 'image/png', 'jpeg': 'image/jpeg', 'jpg': 'image/jpeg', 'gif': 'image/gif', 'css': 'text/css', 'js': 'application/javascript', 'html': 'text/html'} |
||||
img_types = 'png jpg jpeg gif'.split() |
||||
if environ['PATH_INFO'] == '/': |
||||
filename = 'index.html' |
||||
else: |
||||
filename = re.sub(r'[^a-zA-Z0-9_.\-]', '', environ['PATH_INFO']) |
||||
suf = filename.split('.')[-1] |
||||
pathname = '../www/www-static' |
||||
if suf in img_types: |
||||
pathname = '../www/images' |
||||
pathname = '%s/%s' % (pathname, filename) |
||||
if suf not in content_types.keys() or '..' in filename or not os.access(pathname, os.R_OK): |
||||
sys.stderr.write('404 %s\n' % pathname) |
||||
status = '404 NOT FOUND' |
||||
content_type = 'text/plain' |
||||
output = status |
||||
else: |
||||
output = open(pathname).read() |
||||
content_type = content_types[suf] |
||||
status = '200 OK' |
||||
return status, content_type, output |
||||
|
||||
def post_req(environ, start_response, postdata): |
||||
global my_input_q, my_output_q, my_port |
||||
try: |
||||
data = json.loads(postdata) |
||||
msg = gr.message().make_from_string(str(data['command']), -2, data['data'], 0) |
||||
my_output_q.insert_tail(msg) |
||||
time.sleep(0.2) |
||||
except: |
||||
sys.stderr.write('post_req: error processing input: %s:\n' % (postdata)) |
||||
traceback.print_exc(limit=None, file=sys.stderr) |
||||
sys.stderr.write('*** end traceback ***\n') |
||||
|
||||
resp_msg = [] |
||||
while not my_input_q.empty_p(): |
||||
msg = my_input_q.delete_head() |
||||
if msg.type() == -4: |
||||
resp_msg.append(json.loads(msg.to_string())) |
||||
status = '200 OK' |
||||
content_type = 'application/json' |
||||
output = json.dumps(resp_msg) |
||||
return status, content_type, output |
||||
|
||||
def http_request(environ, start_response): |
||||
if environ['REQUEST_METHOD'] == 'GET': |
||||
status, content_type, output = static_file(environ, start_response) |
||||
elif environ['REQUEST_METHOD'] == 'POST': |
||||
postdata = environ['wsgi.input'].read() |
||||
status, content_type, output = post_req(environ, start_response, postdata) |
||||
else: |
||||
status = '200 OK' |
||||
content_type = 'text/plain' |
||||
output = status |
||||
sys.stderr.write('http_request: unexpected input %s\n' % environ['PATH_INFO']) |
||||
|
||||
response_headers = [('Content-type', content_type), |
||||
('Content-Length', str(len(output)))] |
||||
start_response(status, response_headers) |
||||
|
||||
return [output] |
||||
|
||||
def application(environ, start_response): |
||||
failed = False |
||||
try: |
||||
result = http_request(environ, start_response) |
||||
except: |
||||
failed = True |
||||
sys.stderr.write('application: request failed:\n%s\n' % traceback.format_exc()) |
||||
sys.exit(1) |
||||
return result |
||||
|
||||
class http_server(object): |
||||
def __init__(self, input_q, output_q, endpoint, **kwds): |
||||
global my_input_q, my_output_q, my_port |
||||
host, port = endpoint.split(':') |
||||
if my_port is not None: |
||||
raise AssertionError('this server is already active on port %s' % my_port) |
||||
my_input_q = input_q |
||||
my_output_q = output_q |
||||
my_port = int(port) |
||||
|
||||
self.server = create_server(application, host=host, port=my_port) |
||||
|
||||
def run(self): |
||||
self.server.run() |
Loading…
Reference in new issue