101 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Python
		
	
	
	
#!/usr/bin/python3
 | 
						|
import inspect
 | 
						|
import argparse
 | 
						|
from datetime import datetime
 | 
						|
 | 
						|
import bjoern
 | 
						|
import sqlalchemy
 | 
						|
from sqlalchemy.orm import RelationshipProperty, ColumnProperty
 | 
						|
 | 
						|
 | 
						|
def install(arguments):
 | 
						|
    from flaschengeist.app import create_app, install_all
 | 
						|
 | 
						|
    app = create_app()
 | 
						|
    with app.app_context():
 | 
						|
        install_all()
 | 
						|
 | 
						|
 | 
						|
def run(arguments):
 | 
						|
    from flaschengeist.app import create_app
 | 
						|
 | 
						|
    app = create_app()
 | 
						|
    with app.app_context():
 | 
						|
        if arguments.debug:
 | 
						|
            app.run(arguments.host, arguments.port, debug=True)
 | 
						|
        else:
 | 
						|
            bjoern.run(app, arguments.host, arguments.port, reuse_port=True)
 | 
						|
 | 
						|
 | 
						|
def export(arguments):
 | 
						|
    import flaschengeist.system.models as models
 | 
						|
 | 
						|
    known = []
 | 
						|
    done = []
 | 
						|
    classes = {}
 | 
						|
 | 
						|
    def pytype(cls):
 | 
						|
        if isinstance(cls, list):
 | 
						|
            return "Array<{}>".format(pytype(cls[0]))
 | 
						|
        mapper = {"str": "string", "int": "number", "datetime": "Date"}
 | 
						|
        if cls.__name__ in mapper:
 | 
						|
            return mapper[cls.__name__]
 | 
						|
        else:
 | 
						|
            return cls.__name__
 | 
						|
 | 
						|
    def walker(mod):
 | 
						|
        if inspect.ismodule(mod[1]) and mod[1].__name__.startswith(models.__name__) and mod[1].__name__ not in known:
 | 
						|
            known.append(mod[1].__name__)
 | 
						|
            for cls in inspect.getmembers(mod[1], lambda x: inspect.isclass(x) or inspect.ismodule(x)):
 | 
						|
                walker(cls)
 | 
						|
        elif (
 | 
						|
            inspect.isclass(mod[1])
 | 
						|
            and mod[1].__module__.startswith(models.__name__)
 | 
						|
            and mod[0] not in classes
 | 
						|
            and not mod[0].startswith("_")
 | 
						|
            and hasattr(mod[1], "__annotations__")
 | 
						|
        ):
 | 
						|
            d = {param: pytype(ptype) for param, ptype in mod[1].__annotations__.items() if not param.startswith("_")}
 | 
						|
            if len(d) == 1:
 | 
						|
                key, value = d.popitem()
 | 
						|
                classes[mod[0]] = value
 | 
						|
            else:
 | 
						|
                classes[mod[0]] = d
 | 
						|
 | 
						|
    from flaschengeist.app import create_app
 | 
						|
 | 
						|
    app = create_app()
 | 
						|
    with app.app_context():
 | 
						|
        walker(("models", models))
 | 
						|
        with open(arguments.file, "w") as file:
 | 
						|
            for cls, params in classes.items():
 | 
						|
                if isinstance(params, str):
 | 
						|
                    file.write("type {} = {};\n".format(cls, params))
 | 
						|
                else:
 | 
						|
                    file.write("interface {} {{\n".format(cls))
 | 
						|
                    for name in params:
 | 
						|
                        file.write("  {}: {};\n".format(name, params[name]))
 | 
						|
                    file.write("}\n")
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    # create the top-level parser
 | 
						|
    parser = argparse.ArgumentParser()
 | 
						|
    subparsers = parser.add_subparsers(help="sub-command help", dest="sub_command")
 | 
						|
    subparsers.required = True
 | 
						|
    parser_run = subparsers.add_parser("run", help="run flaschengeist")
 | 
						|
    parser_run.set_defaults(func=run)
 | 
						|
    parser_run.add_argument("--host", help="set hostname to listen on", default="127.0.0.1")
 | 
						|
    parser_run.add_argument("--port", help="set port to listen on", type=int, default=5000)
 | 
						|
    parser_run.add_argument("--debug", help="run in debug mode", action="store_true")
 | 
						|
    parser_install = subparsers.add_parser(
 | 
						|
        "install", help="run database setup for flaschengeist and all installed plugins"
 | 
						|
    )
 | 
						|
    parser_install.set_defaults(func=install)
 | 
						|
    parser_export = subparsers.add_parser("export", help="export models to typescript interfaces")
 | 
						|
    parser_export.set_defaults(func=export)
 | 
						|
    parser_export.add_argument("--file", help="Filename where to save", default="flaschengeist.d.ts")
 | 
						|
 | 
						|
    args = parser.parse_args()
 | 
						|
    args.func(args)
 |