Exemplo n.º 1
0
 def start(self):
     self.log.debug("ZuulWeb starting")
     self.stream_manager.start()
     self.wsplugin = WebSocketPlugin(cherrypy.engine)
     self.wsplugin.subscribe()
     cherrypy.engine.start()
Exemplo n.º 2
0

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=
        'HTTP proxy between two clients using websockets. To connect the target, visit http://domain:targetport/runproxy or include http://domain:targetport/proxy.js'
    )
    parser.add_argument('--targetport', default='18082', type=int)
    parser.add_argument('--proxyport', default='18083', type=int)
    args = parser.parse_args()

    cherrypy.config.update({
        'server.socket_host': '0.0.0.0',
        'server.socket_port': args.targetport
    })
    WebSocketPlugin(cherrypy.engine).subscribe()
    cherrypy.tools.websocket = WebSocketTool()
    cherrypy.tree.mount(Root(),
                        '/',
                        config={
                            '/ws': {
                                'tools.websocket.on': True,
                                'tools.websocket.handler_cls': ProxyWebSocket
                            }
                        })

    httpd = BaseHTTPServer.HTTPServer(('', args.proxyport), ProxyHandler)

    cherrypy.engine.start()

    try:
Exemplo n.º 3
0
 def _setup_websocket_plugin(self):
     WebSocketPlugin(cherrypy.engine).subscribe()
     cherrypy.tools.websocket = WebSocketTool()
Exemplo n.º 4
0
def run():
    MEDIA_DIR = os.path.join(DATADIR, 'Pellmonweb', 'media')
    argparser = argparse.ArgumentParser(prog='pellmonweb')
    argparser.add_argument('-D',
                           '--DAEMONIZE',
                           action='store_true',
                           help='Run as daemon')
    argparser.add_argument('-P',
                           '--PIDFILE',
                           default='/tmp/pellmonweb.pid',
                           help='Full path to pidfile')
    argparser.add_argument('-U', '--USER', help='Run as USER')
    argparser.add_argument('-G',
                           '--GROUP',
                           default='nogroup',
                           help='Run as GROUP')
    argparser.add_argument('-C',
                           '--CONFIG',
                           default='pellmon.conf',
                           help='Full path to config file')
    argparser.add_argument('-d',
                           '--DBUS',
                           default='SESSION',
                           choices=['SESSION', 'SYSTEM'],
                           help='which bus to use, SESSION is default')
    argparser.add_argument('-V',
                           '--version',
                           action='version',
                           version='%(prog)s version ' + __version__)
    args = argparser.parse_args()

    global dbus
    dbus = Dbus_handler(args.DBUS)

    #Look for temlates in this directory
    global lookup
    lookup = myLookup(
        directories=[os.path.join(DATADIR, 'Pellmonweb', 'html')], dbus=dbus)

    config_file = args.CONFIG

    pidfile = args.PIDFILE
    if pidfile:
        plugins.PIDFile(cherrypy.engine, pidfile).subscribe()

    if args.USER:

        config_file = os.path.join(CONFDIR, 'pellmon.conf')

        try:
            parser.read(config_file)
        except:
            cherrypy.log("can not parse config file")
            sys.exit(1)
        try:
            config_dir = parser.get('conf', 'config_dir')
            walk_config_dir(config_dir, parser)
        except ConfigParser.NoOptionError:
            pass

        try:
            accesslog = parser.get('weblog', 'accesslog')
            logdir = os.path.dirname(accesslog)
            if not os.path.isdir(logdir):
                os.mkdir(logdir)
            uid = pwd.getpwnam(args.USER).pw_uid
            gid = grp.getgrnam(args.GROUP).gr_gid
            os.chown(logdir, uid, gid)
            if os.path.isfile(accesslog):
                os.chown(accesslog, uid, gid)
        except:
            pass
        try:
            errorlog = parser.get('weblog', 'errorlog')
            logdir = os.path.dirname(errorlog)
            if not os.path.isdir(logdir):
                os.mkdir(logdir)
            uid = pwd.getpwnam(args.USER).pw_uid
            gid = grp.getgrnam(args.GROUP).gr_gid
            os.chown(logdir, uid, gid)
            if os.path.isfile(errorlog):
                os.chown(errorlog, uid, gid)
        except:
            pass
        uid = pwd.getpwnam(args.USER).pw_uid
        gid = grp.getgrnam(args.GROUP).gr_gid
        plugins.DropPrivileges(cherrypy.engine, uid=uid, gid=gid,
                               umask=033).subscribe()

    # Load the configuration file
    try:
        parser.read(config_file)
        config_dir = parser.get('conf', 'config_dir')
        walk_config_dir(config_dir, parser)
    except ConfigParser.NoOptionError:
        pass
    except ConfigParser.NoSectionError:
        cherrypy.log("can not parse config file")
    except:
        cherrypy.log("Config file not found")

    # The RRD database, updated by pellMon
    global polling, db
    try:
        polling = True
        db = parser.get('conf', 'database')
        graph_file = os.path.join(os.path.dirname(db), 'graph.png')
    except:
        polling = False
        db = ''

    # the colors to use when drawing the graph
    global colorsDict
    try:
        colors = parser.items('graphcolors')
        colorsDict = {}
        for key, value in colors:
            colorsDict[key] = value
    except:
        colorsDict = {}

    # Get the names of the polled data
    global polldata
    try:
        polldata = parser.items("pollvalues")
        # Get the names of the polled data
        rrd_ds_names = parser.items("rrd_ds_names")
        ds_names = {}
        for key, value in rrd_ds_names:
            ds_names[key] = value
    except:
        ds_names = {}
        polldata = []

    try:
        # Get the optional scales
        scales = parser.items("scaling")
        scale_data = {}
        for key, value in scales:
            scale_data[key] = value
    except:
        scale_data = {}

    global graph_lines
    graph_lines = []
    global logtick
    logtick = None
    for key, value in polldata:
        if key in colorsDict and key in ds_names:
            graph_lines.append({
                'name': value,
                'color': colorsDict[key],
                'ds_name': ds_names[key]
            })
            if key in scale_data:
                graph_lines[-1]['scale'] = scale_data[key]
        if value == '_logtick' and key in ds_names:
            logtick = ds_names[key]

    global credentials
    try:
        credentials = parser.items('authentication')
    except:
        credentials = [('testuser', '12345')]

    global logfile
    try:
        logfile = parser.get('conf', 'logfile')
    except:
        logfile = None

    try:
        webroot = parser.get('conf', 'webroot')
    except:
        webroot = '/'

    global system_image
    try:
        system_image = os.path.join(os.path.join(MEDIA_DIR, 'img'),
                                    parser.get('conf', 'system_image'))
    except:
        system_image = os.path.join(MEDIA_DIR, 'img/system.svg')

    global frontpage_widgets
    frontpage_widgets = []
    try:
        for row, widgets in parser.items('frontpage_widgets'):
            frontpage_widgets.append([s.strip() for s in widgets.split(',')])
    except ConfigParser.NoSectionError:
        frontpage_widgets = [['systemimage', 'events'], ['graph'],
                             ['consumption7d', 'silolevel']]

    global timeChoices
    timeChoices = ['time1h', 'time3h', 'time8h', 'time24h', 'time3d', 'time1w']
    global timeNames
    timeNames = [
        t.replace(' ', ' ') for t in
        ['1 hour', '3 hours', '8 hours', '24 hours', '3 days', '1 week']
    ]
    global timeSeconds
    timeSeconds = [
        3600, 3600 * 3, 3600 * 8, 3600 * 24, 3600 * 24 * 3, 3600 * 24 * 7
    ]
    ft = False
    fc = False
    for a, b in polldata:
        if b == 'feeder_capacity':
            fc = True
        if b == 'feeder_time':
            ft = True
    if fc and ft:
        consumption_graph = True
        consumption_file = os.path.join(os.path.dirname(db), 'consumption.png')
    else:
        consumption_graph = False
    if websockets:
        #make sure WebSocketPlugin runs after daemonizer plugin (priority 65)
        #see cherrypy plugin documentation for default plugin priorities
        WebSocketPlugin.start.__func__.priority = 66
        WebSocketPlugin(cherrypy.engine).subscribe()
        cherrypy.tools.websocket = WebSocketTool()
    try:
        port = int(parser.get('conf', 'port'))
    except:
        port = 8081

    global_conf = {
            'global':   { #w'server.environment': 'debug',
                          'tools.sessions.on' : True,
                          'tools.sessions.timeout': 7200,
                          'tools.auth.on': True,
                          'server.socket_host': '0.0.0.0',
                          'server.socket_port': port,

                          #'engine.autoreload.on': False,
                          #'checker.on': False,
                          #'tools.log_headers.on': False,
                          #'request.show_tracebacks': False,
                          'request.show_mismatched_params': False,
                          #'log.screen': False,
                          'engine.SIGHUP': None,
                          'engine.SIGTERM': None,

                        }
                  }
    app_conf = {
        '/media': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': MEDIA_DIR
        },
    }

    if websockets:
        ws_conf = {
            '/ws': {
                'tools.websocket.on': True,
                'tools.websocket.handler_cls': WebSocket
            }
        }

    current_dir = os.path.dirname(os.path.abspath(__file__))
    cherrypy.config.update(global_conf)

    # Only daemonize if asked to.
    if args.DAEMONIZE:
        # Don't print anything to stdout/sterr.
        cherrypy.config.update({
            'log.screen': False,
            'engine.autoreload.on': False
        })
        plugins.Daemonizer(cherrypy.engine).subscribe()

    cherrypy.tree.mount(PellMonWeb(), webroot, config=app_conf)
    if websockets:
        cherrypy.tree.mount(WsHandler(),
                            os.path.join(webroot, 'websocket'),
                            config=ws_conf)

    try:
        cherrypy.config.update({'log.access_file': accesslog})
    except:
        pass
    try:
        cherrypy.config.update({'log.error_file': errorlog})
    except:
        pass

    GObject.threads_init()

    # Always start the engine; this will start all other services
    try:
        cherrypy.engine.start()
    except:
        # Assume the error has been logged already via bus.log.
        sys.exit(1)
    else:
        # Needed to be able to use threads with a glib main loop running

        # A main loop is needed for dbus "name watching" to work
        main_loop = GLib.MainLoop()

        # cherrypy has it's own mainloop, cherrypy.engine.block, that
        # regularly calls engine.publish every 100ms. The most reliable
        # way to run dbus and cherrypy together seems to be to use the
        # glib mainloop for both, ie call engine.publish from the glib
        # mainloop instead of calling engine.block.
        def publish():
            try:
                cherrypy.engine.publish('main')
                if cherrypy.engine.execv:
                    main_loop.quit()
                    cherrypy.engine._do_execv()
            except KeyboardInterrupt:
                pass
            return True

        # Use our own signal handler to stop on ctrl-c, seems to be simpler
        # than subscribing to cherrypy's signal handler
        def signal_handler(signal, frame):
            cherrypy.engine.exit()
            main_loop.quit()

        signal.signal(signal.SIGINT, signal_handler)

        # Handle cherrypy's main loop needs from here
        GLib.timeout_add(100, publish)

        dbus.start()
        try:
            main_loop.run()
        except KeyboardInterrupt:
            pass
Exemplo n.º 5
0
    def run(self, host="127.0.0.1", port=8000, dir='.', mode=0, csiDevice=-1):
        dir = os.path.abspath(dir)
        Path(dir).mkdir(parents=True, exist_ok=True)
        CP_CONF = {
            '/vendor': {
                'tools.staticdir.on': True,
                'tools.staticdir.dir': os.path.abspath('./vendor')
            },
            '/css': {
                'tools.staticdir.on': True,
                'tools.staticdir.dir': os.path.abspath('./css')
            },
            '/webfonts': {
                'tools.staticdir.on': True,
                'tools.staticdir.dir': os.path.abspath('./webfonts')
            },
            '/ws': {
                'tools.websocket.on': True,
                'tools.websocket.handler_cls': WebSocketHandler
            }
        }
        accessLogFile = os.path.join(os.getcwd(), "access.log")
        errorLogFile = os.path.join(os.getcwd(), "error.log")
        cherrypy.config.update({
            'server.socket_host': host,
            'server.socket_port': port,
            'engine.autoreload.on': False,
            'log.error_file': errorLogFile,
            'log.access_file': accessLogFile
        })
        cherrypy.log("Recording to: " + dir)

        zedStatus = False
        if csiDevice == -1:
            csiDevice, zedStatus = selfTest()
        else:
            _, zedStatus = selfTest()

        csiStatus = True if csiDevice != -1 else False

        csiStreamer = CSIStreamer(dir,
                                  params["csiStreamer"]["recordingInterval"],
                                  csiDevice,
                                  params["csiStreamer"]["stdResolution"],
                                  params["csiStreamer"]["hdResolution"],
                                  params["csiStreamer"]["recordingResolution"],
                                  params["csiStreamer"]["framerate"])
        # threading.Thread(None, csiStreamer.run).start()

        zedStreamer = None

        if ZED_ENABLED:
            zedFrameLock = threading.Lock()
            zedStreamer = ZEDStreamer(
                dir, params["zedStreamer"]["recordingInterval"],
                params["zedStreamer"]["resolution"],
                params["zedStreamer"]["depth"],
                params["zedStreamer"]["framerate"])
            zedStreamThread = threading.Thread(None,
                                               zedStreamer.run,
                                               daemon=True)
            zedStreamThread.start()

        WebSocketPlugin(cherrypy.engine).subscribe()
        cherrypy.tools.websocket = WebSocketTool()
        cherrypy.tree.mount(RecordingHandler(
            dir, csiStreamer, zedStreamer, csiStatus, zedStatus, mode,
            params["recordingHandler"]["previewResolution"],
            params["recordingHandler"]["zedPreviewResolution"]),
                            '/',
                            config=CP_CONF)
        if mode == 0:
            cherrypy.log("All modules enabled")
            cherrypy.tree.mount(BarcodeHandler(
                dir, params["barcodeHandler"]["crop"],
                params["barcodeHandler"]["timeout"],
                params["barcodeHandler"]["previewResolution"],
                params["barcodeHandler"]["recordingResolution"]),
                                '/barcode',
                                config=CP_CONF)
            cherrypy.tree.mount(DetectionHandler(
                dir, params["detectionHandler"]["framerate"],
                params["detectionHandler"]["recordingResolution"],
                params["detectionHandler"]["enginepath"],
                params["detectionHandler"]["H"],
                params["detectionHandler"]["L0"]),
                                '/detection',
                                config=CP_CONF)
        else:
            cherrypy.log("Barcode detection and object detection disabled.")
            cherrypy.tree.mount(DisabledHandler(), '/barcode', config=CP_CONF)
            cherrypy.tree.mount(DisabledHandler(),
                                '/detection',
                                config=CP_CONF)

        cherrypy.tree.mount(FilesHandler(dir), '/files', config=CP_CONF)
        cherrypy.tree.mount(TestHandler(), '/test')
        cherrypy.tree.mount(DocuHandler(), '/documentation', config=CP_CONF)
        cherrypy.engine.start()
        cherrypy.engine.block()
Exemplo n.º 6
0
    def start(self):
        config = {
            'global': {
                "engine.autoreload.on":False,
                'server.socket_host': '0.0.0.0',
                'server.socket_port': self.httpPort,
                'server.show_tracebacks': False,
                'request.show_tracebacks': False,
                'tools.sessions.on': True,
                }
            }

        if self.certs:
            config['global'].update({
                'server.ssl_module': 'builtin',
                'server.ssl_certificate':self.certs.cert,
                'server.ssl_private_key':self.certs.key,
                'server.ssl_certificate_chain':self.certs.chain
                })

        cherrypy.config.update(config)
        
        cherrypy.tools.websocket = WebSocketTool()

        logging.info("STARTING HTTP SERVER")

        current_dir = os.path.dirname(__file__)
        path_to_source_root = os.path.abspath(os.path.join(current_dir, "..", ".."))

        temp_dir_for_tarball = tempfile.mkdtemp()

        logging.info("Serving test-looper tarball and related downloads from %s", temp_dir_for_tarball)

        SubprocessRunner.callAndAssertSuccess(
            ["tar", "cvfz", os.path.join(temp_dir_for_tarball, "test_looper.tar.gz"), 
                "--directory", path_to_source_root, "test_looper"
            ])

        if not self.linuxOnly:
            with DirectoryScope.DirectoryScope(path_to_source_root):
                SubprocessRunner.callAndAssertSuccess(
                    ["zip", "-r", os.path.join(temp_dir_for_tarball, "test_looper.zip"), "test_looper", "-x", "*.pyc", "*.js"]
                    )

            with DirectoryScope.DirectoryScope(temp_dir_for_tarball):
                SubprocessRunner.callAndReturnOutput(
                    ["curl", "-L", "https://bootstrap.pypa.io/get-pip.py", "-O", os.path.join(temp_dir_for_tarball, "get-pip.py")]
                    )
                assert os.path.exists(os.path.join(temp_dir_for_tarball, "get-pip.py"))

            with DirectoryScope.DirectoryScope(temp_dir_for_tarball):
                SubprocessRunner.callAndReturnOutput(
                    ["curl", "-L", "http://www.python.org/ftp/python/2.7.14/python-2.7.14.amd64.msi", "-O", os.path.join(temp_dir_for_tarball, "python-2.7.14.amd64.msi")]
                    )
                assert os.path.exists(os.path.join(temp_dir_for_tarball, "python-2.7.14.amd64.msi"))

            with DirectoryScope.DirectoryScope(temp_dir_for_tarball):
                SubprocessRunner.callAndReturnOutput(
                    ["curl", "-L", "https://github.com/git-for-windows/git/releases/download/v2.15.1.windows.2/Git-2.15.1.2-64-bit.exe", "-O", os.path.join(temp_dir_for_tarball, "Git-2.15.1.2-64-bit.exe")]
                    )
                assert os.path.exists(os.path.join(temp_dir_for_tarball, "Git-2.15.1.2-64-bit.exe"))
                

        cherrypy.tree.mount(self, '/', {
            '/favicon.ico': {
                'tools.staticfile.on': True,
                'tools.staticfile.filename': os.path.join(current_dir,
                                                          'content',
                                                          'favicon.ico')
                },
            '/get-pip.py': {
                'tools.staticfile.on': True,
                'tools.staticfile.filename': os.path.join(temp_dir_for_tarball,
                                                          'get-pip.py')
                },
            '/test_looper.tar.gz': {
                'tools.staticfile.on': True,
                'tools.staticfile.filename': os.path.join(temp_dir_for_tarball,
                                                          'test_looper.tar.gz')
                },
            '/test_looper.zip': {
                'tools.staticfile.on': True,
                'tools.staticfile.filename': os.path.join(temp_dir_for_tarball,
                                                          'test_looper.zip')
                },
            '/test_looper.zip': {
                'tools.staticfile.on': True,
                'tools.staticfile.filename': os.path.join(temp_dir_for_tarball,
                                                          'test_looper.zip')
                },
            '/python-2.7.14.amd64.msi': {
                'tools.staticfile.on': True,
                'tools.staticfile.filename': os.path.join(temp_dir_for_tarball,
                                                          'python-2.7.14.amd64.msi')
                },
            '/Git-2.15.1.2-64-bit.exe': {
                'tools.staticfile.on': True,
                'tools.staticfile.filename': os.path.join(temp_dir_for_tarball,
                                                          'Git-2.15.1.2-64-bit.exe')
                },
            '/css': {
                'tools.staticdir.on': True,
                'tools.staticdir.dir': os.path.join(current_dir, 'css')
                },
            '/js': {
                'tools.staticdir.on': True,
                'tools.staticdir.dir': os.path.join(current_dir, 'content', 'js')
                },
            '/interactive_socket': {
                'tools.websocket.on': True, 
                'tools.websocket.handler_cls': MakeWebsocketHandler(self),
                'tools.websocket.protocols': ['protocol']
                }
            })

        cherrypy.server.socket_port = self.httpPort

        cherrypy.engine.autoreload.on = False

        cherrypy.engine.signals.subscribe()

        WebSocketPlugin(cherrypy.engine).subscribe()

        cherrypy.engine.start()
Exemplo n.º 7
0
def webRoot():
    # We don't want Cherrypy writing temp files for no reason
    cherrypy._cpreqbody.Part.maxrambytes = 64 * 1024

    from cherrypy import _cperror

    logging.getLogger("cherrypy.access").propagate = False

    from . import tagpoints
    from . import builtintags

    def tagErrorHandler(tag, f, val):
        try:
            from . import newevt
            if f.__module__ in newevt.eventsByModuleName:
                newevt.eventsByModuleName[f.__module__]._handle_exception()
            else:
                if not hasattr(f, "_kaithemFirstErrorMarker"):
                    f._kaithemFirstErrorMarker = True
                    messagebus.postMessage(
                        "/system/notifications/errors",
                        "First err in tag subscriber " + str(f) + " from " +
                        str(f.__module__) + " to " + tag.name)
        except:
            print(traceback.format_exc(chain=True))

    tagpoints.subscriberErrorHandlers = [tagErrorHandler]

    tagpoints.loadAllConfiguredTags(os.path.join(directories.vardir, "tags"))

    # We want a notification anytime every first error in a scheduled event.
    # This can stay even with real python logging, we want the front page notificaton.
    from . import scheduling

    def handleFirstError(f):
        "Callback to deal with the first error from any given event"
        m = f.__module__
        messagebus.postMessage(
            "/system/notifications/errors",
            "Problem in scheduled event function: " + repr(f) +
            " in module: " + m + ", check logs for more info.")

    scheduling.handleFirstError = handleFirstError

    from . import logviewer

    try:
        from . import timesync
    except:
        logger.exception("Could not start time sync module")
        messagebus.postMessage(
            '/system/notifications/errors',
            """Failed to initialize the time sync module or zeroconf discovery
        This may be because you are using a python version older than 3.3, or because
        netifaces is not installed. Some features may not work correctly.
        """)

    from . import pages
    from . import weblogin
    from . import pages

    from . import ManageUsers
    from . import newevt
    from . import registry
    from . import persist
    persist.registry = registry
    from . import modules
    from . import modules_interface
    from . import settings
    from . import usrpages
    from . import systasks
    from . import widgets

    from . import alerts
    logger.info("Loaded core python code")
    from . import config as cfgmodule
    if not config['host'] == 'default':
        bindto = config['host']
    else:
        if config['local-access-only']:
            bindto = '127.0.0.1'
        else:
            bindto = '::'

    mode = int(
        cfgmodule.argcmd.nosecurity) if cfgmodule.argcmd.nosecurity else None
    # limit nosecurity to localhost
    if mode == 1:
        bindto = '127.0.0.1'

    #cherrypy.process.servers.check_port(bindto, config['http-port'], timeout=1.0)
    #cherrypy.process.servers.check_port(bindto, config['https-port'], timeout=1.0)
    logger.info("Ports are free")

    MyExternalIPAdress = util.updateIP()

    if config['change-process-title']:
        try:
            import setproctitle
            setproctitle.setproctitle("kaithem")
            logger.info("setting process title")
        except:
            logger.warning("error setting process title")

    from ws4py.server.cherrypyserver import WebSocketPlugin, WebSocketTool
    from ws4py.websocket import EchoWebSocket, WebSocket
    WebSocketPlugin(cherrypy.engine).subscribe()
    cherrypy.tools.websocket = WebSocketTool()
    logger.info("activated websockets")

    sys.modules['kaithem'] = sys.modules['__main__']

    # Load all modules from the active modules directory
    modules.initModules()
    logger.info("Loaded modules")

    def save():
        if config['save-before-shutdown']:
            messagebus.postMessage('/system/notifications/important/',
                                   "System saving before shutting down")
            util.SaveAllState()

    # let the user choose to have the server save everything before a shutdown
    if config['save-before-shutdown']:
        atexit.register(save)
        cherrypy.engine.subscribe("exit", save)

    import collections

    # Super simple hacky cache. Maybe we should
    # Just mostly eliminate zips and use files directly?
    zipcache = collections.OrderedDict()

    # This class represents the "/" root of the web app
    class webapproot():

        # This lets users mount stuff at arbitrary points, so long
        # As it doesn't conflict with anything.

        # foo.bar.com/foo maps to foo,bar,/,foo
        # bar.com/foo is just foo
        def _cp_dispatch(self, vpath):

            sdpath = pages.getSubdomain()

            vpath2 = vpath[:]

            # For binding the root of subdomains

            while vpath2:
                # Check for any subdomain specific handling.
                if tuple(sdpath + ['/'] + vpath2) in pages.nativeHandlers:
                    # found match, remove N elements from the beginning of the path,
                    # where n is the length of the "mountpoint", becsause the mountpoint
                    # already consumed those.

                    # Don't do it for the fake one we add just to make this loop work though
                    for i in vpath2:
                        vpath.pop(0)

                    x = pages.nativeHandlers[tuple(sdpath + ['/'] + vpath2)]

                    # Traverse to the actual function, if there is a match, else return the index.

                    if vpath and hasattr(x, vpath[0]):
                        x2 = getattr(x, vpath[0])
                        if hasattr(x2, 'exposed') and x2.exposed:
                            vpath.pop(0)
                            x = x2
                    if not isinstance(x, Exception):
                        return x
                    else:
                        raise x

                if tuple(vpath2) in pages.nativeHandlers:
                    # found match, remove N elements from the beginning of the path,
                    # where n is the length of the "mountpoint", because the mountpoint
                    # already consumed those
                    for i in range(len(vpath2)):
                        vpath.pop(0)

                    x = pages.nativeHandlers[tuple(vpath2)]
                    if vpath and hasattr(x, vpath[0]):
                        x2 = getattr(x, vpath[0])
                        if vpath and hasattr(x2, 'exposed') and x2.exposed:
                            vpath.pop(0)
                            x = x2
                    if not isinstance(x, Exception):
                        return x
                    else:
                        raise x

                if None in pages.nativeHandlers:
                    return pages.nativeHandlers[None]

                # Successively remove things from the end till we get a
                # prefix match
                vpath2.pop(-1)

            return None

        @cherrypy.expose
        def default(self, *path, **data):
            return self._cp_dispatch(list(path))(*path, **data)

        # Keep the dispatcher from freaking out. The actual handling
        # Is done by a cherrypy tool. These just keeo cp_dispatch from being called
        # I have NO clue why the favicon doesn't have this issue.
        @cherrypy.expose
        def static(self, *path, **data):
            pass

        @cherrypy.expose
        def usr(self, *path, **data):
            pass

        @cherrypy.expose
        def index(self, *path, **data):
            pages.require("/admin/mainpage.view")
            cherrypy.response.cookie['LastSawMainPage'] = time.time()
            return pages.get_template('index.html').render(
                api=notifications.api, alertsapi=alerts.api)

        @cherrypy.expose
        def dropdownpanel(self, *path, **data):
            pages.require("/admin/mainpage.view")
            return pages.get_template('dropdownpanel.html').render(
                api=notifications.api, alertsapi=alerts.api)

        # @cherrypy.expose
        # def alerts(self, *path, **data):
        #     pages.require("/admin/mainpage.view")
        #     return pages.get_template('alerts.html').render(api=notifications.api, alertsapi=alerts.api)

        @cherrypy.expose
        def tagpoints(self, *path, show_advanced='', **data):
            # This page could be slow because of the db stuff, so we restrict it more
            pages.require("/admin/settings.edit")
            if "new_numtag" in data:
                pages.postOnly()
                return pages.get_template('settings/tagpoint.html').render(
                    new_numtag=data['new_numtag'],
                    tagname=data['new_numtag'],
                    show_advanced=True)
            if "new_strtag" in data:
                pages.postOnly()
                return pages.get_template('settings/tagpoint.html').render(
                    new_strtag=data['new_strtag'],
                    tagname=data['new_strtag'],
                    show_advanced=True)

            if data:
                pages.postOnly()

            if path:
                if not path[0] in tagpoints.allTags:
                    raise ValueError("This tag does not exist")
                return pages.get_template('settings/tagpoint.html').render(
                    tagName=path[0], data=data, show_advanced=show_advanced)
            else:
                return pages.get_template('settings/tagpoints.html').render(
                    data=data)

        @cherrypy.expose
        def tagpointlog(self, *path, **data):
            # This page could be slow because of the db stuff, so we restrict it more
            pages.require("/admin/settings.edit")
            pages.postOnly()
            if not 'exportRows' in data:
                return pages.get_template('settings/tagpointlog.html').render(
                    tagName=path[0], data=data)
            else:

                import pytz
                import datetime
                import dateutil.parser

                for i in tagpoints.allTags[path[0]]().configLoggers:
                    if i.accumType == data['exportType']:
                        tz = pytz.timezone(
                            auth.getUserSetting(pages.getAcessingUser(),
                                                'timezone'))
                        logtime = tz.localize(
                            dateutil.parser.parse(
                                data['logtime'])).timestamp()
                        raw = i.getDataRange(logtime,
                                             time.time() + 10000000,
                                             int(data['exportRows']))

                        if data['exportFormat'] == "csv.iso":
                            cherrypy.response.headers[
                                'Content-Disposition'] = 'attachment; filename="%s"' % path[
                                    0].replace(
                                        "/", "_").replace(".", "_").replace(
                                            ":", "_")[1:] + "_" + data[
                                                'exportType'] + tz.localize(
                                                    dateutil.parser.parse(
                                                        data['logtime'])
                                                ).isoformat() + ".csv"
                            cherrypy.response.headers[
                                'Content-Type'] = 'text/csv'
                            d = [
                                "Time(ISO), " + path[0].replace(",", '') +
                                ' <accum ' + data['exportType'] + '>'
                            ]
                            for i in raw:
                                dt = datetime.datetime.fromtimestamp(i[0])
                                d.append(dt.isoformat() + "," +
                                         str(i[1])[:128])
                            return '\r\n'.join(d) + '\r\n'

        @cherrypy.expose
        def zipstatic(self, *path, **data):
            """
            take everything but the last path element, use it as a path relative to static dir
            open as a zip, use the last as filename in the zip, return it.
            """
            if ".." in path:
                return
            try:
                if path in zipcache:
                    zipcache.move_to_end(path)
                    return zipcache[path]
            except:
                print("err in cache for zip")
            cherrypy.response.headers['Cache-Control'] = "max-age=28800"

            m = mimetypes.guess_type(path[-1])
            cherrypy.response.headers['Content-Type'] = m[0]
            p = os.path.join(ddn, 'static', *path[:-1])
            with zipfile.ZipFile(p) as f:
                d = f.read(path[-1])
            zipcache[path] = d
            if len(zipcache) > 64:
                zipcache.pop(last=False)
            return d

        @cherrypy.expose
        def pagelisting(self, *path, **data):
            # Pagelisting knows to only show pages if you have permissions
            return pages.get_template('pagelisting.html').render_unicode(
                modules=modules.ActiveModules)

        # docs, helpmenu, and license are just static pages.
        @cherrypy.expose
        def docs(self, *path, **data):
            if path:
                if path[0] == "thirdparty":
                    p = os.path.normpath(
                        os.path.join(directories.srcdir, "docs",
                                     "/".join(path)))
                    if not p.startswith(
                            os.path.join(directories.srcdir, "docs")):
                        raise RuntimeError("Invalid URL")
                    cherrypy.response.headers[
                        'Content-Type'] = mimetypes.guess_type(p)[0]

                    with open(p, "rb") as f:
                        return (f.read())
                return pages.get_template('help/' + path[0] + '.html').render(
                    path=path, data=data)
            return pages.get_template('help/help.html').render()

        @cherrypy.expose
        def makohelp(self, *path, **data):
            return pages.get_template('help/makoreference.html').render()

        @cherrypy.expose
        def about(self, *path, **data):
            return pages.get_template('help/about.html').render(
                myip=MyExternalIPAdress)

        @cherrypy.expose
        def changelog(self, *path, **data):
            return pages.get_template('help/changes.html').render(
                myip=MyExternalIPAdress)

        @cherrypy.expose
        def helpmenu(self, *path, **data):
            return pages.get_template('help/index.html').render()

        @cherrypy.expose
        def license(self, *path, **data):
            return pages.get_template('help/license.html').render()

        @cherrypy.expose
        def aerolabs_blockrain(self, *path, **data):
            # There is no reason to be particularly concerned here, I have no reason not to trust
            # Aerolabs, this is just for the people that hate hidden games and such.
            cherrypy.response.headers[
                'Content-Security-Policy'] = "connect-src none"
            return pages.get_template('blockrain.html').render()

    class Errors():
        @cherrypy.expose
        def permissionerror(self, ):
            cherrypy.response.status = 403
            return pages.get_template('errors/permissionerror.html').render()

        @cherrypy.expose
        def alreadyexists(self, ):
            cherrypy.response.status = 400
            return pages.get_template('errors/alreadyexists.html').render()

        @cherrypy.expose
        def gosecure(self, ):
            cherrypy.response.status = 426
            return pages.get_template('errors/gosecure.html').render()

        @cherrypy.expose
        def loginerror(self, ):
            cherrypy.response.status = 400
            return pages.get_template('errors/loginerror.html').render()

        @cherrypy.expose
        def nofoldermoveerror(self, ):
            cherrypy.response.status = 400
            return pages.get_template('errors/nofoldermove.html').render()

        @cherrypy.expose
        def wrongmethod(self, ):
            cherrypy.response.status = 405
            return pages.get_template('errors/wrongmethod.html').render()

        @cherrypy.expose
        def error(self, ):
            cherrypy.response.status = 500
            return pages.get_template('errors/error.html').render(
                info="An Error Occurred")

    def cpexception():
        cherrypy.response.status = 500
        try:
            cherrypy.response.body = bytes(
                pages.get_template('errors/cperror.html').render(
                    e=_cperror.format_exc(),
                    mk=mako.exceptions.html_error_template().render().decode(
                    )), 'utf8')
        except:
            cherrypy.response.body = bytes(
                pages.get_template('errors/cperror.html').render(
                    e=_cperror.format_exc(), mk=""), 'utf8')

    import zipfile

    from . import devices, btadmin

    # There are lots of other objects ad classes represeting subfolders of the website so we attatch them
    root = webapproot()
    root.login = weblogin.LoginScreen()
    root.auth = ManageUsers.ManageAuthorization()
    root.modules = modules_interface.WebInterface()
    root.settings = settings.Settings()
    root.settings.bt = btadmin.WebUI()
    root.errors = Errors()
    root.pages = usrpages.KaithemPage()
    root.logs = messagelogging.WebInterface()
    root.notifications = notifications.WI()
    root.widgets = widgets.WebInterface()
    root.syslog = logviewer.WebInterface()
    root.devices = devices.WebDevices()

    if not os.path.abspath(__file__).startswith("/usr/bin"):
        sdn = os.path.join(
            os.path.dirname(os.path.dirname(os.path.realpath(__file__))),
            "src")
        ddn = os.path.join(
            os.path.dirname(os.path.dirname(os.path.realpath(__file__))),
            "data")
    else:
        sdn = "/usr/lib/kaithem/src"
        ddn = "/usr/share/kaithem"

    def allow_upload(*args, **kwargs):
        # Only do the callback if needed. Assume it's really big if no header.
        if int(cherrypy.request.headers.get(
                "Content-Length", 2**32)) > cherrypy.request.body.maxbytes:
            cherrypy.request.body.maxbytes = cherrypy.request.config[
                'tools.allow_upload.f']()

    cherrypy.tools.allow_upload = cherrypy.Tool('before_request_body',
                                                allow_upload)

    site_config = {
        "request.body.maxbytes":
        64 * 1024,
        "tools.encode.on":
        True,
        "tools.encode.encoding":
        'utf-8',
        "tools.decode.on":
        True,
        "tools.decode.encoding":
        'utf-8',
        'request.error_response':
        cpexception,
        'log.screen':
        config['cherrypy-log-stdout'],
        'server.socket_host':
        bindto,
        'server.socket_port':
        config['https-port'],
        'server.ssl_module':
        'builtin',
        'server.ssl_certificate':
        os.path.join(directories.ssldir, 'certificate.cert'),
        'server.ssl_private_key':
        os.path.join(directories.ssldir, 'certificate.key'),
        'server.thread_pool':
        config['https-thread-pool'],
        'engine.autoreload.frequency':
        5,
        'engine.autoreload.on':
        False,
        'tools.allow_upload.on':
        True,
        'tools.allow_upload.f':
        lambda: auth.getUserLimit(pages.getAcessingUser(), "web.maxbytes") or
        64 * 1024,
    }

    wscfg = {
        'tools.websocket.on': True,
        'tools.websocket.handler_cls': widgets.websocket
    }

    wscfg_raw = {
        'tools.websocket.on': True,
        'tools.websocket.handler_cls': widgets.rawwebsocket
    }

    try:
        from hardline import ws4py_drayer
        wscfg3 = {
            'tools.websocket.on': True,
            'tools.websocket.handler_cls': ws4py_drayer.DrayerAPIWebSocket
        }
        root.drayer_api = ws4py_drayer.WebInterface()
    except Exception as e:
        wscfg3 = {}
        logging.exception("Could not load the Drayer WS API")
        messagebus.postMessage(
            "/system/notifications/errors",
            "Drayer Server API disabled due to loading error, see logs")

    cnf = {
        '/static': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': os.path.join(ddn, 'static'),
            "tools.sessions.on": False,
            "tools.addheader.on": True,
            'tools.expires.on': True,
            'tools.expires.secs': 3600 + 48  # expire in 48 hours
        },
        '/static/js': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': os.path.join(sdn, 'js'),
            "tools.sessions.on": False,
            "tools.addheader.on": True
        },
        '/static/vue': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': os.path.join(sdn, 'vue'),
            "tools.sessions.on": False,
            "tools.addheader.on": True
        },
        '/static/css': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': os.path.join(sdn, 'css'),
            "tools.sessions.on": False,
            "tools.addheader.on": True
        },
        '/static/docs': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': os.path.join(sdn, 'docs'),
            "tools.sessions.on": False,
            "tools.addheader.on": True
        },
        '/static/zip': {
            'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
            "tools.addheader.on": True
        },
        '/pages': {
            'tools.allow_upload.on':
            True,
            'tools.allow_upload.f':
            lambda: auth.getUserLimit(pages.getAcessingUser(), "web.maxbytes")
            or 64 * 1024,
            'request.dispatch':
            cherrypy.dispatch.MethodDispatcher()
        },
        '/widgets/ws': wscfg,
        '/widgets/wsraw': wscfg_raw,
        '/drayer_api': wscfg3
    }

    if not config['favicon-png'] == "default":
        cnf['/favicon.png'] = {
            'tools.staticfile.on':
            True,
            'tools.staticfile.filename':
            os.path.join(directories.datadir, "static", config['favicon-png']),
            'tools.expires.on':
            True,
            'tools.expires.secs':
            3600  # expire in an hour
        }

    if not config['favicon-ico'] == "default":
        cnf['/favicon.ico'] = {
            'tools.staticfile.on':
            True,
            'tools.staticfile.filename':
            os.path.join(directories.datadir, "static", config['favicon-ico']),
            'tools.expires.on':
            True,
            'tools.expires.secs':
            3600  # expire in an hour
        }

    # Let the user create additional static directories
    for i in config['serve-static']:
        if i not in cnf:
            cnf["/usr/static/" + i] = {
                'tools.staticdir.on': True,
                'tools.staticdir.dir': config['serve-static'][i],
                "tools.sessions.on": False,
                "tools.addheader.on": True
            }

    def addheader(*args, **kwargs):
        "This function's only purpose is to tell the browser to cache requests for an hour"
        cherrypy.response.headers['Cache-Control'] = "max-age=28800"
        cherrypy.response.headers["Access-Control-Allow-Origin"] = "*"

        #del cherrypy.response.headers['Expires']

    def pageloadnotify(*args, **kwargs):
        systasks.aPageJustLoaded()

    # As far as I can tell, this second server inherits everything from the "implicit" server
    # except what we override.
    server2 = cherrypy._cpserver.Server()
    server2.socket_port = config['http-port']
    server2._socket_host = bindto
    server2.thread_pool = config['http-thread-pool']
    server2.subscribe()

    cherrypy.config.update(site_config)
    cherrypy.tools.pageloadnotify = cherrypy.Tool('on_start_resource',
                                                  pageloadnotify)
    cherrypy.config['tools.pageloadnotify.on'] = True

    cherrypy.tools.addheader = cherrypy.Tool('before_finalize', addheader)

    if hasattr(cherrypy.engine, 'signal_handler'):
        del cherrypy.engine.signal_handler.handlers['SIGUSR1']
        cherrypy.engine.signal_handler.subscribe()

    cherrypy.tree.mount(root, config=cnf)

    if time.time() < 1420070400:
        messagebus.postMessage(
            '/system/notifications/errors',
            "System Clock is wrong, some features may not work properly.")

    if time.time() < util.min_time:
        messagebus.postMessage(
            '/system/notifications/errors',
            "System Clock may be wrong, or time has been set backwards at some point. If system clock is correct and this error does not go away, you can fix it manually be correcting folder name timestamps in the var dir."
        )

    cherrypy.engine.start()

    # Unlike other shm stuff that only gets used after startup, this
    # Can be used both before and after we are fully loaded.
    # So we need to hand off everything to the user we will actually run as.

    # This is also useful for when someone directly modifies config
    # Over SSH and we want to adopt those changes to the kaithem usr.

    # It's even useful if we ever change the user for some reason.

    # We only do this if we start as root though.

    if not config['run-as-user'] == 'root' and getpass.getuser() == 'root':
        try:
            d = "/dev/shm/kaithem_pyx_" + config['run-as-user']
            directories.rchown(d, config['run-as-user'])
            directories.rchown(directories.vardir, config['run-as-user'])
            directories.rchown(directories.logdir, config['run-as-user'])
            # Might as well own our own SSL dir, that way we can change certs via the webUI.
            directories.rchown(directories.ssldir, config['run-as-user'])
            directories.rchown(directories.usersdir, config['run-as-user'])
            directories.rchown(directories.regdir, config['run-as-user'])
        except:
            logger.exception("This is normal on non-unix")

    # If configured that way on unix, check if we are root and drop root.
    util.drop_perms(config['run-as-user'], config['run-as-group'])
    pylogginghandler.onUserChanged()
    messagebus.postMessage('/system/startup', 'System Initialized')
    messagebus.postMessage('/system/notifications/important',
                           'System Initialized')

    r = util.zeroconf

    import zeroconf
    # Register an NTP service
    desc = {}

    if cfg.config['advertise-webui']:
        try:
            import socket
            if not cfg.config['webui-servicename'] == "default":
                localserver_name = cfg.config['webui-servicename']
            else:
                localserver_name = "kaithem_" + socket.gethostname()

            info = zeroconf.ServiceInfo(
                "_http._tcp.local.", localserver_name + "._http._tcp.local.",
                [None], cfg.config['http-port'], 0, 0, desc)
            r.register_service(info)
            info2 = zeroconf.ServiceInfo(
                "_https._tcp.local.", localserver_name + "._https._tcp.local.",
                [None], cfg.config['https-port'], 0, 0, desc)
            r.register_service(info2)
        except:
            logger.exception("Error advertising MDNS service")

    # Open a port to the outside world. Note that this can only be enabled through the webUI,
    # You are safe unless someone turns it on..
    workers.do(systasks.doUPnP)
Exemplo n.º 8
0
    def start_server(cls, visibility=False, ao="alsa:device=[plughw:1,0]"):
        if os.path.isfile(PLAYLIST_FILE):
            f = open(PLAYLIST_FILE, "r")
            try:
                cls.playlist = json.loads(f.read())
            except:
                pass
            finally:
                f.close()
        else:
            cls.playlist = []
        
        cls.currently_playing = None
        cls.user_selected_flag = False
        cls.shutdown_flag = False
        cls.lock = threading.Lock()
        cls.play_lock = threading.Lock()
        cls.mpv = mpv.MPV(None, no_video="", ao=ao)
        cls.volume = 100.0
        cls.play_queue = queue.Queue(maxsize=50)

        # threaded debug
        if DEBUG:
            cls._thread_debug = threading.Thread(target=cls._debug)
            cls._thread_debug.start()

        # threaded broadcast of position
        cls._thread_broadcast_pos = threading.Thread(target=cls._broadcast_position)
        cls._thread_broadcast_pos.start()

        # threaded play
        cls._thread_play = threading.Thread(target=cls._play)
        cls._thread_play.start()

        # start mpv listeners
        cls.mpv.register_event_callback(mpv.MpvEventID.END_FILE, cls._mpv_eof)

        # set mpv to paused initially
        cls.mpv.pause = True

        cherrypy_config = {
            "/rq": {
                "tools.websocket.on": True,
                "tools.websocket.handler_cls": JukeboxWebWorker,
                "tools.secureheaders.on": True,
            }
        }
        cherrypy.config.update({
            "log.access_file": "access_log",
            "log.error_file": "error_log"
        })

        cherrypy.config.update({"server.socket_port": WS_PORT})
        if visibility:
            cherrypy.config.update({"server.socket_host": "0.0.0.0"})

        # set the priority according to your needs if you are hooking something
        # else on the 'before_finalize' hook point.
        cherrypy.tools.secureheaders = cherrypy.Tool('before_finalize', secureheaders, priority=60)

        cls._wsp = WebSocketPlugin(cherrypy.engine)
        cls._wsp.subscribe()
        cherrypy.tools.websocket = WebSocketTool()

        cherrypy.engine.subscribe("stop", cls.stop_server)

        cherrypy.quickstart(JukeboxWebService(), "/", config=cherrypy_config)
Exemplo n.º 9
0
def main(argv: list):
    # Get study parameters from the command-line
    parser = argparse.ArgumentParser()
    parser.add_argument('-f',
                        '--finger_count',
                        type=int,
                        default=2,
                        help='Number of fingers acquired per user')
    parser.add_argument('-e',
                        '--enrollment_count',
                        type=int,
                        default=20,
                        help='Number of enrollment images per finger')
    parser.add_argument('-v',
                        '--verification_count',
                        type=int,
                        default=15,
                        help='Number of verification images per finger')
    parser.add_argument('-p',
                        '--port',
                        type=int,
                        default=9000,
                        help='The port for the webserver')
    parser.add_argument('-d',
                        '--picture_dir',
                        default='./fingers',
                        help='Directory for the fingerprint captures')
    parser.add_argument('-l', '--log_dir', help='Log files directory')
    parser.add_argument('-s',
                        '--syslog',
                        action='store_true',
                        help='Log to syslog')

    args = parser.parse_args(argv)
    # Configure cherrypy server
    cherrypy.config.update({'server.socket_port': args.port})
    if args.log_dir:
        log_name = 'server-%s.log' % (datetime.now().strftime('%Y%m%d_%H%M%S'))
        cherrypy.config.update({
            'log.access_file':
            os.path.join(args.log_dir, 'access.log'),
            'log.error_file':
            os.path.join(args.log_dir, log_name),
            'log.screen':
            False
        })
    if args.syslog:
        h = logging.handlers.SysLogHandler(
            address='/dev/log',
            facility=logging.handlers.SysLogHandler.LOG_LOCAL1)
        h.setLevel(logging.DEBUG)
        h.setFormatter(cherrypy._cplogging.logfmt)
        logger = logging.getLogger('cherrypy.access')
        logger.setLevel(logging.DEBUG)
        logger.addHandler(h)
        logger = logging.getLogger('cherrypy.error')
        logger.setLevel(logging.DEBUG)
        logger.addHandler(h)
        cherrypy.config.update({'log.screen': False})

    WebSocketPlugin(cherrypy.engine).subscribe()
    cherrypy.tools.websocket = WebSocketTool()

    cherrypy.quickstart(Root(args),
                        '/',
                        config={
                            '/finger': {
                                'tools.websocket.on': True,
                                'tools.websocket.handler_cls': FingerWebSocket
                            },
                            '/static': {
                                'tools.staticdir.on': True,
                                'tools.staticdir.dir': HTML_DIR
                            }
                        })
Exemplo n.º 10
0
def startFrontendThread():
    template.initializeTemplateSystem()

    cherrypy.config.update({
        'server.socket_host':
        config.getLocalConfigValue('server.ipAddress'),
        'server.socket_port':
        config.getLocalConfigValue('server.port'),
        'log.screen':
        False,
        'log.access_file':
        '',
        'log.error_file':
        ''
    })
    cherrypy.engine.unsubscribe('graceful', cherrypy.log.reopen_files)

    distping.configureLogging()

    # Configure SSL
    if (config.getLocalConfigValue('server.ssl.enabled')):
        cherrypy.config.update({
            'server.ssl_certificate':
            config.getLocalConfigValue('server.ssl.certificate'),
            'server.ssl_private_key':
            config.getLocalConfigValue('server.ssl.privateKey')
        })

        if (config.getLocalConfigValue('server.ssl.certificateChain') != ''):
            cherrypy.config.update({
                'server.ssl_certificate_chain':
                config.getLocalConfigValue('server.ssl.certificateChain')
            })

    distPingFrontend = DistPingFrontend()

    WebSocketPlugin(cherrypy.engine).subscribe()
    cherrypy.tools.websocket = WebSocketTool()

    cherrypy.quickstart(
        distPingFrontend,
        '/',
        config={
            '/': {
                'tools.staticdir.on': True,
                'tools.staticdir.root': distping.getRootDirectory() + '/web',
                'tools.staticdir.dir': '',

                # Auth
                'tools.auth_basic.on': True,
                'tools.auth_basic.realm': 'DistPing',
                'tools.auth_basic.checkpassword': validateUsernameAndPassword
            },
            '/ws': {
                'tools.websocket.on': True,
                'tools.websocket.handler_cls': DistPingServer,

                # Auth
                'tools.auth_basic.on': False,
            },
            '/favicon.ico': {
                'tools.staticfile.on':
                True,
                'tools.staticfile.filename':
                distping.getRootDirectory() + '/web/resources/img/favicon.ico'
            }
        })
Exemplo n.º 11
0
    @login_required
    def socket(self):
        handler = cp.request.ws_handler
        handler.session_id = cp.request.cookie['session_id'].value

    def _cp_dispatch(self, vpath):
        if vpath[0] == 'profile':
            cp.request.params['username'] = vpath.pop()
        return vpath


def error_404(status, message, traceback, version):
    return serve_file(cwd + '/static/error_404.html')


WebSocketPlugin(cp.engine).subscribe()
cp.tools.websocket = WebSocketTool()

cfg = {
    '/favicon.ico': {
        'tools.staticfile.on': True,
        'tools.staticfile.filename': cwd + '/static/favicon.ico',
    },
    '/apple-touch-icon.png': {
        'tools.staticfile.on': True,
        'tools.staticfile.filename': cwd + '/static/apple-touch-icon.png'
    },
    '/manifest.json': {
        'tools.staticfile.on': True,
        'tools.staticfile.filename': cwd + '/static/manifest.json',
    },
Exemplo n.º 12
0
        self._priority = cherrypy.tools.sessions._priority + 1  # must be initialized after the sessions tool

    def upgrade(self, **kwargs):
        try:
            kwargs['handler_cls'].check_authentication()
        except WebSocketAuthError:
            raise cherrypy.HTTPError(
                401,
                'You must be logged in to establish a websocket connection.')
        except:
            log.error('unexpected websocket authentication error',
                      exc_info=True)
            raise cherrypy.HTTPError(401, 'unexpected authentication error')
        else:
            return WebSocketTool.upgrade(self, **kwargs)


cherrypy.tools.websockets = WebSocketChecker()

websocket_plugin = WebSocketPlugin(cherrypy.engine)
if hasattr(WebSocketPlugin.start, '__func__'):
    WebSocketPlugin.start.__func__.priority = 66
else:
    WebSocketPlugin.start.priority = 66
websocket_plugin.subscribe()

local_broadcaster = Caller(local_broadcast)
broadcaster = Caller(WebSocketDispatcher.broadcast)
responder = Caller(WebSocketDispatcher.handle_message,
                   threads=config['ws.thread_pool'])
Exemplo n.º 13
0
    ch.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(name)s - %(asctime)s - %(levelname)s'
                                  ' - %(message)s')
    ch.setFormatter(formatter)
    interface_logger.addHandler(ch)

    # create the preset folder if it does not exist:
    preset_dir = os.path.abspath(args.presetdir)
    if (not os.path.isdir(preset_dir)):
        print("Preset folder {} did not exist, creating.".format(preset_dir))
        os.makedirs(preset_dir)

    # Add the websocket requirements.
    cherrypy.tools.websocket = WebSocketTool()

    a = WebSocketPlugin(cherrypy.engine)
    a.manager = WebSocketManager()
    a.subscribe()

    stack_interface = interface.StackInterface()
    stack_interface.daemon = True
    stack_interface.start()
    server_tree = FocusStackRoot(stack_interface, preset_dir=preset_dir)

    # create a broadcast function which relays messages received over the
    # serial port to the websockets via the websocketmanager.
    def broadcaster():
        m = stack_interface.get_message()
        if m:
            payload = dict(m)
            payload["msg_type"] = message.msg_type_name[payload["msg_type"]]