from db import get_connection, getRethinkDB from dataclasses import fields from typing import List, Type from flask import request, render_template r = getRethinkDB() def get_bool_attribute_names(cls: Type) -> List[str]: return [field.name for field in fields(cls) if field.type == bool] def create_routes(cls, app): print("creating routes for " + cls.__name__) table_name = cls.get_table_name() if table_name not in r.table_list().run(get_connection()): print("creating table " + table_name) r.table_create(table_name).run(get_connection()) get_endpoint = f"{cls.__name__}_get" get_create_endpoint = f"{cls.__name__}_get_create" post_create_endpoint = f"{cls.__name__}_post_create" get_update_endpoint = f"{cls.__name__}_get_update" post_update_endpoint = f"{cls.__name__}_post_update" post_delete_endpoint = f"{cls.__name__}_post_delete" @app.route(cls.get_route_prefix() + "/", methods=['GET'], endpoint=get_endpoint) def get(): cursor = r.table(table_name).run(get_connection()) fields = list(cursor) return render_template(cls.get_template_prefix() + "/index.html", data={ "title": cls.__name__, "fields": [cls.format(field) for field in fields], "prefix": cls.get_route_prefix(), "order": cls.get_order() }) @app.route(cls.get_route_prefix() + "/create", methods=['GET'], endpoint=get_create_endpoint) def get_create(): return render_template(cls.get_template_prefix() + "/create.html", data={ "name": cls.__name__, "prefix": cls.get_route_prefix(), "computed": cls.get_computed_properties(), "fields": {field.name: field.type.__name__ for field in fields(cls)} }) @app.route(cls.get_route_prefix() + "/create", methods=['POST'], endpoint=post_create_endpoint) def post_create(): if request.headers['Content-Type'] == 'application/x-www-form-urlencoded': data = request.form.to_dict() data.update(cls.compute_properties()) for key in get_bool_attribute_names(cls): data[key] = key in request.form r.table(table_name).insert(data).run(get_connection()) return "Resource created", 201 return "Unsupported Content-Type", 415 @app.route(cls.get_route_prefix() + "/update/", methods=['GET'], endpoint=get_update_endpoint) def get_update(id): cursor = r.table(table_name).get(id).run(get_connection()) return render_template(cls.get_template_prefix() + "/update.html", data={ "name": cls.__name__, "field": cursor, "fields": {field.name: field.type.__name__ for field in fields(cls)}, "prefix": cls.get_route_prefix(), "order": cls.get_order(), "computed": cls.get_computed_properties() }) @app.route(cls.get_route_prefix() + "/update/", methods=['POST'], endpoint=post_update_endpoint) def post_update(id): if request.headers['Content-Type'] == 'application/x-www-form-urlencoded': data = request.form.to_dict() for key in get_bool_attribute_names(cls): data[key] = key in request.form r.table(table_name).get(id).update(data).run(get_connection()) return "Resource " + id + " updated", 204 return "Unsupported Content-Type", 415 @app.route(cls.get_route_prefix() + '/delete/', methods=['POST'], endpoint=post_delete_endpoint) def post_delete(id): if request.headers['Content-Type'] == 'application/x-www-form-urlencoded': r.table(table_name).get(id).delete().run(get_connection()) return "Resource " + id + " deleted", 204 return "Unsupported Content-Type", 415