From 218366342a03c9be2075b6d7aec417dd41caf825 Mon Sep 17 00:00:00 2001 From: Karan Jayachandra Date: Sun, 6 Jul 2025 22:44:14 +0200 Subject: Moved a lot of the code into database queries --- app/controller.py | 178 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 91 insertions(+), 87 deletions(-) (limited to 'app/controller.py') diff --git a/app/controller.py b/app/controller.py index 498715d..1937af8 100644 --- a/app/controller.py +++ b/app/controller.py @@ -1,99 +1,103 @@ -from typing import Tuple +from math import floor +from app import app, db +from datetime import date from operator import attrgetter -from app.data import Game, PLAYER_PER_COURT -from app.model import Player, PlayerList, CourtList +from sqlalchemy import select, func +from app.model import ( + Player, + Players, + Courts, + Game, + DisplayPlayer, + DisplayTeam, + DisplayGame, +) from app.utilities import ( - _create_placeholders, - _select_players, - _create_shuffle_games, - _create_team_games, + get_placeholder_games, + get_team_games, + get_shuffle_games, separate_teams_and_players, - split_courts, ) -class RoundGenerator: - proposed_games: list[Game] = [] - proposed_players: list[Player] = [] - - def __init__(self) -> None: - self.courts = CourtList() - self.players = PlayerList() - self.reset() - - def _separate_courts(self, courts: dict) -> Tuple[dict, dict]: - possible_games = min(len(courts), self.players.get_possible_game_count()) - courts_as_list = list(courts.items()) - used_courts = dict(courts_as_list[:possible_games]) - unused_courts = dict(courts_as_list[possible_games:]) - return used_courts, unused_courts +class Session: + levels: int = 10 + teams: bool = False + proposal: list[DisplayGame] = [] + courts: Courts = Courts() + players: Players = Players() - def _create_inactive_games(self) -> list[Game]: - active_courts, reserved_courts = self.courts.separate_courts() - reserved_games = _create_placeholders(reserved_courts, "RESERVED") - _, unused_courts = self._separate_courts(active_courts) - blank_games = _create_placeholders(unused_courts, "---") - games = reserved_games + blank_games - return games + def __init__(self): + games = db.session.query(Game).filter(Game.date.date() == date.today()).all() + if len(games) > 0: + return + id = self.players.default_id() + player_data = {f"player_{i+1}": id for i in range(4)} + for court in self.courts.all(): + args = {"round_id": 0, "court_id": court.id} | player_data + db.session.add(Game(*args)) + db.session.commit() - def _create_active_games( - self, total_levels: int, group_by_team: bool - ) -> Tuple[list[Game], list[Player]]: - active_courts = self.courts.separate_courts()[0] - used_courts = self._separate_courts(active_courts)[0] - required_player_count = len(used_courts) * PLAYER_PER_COURT - active_players = self.players.get_players() - if group_by_team: - active_teams, team_less_players = separate_teams_and_players(active_players) - regular_court_count = len(used_courts) - len(active_teams) - regular_courts, team_courts = split_courts(used_courts, regular_court_count) - new_player_count = required_player_count - ( - PLAYER_PER_COURT * len(active_teams) - ) - regular_players = _select_players(team_less_players, new_player_count) - regular_games = _create_shuffle_games( - regular_courts, regular_players, total_levels - ) - team_games, selected_team_players = _create_team_games( - team_courts, active_teams - ) - selected_players = regular_players + selected_team_players - games = regular_games + team_games - else: - selected_players = _select_players(active_players, required_player_count) - games = _create_shuffle_games(used_courts, selected_players, total_levels) - return games, selected_players + def round(self) -> int: + query = select(func.max(Game.round_id)).where(Game.date.date() == date.today()) + round_id = db.session.scalars(query).first() + if round_id is None: + raise ValueError(f"Database isn't initialized") + return round_id - def update_player_list(self, csv_location): - self.players = PlayerList(csv_location) - - def clear(self) -> list[Game]: - self.proposed_games = [] - self.proposed_players = [] - return self.games - - def propose(self, levels: int, group_by_team: bool) -> list[Game]: - inactive_games = self._create_inactive_games() - active_games, selected_players = self._create_active_games( - levels, group_by_team + def all(self) -> list[DisplayGame]: + games = ( + db.session.query(Game) + .filter(Game.date.date() == date.today()) + .filter(Game.round_id == self.round()) + .order_by(Game.court_id) + .all() ) - games = active_games + inactive_games - games.sort(key=attrgetter("court")) - self.proposed_games = games - self.proposed_players = selected_players - return self.proposed_games + dg = [] + for game in games: + dp = [] + for i in range(4): + p = db.session.get(Player, getattr(game, f"player_{i+1}")) + if p is None: + raise ValueError(f"Player id mismatch.") + t1 = DisplayTeam(DisplayPlayer(dp[0]), DisplayPlayer(dp[1])) + t2 = DisplayTeam(DisplayPlayer(dp[2]), DisplayPlayer(dp[3])) + db.session.get(Player, game.player_2) + dg.append(DisplayGame(game.court_id, t1, t2)) + return dg + + def propose(self) -> list[DisplayGame]: + reserved_courts = [court for court in self.courts.all() if not court.status] + reserved_games = get_placeholder_games(reserved_courts, "RESERVED") + active_courts = self.courts.active() + active_players = self.players.active() + game_count = floor(len(active_players) / app.config["PLAYER_PER_COURT"]) + game_count = min(len(active_courts), game_count) + used_courts = active_courts[:game_count] + unused_courts = active_courts[game_count:] + blank_games = get_placeholder_games(unused_courts, "---") + active_teams = {} + if self.teams: + active_teams, active_players = separate_teams_and_players(active_players) + team_courts = used_courts[: len(active_teams)] + shuffle_courts = used_courts[len(active_teams) :] + team_games = get_team_games(team_courts, active_teams) + shuffle_games = get_shuffle_games(shuffle_courts, active_players, self.levels) + self.proposal = shuffle_games + team_games + blank_games + reserved_games + self.proposal.sort(key=attrgetter("court_id")) + return self.proposal - def confirm(self) -> list[Game]: - if len(self.proposed_games) == 0: - return self.games - self.games = self.proposed_games - identifiers = [int(player.id) for player in self.proposed_players] - self.players.increment_game_count(identifiers) - self.round += 1 - return self.clear() + def confirm(self) -> list[DisplayGame]: + if len(self.proposal) == 0: + return self.all() + for game in self.proposal: + db.session.add(game) + db.session.commit() + self.proposal = [] + return self.all() - def reset(self): - self.round = 0 - self.games = _create_placeholders(self.courts.get_courts(), "---") - self.players.reset_game_count() - return self.games + def reset(self) -> list[DisplayGame]: + db.session.query(Game).filter(Game.date.date() == date.today()).delete() + db.session.commit() + self.__init__() + return self.all() -- cgit v1.3.1