From 29762ae910a2c060b66770c8a42bc0a9c2269e6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20Sch=C3=B6nfelder?= <carl@schonfelder.se> Date: Thu, 25 Feb 2021 11:26:15 +0100 Subject: [PATCH] #10: new database models --- server/app/api/users.py | 1 + server/app/database/__init__.py | 7 +- server/app/database/models.py | 200 ++++++++++++++++++++++++++++++-- 3 files changed, 195 insertions(+), 13 deletions(-) diff --git a/server/app/api/users.py b/server/app/api/users.py index db7859f2..0d92ee52 100644 --- a/server/app/api/users.py +++ b/server/app/api/users.py @@ -5,6 +5,7 @@ from app.api import api_blueprint from app.database.models import Blacklist, User from app.utils.validator import edit_user_schema, login_schema, register_schema, validateObject from flask import request +from flask.globals import session from flask_jwt_extended import ( create_access_token, create_refresh_token, diff --git a/server/app/database/__init__.py b/server/app/database/__init__.py index d755b84e..4a1dc8b7 100644 --- a/server/app/database/__init__.py +++ b/server/app/database/__init__.py @@ -1,13 +1,10 @@ -from flask_sqlalchemy.model import Model import sqlalchemy as sa +from flask_sqlalchemy.model import Model from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.sql import func class Base(Model): - @declared_attr - def __tablename__(self): - return self.__class__.__name__.replace("Model", "s").lower() - + __abstract__ = True created = sa.Column(sa.DateTime(timezone=True), server_default=func.now()) updated = sa.Column(sa.DateTime(timezone=True), onupdate=func.now()) diff --git a/server/app/database/models.py b/server/app/database/models.py index bd486a14..5452ce3d 100644 --- a/server/app/database/models.py +++ b/server/app/database/models.py @@ -1,22 +1,38 @@ -from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method +from app import bcrypt, db from sqlalchemy.ext.declarative import declared_attr +from sqlalchemy.ext.hybrid import hybrid_method, hybrid_property -from app import bcrypt, db -from app.database import Base +STRING_SIZE = 254 class Blacklist(db.Model): id = db.Column(db.Integer, primary_key=True) jti = db.Column(db.String, unique=True, nullable=False) - @declared_attr - def __tablename__(self): - return "blacklist" - def __init__(self, jti): self.jti = jti +class Role(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(STRING_SIZE), unique=True) + + users = db.relationship("User", backref="role") + + def __init__(self, name): + self.name = name + + +class City(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(STRING_SIZE), unique=True) + + users = db.relationship("User", backref="city") + + def __init__(self, name): + self.name = name + + class User(db.Model): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(254), unique=True, nullable=False) @@ -28,9 +44,16 @@ class User(db.Model): twoAuthConfirmed = db.Column(db.Boolean, default=True) # Change to false for Two factor authen twoAuthCode = db.Column(db.String(100), nullable=True) - def __init__(self, email, plaintext_password, name=""): + role_id = db.Column(db.Integer, db.ForeignKey("role.id"), nullable=True) # Change to false + city_id = db.Column(db.Integer, db.ForeignKey("city.id"), nullable=True) # Change to false + + media = db.relationship("Media", backref="upload_by") + + def __init__(self, email, plaintext_password, role_id=None, city_id=None, name=None): self._password = bcrypt.generate_password_hash(plaintext_password) self.email = email + self.role_id = role_id + self.city_id = city_id self.name = name self.authenticated = False @@ -48,3 +71,164 @@ class User(db.Model): @hybrid_method def is_correct_password(self, plaintext_password): return bcrypt.check_password_hash(self._password, plaintext_password) + + +class Media(db.Model): + id = db.Column(db.Integer, primary_key=True) + filename = db.Column(db.String(STRING_SIZE), unique=True) + type = db.Column(db.String(STRING_SIZE), nullable=False) + upload_by_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False) + + def __init__(self, filename, type, upload_by_id): + self.filename = filename + self.type = type + self.upload_by_id = upload_by_id + + +class Style(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(STRING_SIZE), unique=True) + css = db.Column(db.Text, nullable=True) + bg_image_id = db.Column(db.Integer, db.ForeignKey("media.id"), nullable=True) + + bg_image = db.relationship("Media", foreign_keys=[bg_image_id], uselist=False) + + def __init__(self, name, css=None, bg_image_id=None): + self.name = name + self.css = css + self.bg_image_id = bg_image_id + + +class Competition(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(STRING_SIZE), unique=True) + style_id = db.Column(db.Integer, db.ForeignKey("style.id"), nullable=False) + city_id = db.Column(db.Integer, db.ForeignKey("city.id"), nullable=False) + + style = db.relationship("Style", foreign_keys=[style_id], uselist=False) + city = db.relationship("City", foreign_keys=[city_id], uselist=False) + + def __init__(self, name, style_id, city_id): + self.name = name + self.style_id = style_id + self.city_id = city_id + + +class Team(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(STRING_SIZE), unique=True) + competition_id = db.Column(db.Integer, db.ForeignKey("competition.id"), nullable=False) + competition = db.relationship("Competition", foreign_keys=[competition_id], uselist=False) + + def __init__(self, name, competition_id): + self.name = name + self.competition_id = competition_id + + +class Slide(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(STRING_SIZE), unique=True) + order = db.Column(db.Integer, nullable=False) + tweak_settings = db.Column(db.Text, nullable=True) + competition_id = db.Column(db.Integer, db.ForeignKey("competition.id"), nullable=False) + + competition = db.relationship("Competition", foreign_keys=[competition_id], uselist=False) + + def __init__(self, name, order, competition_id, tweak_settings=None): + self.name = name + self.order = order + self.competition_id = competition_id + self.tweak_settings = tweak_settings + + +class Question(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(STRING_SIZE), unique=True) + title = db.Column(db.String(STRING_SIZE), nullable=False) + timer = db.Column(db.Integer, nullable=False) + slide_id = db.Column(db.Integer, db.ForeignKey("slide.id"), nullable=False) + + slide = db.relationship("Slide", foreign_keys=[slide_id], uselist=False) + + def __init__(self, name, title, timer, slide_id): + self.name = name + self.title = title + self.timer = timer + self.slide_id = slide_id + + +class TrueFalseQuestion(db.Model): + id = db.Column(db.Integer, primary_key=True) + true_false = db.Column(db.Boolean, nullable=False, default=False) + question_id = db.Column(db.Integer, db.ForeignKey("question.id"), nullable=False) + + question = db.relationship("Question", foreign_keys=[question_id], uselist=False) + + def __init__(self, true_false, question_id): + self.true_false = true_false + self.question_id = question_id + + +class TextQuestion(db.Model): + id = db.Column(db.Integer, primary_key=True) + question_id = db.Column(db.Integer, db.ForeignKey("question.id"), nullable=False) + question = db.relationship("Question", foreign_keys=[question_id], uselist=False) + + def __init__(self, question_id): + self.question_id = question_id + + +class TextQuestionAlternative(db.Model): + id = db.Column(db.Integer, primary_key=True) + text = db.Column(db.String(STRING_SIZE), nullable=False) + text_question_id = db.Column(db.Integer, db.ForeignKey("text_question.id"), nullable=False) + text_question = db.relationship("TextQuestion", foreign_keys=[text_question_id], uselist=False) + + def __init__(self, text, text_question_id): + self.text = text + self.text_question_id = text_question_id + + +class MCQuestion(db.Model): + id = db.Column(db.Integer, primary_key=True) + title = db.Column(db.String(STRING_SIZE), nullable=False) + timer = db.Column(db.Integer, nullable=False) + question_id = db.Column(db.Integer, db.ForeignKey("question.id"), nullable=False) + + question = db.relationship("Question", foreign_keys=[question_id], uselist=False) + + def __init__(self, title, timer, slide_id): + self.title = title + self.timer = timer + self.slide_id = slide_id + + +class MCQuestionAlternative(db.Model): + id = db.Column(db.Integer, primary_key=True) + text = db.Column(db.String(STRING_SIZE), nullable=False) + true_false = db.Column(db.Boolean, nullable=False, default=False) + mc_id = db.Column(db.Integer, db.ForeignKey("mc_question.id"), nullable=False) + + mc = db.relationship("MCQuestion", foreign_keys=[mc_id], uselist=False) + + def __init__(self, text, true_false, mc_id): + self.text = text + self.true_false = true_false + self.mc_id = mc_id + + +class AnsweredQuestion(db.Model): + id = db.Column(db.Integer, primary_key=True) + data = db.Column(db.Text, nullable=False) + score = db.Column(db.Integer, nullable=False) + question_id = db.Column(db.Integer, db.ForeignKey("question.id"), nullable=False) + team_id = db.Column(db.Integer, db.ForeignKey("team.id"), nullable=False) + + question = db.relationship("Question", foreign_keys=[question_id], uselist=False) + team = db.relationship("Team", foreign_keys=[team_id], uselist=False) + + def __init__(self, data, score, question_id, team_id): + self.data = data + self.score = score + self.question_id = question_id + self.team_id = team_id -- GitLab