from app import app, db from sqlalchemy.orm import Mapped from datetime import date, datetime from typing import Optional, Annotated from sqlalchemy.orm import mapped_column as mc from sqlalchemy import String, Boolean, Integer, ForeignKey class User(db.Model): id: Mapped[int] = mc(primary_key=True) username: Mapped[str] = mc(String(64), index=True, unique=True) password_hash: Mapped[Optional[str]] = mc(String(256)) def __repr__(self): return f"User {self.username}" class Court(db.Model): id: Mapped[int] = mc(primary_key=True) status: Mapped[bool] = mc(Boolean, default=True) def __repr__(self): return f"Court {self.id} is {"active" if self.status else "inactive"}" class Player(db.Model): id: Mapped[int] = mc(primary_key=True) first_name: Mapped[str] = mc(String(64), index=True) last_name: Mapped[str] = mc(String(64), index=True) team: Mapped[int] = mc(Integer, index=True) status: Mapped[bool] = mc(Boolean) level: Mapped[int] = mc(Integer) def __init__( self, id, first_name, last_name, team=0, status=False, level=int(app.config["MIN_PLAYER_LEVEL"]), ): self.id = id self.first_name = first_name self.last_name = last_name self.team = team self.status = status self.level = level def __repr__(self): return f"{self.first_name} {self.last_name} is {"active" if self.status else "inactive"}" class Game(db.Model): id: Mapped[int] = mc(primary_key=True) round_id: Mapped[int] = mc(Integer, index=True) court_id: Mapped[int] = mc(ForeignKey(Court.id), index=True) player_1: Mapped[int] = mc(ForeignKey(Player.id), index=True) player_2: Mapped[int] = mc(ForeignKey(Player.id), index=True) player_3: Mapped[int] = mc(ForeignKey(Player.id), index=True) player_4: Mapped[int] = mc(ForeignKey(Player.id), index=True) date: Mapped[datetime] = mc(index=True, default=lambda: date.today()) def __init__( self, round_id: Optional[int], court_id: int, player_1: int, player_2: int, player_3: int, player_4: int, ): if round_id is not None: self.round_id = round_id self.court_id = court_id self.player_1 = player_1 self.player_2 = player_2 self.player_3 = player_3 self.player_4 = player_4 class DisplayGame: court: Court team_1: Annotated[list[Player], 2] team_2: Annotated[list[Player], 2] def __init__(self, game: Game): court = db.session.get(Court, game.court_id) if court is None: raise ValueError(f"Unknown court") self.court = court players = [] for i in range(4): player_id = getattr(game, f"player_{i+1}") p = db.session.get(Player, player_id) if p is None: raise ValueError(f"Player ID: {player_id} mismatch.") players.append(p) self.team_1 = players[:2] self.team_2 = players[2:] def to_game(self, round_id) -> Game: return Game( round_id, self.court.id, self.team_1[0].id, self.team_1[1].id, self.team_2[0].id, self.team_2[1].id, )