From 393a76ebc20ea9aac1f77bb68fef50d5ecfe235f Mon Sep 17 00:00:00 2001 From: robban64 <carl@schonfelder.se> Date: Wed, 14 Apr 2021 15:02:55 +0200 Subject: [PATCH] add: component --- server/app/apis/__init__.py | 3 ++ server/app/apis/components.py | 30 +++++++++++ server/app/core/dto.py | 6 +++ server/app/core/schemas.py | 14 ++++++ server/app/database/controller/add.py | 8 +++ server/app/database/controller/get.py | 7 ++- server/app/database/models.py | 72 +++++++++++++++++++++++++++ 7 files changed, 138 insertions(+), 2 deletions(-) diff --git a/server/app/apis/__init__.py b/server/app/apis/__init__.py index 3b2ed213..9e3bd034 100644 --- a/server/app/apis/__init__.py +++ b/server/app/apis/__init__.py @@ -44,6 +44,7 @@ from flask_restx import Api from .auth import api as auth_ns from .competitions import api as comp_ns +from .components import api as component_ns from .media import api as media_ns from .misc import api as misc_ns from .questions import api as question_ns @@ -58,6 +59,8 @@ flask_api.add_namespace(user_ns, path="/api/users") flask_api.add_namespace(auth_ns, path="/api/auth") flask_api.add_namespace(comp_ns, path="/api/competitions") flask_api.add_namespace(slide_ns, path="/api/competitions/<CID>/slides") +flask_api.add_namespace(component_ns, path="/api/competitions/<CID>/slides/<SID>/components/") + flask_api.add_namespace(team_ns, path="/api/competitions/<CID>/teams") flask_api.add_namespace(question_ns, path="/api/competitions/<CID>/questions") # flask_api.add_namespace(question_ns, path="/api/competitions/<CID>/slides/<SID>/question") diff --git a/server/app/apis/components.py b/server/app/apis/components.py index e69de29b..360463dc 100644 --- a/server/app/apis/components.py +++ b/server/app/apis/components.py @@ -0,0 +1,30 @@ +import app.database.controller as dbc +from app.apis import admin_required, item_response, list_response +from app.core.dto import ComponentDTO +from app.core.parsers import competition_parser, competition_search_parser +from app.database.models import Competition +from flask.globals import request +from flask_jwt_extended import jwt_required +from flask_restx import Resource + +api = ComponentDTO.api +schema = ComponentDTO.schema +list_schema = ComponentDTO.list_schema + + +@api.route("/<component_id>") +@api.param("CID, SID, component_id") +class ComponentByID(Resource): + @jwt_required + def get(self, CID, SID, component_id): + item = dbc.get.component(component_id) + return item_response(schema.dump(item)) + + +@api.route("/") +@api.param("CID, SID") +class ComponentList(Resource): + @jwt_required + def post(self, CID, SID): + item = dbc.add.component(**request.args) + return item_response(schema.dump(item)) diff --git a/server/app/core/dto.py b/server/app/core/dto.py index 99d467ba..3e6b0cda 100644 --- a/server/app/core/dto.py +++ b/server/app/core/dto.py @@ -5,6 +5,12 @@ from flask_restx import Namespace, fields from flask_uploads import IMAGES, UploadSet +class ComponentDTO: + api = Namespace("component") + schema = schemas.ComponentSchema(many=False) + list_schema = schemas.ComponentSchema(many=True) + + class MediaDTO: api = Namespace("media") image_set = UploadSet("photos", IMAGES) diff --git a/server/app/core/schemas.py b/server/app/core/schemas.py index 27440642..fca727b2 100644 --- a/server/app/core/schemas.py +++ b/server/app/core/schemas.py @@ -113,3 +113,17 @@ class CompetitionSchema(BaseSchema): name = ma.auto_field() year = ma.auto_field() city_id = ma.auto_field() + + +class ComponentSchema(BaseSchema): + class Meta(BaseSchema.Meta): + model = models.Component + + id = ma.auto_field() + x = ma.auto_field() + y = ma.auto_field() + w = ma.auto_field() + h = ma.auto_field() + slide_id = ma.auto_field() + text = ma.auto_field() + image_id = ma.auto_field() diff --git a/server/app/database/controller/add.py b/server/app/database/controller/add.py index f612cdd6..8d17cdb6 100644 --- a/server/app/database/controller/add.py +++ b/server/app/database/controller/add.py @@ -4,6 +4,8 @@ from app.database.models import ( Blacklist, City, Competition, + Component, + ImageComponent, Media, MediaType, Question, @@ -11,6 +13,7 @@ from app.database.models import ( Role, Slide, Team, + TextComponent, User, ) from flask_restx import abort @@ -31,6 +34,11 @@ def db_add(func): return wrapper +@db_add +def component(x, y, w, h, data, type_id, item_slide): + return Component(x, y, w, h, data, item_slide.id, type_id) + + @db_add def blacklist(jti): return Blacklist(jti) diff --git a/server/app/database/controller/get.py b/server/app/database/controller/get.py index a2b45fed..02e6df6a 100644 --- a/server/app/database/controller/get.py +++ b/server/app/database/controller/get.py @@ -1,11 +1,14 @@ -from app.database.models import Competition, Question, Slide, Team, User -from sqlalchemy.sql.expression import outerjoin +from app.database.models import Competition, Component, ImageComponent, Question, Slide, Team, TextComponent, User def user_exists(email): return User.query.filter(User.email == email).count() > 0 +def component(ID): + return Component.query.filter(Component.id == ID) + + def competition(CID, required=True, error_msg=None): return Competition.query.filter(Competition.id == CID).first_extended(required, error_msg) diff --git a/server/app/database/models.py b/server/app/database/models.py index 5a17fb0d..cc492222 100644 --- a/server/app/database/models.py +++ b/server/app/database/models.py @@ -130,6 +130,8 @@ class Slide(db.Model): background_image_id = db.Column(db.Integer, db.ForeignKey("media.id"), nullable=True) background_image = db.relationship("Media", uselist=False) + components = db.relationship("Component", backref="slide") + def __init__(self, order, competition_id): self.order = order self.competition_id = competition_id @@ -181,6 +183,76 @@ class QuestionAnswer(db.Model): self.team_id = team_id +class Component(db.Model): + # __mapper_args__ = {"polymorphic_on": type, "polymorphic_identity": "component"} + id = db.Column(db.Integer, primary_key=True) + x = db.Column(db.Integer, nullable=False, default=0) + y = db.Column(db.Integer, nullable=False, default=0) + w = db.Column(db.Integer, nullable=False, default=1) + h = db.Column(db.Integer, nullable=False, default=1) + data = db.Column(db.Text) + type_id = db.Column(db.Integer, db.ForeignKey("component_type.id"), nullable=False) + + slide_id = db.Column(db.Integer, db.ForeignKey("slide.id"), nullable=False) + + def __init__(self, x, y, w, h, data, slide_id, type_id): + self.x = x + self.y = y + self.w = w + self.h = h + self.data = data + self.slide_id = slide_id + self.type_id = type_id + + +""" +class ImageComponent(Component): + __mapper_args__ = {"polymorphic_identity": "image_component"} + + id = db.Column(db.Integer, db.ForeignKey("component.id"), primary_key=True) + # id = db.Column(db.Integer, primary_key=True) + image_id = db.Column(db.Integer, db.ForeignKey("media.id"), nullable=False) + image = db.relationship("Media", uselist=False) + + def __init__(self, id, image_id, x, y, w, h, slide_id, type): + super.__init__(x, y, w, h, slide_id, type) + self.id = id + self.image_id = image_id + + +class TextComponent(Component): + __mapper_args__ = {"polymorphic_identity": "text_component"} + id = db.Column(db.Integer, db.ForeignKey("component.id"), primary_key=True) + text = db.Column(db.Text, default="", nullable=False) + + def __init__(self, id, text, x, y, w, h, slide_id, type): + super.__init__(x, y, w, h, slide_id, type) + self.id = id + self.text = text +""" + + +class Code(db.Model): + table_args = (db.UniqueConstraint("pointer", "type"),) + id = db.Column(db.Integer, primary_key=True) + code = db.Column(db.Text, unique=True) + pointer = db.Column(db.Integer, nullable=False) + + view_type_id = db.Column(db.Integer, db.ForeignKey("view_type.id"), nullable=False) + + +class ViewType(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.Text) + codes = db.relationship("Code", backref="view_type") + + +class ComponentType(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.Text) + components = db.relationship("Component", backref="component_type") + + class MediaType(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(STRING_SIZE), unique=True) -- GitLab