aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaran Jayachandra <karan.jayachandra@nxp.com>2024-10-16 23:28:46 +0200
committerKaran Jayachandra <karan.jayachandra@nxp.com>2024-10-16 23:28:46 +0200
commit156056e9c31468564fb53ca284996a5de41471fb (patch)
treed7cf9efc12e0fb411de3f9b33ac2f478cb29133b
parent74480cbe2b335fd141cdf5f07bb08808c0d08692 (diff)
Working version with all functionality
-rw-r--r--app.py12
-rw-r--r--controller.py7
-rw-r--r--model.py33
-rw-r--r--static/custom.css15
-rw-r--r--templates/controls.j251
-rw-r--r--templates/court.j21
-rw-r--r--templates/games.j22
-rw-r--r--templates/index.j279
-rw-r--r--templates/player.j21
-rw-r--r--templates/time.j23
10 files changed, 125 insertions, 79 deletions
diff --git a/app.py b/app.py
index 261c76b..22f6767 100644
--- a/app.py
+++ b/app.py
@@ -9,7 +9,9 @@ from flask import Flask, render_template, request
load_dotenv()
app = Flask("Match Up! Backend")
app.config.from_object(getenv("APP_SETTINGS"))
-rg = RoundGenerator(courts=CourtList(12), players=PlayerList(getenv("DATABASE")))
+rg = RoundGenerator(
+ courts=CourtList(int(getenv("COURTS"))), players=PlayerList(getenv("DATABASE"))
+)
re = Environment(loader=FileSystemLoader("templates"))
@@ -18,6 +20,12 @@ def home():
return render_template("index.j2")
+@app.route("/time", methods=["GET"])
+def get_time():
+ mins, secs = rg.timer.get()
+ return render_template("time.j2", mins=mins, secs=secs)
+
+
@app.route("/guests", methods=["GET"])
def get_guests():
return render_template("guests.j2", guests=rg.players.guests)
@@ -68,9 +76,7 @@ def get_list_of_players():
def toggle_court(court_number):
id = int(court_number)
status = rg.courts.toggle_court_status(id)
- print(status)
t = re.from_string('{% from "macros.j2" import court %}{{ court(id, status) }}')
- print(render_template(t, id=id, status=status))
return render_template(t, id=id, status=status)
diff --git a/controller.py b/controller.py
index 1116443..2e09e9f 100644
--- a/controller.py
+++ b/controller.py
@@ -2,7 +2,7 @@ from typing import Tuple
from operator import attrgetter
from dataclasses import dataclass
from utilities import sample_list
-from model import Team, Game, PlayerList, CourtList, MAX_LEVEL, PLAYER_PER_COURT
+from model import Team, Game, PlayerList, CourtList, Timer, MAX_LEVEL, PLAYER_PER_COURT
def _create_placeholders(courts: dict, name: str) -> list[Game]:
@@ -49,6 +49,7 @@ class RoundGenerator:
proposal: tuple = tuple()
def __post_init__(self) -> None:
+ self.timer = Timer()
self.history = {key: 0 for key, _ in self.players.get_players().items()}
self.games = self._generate_proposal(MAX_LEVEL)[0]
@@ -110,7 +111,9 @@ class RoundGenerator:
return self.games
self.games = proposed_games
for player_id in proposed_players:
- self.history[player_id] = self.history[player_id] + 1
+ if player_id < self.players.guest_id_start:
+ self.history[player_id] = self.history[player_id] + 1
self.proposal = tuple()
self.round += 1
+ self.timer.start()
return self.games
diff --git a/model.py b/model.py
index f768d0f..c69ba48 100644
--- a/model.py
+++ b/model.py
@@ -1,6 +1,7 @@
from math import floor
from csv import reader
from typing import Tuple
+from time import time, strftime
from dataclasses import dataclass
MIN_LEVEL = 1
@@ -101,3 +102,35 @@ class PlayerList:
}
players.update(guests)
return players
+
+
+@dataclass
+class Timer:
+ ref: float = None
+ running: bool = False
+ max_mins: int = 1
+ default: str = ("00", "00")
+
+ def __post_init__(self):
+ self.max_seconds = self.max_mins * 60
+
+ def start(self):
+ self.ref = time() + self.max_seconds
+ self.running = True
+
+ def stop(self):
+ self.ref = None
+ self.running = False
+
+ def get(self):
+ if not self.running:
+ return self.default
+ total_seconds = self.ref - time()
+ if total_seconds < 0:
+ self.stop()
+ return self.default
+ mins = f"{int(total_seconds // 60):02d}"
+ secs = f"{int(total_seconds % 60):02d}"
+ print(mins)
+ print(secs)
+ return mins, secs
diff --git a/static/custom.css b/static/custom.css
new file mode 100644
index 0000000..3e57091
--- /dev/null
+++ b/static/custom.css
@@ -0,0 +1,15 @@
+button, input, .select, .select select {
+ width: 100%;
+}
+table {
+ font-size: 30px;
+}
+td {
+ width: 20%;
+}
+img {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%,-50%);
+} \ No newline at end of file
diff --git a/templates/controls.j2 b/templates/controls.j2
new file mode 100644
index 0000000..1799e01
--- /dev/null
+++ b/templates/controls.j2
@@ -0,0 +1,51 @@
+<div class="columns">
+ <div class="column">
+ <div class="field has-addons">
+ <div class="control">
+ <button class="button is-large is-responsive is-dark"
+ style="text-align:center"
+ hx-post="/decrement"
+ hx-swap="outerHTML"
+ hx-target="#guests">-</button>
+ </div>
+ <div hx-get="/guests" hx-swap="outerHTML" hx-trigger="revealed"></div>
+ <div class="control">
+ <button class="button is-large is-responsive is-dark"
+ style="text-align:center"
+ hx-post="/increment"
+ hx-swap="outerHTML"
+ hx-target="#guests">+</button>
+ </div>
+ </div>
+ </div>
+ <div class="column">
+ <div class="select is-large is-responsive">
+ <select name="type">
+ <option>10 Levels</option>
+ <option>8 Levels</option>
+ <option>6 Levels</option>
+ <option>4 Levels</option>
+ <option>2 Levels</option>
+ <option>0 Levels</option>
+ </select>
+ </div>
+ </div>
+ <div class="column">
+ <button class="button is-dark is-large is-responsive"
+ hx-post="/propose"
+ hx-target="#games"
+ hx-include="[name='type']">New Round</button>
+ </div>
+ <div class="column"></div>
+ <div class="column">
+ <button class="button is-dark is-large is-responsive"
+ hx-post="/confirm"
+ hx-target="#games">Start Round</button>
+ </div>
+ <div class="column">
+ <button class="button is-dark is-large is-responsive"
+ hx-post="/clear"
+ hx-target="#games">Reset</button>
+ </div>
+</div>
+<div hx-post="/clear" hx-swap="outerHTML" hx-trigger="revealed"></div>
diff --git a/templates/court.j2 b/templates/court.j2
deleted file mode 100644
index d7aec86..0000000
--- a/templates/court.j2
+++ /dev/null
@@ -1 +0,0 @@
-{% from "macros.j2" import court %}{{ court(key, value) }} \ No newline at end of file
diff --git a/templates/games.j2 b/templates/games.j2
index 50e1087..0285de1 100644
--- a/templates/games.j2
+++ b/templates/games.j2
@@ -9,7 +9,7 @@
</thead>
<tbody>
{% for game in games %}
- <tr>
+ <tr {% if game.team1.player1 == 'RESERVED' %} class="is-danger" {% endif %}>
<th align="center">{{ game.court }}</th>
<td>{{ game.team1.player1 }}</th>
<td>{{ game.team1.player2 }}</th>
diff --git a/templates/index.j2 b/templates/index.j2
index 4ccdf92..fcea4e3 100644
--- a/templates/index.j2
+++ b/templates/index.j2
@@ -6,24 +6,8 @@
<title>Match Up!</title>
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='bulma.min.css') }}">
+ <link rel="stylesheet" href="{{ url_for('static', filename='custom.css') }}">
<script src="{{ url_for('static', filename='htmx.min.js') }}"></script>
- <style>
- button, input, .select, .select select {
- width: 100%;
- }
- table {
- font-size: 30px;
- }
- td {
- width: 20%;
- }
- img {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%,-50%);
- }
- </style>
</head>
<body>
<section class="section">
@@ -36,63 +20,16 @@
</div>
</div>
<div class="level-item">
- <p class="title">Today's Games</p>
+ <p class="title">Match Up!</p>
+ </div>
+ <div class="level-right">
+ <div hx-get="/time" hx-swap="outerHTML" hx-trigger="revealed"></div>
</div>
</nav>
</section>
<section class="section">
- <p class="title">Games</p>
- <div class="columns">
- <div class="column">
- <div class="field has-addons">
- <div class="control">
- <button class="button is-large is-responsive is-dark"
- style="text-align:center"
- hx-post="/decrement"
- hx-swap="outerHTML"
- hx-target="#guests">-</button>
- </div>
- <div hx-get="/guests" hx-swap="outerHTML" hx-trigger="revealed"></div>
- <div class="control">
- <button class="button is-large is-responsive is-dark"
- style="text-align:center"
- hx-post="/increment"
- hx-swap="outerHTML"
- hx-target="#guests">+</button>
- </div>
- </div>
- </div>
- <div class="column">
- <div class="select is-large is-responsive">
- <select name="type">
- <option>10 Levels</option>
- <option>8 Levels</option>
- <option>6 Levels</option>
- <option>4 Levels</option>
- <option>2 Levels</option>
- <option>0 Levels</option>
- </select>
- </div>
- </div>
- <div class="column">
- <button class="button is-dark is-large is-responsive"
- hx-post="/propose"
- hx-target="#games"
- hx-include="[name='type']">New Round</button>
- </div>
- <div class="column"></div>
- <div class="column">
- <button class="button is-dark is-large is-responsive"
- hx-post="/confirm"
- hx-target="#games">Start Round</button>
- </div>
- <div class="column">
- <button class="button is-dark is-large is-responsive"
- hx-post="/clear"
- hx-target="#games">Reset</button>
- </div>
- </div>
- <div hx-post="/clear" hx-swap="outerHTML" hx-trigger="revealed"></div>
+ <p class="title">Games</p>
+ {% include 'controls.j2' %}
</section>
<section class="section">
<h2 class="title">Courts</h2>
@@ -104,7 +41,7 @@
</section>
<footer class="footer">
<div class="content has-text-centered">
- Made by <a href="https://karanjayachandra.com/">K. Jayachandra</a> using <a href="https://flask.palletsprojects.com">Flask</a>, <a href="https://htmx.org/">HTMX</a> and <a href="https://bulma.io">Bulma</a>
+ Made by <a href="https://karanjayachandra.com/">Karan</a> using <a href="https://flask.palletsprojects.com">Flask</a>, <a href="https://htmx.org/">HTMX</a> and <a href="https://bulma.io">Bulma</a>
</div>
</footer>
</body>
diff --git a/templates/player.j2 b/templates/player.j2
deleted file mode 100644
index 68a1ea4..0000000
--- a/templates/player.j2
+++ /dev/null
@@ -1 +0,0 @@
-{% from "macros.j2" import player %}{{ player(id, status, name) }} \ No newline at end of file
diff --git a/templates/time.j2 b/templates/time.j2
new file mode 100644
index 0000000..d006fc4
--- /dev/null
+++ b/templates/time.j2
@@ -0,0 +1,3 @@
+<div hx-get="/time" hx-swap="outerHTML" hx-trigger="every 1s">
+ <p class="title">Timer: {{mins}}:{{secs}}</p>
+</div> \ No newline at end of file