class Word(db.Model): __tablename__ = "word" id = db.Column(db.Integer, primary_key=True) word = db.Column(db.String(100), unique=True, nullable=False) times_used = db.Column(db.Integer, default=1) language_id = db.Column(db.Integer, db.ForeignKey("language.id")) plays = db.relationship("Play", backref="word", lazy=True) def __repr__(self) -> str: return f"<Word {self.word}>" @classmethod def get_by_language(cls, language, page, per_page): return (cls.query.filter_by(language=language).order_by( desc(cls.times_used)).paginate(page=page, per_page=per_page)) @classmethod def get_by_word(cls, word): return cls.query.filter_by(word=word).first_or_404() def update_word_count(self): self.times_used += 1 def save(self): db.session.add(self) db.session.commit()
class Game(db.Model): id = db.Column(db.Integer, primary_key=True) date = db.Column(db.DateTime, default=dt.now, nullable=False) gametype = db.Column(db.Enum(GametypeEnum), default=GametypeEnum.normal, nullable=False) is_active = db.Column(db.Boolean(name="is_active"), default=False) winner_id = db.Column(db.Integer, db.ForeignKey("player.id")) plays = db.relationship("Play", backref="game", lazy=True) players = db.relationship( "Player", secondary=game_players, lazy="subquery", backref=db.backref("games", lazy=True), ) def __repr__(self) -> str: return f"<Game {self.gametype} {self.date}" @classmethod def get_by_date(cls, date): new_date = dt.strptime(date, "%Y-%m-%dT%H:%M:%S") return cls.query.filter_by(date=new_date).first_or_404() def save(self): db.session.add(self) db.session.commit()
class Admin(UserMixin, db.Model): """Model for administrator""" id = db.Column(db.Integer, primary_key=True) admin_name = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(100), unique=True, nullable=False) _password = db.Column("password", db.String(255), nullable=False) active = db.Column(db.Boolean(name="is_active"), default=True) @hybrid_property def password(self): return self._password @password.setter def password(self, value): self._password = pwd_context.hash(value) @login_manager.user_loader def load_user(id): return Admin.query.get(int(id)) def verify_password(self, password): return pwd_context.verify(password, self._password) def __repr__(self) -> str: return f"<Admin {self.admin_name}>"
class Language(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(120), unique=True) code = db.Column(db.String(2), unique=True) words = db.relationship("Word", backref="language", lazy=True) def __repr__(self) -> str: return f"<Language {self.name}>" @classmethod def get_by_name(cls, language_name): """Queries the database by language name. Args: language_name (string): Full language name Returns: Language object: Query result corresponding to selected language. """ return cls.query.filter_by(name=language_name).first_or_404() def save(self): """Saves current status of language instance.""" db.session.add(self) db.session.commit()
class Player(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), unique=True) avatar = db.Column(db.Integer) won_games = db.relationship("Game", backref="winner", lazy=True) plays = db.relationship("Play", backref="player", lazy=True) def __repr__(self) -> str: return f"Player {self.name}" @classmethod def get_by_name(cls, name): return cls.query.filter_by(name=name).first_or_404() def save(self): db.session.add(self) db.session.commit()
class TokenBlacklist(db.Model): """Blacklist representation""" id = db.Column(db.Integer, primary_key=True) jti = db.Column(db.String(36), nullable=False, unique=True) token_type = db.Column(db.String(10), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey("admin.id"), nullable=False) revoked = db.Column(db.Boolean(name="is_revoked"), nullable=False) expires = db.Column(db.DateTime, nullable=False) admin = db.relationship("Admin", lazy="joined") def to_dict(self): return { "token_id": self.id, "jti": self.jti, "token_type": self.token_type, "admin_identity": self.admin_identity, "revoked": self.revoked, "expires": self.expires, }
class Play(db.Model): id = db.Column(db.Integer, primary_key=True) turn_number = db.Column(db.Integer) score = db.Column(db.Integer) cumulative_score = db.Column(db.Integer, default=0) word_id = db.Column(db.Integer, db.ForeignKey("word.id"), nullable=False) game_id = db.Column(db.Integer, db.ForeignKey("game.id"), nullable=False) player_id = db.Column(db.Integer, db.ForeignKey("player.id"), nullable=False) def __repr__(self) -> str: return f"word: {self.word_id}, score: {self.score}" @classmethod def create_play(cls, data): try: word = Word.get_by_word(word=data["word"]) game = Game.get_by_date(date=data["date"]) player = Player.get_by_name(name=data["player"]) language = Language.get_by_name(language_name=data["language"]) except KeyError: return { "message": "A field in the data sent is missing, check values" }, HTTPStatus.BAD_REQUEST if word is None: word = Word(word=data["word"], language=language) word.save() else: word.update_word_count() last_play = (cls.query.filter_by(game_id=game.id).order_by( Play.id.desc()).first()) if last_play is None: cumulative_score = data["score"] else: cumulative_score = last_play.cumulative_score + data["score"] new_play = cls( turn_number=data["turn_number"], score=data["score"], word=word, game=game, player=player, cumulative_score=cumulative_score, ) new_play.save_play() return (new_play) @classmethod def get_by_player(cls, player, page, per_page): return cls.query.filter_by(player=player).paginate(page=page, per_page=per_page) @classmethod def get_by_game(cls, game, page, per_page): return cls.query.filter_by(game=game).paginate(page=page, per_page=per_page) def delete_play(self): db.session.delete(self) db.session.commit() def save_play(self): db.session.add(self) db.session.commit()
import enum from datetime import datetime as dt from scrabbleScoreboard.extensions import db game_players = db.Table( "game_players", db.Column("game_id", db.Integer, db.ForeignKey("game.id"), primary_key=True), db.Column("player_id", db.Integer, db.ForeignKey("player.id"), primary_key=True), ) class GametypeEnum(enum.Enum): normal = "normal" timed = "timed" class Game(db.Model): id = db.Column(db.Integer, primary_key=True) date = db.Column(db.DateTime, default=dt.now, nullable=False) gametype = db.Column(db.Enum(GametypeEnum), default=GametypeEnum.normal, nullable=False) is_active = db.Column(db.Boolean(name="is_active"), default=False)