aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaran Jayachandra <mail@karanjayachandra.com>2025-07-13 18:20:04 +0200
committerKaran Jayachandra <mail@karanjayachandra.com>2025-07-13 18:20:04 +0200
commitd5d64f2b1047f864811d23f19f109a6513c22a2a (patch)
treeccea4ca1a4e58e65f74819daa67b8997d583ec71
parent673361f4475f0fde43fefa57735d766b4cb22c30 (diff)
Working version with several bugs
-rw-r--r--app/controller.py33
-rw-r--r--app/model.py68
-rw-r--r--app/routes.py7
-rw-r--r--app/templates/controls.j24
-rw-r--r--app/templates/games.j212
-rw-r--r--app/templates/macros.j22
-rw-r--r--app/utilities.py4
7 files changed, 78 insertions, 52 deletions
diff --git a/app/controller.py b/app/controller.py
index 1937af8..5bdeba7 100644
--- a/app/controller.py
+++ b/app/controller.py
@@ -2,7 +2,7 @@ from math import floor
from app import app, db
from datetime import date
from operator import attrgetter
-from sqlalchemy import select, func
+from sqlalchemy import select, func, Date
from app.model import (
Player,
Players,
@@ -28,19 +28,19 @@ class Session:
players: Players = Players()
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()
+ with app.app_context():
+ 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:
- query = select(func.max(Game.round_id)).where(Game.date.date() == date.today())
- round_id = db.session.scalars(query).first()
+ games = db.session.query(Game).filter(func.date(Game.date) == date.today()).all()
+ round_id = max([game.round_id for game in games])
+ print(round_id)
if round_id is None:
raise ValueError(f"Database isn't initialized")
return round_id
@@ -48,7 +48,7 @@ class Session:
def all(self) -> list[DisplayGame]:
games = (
db.session.query(Game)
- .filter(Game.date.date() == date.today())
+ .filter(func.date(Game.date) == date.today())
.filter(Game.round_id == self.round())
.order_by(Game.court_id)
.all()
@@ -60,6 +60,7 @@ class Session:
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)
@@ -71,7 +72,9 @@ class Session:
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"])
+ for player in active_players:
+ print(player)
+ 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:]
@@ -97,7 +100,7 @@ class Session:
return self.all()
def reset(self) -> list[DisplayGame]:
- db.session.query(Game).filter(Game.date.date() == date.today()).delete()
+ db.session.query(Game).filter(Game.date.cast(Date) == date.today()).delete()
db.session.commit()
self.__init__()
return self.all()
diff --git a/app/model.py b/app/model.py
index 2833bb1..56921f4 100644
--- a/app/model.py
+++ b/app/model.py
@@ -31,11 +31,12 @@ class Court(db.Model):
class Courts:
def __init__(self):
- if app.config["COURT_COUNT"] is not None:
- db.session.query(Court).delete()
- for i in range(app.config["COURT_COUNT"]):
- db.session.add(Court())
- db.session.commit()
+ with app.app_context():
+ if app.config["COURT_COUNT"] is not None:
+ db.session.query(Court).delete()
+ for i in range(int(app.config["COURT_COUNT"])):
+ db.session.add(Court())
+ db.session.commit()
def get(self, id: int) -> bool:
court = db.session.get(Court, id)
@@ -69,9 +70,17 @@ class Player(db.Model):
id: Mapped[int] = mc(primary_key=True)
first_name: Mapped[str] = mc(String(64), index=True, default="---")
last_name: Mapped[str] = mc(String(64), index=True, default="---")
- team: Mapped[int] = mc(Integer, index=True, default=0)
- status: Mapped[bool] = mc(Boolean, default=False)
- level: Mapped[int] = mc(Integer, default=app.config["MIN_PLAYER_LEVEL"])
+ 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"}"
@@ -80,8 +89,8 @@ class Player(db.Model):
def initialize_random_database(
player_count: int = 80, guest_per_level: int = 4
) -> None:
- db.session.add(Player(*{"first_name": "---", "last_name": ""}))
- db.session.add(Player(*{"first_name": "RESERVED", "last_name": ""}))
+ db.session.add(Player(**{"id": 0, "first_name": "---", "last_name": ""}))
+ db.session.add(Player(**{"id": 1, "first_name": "RESERVED", "last_name": ""}))
total_teams = 5
players_per_team = 5
for i in range(player_count):
@@ -98,29 +107,32 @@ def initialize_random_database(
app.config["MIN_PLAYER_LEVEL"], app.config["MAX_PLAYER_LEVEL"]
),
}
- db.session.add(Player(*args))
+ db.session.add(Player(**args))
meta_data = {"first_name": "Guest", "team": 0, "status": False}
for level_id, level in enumerate(app.config["GUEST_LEVELS"]):
for player_id in range(guest_per_level):
unique_id = (level_id * guest_per_level) + player_id + 1
args = meta_data | {"last_name": str(unique_id), "level": level}
- db.session.add(Player(*args))
+ db.session.add(Player(**args))
db.session.commit()
class Players:
def __init__(self) -> None:
- if app.config["DATABASE_CSV"] is not None:
- data = read_csv(app.config["DATABASE_CSV"])
- db.session.query(Player).delete()
- for entry in data.to_dict("records"):
- args = entry | {"status": False}
- db.session.add(Player(*args))
- db.session.commit()
- else:
- if len(self.all()) == 0:
- initialize_random_database()
+ with app.app_context():
+ if app.config["DATABASE_CSV"] is not None:
+ data = read_csv(app.config["DATABASE_CSV"])
+ db.session.query(Player).delete()
+ db.session.add(Player(**{"id": 0, "first_name": "---", "last_name": ""}))
+ db.session.add(Player(**{"id": 1, "first_name": "RESERVED", "last_name": ""}))
+ for entry in data.to_dict("records"):
+ args = entry | {"status": False}
+ db.session.add(Player(**args))
+ db.session.commit()
+ else:
+ if len(self.all()) == 0:
+ initialize_random_database()
def default_id(self):
query = select(Player).where(Player.first_name == "---")
@@ -184,12 +196,22 @@ class Game(db.Model):
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: int, court_id: int, player_1: int, player_2: int, player_3: int, player_4: int):
+ 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 DisplayPlayer:
def __init__(self, player: Player):
self.id = player.id
- self.name = f"{player.first_name} {player.last_name}"
+ self.first_name = player.first_name
+ self.last_name = player.last_name
@dataclass
diff --git a/app/routes.py b/app/routes.py
index 2cc6009..bc85e48 100644
--- a/app/routes.py
+++ b/app/routes.py
@@ -1,7 +1,7 @@
from app import app
from app.forms import LoginForm
from app.controller import Session
-from flask import render_template, request, url_for, Response, flash, redirect
+from flask import render_template, request, url_for, Response, flash, redirect, get_template_attribute, render_template_string
g = Session()
@@ -50,8 +50,9 @@ def reset_games():
def toggle_player(player_request):
id = int(player_request)
player = g.players.toggle(id)
- t = '{% from "macros.j2" import player_button %}{{player_button(player)}}'
- return render_template(t, player=player)
+ button = get_template_attribute("macros.j2", "player_button")
+ t = '{% from "macros.j2" import player_button %}'
+ return render_template_string("{{player_button(player)}}", player=player, player_button=button)
@app.route("/players", methods=["GET"])
diff --git a/app/templates/controls.j2 b/app/templates/controls.j2
index 0183c97..eba086d 100644
--- a/app/templates/controls.j2
+++ b/app/templates/controls.j2
@@ -1,8 +1,8 @@
{% from "macros.j2" import court_button %}
<div class="fixed-grid has-6-cols">
<div class="grid">
- {% for key, value in courts.items() %}
- {{ court_button(key, value) }}
+ {% for court in courts %}
+ {{ court_button(court.id, court.status) }}
{% endfor %}
</div>
</div>
diff --git a/app/templates/games.j2 b/app/templates/games.j2
index 46150f7..ccfd395 100644
--- a/app/templates/games.j2
+++ b/app/templates/games.j2
@@ -9,12 +9,12 @@
</thead>
<tbody>
{% for game in games %}
- <tr {% if game.team1.player1.first == 'RESERVED' %} class="is-danger" {% endif %}>
- <th align="center" style="width: 8%;">{{ game.court }}</th>
- <td style="width: 23%;"><strong>{{ game.team1.player1.first }}</strong>{{ " " + game.team1.player1.last }}</th>
- <td style="width: 23%;"><strong>{{ game.team1.player2.first }}</strong>{{ " " + game.team1.player2.last }}</th>
- <td style="width: 23%;"><strong>{{ game.team2.player1.first }}</strong>{{ " " + game.team2.player1.last }}</th>
- <td style="width: 23%;"><strong>{{ game.team2.player2.first }}</strong>{{ " " + game.team2.player2.last }}</th>
+ <tr {% if game.team_1.player_1.first_name == 'RESERVED' %} class="is-danger" {% endif %}>
+ <th align="center" style="width: 8%;">{{ game.court_id }}</th>
+ <td style="width: 23%;"><strong>{{ game.team_1.player_1.first_name }}</strong>{{ " " + game.team_1.player_1.last_name }}</th>
+ <td style="width: 23%;"><strong>{{ game.team_1.player_2.first_name }}</strong>{{ " " + game.team_1.player_2.last_name }}</th>
+ <td style="width: 23%;"><strong>{{ game.team_2.player_1.first_name }}</strong>{{ " " + game.team_2.player_1.last_name }}</th>
+ <td style="width: 23%;"><strong>{{ game.team_2.player_2.first_name }}</strong>{{ " " + game.team_2.player_2.last_name }}</th>
</tr>
{% endfor %}
</tbody>
diff --git a/app/templates/macros.j2 b/app/templates/macros.j2
index 2974744..a4b2fc1 100644
--- a/app/templates/macros.j2
+++ b/app/templates/macros.j2
@@ -7,7 +7,7 @@
{% macro player_button(player) -%}
<button class="button is-responsive {% if player.status %}is-success{% else %}is-danger {% endif %}"
hx-post="{{ "/player-toggle/" ~ player.id}}"
- hx-swap="outerHTML"> {{ player.first + " " + player.last}} </button>
+ hx-swap="outerHTML"> {{ player.first_name + " " + player.last_name}} </button>
{%- endmacro %}
{% macro guest_control(level, value) -%}
diff --git a/app/utilities.py b/app/utilities.py
index 00dc14a..c84e1bf 100644
--- a/app/utilities.py
+++ b/app/utilities.py
@@ -89,7 +89,7 @@ def get_team_games(
) -> list[DisplayGame]:
games = []
for court, (_, players) in zip(courts, teams.items()):
- players = sample(players, app.config["PLAYER_PER_COURT"])
+ players = sample(players, app.config["PLAYERS_PER_COURT"])
players.sort(key=lambda x: x.level, reverse=True)
dp = [DisplayPlayer(p) for p in players]
games.append(
@@ -101,7 +101,7 @@ def get_team_games(
def get_shuffle_games(
courts: list[Court], players: Sequence[Player], total_levels: int
) -> list[DisplayGame]:
- required_player_count = len(courts) * app.config["PLAYER_PER_COURT"]
+ required_player_count = len(courts) * app.config["PLAYERS_PER_COURT"]
selected_players = select_players(players, required_player_count)
court_players = group_by_four(selected_players, total_levels)
games = []