summaryrefslogtreecommitdiff
path: root/app/controller.py
blob: d8a178f78b9afaf3f6c6bee9ce35630b32337643 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
from math import floor
from app import app, db
from datetime import date
from operator import attrgetter
from sqlalchemy import func, Date
from app.model import (
    Player,
    Players,
    Courts,
    Game,
    DisplayPlayer,
    DisplayTeam,
    DisplayGame,
)
from app.utilities import (
    get_placeholder_games,
    get_team_games,
    get_shuffle_games,
    separate_teams_and_players,
)


class Session:
    levels: int = 10
    teams: bool = False
    proposal: list[DisplayGame] = []
    courts: Courts = Courts()
    players: Players = Players()

    def __init__(self):
        with app.app_context():
            games = db.session.query(Game)
            db.session.query(Game).delete()
            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 round(self) -> int:
        games = (
            db.session.query(Game).filter(func.date(Game.date) == date.today()).all()
        )
        round_id = max([game.round_id for game in games])
        if round_id is None:
            raise ValueError(f"Database isn't initialized")
        return round_id

    def all(self) -> list[DisplayGame]:
        games = (
            db.session.query(Game)
            .filter(func.date(Game.date) == date.today())
            .filter(Game.round_id == self.round())
            .order_by(Game.court_id)
            .all()
        )
        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.")
                dp.append(p)
            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["PLAYERS_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[DisplayGame]:
        if len(self.proposal) == 0:
            return self.all()
        round_number = self.round() + 1
        for game in self.proposal:
            db.session.add(
                Game(
                    round_number,
                    game.court_id,
                    game.team_1.player_1.id,
                    game.team_1.player_2.id,
                    game.team_2.player_1.id,
                    game.team_2.player_2.id,
                )
            )
        db.session.commit()
        self.proposal = []
        return self.all()

    def reset(self) -> list[DisplayGame]:
        db.session.query(Game).filter(Game.date.cast(Date) == date.today()).delete()
        db.session.commit()
        self.__init__()
        return self.all()