""" A simple Flask application for interacting with WHSPAH shockers. """ import argparse import logging import json import os import waitress.server import flask import whspah ACTION_MAP = {'shock': whspah.MODES.SHOCK, 'vibrate': whspah.MODES.VIBRATE, 'beep': whspah.MODES.BEEP} app = flask.Flask(__name__, static_folder='./www/') @app.route('/', defaults={'path': 'index.html'}) @app.route('/') def staticPage(path): """ Returns anything requested in the static folder. """ if os.path.isfile(os.path.join(app.static_folder, path, 'index.html')): path = os.path.join(path, 'index.html') return flask.send_from_directory(app.static_folder, path) @app.route('/transmit', methods=['POST'], strict_slashes=False) def transmit(): """ Transmits the data contained within the POST request through WHSPAH. """ data = json.loads(flask.request.data) try: txID = int(data['transmitterID']) channel = int(data['channel']) action = ACTION_MAP[data['action']] intensity = int(data.get('intensity', 0)) lucal = bool(data.get('lucalEncoded', False)) except (ValueError, KeyError): return {'success': False, 'message': 'Request must contain the following keys:\n'+ 'txID: int,\n'+ 'channel: int,\n'+ 'action: "shock", "vibrate" or "beep",\n'+ 'intensity (optional): int\n'+ 'lucalEncoded (optional): bool'}, 400 tx: whspah.Transmitter = app.config['transmitter'] tx.transmit(txID, channel, action, intensity, lucal) return {'success': True}, 200 if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('-d', '--debug', action='store_true') parser.add_argument('--ip', type=str, default='0.0.0.0') parser.add_argument('--port', type=int, default=8000) args = parser.parse_args() if args.debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) app.config['transmitter'] = whspah.Transmitter() if args.debug: app.run(host=args.ip, port=args.port, debug=True) else: server = waitress.server.create_server(app, host=args.ip, port=args.port) print(f'Serving at http://{args.ip}:{args.port}/') try: server.run() except KeyboardInterrupt: pass server.close()