from app.core import bcrypt, db from sqlalchemy.ext.hybrid import hybrid_method, hybrid_property from app.database.types import ID_IMAGE_COMPONENT, ID_QUESTION_COMPONENT, ID_TEXT_COMPONENT STRING_SIZE = 254 class Blacklist(db.Model): id = db.Column(db.Integer, primary_key=True) jti = db.Column(db.String, unique=True) expire_date = db.Column(db.Integer, nullable=True) 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 # TODO Region? 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") competitions = db.relationship("Competition", 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(STRING_SIZE), unique=True) name = db.Column(db.String(STRING_SIZE), nullable=True) _password = db.Column(db.LargeBinary(60), nullable=False) authenticated = db.Column(db.Boolean, default=False) # twoAuthConfirmed = db.Column(db.Boolean, default=True) # twoAuthCode = db.Column(db.String(STRING_SIZE), nullable=True) role_id = db.Column(db.Integer, db.ForeignKey("role.id"), nullable=False) city_id = db.Column(db.Integer, db.ForeignKey("city.id"), nullable=False) media = db.relationship("Media", backref="upload_by") def __init__(self, email, plaintext_password, role_id, city_id, name=None): self._password = bcrypt.generate_password_hash(plaintext_password) self.email = email self.role_id = role_id self.city_id = city_id self.authenticated = False self.name = name @hybrid_property def password(self): return self._password @password.setter def set_password(self, plaintext_password): self._password = bcrypt.generate_password_hash(plaintext_password) @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_id = db.Column(db.Integer, db.ForeignKey("media_type.id"), nullable=False) upload_by_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False) def __init__(self, filename, type_id, upload_by_id): self.filename = filename self.type_id = type_id self.upload_by_id = upload_by_id class Competition(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(STRING_SIZE), unique=True) year = db.Column(db.Integer, nullable=False, default=2020) font = db.Column(db.String(STRING_SIZE), nullable=False) city_id = db.Column(db.Integer, db.ForeignKey("city.id"), nullable=False) background_image_id = db.Column(db.Integer, db.ForeignKey("media.id"), nullable=True) background_image = db.relationship("Media", uselist=False) slides = db.relationship("Slide", backref="competition") teams = db.relationship("Team", backref="competition") background_image = db.relationship("Media", uselist=False) def __init__(self, name, year, city_id): self.name = name self.year = year self.city_id = city_id self.font = "Calibri" class Team(db.Model): __table_args__ = (db.UniqueConstraint("competition_id", "name"),) id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(STRING_SIZE), nullable=False) competition_id = db.Column(db.Integer, db.ForeignKey("competition.id"), nullable=False) question_answers = db.relationship("QuestionAnswer", backref="team") def __init__(self, name, competition_id): self.name = name self.competition_id = competition_id class Slide(db.Model): __table_args__ = (db.UniqueConstraint("order", "competition_id"),) id = db.Column(db.Integer, primary_key=True) order = db.Column(db.Integer, nullable=False) title = db.Column(db.String(STRING_SIZE), nullable=False, default="") body = db.Column(db.Text, nullable=False, default="") timer = db.Column(db.Integer, nullable=False, default=0) settings = db.Column(db.Text, nullable=False, default="{}") competition_id = db.Column(db.Integer, db.ForeignKey("competition.id"), nullable=False) 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") questions = db.relationship("Question", backref="questions") def __init__(self, order, competition_id): self.order = order self.competition_id = competition_id class Question(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(STRING_SIZE), nullable=False) total_score = db.Column(db.Integer, nullable=False, default=1) type_id = db.Column(db.Integer, db.ForeignKey("question_type.id"), nullable=False) slide_id = db.Column(db.Integer, db.ForeignKey("slide.id"), nullable=False) question_answers = db.relationship("QuestionAnswer", backref="question") alternatives = db.relationship("QuestionAlternative", backref="question") def __init__(self, name, total_score, type_id, slide_id): self.name = name self.total_score = total_score self.type_id = type_id self.slide_id = slide_id class QuestionAlternative(db.Model): id = db.Column(db.Integer, primary_key=True) text = db.Column(db.String(STRING_SIZE), nullable=False) value = db.Column(db.Integer, nullable=False) question_id = db.Column(db.Integer, db.ForeignKey("question.id"), nullable=False) def __init__(self, text, value, question_id): self.text = text self.value = value self.question_id = question_id class QuestionAnswer(db.Model): __table_args__ = (db.UniqueConstraint("question_id", "team_id"),) id = db.Column(db.Integer, primary_key=True) answer = db.Column(db.String(STRING_SIZE), nullable=False) score = db.Column(db.Integer, nullable=False, default=0) question_id = db.Column(db.Integer, db.ForeignKey("question.id"), nullable=False) team_id = db.Column(db.Integer, db.ForeignKey("team.id"), nullable=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 class Component(db.Model): 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) view_type_id = db.Column(db.Integer, db.ForeignKey("view_type.id"), nullable=True) slide_id = db.Column(db.Integer, db.ForeignKey("slide.id"), nullable=False) type_id = db.Column(db.Integer, db.ForeignKey("component_type.id"), nullable=False) __mapper_args__ = {"polymorphic_on": type_id} def __init__(self, slide_id, type_id, view_type_id, x=0, y=0, w=1, h=1): self.x = x self.y = y self.w = w self.h = h self.slide_id = slide_id self.type_id = type_id self.view_type_id = view_type_id class TextComponent(Component): text = db.Column(db.Text, default="", nullable=False) # __tablename__ = None __mapper_args__ = {"polymorphic_identity": ID_TEXT_COMPONENT} class ImageComponent(Component): media_id = db.Column(db.Integer, db.ForeignKey("media.id"), nullable=True) media = db.relationship("Media", uselist=False) # __tablename__ = None __mapper_args__ = {"polymorphic_identity": ID_IMAGE_COMPONENT} class QuestionComponent(Component): question_id = db.Column(db.Integer, db.ForeignKey("question.id"), nullable=True) # __tablename__ = None __mapper_args__ = {"polymorphic_identity": ID_QUESTION_COMPONENT} class Code(db.Model): id = db.Column(db.Integer, primary_key=True) code = db.Column(db.Text, unique=True) view_type_id = db.Column(db.Integer, db.ForeignKey("view_type.id"), nullable=False) competition_id = db.Column(db.Integer, db.ForeignKey("competition.id"), nullable=False) team_id = db.Column(db.Integer, db.ForeignKey("team.id"), nullable=True) view_type = db.relationship("ViewType", uselist=False) def __init__(self, code, view_type_id, competition_id=None, team_id=None): self.code = code self.view_type_id = view_type_id self.competition_id = competition_id self.team_id = team_id class ViewType(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(STRING_SIZE), unique=True) def __init__(self, name): self.name = name class ComponentType(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(STRING_SIZE), unique=True) components = db.relationship("Component", backref="component_type") def __init__(self, name): self.name = name class MediaType(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(STRING_SIZE), unique=True) media = db.relationship("Media", backref="type") def __init__(self, name): self.name = name class QuestionType(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(STRING_SIZE), unique=True) questions = db.relationship("Question", backref="type") def __init__(self, name): self.name = name