aboutsummaryrefslogtreecommitdiffstats
path: root/bin/fg21sim-webui
blob: 20d1a36e47f0282ab950a923b4c75d06dc286ffd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env python3
# -*- mode: python -*-
#
# Copyright (c) 2016 Weitian LI <liweitianux@live.com>
# MIT license

"""
Start (and/or control) the Web user interface (UI) of "fg21sim",
which is built using the Tornado_ web server and WebSocket_ protocol.

.. _Tornado: http://www.tornadoweb.org/

.. _WebSocket: https://en.wikipedia.org/wiki/WebSocket ,
   http://caniuse.com/#feat=websockets
"""


import os
import sys
import logging
import ipaddress
import webbrowser

import tornado.ioloop
from tornado.options import define, options, parse_command_line

from fg21sim.configs import configs
from fg21sim.utils import setup_logging
from fg21sim.webui import Application


# Each module can defines its own options, which are added to the global
# namespace.  Therefore the defined options can also be used by other modules.
define("host", default="localhost", type=str,
       help=("IP address or hostname the server will listen on. "
             "Specify '0.0.0.0' or '' (empty string) to listen on "
             "all available interfaces."))
define("port", default=21127, type=int, help="Server listen port")
define("debug", default=False, help="Enable the debug mode")
define("no_browser", default=False,
       help="Do not open the Web UI in a browser after startup")
define("hosts_allowed", default="any", type=str,
       help=("Hosts allowed to access the Web UI. "
             "The network addresses should be given in CIDR format, e.g., "
             "'192.168.0.0/24'. "
             "Specify 'any' to allow any hosts. "
             "Note that the localhost/127.0.0.1 is always allowed."))


def main():
    options.logging = None
    parse_command_line()

    # Validate the value of ``options.hosts_allowed``
    if options.hosts_allowed.upper() != "ANY":
        try:
            ipaddress.ip_network(options.hosts_allowed)
        except ValueError as e:
            raise ValueError("Option 'hosts_allowed' invalid: " + str(e))

    if options.host == "":
        options.host = "0.0.0.0"

    loglevel = "DEBUG" if options.debug else None
    setup_logging(dict_config=configs.logging, level=loglevel)
    tool = os.path.basename(sys.argv[0])
    logger = logging.getLogger(tool)
    logger.info("COMMAND: {0}".format(" ".join(sys.argv)))

    application = Application(debug=options.debug)
    application.listen(options.port, address=options.host)
    listen_url = "http://{host}:{port}".format(host=options.host,
                                               port=options.port)
    access_url = "http://{host}:{port}".format(host="localhost",
                                               port=options.port)
    logger.info("Tornado started on: {0}".format(listen_url))
    logger.info("You can use the Web UI by accessing:" +
                "\n\t{0}".format(access_url))
    if not options.no_browser:
        # Open the Web UI in a new browser tab
        webbrowser.open_new_tab(access_url)

    logger.info("Hosts allowed to access the Web UI: {0}".format(
        options.hosts_allowed))
    tornado.ioloop.IOLoop.current().start()


if __name__ == "__main__":
    main()