aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorKaran Jayachandra <mail@karanjayachandra.com>2025-07-14 12:25:55 +0200
committerKaran Jayachandra <mail@karanjayachandra.com>2025-07-14 12:25:55 +0200
commit729203409fb73fdbac19b8af9d647883a5ac96b0 (patch)
tree5cef1d2b3f7bb61551dd105974e66b11b81fff98 /app
parentec3af3f76ae1785bfb8c1dfbc69788e95fc7954d (diff)
Back to working
Diffstat (limited to 'app')
-rw-r--r--app/config.py5
-rw-r--r--app/controller.py173
-rw-r--r--app/model.py205
-rw-r--r--app/routes.py34
-rw-r--r--app/static/custom.js10
-rw-r--r--app/templates/games.j212
-rw-r--r--app/templates/players.j217
-rw-r--r--app/utilities.py68
8 files changed, 285 insertions, 239 deletions
diff --git a/app/config.py b/app/config.py
index fa16e1f..d7509a1 100644
--- a/app/config.py
+++ b/app/config.py
@@ -4,10 +4,11 @@ from os.path import abspath, dirname, join
class Config:
SECRET_KEY = environ.get("SECRET_KEY") or None
- DATABASE_CSV = environ.get("DATABASE_CSV") or None
SQLALCHEMY_DATABASE_URI = "sqlite:///" + join(abspath(dirname(__file__)), "app.db")
COURT_COUNT = 12
PLAYERS_PER_COURT = 4
- GUEST_LEVELS = [1, 3, 5]
MIN_PLAYER_LEVEL = 1
MAX_PLAYER_LEVEL = 10
+ DEFAULTS = {"---": 1, "RESERVED": 2}
+ GUEST_COUNT = 4
+ GUESTS = {"Beginner": 1, "Novice": 3, "Intermediate": 5} \ No newline at end of file
diff --git a/app/controller.py b/app/controller.py
index d8a178f..1c2c5bf 100644
--- a/app/controller.py
+++ b/app/controller.py
@@ -1,15 +1,14 @@
from math import floor
from app import app, db
from datetime import date
+from typing import Sequence
+from pandas import DataFrame
from operator import attrgetter
-from sqlalchemy import func, Date
+from sqlalchemy import func, select, not_
from app.model import (
Player,
- Players,
- Courts,
+ Court,
Game,
- DisplayPlayer,
- DisplayTeam,
DisplayGame,
)
from app.utilities import (
@@ -17,9 +16,103 @@ from app.utilities import (
get_team_games,
get_shuffle_games,
separate_teams_and_players,
+ initialize_random_database,
+ initialize_default_players,
)
+class Courts:
+
+ def __init__(self):
+ with app.app_context():
+ courts = db.session.query(Court).all()
+ if len(courts) == 0:
+ for _ in range(app.config["COURT_COUNT"]):
+ db.session.add(Court())
+ db.session.commit()
+
+ def toggle(self, id: int) -> bool:
+ court = db.session.get(Court, id)
+ if court is None:
+ raise ValueError(f"Court {id} doesn't exist.")
+ new_status = not court.status
+ court.status = new_status
+ db.session.commit()
+ return new_status
+
+ def active(self):
+ return db.session.query(Court).where(Court.status).all()
+
+ def inactive(self):
+ return db.session.query(Court).where(not_(Court.status)).all()
+
+ def all(self) -> list[Court]:
+ return db.session.query(Court).order_by(Court.id).all()
+
+
+class Players:
+
+ def __init__(self) -> None:
+ with app.app_context():
+ if len(self.regulars()) == 0:
+ initialize_random_database()
+
+ def update(self, data: DataFrame):
+ initialize_default_players()
+ for entry in data.to_dict("records"):
+ args = entry | {"status": False}
+ db.session.add(Player(**args)) # type: ignore
+ db.session.commit()
+
+ def get(self, id: int) -> bool:
+ player = db.session.get(Player, id)
+ if player is None:
+ raise ValueError(f"User {id} doesn't exist.")
+ return player.status
+
+ def toggle(self, id: int) -> Player:
+ player = db.session.get(Player, id)
+ if player is None:
+ raise ValueError(f"User {id} doesn't exist.")
+ player.status = not player.status
+ db.session.commit()
+ return player
+
+ def regulars(self) -> list[Player]:
+ filter_list = list(app.config["GUESTS"].keys()) + list(
+ app.config["DEFAULTS"].keys()
+ )
+ return (
+ db.session.query(Player)
+ .where(Player.id > 1)
+ .where(Player.first_name.not_in(filter_list))
+ .order_by(Player.first_name, Player.last_name)
+ .all()
+ )
+
+ def guests(self) -> list[Player]:
+ return (
+ db.session.query(Player)
+ .where(Player.id > 1)
+ .where(Player.first_name.in_(app.config["GUESTS"].keys()))
+ .order_by(Player.first_name, Player.last_name)
+ .all()
+ )
+
+ def active(self) -> Sequence[Player]:
+ query = (
+ select(Player)
+ .where(Player.status)
+ .order_by(Player.first_name, Player.last_name)
+ )
+ return db.session.scalars(query).all()
+
+ def reset(self):
+ for player in db.session.scalars(select(Player)):
+ player.status = False
+ db.session.commit()
+
+
class Session:
levels: int = 10
teams: bool = False
@@ -27,27 +120,33 @@ class Session:
courts: Courts = Courts()
players: Players = Players()
+ def _today(self):
+ games = (
+ db.session.query(Game).filter(func.date(Game.date) == date.today()).all()
+ )
+ return games
+
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()
+ if len(self._today()) == 0:
+ query = select(Player).where(Player.first_name == "---")
+ player = db.session.scalars(query).first()
+ if player is None:
+ raise ValueError(f"Database isn't initialized.")
+ player_data = {f"player_{i+1}": player.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()
- )
+ games = self._today()
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]:
+ def current_round(self) -> list[DisplayGame]:
games = (
db.session.query(Game)
.filter(func.date(Game.date) == date.today())
@@ -55,22 +154,11 @@ class Session:
.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
+ games = [DisplayGame(game) for game in games]
+ return games
def propose(self) -> list[DisplayGame]:
- reserved_courts = [court for court in self.courts.all() if not court.status]
+ reserved_courts = self.courts.inactive()
reserved_games = get_placeholder_games(reserved_courts, "RESERVED")
active_courts = self.courts.active()
active_players = self.players.active()
@@ -87,30 +175,21 @@ class Session:
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"))
+ 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
+ return self.current_round()
+ round_id = 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.add(game.to_game(round_id))
db.session.commit()
self.proposal = []
- return self.all()
+ return self.current_round()
def reset(self) -> list[DisplayGame]:
- db.session.query(Game).filter(Game.date.cast(Date) == date.today()).delete()
+ db.session.query(Game).filter(func.date(Game.date) == date.today()).delete()
db.session.commit()
self.__init__()
- return self.all()
+ return self.current_round()
diff --git a/app/model.py b/app/model.py
index 2f8c609..3ec663e 100644
--- a/app/model.py
+++ b/app/model.py
@@ -1,14 +1,9 @@
-from math import floor
from app import app, db
-from pandas import read_csv
-from dataclasses import dataclass
from sqlalchemy.orm import Mapped
from datetime import date, datetime
-from random import randint, getrandbits
-from typing import Tuple, Optional, Sequence
+from typing import Optional, Annotated
from sqlalchemy.orm import mapped_column as mc
-from names import get_first_name, get_last_name
-from sqlalchemy import String, Boolean, Integer, ForeignKey, select
+from sqlalchemy import String, Boolean, Integer, ForeignKey
class User(db.Model):
@@ -28,48 +23,10 @@ class Court(db.Model):
return f"Court {self.id} is {"active" if self.status else "inactive"}"
-class Courts:
-
- def __init__(self):
- 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)
- if court is None:
- raise ValueError(f"Court {id} doesn't exist.")
- return court.status
-
- def toggle(self, id: int) -> bool:
- court = db.session.get(Court, id)
- if court is None:
- raise ValueError(f"Court {id} doesn't exist.")
- new_status = not court.status
- court.status = new_status
- db.session.commit()
- return new_status
-
- def active(self):
- return db.session.query(Court).where(Court.status).all()
-
- def all(self) -> list[Court]:
- courts = [court for court in db.session.query(Court).order_by(Court.id)]
- return courts
-
- def reset(self):
- for court in db.session.scalars(select(Court)):
- court.status = True
- db.session.commit()
-
-
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="---")
+ 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)
@@ -94,111 +51,6 @@ class Player(db.Model):
return f"{self.first_name} {self.last_name} is {"active" if self.status else "inactive"}"
-def initialize_random_database(
- player_count: int = 80, guest_per_level: int = 4
-) -> None:
- 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):
- if i < total_teams * players_per_team:
- team = floor(i / players_per_team) + 1
- else:
- team = 0
- args = {
- "first_name": get_first_name(),
- "last_name": get_last_name(),
- "team": team,
- "status": bool(getrandbits(1)),
- "level": randint(
- app.config["MIN_PLAYER_LEVEL"], app.config["MAX_PLAYER_LEVEL"]
- ),
- }
- 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.commit()
-
-
-class Players:
-
- def __init__(self) -> None:
- 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)) # type: ignore
- db.session.commit()
- else:
- if len(self.all()) == 0:
- initialize_random_database()
-
- def default_id(self):
- query = select(Player).where(Player.first_name == "---")
- player = db.session.scalars(query).first()
- if player is None:
- raise ValueError(f"Database isn't initialized.")
- return player.id
-
- def reserved_id(self):
- query = select(Player).where(Player.first_name == "RESERVED")
- player = db.session.scalars(query).first()
- if player is None:
- raise ValueError(f"Database isn't initialized.")
- return player.id
-
- def get(self, id: int) -> bool:
- player = db.session.get(Player, id)
- if player is None:
- raise ValueError(f"User {id} doesn't exist.")
- return player.status
-
- def toggle(self, id: int) -> Player:
- player = db.session.get(Player, id)
- if player is None:
- raise ValueError(f"User {id} doesn't exist.")
- player.status = not player.status
- db.session.commit()
- return player
-
- def all(self) -> Tuple[list[Player], list[Player]]:
- players = (
- db.session.query(Player)
- .where(Player.id > 1)
- .order_by(Player.first_name, Player.last_name)
- )
- regulars = [p for p in players if p.first_name != "Guest"]
- guests = [p for p in players if p.first_name == "Guest"]
- guests.sort(key=lambda x: int(x.last_name))
- return regulars, guests
-
- def active(self) -> Sequence[Player]:
- query = (
- select(Player)
- .where(Player.status)
- .order_by(Player.first_name, Player.last_name)
- )
- return db.session.scalars(query).all()
-
- def reset(self):
- for player in db.session.scalars(select(Player)):
- player.status = False
- db.session.commit()
-
-
class Game(db.Model):
id: Mapped[int] = mc(primary_key=True)
round_id: Mapped[int] = mc(Integer, index=True)
@@ -211,14 +63,15 @@ class Game(db.Model):
def __init__(
self,
- round_id: int,
+ round_id: Optional[int],
court_id: int,
player_1: int,
player_2: int,
player_3: int,
player_4: int,
):
- self.round_id = round_id
+ 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
@@ -226,22 +79,32 @@ class Game(db.Model):
self.player_4 = player_4
-class DisplayPlayer:
-
- def __init__(self, player: Player):
- self.id = player.id
- self.first_name = player.first_name
- self.last_name = player.last_name
-
-
-@dataclass
-class DisplayTeam:
- player_1: DisplayPlayer
- player_2: DisplayPlayer
+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:]
-@dataclass
-class DisplayGame:
- court_id: int
- team_1: DisplayTeam
- team_2: DisplayTeam
+ 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,
+ )
diff --git a/app/routes.py b/app/routes.py
index cffbae9..ce9b714 100644
--- a/app/routes.py
+++ b/app/routes.py
@@ -1,6 +1,8 @@
from app import app
+from pandas import read_csv
from app.forms import LoginForm
from app.controller import Session
+from werkzeug.utils import secure_filename
from flask import (
render_template,
request,
@@ -48,7 +50,9 @@ def confirm_games():
@app.route("/clear", methods=["POST"])
def clear_games():
- return render_template("games.j2", games=g.all(), title=f"Round: {g.round()}")
+ return render_template(
+ "games.j2", games=g.current_round(), title=f"Round: {g.round()}"
+ )
@app.route("/reset", methods=["POST"])
@@ -66,9 +70,11 @@ def toggle_player(player_request):
@app.route("/players", methods=["GET"])
def get_list_of_players():
- regulars, guests = g.players.all()
return render_template(
- "players.j2", regulars=regulars, guests=guests, url_for=url_for
+ "players.j2",
+ regulars=g.players.regulars(),
+ guests=g.players.guests(),
+ url_for=url_for,
)
@@ -79,6 +85,28 @@ def reset_all_players():
response.headers["HX-Refresh"] = "true"
return response
+@app.route("/update_players", methods=["POST"])
+def update_all_players():
+ file = request.files.get("players")
+ response = Response("File name or data has issues!", 400)
+ response.headers["HX-Refresh"] = "true"
+ if file is None:
+ return response
+ elif file.filename is None:
+ return response
+ file_name = secure_filename(file.filename)
+ try:
+ data = read_csv(file_name)
+ required_columns = ["id","first_name","last_name","level","team"]
+ if not all([item in data.columns for item in required_columns]):
+ raise ImportError(f"All columns aren't available in the data.")
+ except:
+ return response
+ g.players.update(data)
+ response = Response("Players updated!")
+ response.headers["HX-Refresh"] = "true"
+ return response
+
@app.route("/court-toggle/<court_number>", methods=["POST"])
def toggle_court(court_number):
diff --git a/app/static/custom.js b/app/static/custom.js
index 2e4b049..47f64ca 100644
--- a/app/static/custom.js
+++ b/app/static/custom.js
@@ -84,4 +84,12 @@ document.getElementById("timer-dec").addEventListener('click', ()=> {
minsPerRound -= 1;
resetTimer();
}
-}); \ No newline at end of file
+});
+
+const fileInput = document.querySelector("#file-js input[type=file]");
+ fileInput.onchange = () => {
+ if (fileInput.files.length > 0) {
+ const fileName = document.querySelector("#file-js .file-name");
+ fileName.textContent = fileInput.files[0].name;
+ }
+}; \ No newline at end of file
diff --git a/app/templates/games.j2 b/app/templates/games.j2
index ccfd395..dff1e0f 100644
--- a/app/templates/games.j2
+++ b/app/templates/games.j2
@@ -9,12 +9,12 @@
</thead>
<tbody>
{% for game in games %}
- <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 {% if game.team_1[0].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[0].first_name }}</strong>{{ " " + game.team_1[0].last_name }}</th>
+ <td style="width: 23%;"><strong>{{ game.team_1[1].first_name }}</strong>{{ " " + game.team_1[1].last_name }}</th>
+ <td style="width: 23%;"><strong>{{ game.team_2[0].first_name }}</strong>{{ " " + game.team_2[0].last_name }}</th>
+ <td style="width: 23%;"><strong>{{ game.team_2[1].first_name }}</strong>{{ " " + game.team_2[1].last_name }}</th>
</tr>
{% endfor %}
</tbody>
diff --git a/app/templates/players.j2 b/app/templates/players.j2
index 0beeee9..16e3878 100644
--- a/app/templates/players.j2
+++ b/app/templates/players.j2
@@ -25,6 +25,23 @@
<button class="button is-dark is-responsive"
hx-post="/reset_players">RESET!</button>
</div>
+ <div class="column">
+ <form method="POST" enctype="multipart/form-data" hx-post="/update_players">
+ <div id="file-js" class="file has-name is-fullwidth">
+ <label class="file-label">
+ <input class="file-input" type="file" name="players" />
+ <span class="file-cta">
+ <span class="file-icon">
+ <i class="fas fa-upload"></i>
+ </span>
+ <span class="file-label"> Choose a file… </span>
+ </span>
+ <span class="file-name"> No file uploaded </span>
+ </label>
+ <button class="button is-dark is-responsive">UPDATE!</button>
+ </div>
+ </form>
+ </div>
{{ footer() }}
</section>
</body>
diff --git a/app/utilities.py b/app/utilities.py
index 133f9e1..cd75d2a 100644
--- a/app/utilities.py
+++ b/app/utilities.py
@@ -1,9 +1,12 @@
+from math import floor
from app import app, db
from datetime import date
from sqlalchemy import func
from typing import Tuple, Sequence
from random import shuffle, sample
-from app.model import Player, DisplayPlayer, Court, Game, DisplayGame, DisplayTeam
+from random import randint, getrandbits
+from names import get_first_name, get_last_name
+from app.model import Player, Court, Game, DisplayGame
def _shuffle_two_lists(a: list, b: list) -> Tuple[list, list]:
@@ -87,8 +90,10 @@ def get_placeholder_games(courts: list[Court], name: str) -> list[DisplayGame]:
p = db.session.query(Player).where(Player.first_name == name).first()
if p is None:
raise ValueError(f"Database isn't initialized.")
- dummy_team = DisplayTeam(DisplayPlayer(p), DisplayPlayer(p))
- games = [DisplayGame(court.id, dummy_team, dummy_team) for court in courts]
+ player_data = {"round_id": None} | {f"player_{i+1}": p.id for i in range(4)}
+ games = [
+ DisplayGame(Game(**({"court_id": court.id} | player_data))) for court in courts # type: ignore
+ ]
return games
@@ -99,10 +104,10 @@ def get_team_games(
for court, (_, players) in zip(courts, teams.items()):
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(
- DisplayGame(court.id, DisplayTeam(dp[0], dp[3]), DisplayTeam(dp[1], dp[2]))
+ game = Game(
+ None, court.id, players[0].id, players[3].id, players[1].id, players[2].id
)
+ games.append(DisplayGame(game))
return games
@@ -114,8 +119,53 @@ def get_shuffle_games(
court_players = group_by_four(selected_players, total_levels)
games = []
for court, players in zip(courts, court_players):
- dp = [DisplayPlayer(p) for p in players]
- games.append(
- DisplayGame(court.id, DisplayTeam(dp[0], dp[3]), DisplayTeam(dp[1], dp[2]))
+ game = Game(
+ None, court.id, players[0].id, players[3].id, players[1].id, players[2].id
)
+ games.append(DisplayGame(game))
return games
+
+
+def initialize_default_players():
+ db.session.query(Player).delete()
+ for k, v in app.config["DEFAULTS"].items():
+ db.session.add(Player(**{"id": v, "first_name": k, "last_name": ""}))
+ guest_offset = 10000
+ for i, (k, v) in enumerate(app.config["GUESTS"].items()):
+ level_offset = app.config["GUEST_COUNT"] * i
+ for j in range(app.config["GUEST_COUNT"]):
+ db.session.add(
+ Player(
+ **{
+ "id": guest_offset + level_offset + j,
+ "first_name": k,
+ "last_name": f"{j + 1}",
+ "level": v,
+ }
+ )
+ )
+ db.session.commit()
+
+
+def initialize_random_database():
+ initialize_default_players()
+ player_count = 80
+ total_teams = 5
+ players_per_team = 5
+ for i in range(player_count):
+ if i < total_teams * players_per_team:
+ team = floor(i / players_per_team) + 1
+ else:
+ team = 0
+ args = {
+ "id": 3 + i,
+ "first_name": get_first_name(),
+ "last_name": get_last_name(),
+ "team": team,
+ "status": bool(getrandbits(1)),
+ "level": randint(
+ app.config["MIN_PLAYER_LEVEL"], app.config["MAX_PLAYER_LEVEL"]
+ ),
+ }
+ db.session.add(Player(**args))
+ db.session.commit()