def __init__(self):
     """
     Constructor
     Get the Model tier: Hierarchy (from file or construct it from the Internet)
     Get the View tier: SchemaView
     Start the http demon
     """
     super().__init__()
     self.cloud = True  # Running on server
     self.Restart = False  # Don't restart unless it's local
     self.hierarchy = Hierarchy()  # the model
     self.view = SchemaView(self.hierarchy.version)  # the view
     self.schema_bot = None  # Bot to update the model
     self._httpd = None  # simple server placeholder (for localhost only)
Esempio n. 2
0
 def setUpClass(cls):
     cls.hierarchy = Hierarchy()
     cls.view = SchemaView()
Esempio n. 3
0
 def setUpClass(cls):
     cls.hierarchy = Hierarchy()
     cls.view = SchemaView(SCHEMA_VERSION)
     cls.tests = ['micro', 'rdfa', 'json']
    def __call__(self, environ, start_response):
        """
        Class method passed to the http demon

        Here is where all GET and POST get treated

        Here is where the Model is invoked

        Here is where the View is invoked

        :param environ: A |mapping| |external_link| object representing the string environment concerning the request

        :param start_response: Callable. Used to begin the HTTP response

        :return: Requested page.

        .. |mapping| raw:: html

            <a href="https://docs.python.org/3.5/glossary.html#term-mapping" target="_blank">mapping</a>
        """
        path_info = None
        try:
            # Default status
            self.status = '200 OK'

            # Create a context from the environment
            ctx = EZContext(environ)

            # Get the path info - This is to redirect the flow
            # This is not in the ctx
            path_info = environ['PATH_INFO'][1:]
            if path_info in ['quit', 'restart']:
                # Only quit or restart when localhost
                if self.cloud:
                    raise SchemaNotFoundError

                self.headers = [('Content-type', 'text/plain; charset=utf-8')]
                # Configure Apache to filter out these requests
                # localhost:port/quit or /restart can then be used
                if 'restart' == path_info:
                    self.Restart = True

                # The http demon will not stop from a call in this thread
                # Another thread is needed to stop the server
                q = EZQuit(self._httpd)
                q.start()

                # Returns a string to the browser
                rc = '/{0}: {1}'.format(path_info, datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
            elif '.ico' in path_info or '.png' in path_info or '.jpg' in path_info:
                # This code should be eliminated when used as a module with Apache
                with open('view/{0}'.format(path_info), 'rb') as f:
                    txt = f.read()

                if '.ico' in path_info:
                    self.headers = [('Content-type', 'image/ico'), ('Content-length', str(len(txt)))]
                elif '.png' in path_info:
                    self.headers = [('Content-type', 'image/png'), ('Content-length', str(len(txt)))]
                elif '.jpg' in path_info:
                    self.headers = [('Content-type', 'image/jpg'), ('Content-length', str(len(txt)))]

                rc = [txt]
            elif '.js' in path_info:
                # This code should be eliminated when used as a module with Apache
                self.headers = [('Content-type', 'text/js; charset=utf-8')]
                with open('view/{0}'.format(path_info)) as f:
                    rc = f.read()
            elif '.css' in path_info:
                # This code should be eliminated when used as a module with Apache
                self.headers = [('Content-type', 'text/css; charset=utf-8')]
                with open('view/{0}'.format(path_info)) as f:
                    rc = f.read()
            elif path_info == 'robots.txt':
                # This code should be eliminated when used as a module with Apache
                self.headers = [('Content-type', 'text/plain; charset=utf-8')]
                with open('view/{0}'.format(path_info)) as f:
                    rc = f.read()
            else:
                # Return html
                self.headers = [('Content-type', 'text/html; charset=utf-8')]
                if not path_info:
                    try:
                        with open('view/index.html') as f:
                            # info('Controller log - 1')
                            rc = f.read()
                    except FileNotFoundError:
                        # Returns the whole hierarchy - Similar to http://schema.org/docs/full.html
                        # info('Controller log - 2')
                        rc = self.view.get_index(self.hierarchy.hierarchy)
                        with open('view/index.html', 'w') as f:
                            f.write(rc)
                elif 'schema_bot' == path_info:
                    if ctx.get('check'):
                        # info('Controller log - 3')
                        rc = self.view.get_schema_bot_ajax(self.schema_bot)
                        if 'Busy' != rc:
                            self.schema_bot = None
                        elif 'Updated' in rc:
                            self.hierarchy = Hierarchy()
                            # index = self.view.get_index(self.hierarchy)
                            # with open('view/index.html', 'w') as f:
                            #     f.write(index)
                    else:
                        # No bot, then start one
                        if self.schema_bot is None:
                            self.schema_bot = Bot()
                            self.schema_bot.start()
                        rc = self.view.get_schema_bot_html()
                elif 'AddRoles' == path_info:
                    # info('Controller log - 5')
                    rc = 'yo!'
                elif 'GenerateOntology' == path_info:
                    # Put it all together
                    # Output the Scheme the user has constructed
                    # Output a link to the Google Structured Data Testing Tool
                    schema_type = ctx.get('type')
                    # print(schema_type)
                    schema = SchemaClass(ctx.get('path'))
                    # schema = self.hierarchy.get_schema(ctx.get('path'))
                    if 'RDFa' == schema_type:
                        rc = self.view.generate_rdfa(schema, ctx)
                    elif 'JSON' == schema_type:
                        rc = self.view.generate_json(schema, ctx)
                    else:
                        rc = self.view.generate_microdata(schema, ctx)
                elif 'GenerateSchema' == path_info:
                    # Put it all together
                    # Output the Scheme the user has constructed
                    # Output a link to the Google Structured Data Testing Tool
                    if 'GET' == ctx.get('REQUEST_METHOD'):
                        raise (BaseException('Invalid method'))

                    schema_type = ctx.get('type')
                    # print(schema_type)
                    schema = self.hierarchy.get_schema(ctx.get('path'))
                    if 'RDFa' == schema_type:
                        rc = self.view.generate_rdfa(schema, ctx)
                    elif 'JSON' == schema_type:
                        rc = self.view.generate_json(schema, ctx)
                    else:
                        rc = self.view.generate_microdata(schema, ctx)
                elif ctx.get('next_element'):  # If the Action is POST
                    # AJAX call for the next level down from the top level Scheme the user is constructing
                    # info('Controller log - 6')

                    schema = self.hierarchy.get_schema(ctx.get('next_element'))
                    id = int(ctx.get('select_id'))
                    # The id of the container div - use for next level
                    rc = self.view.ajax_properties(schema, ctx.get('id'), False, id)
                else:  # Otherwise the action is GET - This is what happens first
                    # 1. Get the Hierarchy
                    # 2. next_element (or not) - get the AJAX properties of the next_element
                    # 3. GenerateSchema - Output the schema so it can be used by the user
                    # info('Controller log - 7')

                    schema = self.hierarchy.get_schema(path_info)
                    if schema.name != path_info:
                        path_info = schema.name

                    breadcrumb = ctx.get('breadcrumb')
                    if not breadcrumb:
                        breadcrumb = path_info

                    list_hierarchy, breadcrumb = self.hierarchy.get_hierarchy(breadcrumb)
                    rc = self.view.show_schema_properties(schema, list_hierarchy, breadcrumb)
        except SchemaNotFoundError:
            self.status = '404 Error'
            self.headers = [('Content-type', 'text/plain; charset=utf-8')]
            rc = 'Schema "{0}" not found'.format(path_info)
        except BaseException as err:
            # If Invalid method
            self.status = '405 Error'
            self.headers = [('Content-type', 'text/plain; charset=utf-8')]
            rc = err.args[0]
        except Exception as err:
            # If something unexpected happens, return a reasonable message
            self.status = '300 Error'
            self.headers = [('Content-type', 'text/plain; charset=utf-8')]
            rc = err.args[0]

        # Finally, return the info to the browser
        return self._do_return(start_response, rc)
class Controller(handlers.CGIHandler):
    """
    The Controller class manages the flow of requests for Generating Schemas
    """

    # Class variable to maintain the 'restart' state
    Restart = False

    def __init__(self):
        """
        Constructor
        Get the Model tier: Hierarchy (from file or construct it from the Internet)
        Get the View tier: SchemaView
        Start the http demon
        """
        super().__init__()
        self.cloud = True  # Running on server
        self.Restart = False  # Don't restart unless it's local
        self.hierarchy = Hierarchy()  # the model
        self.view = SchemaView(self.hierarchy.version)  # the view
        self.schema_bot = None  # Bot to update the model
        self._httpd = None  # simple server placeholder (for localhost only)
        # basicConfig(filename='_controller.log', level=DEBUG)

    def run(self, host='localhost', port=8000, cloud=False):
        self.cloud = cloud
        self.view.cloud = cloud

        # Initialize the server deamon
        self._httpd = simple_server.make_server(host, port, self.__call__)
        print("Serving on port {0}...".format(port))

        # Start the server
        self._httpd.serve_forever()

    def _do_return(self, start_response, rc):
        """
        Returns the response to the client

        :type rc: list or str
        """
        start_response(self.status, self.headers)
        # rc can be a list or text
        if isinstance(rc, list):
            return rc  # favicon.ico, etc

        # Use the default UTF-8 encoding
        try:
            return [rc.encode()]
        except AttributeError:
            return [rc]

    # This closes the server so the socket is liberated
    def server_close(self):
        """
        Class method closes the http demon
        """
        self._httpd.server_close()

    def __call__(self, environ, start_response):
        """
        Class method passed to the http demon

        Here is where all GET and POST get treated

        Here is where the Model is invoked

        Here is where the View is invoked

        :param environ: A |mapping| |external_link| object representing the string environment concerning the request

        :param start_response: Callable. Used to begin the HTTP response

        :return: Requested page.

        .. |mapping| raw:: html

            <a href="https://docs.python.org/3.5/glossary.html#term-mapping" target="_blank">mapping</a>
        """
        path_info = None
        try:
            # Default status
            self.status = '200 OK'

            # Create a context from the environment
            ctx = EZContext(environ)

            # Get the path info - This is to redirect the flow
            # This is not in the ctx
            path_info = environ['PATH_INFO'][1:]
            if path_info in ['quit', 'restart']:
                # Only quit or restart when localhost
                if self.cloud:
                    raise SchemaNotFoundError

                self.headers = [('Content-type', 'text/plain; charset=utf-8')]
                # Configure Apache to filter out these requests
                # localhost:port/quit or /restart can then be used
                if 'restart' == path_info:
                    self.Restart = True

                # The http demon will not stop from a call in this thread
                # Another thread is needed to stop the server
                q = EZQuit(self._httpd)
                q.start()

                # Returns a string to the browser
                rc = '/{0}: {1}'.format(path_info, datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
            elif '.ico' in path_info or '.png' in path_info or '.jpg' in path_info:
                # This code should be eliminated when used as a module with Apache
                with open('view/{0}'.format(path_info), 'rb') as f:
                    txt = f.read()

                if '.ico' in path_info:
                    self.headers = [('Content-type', 'image/ico'), ('Content-length', str(len(txt)))]
                elif '.png' in path_info:
                    self.headers = [('Content-type', 'image/png'), ('Content-length', str(len(txt)))]
                elif '.jpg' in path_info:
                    self.headers = [('Content-type', 'image/jpg'), ('Content-length', str(len(txt)))]

                rc = [txt]
            elif '.js' in path_info:
                # This code should be eliminated when used as a module with Apache
                self.headers = [('Content-type', 'text/js; charset=utf-8')]
                with open('view/{0}'.format(path_info)) as f:
                    rc = f.read()
            elif '.css' in path_info:
                # This code should be eliminated when used as a module with Apache
                self.headers = [('Content-type', 'text/css; charset=utf-8')]
                with open('view/{0}'.format(path_info)) as f:
                    rc = f.read()
            elif path_info == 'robots.txt':
                # This code should be eliminated when used as a module with Apache
                self.headers = [('Content-type', 'text/plain; charset=utf-8')]
                with open('view/{0}'.format(path_info)) as f:
                    rc = f.read()
            else:
                # Return html
                self.headers = [('Content-type', 'text/html; charset=utf-8')]
                if not path_info:
                    try:
                        with open('view/index.html') as f:
                            # info('Controller log - 1')
                            rc = f.read()
                    except FileNotFoundError:
                        # Returns the whole hierarchy - Similar to http://schema.org/docs/full.html
                        # info('Controller log - 2')
                        rc = self.view.get_index(self.hierarchy.hierarchy)
                        with open('view/index.html', 'w') as f:
                            f.write(rc)
                elif 'schema_bot' == path_info:
                    if ctx.get('check'):
                        # info('Controller log - 3')
                        rc = self.view.get_schema_bot_ajax(self.schema_bot)
                        if 'Busy' != rc:
                            self.schema_bot = None
                        elif 'Updated' in rc:
                            self.hierarchy = Hierarchy()
                            # index = self.view.get_index(self.hierarchy)
                            # with open('view/index.html', 'w') as f:
                            #     f.write(index)
                    else:
                        # No bot, then start one
                        if self.schema_bot is None:
                            self.schema_bot = Bot()
                            self.schema_bot.start()
                        rc = self.view.get_schema_bot_html()
                elif 'AddRoles' == path_info:
                    # info('Controller log - 5')
                    rc = 'yo!'
                elif 'GenerateOntology' == path_info:
                    # Put it all together
                    # Output the Scheme the user has constructed
                    # Output a link to the Google Structured Data Testing Tool
                    schema_type = ctx.get('type')
                    # print(schema_type)
                    schema = SchemaClass(ctx.get('path'))
                    # schema = self.hierarchy.get_schema(ctx.get('path'))
                    if 'RDFa' == schema_type:
                        rc = self.view.generate_rdfa(schema, ctx)
                    elif 'JSON' == schema_type:
                        rc = self.view.generate_json(schema, ctx)
                    else:
                        rc = self.view.generate_microdata(schema, ctx)
                elif 'GenerateSchema' == path_info:
                    # Put it all together
                    # Output the Scheme the user has constructed
                    # Output a link to the Google Structured Data Testing Tool
                    if 'GET' == ctx.get('REQUEST_METHOD'):
                        raise (BaseException('Invalid method'))

                    schema_type = ctx.get('type')
                    # print(schema_type)
                    schema = self.hierarchy.get_schema(ctx.get('path'))
                    if 'RDFa' == schema_type:
                        rc = self.view.generate_rdfa(schema, ctx)
                    elif 'JSON' == schema_type:
                        rc = self.view.generate_json(schema, ctx)
                    else:
                        rc = self.view.generate_microdata(schema, ctx)
                elif ctx.get('next_element'):  # If the Action is POST
                    # AJAX call for the next level down from the top level Scheme the user is constructing
                    # info('Controller log - 6')

                    schema = self.hierarchy.get_schema(ctx.get('next_element'))
                    id = int(ctx.get('select_id'))
                    # The id of the container div - use for next level
                    rc = self.view.ajax_properties(schema, ctx.get('id'), False, id)
                else:  # Otherwise the action is GET - This is what happens first
                    # 1. Get the Hierarchy
                    # 2. next_element (or not) - get the AJAX properties of the next_element
                    # 3. GenerateSchema - Output the schema so it can be used by the user
                    # info('Controller log - 7')

                    schema = self.hierarchy.get_schema(path_info)
                    if schema.name != path_info:
                        path_info = schema.name

                    breadcrumb = ctx.get('breadcrumb')
                    if not breadcrumb:
                        breadcrumb = path_info

                    list_hierarchy, breadcrumb = self.hierarchy.get_hierarchy(breadcrumb)
                    rc = self.view.show_schema_properties(schema, list_hierarchy, breadcrumb)
        except SchemaNotFoundError:
            self.status = '404 Error'
            self.headers = [('Content-type', 'text/plain; charset=utf-8')]
            rc = 'Schema "{0}" not found'.format(path_info)
        except BaseException as err:
            # If Invalid method
            self.status = '405 Error'
            self.headers = [('Content-type', 'text/plain; charset=utf-8')]
            rc = err.args[0]
        except Exception as err:
            # If something unexpected happens, return a reasonable message
            self.status = '300 Error'
            self.headers = [('Content-type', 'text/plain; charset=utf-8')]
            rc = err.args[0]

        # Finally, return the info to the browser
        return self._do_return(start_response, rc)

    # Unused CGIHandler abstract method
    def get_stdin(self):
        pass

    # Unused CGIHandler abstract method
    def _flush(self):
        pass

    # Unused CGIHandler abstract method
    def get_stderr(self):
        pass

    # Unused CGIHandler abstract method
    def add_cgi_vars(self):
        pass

    # Unused CGIHandler abstract method
    def _write(self, data):
        pass
Esempio n. 6
0
 def setUpClass(cls):
     cls.schema = Hierarchy()