Пример #1
0
class ScriptForm(object):
    """
    'Main' class that orchestrates parsing the Form configurations and running
    the webserver.
    """
    def __init__(self, config_file, cache=True):
        self.config_file = config_file
        self.cache = cache
        self.log = logging.getLogger('SCRIPTFORM')
        self.form_config_singleton = None
        self.websrv = None
        self.running = False
        self.httpd = None

        # Init form config so it can raise errors about problems.
        self.get_form_config()

    def get_form_config(self):
        """
        Read and return the form configuration in the form of a FormConfig
        instance. If it has already been read, a cached version is returned.
        """
        # Cache
        if self.cache and self.form_config_singleton is not None:
            return self.form_config_singleton

        file_contents = file(self.config_file, 'r').read()
        try:
            config = json.loads(file_contents)
        except ValueError as err:
            sys.stderr.write("Error in form configuration '{}': {}\n".format(
                self.config_file, err))
            sys.exit(1)

        static_dir = None
        custom_css = None
        users = None
        forms = []

        if 'static_dir' in config:
            static_dir = config['static_dir']
        if 'custom_css' in config:
            custom_css = file(config['custom_css'], 'r').read()
        if 'users' in config:
            users = config['users']
        for form in config['forms']:
            form_name = form['name']
            if not form['script'].startswith('/'):
                # Script is relative to the current dir
                script = os.path.join(os.path.realpath(os.curdir),
                                      form['script'])
            else:
                # Absolute path to the script
                script = form['script']
            forms.append(
                FormDefinition(form_name,
                               form['title'],
                               form['description'],
                               form.get('fields', None),
                               script,
                               fields_from=form.get("fields_from", None),
                               default_value=form.get('default_value', ""),
                               output=form.get('output', 'escaped'),
                               hidden=form.get('hidden', False),
                               submit_title=form.get('submit_title', 'Submit'),
                               allowed_users=form.get('allowed_users', None),
                               run_as=form.get('run_as', None)))

        form_config = FormConfig(config['title'], forms, users, static_dir,
                                 custom_css)
        self.form_config_singleton = form_config
        return form_config

    def run(self, listen_addr='0.0.0.0', listen_port=8081):
        """
        Start the webserver on address `listen_addr` and port `listen_port`.
        This call is blocking until the user hits Ctrl-c, the shutdown() method
        is called or something like SystemExit is raised in a handler.
        """
        ScriptFormWebApp.scriptform = self
        self.httpd = ThreadedHTTPServer((listen_addr, listen_port),
                                        ScriptFormWebApp)
        self.httpd.daemon_threads = True
        self.log.info("Listening on %s:%s", listen_addr, listen_port)
        self.running = True
        self.httpd.serve_forever()
        self.running = False

    def shutdown(self):
        """
        Shutdown the server. This interupts the run() method and must thus be
        run in a seperate thread.
        """
        self.log.info("Attempting server shutdown")

        def t_shutdown(scriptform_instance):
            """
            Callback for when the server is shutdown.
            """
            scriptform_instance.log.info(self.websrv)
            # Undocumented feature to shutdow the server.
            scriptform_instance.httpd.socket.close()
            scriptform_instance.httpd.shutdown()

        # We need to spawn a new thread in which the server is shut down,
        # because doing it from the main thread blocks, since the server is
        # waiting for connections..
        thread.start_new_thread(t_shutdown, (self, ))
Пример #2
0
class ScriptForm(object):
    """
    'Main' class that orchestrates parsing the Form configurations and running
    the webserver.
    """
    def __init__(self, config_file, cache=True):
        self.config_file = config_file
        self.cache = cache
        self.log = logging.getLogger('SCRIPTFORM')
        self.form_config_singleton = None
        self.websrv = None
        self.running = False
        self.httpd = None

        # Init form config so it can raise errors about problems.
        self.get_form_config()

    def get_form_config(self):
        """
        Read and return the form configuration in the form of a FormConfig
        instance. If it has already been read, a cached version is returned.
        """
        # Cache
        if self.cache and self.form_config_singleton is not None:
            return self.form_config_singleton

        config = json.load(file(self.config_file, 'r'))

        static_dir = None
        custom_css = None
        users = None
        forms = []

        if 'static_dir' in config:
            static_dir = config['static_dir']
        if 'custom_css' in config:
            custom_css = file(config['custom_css'], 'r').read()
        if 'users' in config:
            users = config['users']
        for form in config['forms']:
            form_name = form['name']
            if not form['script'].startswith('/'):
                # Script is relative to the current dir
                script = os.path.join(os.path.realpath(os.curdir),
                                      form['script'])
            else:
                # Absolute path to the script
                script = form['script']
            forms.append(
                FormDefinition(form_name,
                               form['title'],
                               form['description'],
                               form['fields'],
                               script,
                               output=form.get('output', 'escaped'),
                               hidden=form.get('hidden', False),
                               submit_title=form.get('submit_title', 'Submit'),
                               allowed_users=form.get('allowed_users', None),
                               run_as=form.get('run_as', None))
            )

        form_config = FormConfig(
            config['title'],
            forms,
            users,
            static_dir,
            custom_css
        )
        self.form_config_singleton = form_config
        return form_config

    def run(self, listen_addr='0.0.0.0', listen_port=80):
        """
        Start the webserver on address `listen_addr` and port `listen_port`.
        This call is blocking until the user hits Ctrl-c, the shutdown() method
        is called or something like SystemExit is raised in a handler.
        """
        ScriptFormWebApp.scriptform = self
        self.httpd = ThreadedHTTPServer((listen_addr, listen_port),
                                        ScriptFormWebApp)
        self.httpd.daemon_threads = True
        self.log.info("Listening on {0}:{1}".format(listen_addr, listen_port))
        self.running = True
        self.httpd.serve_forever()
        self.running = False

    def shutdown(self):
        """
        Shutdown the server. This interupts the run() method and must thus be
        run in a seperate thread.
        """
        self.log.info("Attempting server shutdown")

        def t_shutdown(scriptform_instance):
            """
            Callback for when the server is shutdown.
            """
            scriptform_instance.log.info(self.websrv)
            # Undocumented feature to shutdow the server.
            scriptform_instance.httpd.socket.close()
            scriptform_instance.httpd.shutdown()

        # We need to spawn a new thread in which the server is shut down,
        # because doing it from the main thread blocks, since the server is
        # waiting for connections..
        thread.start_new_thread(t_shutdown, (self, ))