bracket-feature
laurent 1 year ago
commit 777702624a
  1. 41
      tournaments/models/group_stage.py
  2. 50
      tournaments/models/tournament.py
  3. 6
      tournaments/templates/tournaments/group_stages.html
  4. 12
      tournaments/views.py

@ -1,3 +1,4 @@
from asyncio.streams import StreamReaderProtocol
from django.db import models
from . import Tournament, FederalMatchCategory
import uuid
@ -23,7 +24,11 @@ class GroupStage(models.Model):
if self.name:
return self.name
else:
return f"Poule {self.index + 1}"
if self.step == 0:
return f"Poule {self.index + 1}"
else:
return f"Poule {self.index + 1} - " + f"Phase {self.step + 1}"
def next_match(self, player_registration):
matches = self.matches_for_registration(player_registration).filter(end_date__isnull=False).order_by('start_date')
@ -34,16 +39,26 @@ class GroupStage(models.Model):
return [ts.match for ts in team_scores] # map(lambda ts: ts.match, team_scores)
def live_group_stages(self):
lgs = LiveGroupStage(self.display_name())
lgs = LiveGroupStage(self.display_name(), self.step, self.index)
gs_teams = {}
# init all teams
for team_registration in self.teamregistration_set.all():
if team_registration in gs_teams:
team = gs_teams[team_registration]
else:
team = GroupStageTeam(team_registration)
gs_teams[team_registration] = team
if self.step == 0:
# init all teams
for team_registration in self.teamregistration_set.all():
if team_registration in gs_teams:
team = gs_teams[team_registration]
else:
team = GroupStageTeam(team_registration)
gs_teams[team_registration] = team
else:
previous = self.tournament.get_previous_live_group_stages(self.step - 1)
for gs in previous:
team_registration = gs.teams[self.index].team_registration
if team_registration in gs_teams:
team = gs_teams[team_registration]
else:
team = GroupStageTeam(team_registration)
gs_teams[team_registration] = team
# compute matches
for match in self.match_set.all():
@ -109,12 +124,17 @@ class GroupStage(models.Model):
return True
return False
def is_completed(self):
return not self.match_set.filter(end_date__isnull=True).exists()
class LiveGroupStage:
def __init__(self, title):
def __init__(self, title, step, index):
self.title = title
self.teams = []
self.start = None
self.end = None
self.step = step
self.index = index
def add_match(self, match):
if self.start and match.start_date and match.start_date < self.start:
@ -153,6 +173,7 @@ class GroupStageTeam:
self.losses = 0
self.diff = 0
self.weight = team_registration.weight
self.team_registration = team_registration
def wins_losses(self):
return f"{self.wins}/{self.losses}"

@ -401,7 +401,8 @@ class Tournament(models.Model):
for round in self.round_set.filter(parent=None, group_stage_loser_bracket=True).all().order_by('index'):
groups.extend(self.round_match_groups(round, broadcasted, hide_empty_matches=True))
for group_stage in self.groupstage_set.all().order_by('index'):
ordered = sorted(self.get_computed_group_stage(), key=lambda s: (-s.step, s.index))
for group_stage in ordered:
group = self.group_stage_match_group(group_stage, broadcasted, hide_empty_matches=True)
if group:
groups.append(group)
@ -455,10 +456,47 @@ class Tournament(models.Model):
return MatchGroup(name, live_matches)
def live_group_stages(self):
group_stages = list(self.groupstage_set.all())
group_stages.sort(key=lambda gs: gs.index)
group_stages = self.get_computed_group_stage()
return [gs.live_group_stages() for gs in group_stages]
def get_computed_group_stage(self):
# Get all group stages and sort by step (descending) and index (ascending)
group_stages = self.groupstage_set.all().order_by('-step', 'index')
# List to collect live group stages from finished steps
filtered = []
for group_stage in group_stages:
if group_stage.step > 0:
# Check the previous step's group stages
previous_step_group_stages = self.groupstage_set.filter(step=group_stage.step - 1)
# Check if all previous step group stages are completed
if all(gs.is_completed() for gs in previous_step_group_stages):
filtered.append(group_stage)
else:
# Always include step 0
filtered.append(group_stage)
return filtered
def get_previous_live_group_stages(self, step):
previous_step_group_stages = self.groupstage_set.filter(step=step).order_by('index')
return [gs.live_group_stages() for gs in previous_step_group_stages]
def last_group_stage_step(self):
live_group_stages = self.get_computed_group_stage()
# Filter to find the last running step
last_running_step = max(gs.step for gs in live_group_stages) if live_group_stages else None
if last_running_step is not None:
# Get only group stages from the last running step
group_stages_last_step = [gs for gs in live_group_stages if gs.step == last_running_step]
return group_stages_last_step
else:
return []
def broadcast_content(self):
matches, group_stages = self.broadcasted_matches_and_group_stages()
@ -514,7 +552,7 @@ class Tournament(models.Model):
group_stages = []
if len(self.groupstage_set.all()) > 0 and self.no_bracket_match_has_started():
group_stages = self.live_group_stages()
group_stages = [gs.live_group_stages() for gs in self.last_group_stage_step()]
matches = self.broadcasted_group_stages_matches()
first_round = self.first_round()
if first_round and self.has_all_group_stages_started():
@ -535,7 +573,7 @@ class Tournament(models.Model):
matches.extend(previous_round.get_matches_recursive(True))
else:
matches.extend(current_round.all_matches(True))
group_stages = self.live_group_stages()
group_stages = [gs.live_group_stages() for gs in self.last_group_stage_step()]
return matches, group_stages
@ -626,7 +664,7 @@ class Tournament(models.Model):
return matches
def elected_broadcast_group_stages(self):
group_stages = list(self.groupstage_set.all())
group_stages = list(self.last_group_stage_step())
started = [gs for gs in group_stages if gs.starts_soon()]
if len(started) > 0:
return started

@ -10,11 +10,15 @@
{% include 'tournaments/navigation_tournament.html' %}
{% for step in unique_steps %}
<div class="grid-x">
{% for group_stage in group_stages %}
{% include 'tournaments/group_stage_cell.html' %}
{% if group_stage.step == step %}
{% include 'tournaments/group_stage_cell.html' %}
{% endif %}
{% endfor %}
</div>
{% endfor %}
{% endblock %}

@ -146,7 +146,8 @@ def tournament(request, tournament_id):
rounds = list(tournament.round_set.filter(group_stage_loser_bracket=True))
rounds.extend(bracket_rounds)
group_stages = tournament.groupstage_set.order_by('index')
#group_stages = tournament.groupstage_set.order_by('index')
group_stages = sorted(tournament.get_computed_group_stage(), key=lambda s: (s.step, s.index))
#print(len(match_groups))
#print(len(rounds))
@ -256,9 +257,12 @@ def tournament_matches_json(request, tournament_id):
def tournament_group_stages(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)
live_group_stages = list(tournament.live_group_stages())
unique_steps = sorted(set(gs.step for gs in live_group_stages), reverse=True)
return render(request, 'tournaments/group_stages.html', {
'tournament': tournament,
'group_stages': live_group_stages,
'unique_steps': unique_steps,
})
def tournament_broadcasted_group_stages(request, tournament_id):
@ -272,8 +276,10 @@ def tournament_broadcasted_group_stages(request, tournament_id):
def tournament_live_group_stage_json(request, tournament_id):
tournament = get_object_or_404(Tournament, pk=tournament_id)
gs_dicts = [gs.to_dict() for gs in tournament.live_group_stages()]
# group_stages = tournament.live_group_stages()
# Get all live group stages and filter for the last running step
live_group_stages = [gs.live_group_stages() for gs in tournament.last_group_stage_step()]
gs_dicts = [gs.to_dict() for gs in live_group_stages]
data = json.dumps(gs_dicts)
return HttpResponse(data, content_type='application/json')

Loading…
Cancel
Save