From 2c4de8cec39da400683ef796a933e03ef2a347fb Mon Sep 17 00:00:00 2001 From: Emmy D'Anello Date: Tue, 9 Jul 2024 13:26:39 +0200 Subject: [PATCH] Adapt the random draw for the next rounds of ETEAM Signed-off-by: Emmy D'Anello --- draw/consumers.py | 84 +++++++++++-------- .../0006_alter_round_current_pool.py | 27 ++++++ draw/models.py | 4 +- locale/fr/LC_MESSAGES/django.po | 48 ++++++----- 4 files changed, 106 insertions(+), 57 deletions(-) create mode 100644 draw/migrations/0006_alter_round_current_pool.py diff --git a/draw/consumers.py b/draw/consumers.py index ed41520..458c00e 100644 --- a/draw/consumers.py +++ b/draw/consumers.py @@ -1021,14 +1021,18 @@ class DrawConsumer(AsyncJsonWebsocketConsumer): if not await Draw.objects.filter(tournament=self.tournament).aexists(): return await self.alert(_("The draw has not started yet."), 'danger') - if not self.tournament.final: + if not self.tournament.final and settings.TFJM_APP == "TFJM": return await self.alert(_("This is only available for the final tournament."), 'danger') - r2 = await self.tournament.draw.round_set.filter(number=2).aget() + r2 = await self.tournament.draw.round_set.filter(number=self.tournament.draw.current_round.number + 1).aget() self.tournament.draw.current_round = r2 - msg = _("The draw of the round 2 is starting. " - "The passage order is determined from the ranking of the first round, " - "in order to mix the teams between the two days.") + if settings.TFJM_APP == "TFJM": + msg = str(_("The draw of the round {round} is starting. " + "The passage order is determined from the ranking of the first round, " + "in order to mix the teams between the two days.").format(round=r2.number)) + else: + msg = str(_("The draw of the round {round} is starting. " + "The passage order is another time randomly drawn.").format(round=r2.number)) self.tournament.draw.last_message = msg await self.tournament.draw.asave() @@ -1036,29 +1040,30 @@ class DrawConsumer(AsyncJsonWebsocketConsumer): await self.channel_layer.group_send(f"tournament-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.notify', 'title': _("Draw") + " " + settings.APP_NAME, - 'body': _("The draw of the second round is starting!")}) + 'body': str(_("The draw of the second round is starting!"))}) - # Set the first pool of the second round as the active pool - pool = await Pool.objects.filter(round=self.tournament.draw.current_round, letter=1).aget() - r2.current_pool = pool - await r2.asave() + if settings.TFJM_APP == "TFJM": + # Set the first pool of the second round as the active pool + pool = await Pool.objects.filter(round=self.tournament.draw.current_round, letter=1).aget() + r2.current_pool = pool + await r2.asave() - # Fetch notes from the first round - notes = dict() - async for participation in self.tournament.participations.filter(valid=True).prefetch_related('team').all(): - notes[participation] = sum([await pool.aaverage(participation) - async for pool in self.tournament.pools.filter(participations=participation) - .prefetch_related('passages')]) - # Sort notes in a decreasing order - ordered_participations = sorted(notes.keys(), key=lambda x: -notes[x]) - # Define pools and passage orders from the ranking of the first round - async for pool in r2.pool_set.order_by('letter').all(): - for i in range(pool.size): - participation = ordered_participations.pop(0) - td = await TeamDraw.objects.aget(round=r2, participation=participation) - td.pool = pool - td.passage_index = i - await td.asave() + # Fetch notes from the first round + notes = dict() + async for participation in self.tournament.participations.filter(valid=True).prefetch_related('team').all(): + notes[participation] = sum([await pool.aaverage(participation) + async for pool in self.tournament.pools.filter(participations=participation) + .prefetch_related('passages')]) + # Sort notes in a decreasing order + ordered_participations = sorted(notes.keys(), key=lambda x: -notes[x]) + # Define pools and passage orders from the ranking of the first round + async for pool in r2.pool_set.order_by('letter').all(): + for i in range(pool.size): + participation = ordered_participations.pop(0) + td = await TeamDraw.objects.aget(round=r2, participation=participation) + td.pool = pool + td.passage_index = i + await td.asave() # Send pools to users await self.channel_layer.group_send(f"tournament-{self.tournament.id}", @@ -1078,16 +1083,23 @@ class DrawConsumer(AsyncJsonWebsocketConsumer): f"tournament-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.dice', 'team': participation.team.trigram, 'result': None}) - async for td in r2.current_pool.team_draws.prefetch_related('participation__team'): - await self.channel_layer.group_send(f"team-{td.participation.team.trigram}", - {'tid': self.tournament_id, 'type': 'draw.dice_visibility', - 'visible': True}) + if settings.TFJM_APP == "TFJM": + async for td in r2.current_pool.team_draws.prefetch_related('participation__team'): + await self.channel_layer.group_send(f"team-{td.participation.team.trigram}", + {'tid': self.tournament_id, 'type': 'draw.dice_visibility', + 'visible': True}) + + # Notify the team that it can draw a problem + await self.channel_layer.group_send(f"team-{td.participation.team.trigram}", + {'tid': self.tournament_id, 'type': 'draw.notify', + 'title': _("Your turn!"), + 'body': _("It's your turn to draw a problem!")}) + else: + async for td in r2.team_draws.prefetch_related('participation__team'): + await self.channel_layer.group_send(f"team-{td.participation.team.trigram}", + {'tid': self.tournament_id, 'type': 'draw.dice_visibility', + 'visible': True}) - # Notify the team that it can draw a problem - await self.channel_layer.group_send(f"team-{td.participation.team.trigram}", - {'tid': self.tournament_id, 'type': 'draw.notify', - 'title': _("Your turn!"), - 'body': _("It's your turn to draw a problem!")}) await self.channel_layer.group_send(f"volunteer-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.dice_visibility', @@ -1102,7 +1114,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer): await self.channel_layer.group_send(f"tournament-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.set_active', 'round': r2.number, - 'pool': r2.current_pool.get_letter_display()}) + 'pool': r2.current_pool.get_letter_display() if r2.current_pool else None}) @ensure_orga async def cancel_last_step(self, **kwargs): diff --git a/draw/migrations/0006_alter_round_current_pool.py b/draw/migrations/0006_alter_round_current_pool.py new file mode 100644 index 0000000..dccf1da --- /dev/null +++ b/draw/migrations/0006_alter_round_current_pool.py @@ -0,0 +1,27 @@ +# Generated by Django 5.0.6 on 2024-07-09 11:07 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("draw", "0005_alter_round_number_alter_teamdraw_accepted_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="round", + name="current_pool", + field=models.ForeignKey( + default=None, + help_text="The current pool where teams select their problems.", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="draw.pool", + verbose_name="current pool", + ), + ), + ] diff --git a/draw/models.py b/draw/models.py index e5b0edf..6ffa60c 100644 --- a/draw/models.py +++ b/draw/models.py @@ -82,7 +82,7 @@ class Draw(models.Model): elif self.current_round.current_pool.current_team is None: return 'DICE_ORDER_POULE' elif self.current_round.current_pool.current_team.accepted is not None: - if self.current_round.number == 1: + if self.current_round.number < settings.NB_ROUNDS: # The last step can be the last problem acceptation after the first round # only for the final between the two rounds return 'WAITING_FINAL' @@ -205,7 +205,7 @@ class Round(models.Model): current_pool = models.ForeignKey( 'Pool', - on_delete=models.CASCADE, + on_delete=models.SET_NULL, null=True, default=None, related_name='+', diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index df7e273..21fc99a 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: TFJM\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-06 22:34+0200\n" +"POT-Creation-Date: 2024-07-09 13:22+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Emmy D'Anello \n" "Language-Team: LANGUAGE \n" @@ -269,7 +269,7 @@ msgstr "équipes" msgid "round" msgstr "tour" -#: draw/apps.py:10 draw/consumers.py:1038 tfjm/templates/navbar.html:68 +#: draw/apps.py:10 draw/consumers.py:1042 tfjm/templates/navbar.html:68 msgid "Draw" msgstr "Tirage au sort" @@ -311,7 +311,7 @@ msgstr "Le tirage au sort du tournoi {tournament} va commencer." #: draw/consumers.py:256 draw/consumers.py:282 draw/consumers.py:692 #: draw/consumers.py:910 draw/consumers.py:1000 draw/consumers.py:1022 -#: draw/consumers.py:1113 draw/templates/draw/tournament_content.html:5 +#: draw/consumers.py:1125 draw/templates/draw/tournament_content.html:5 msgid "The draw has not started yet." msgstr "Le tirage au sort n'a pas encore commencé." @@ -363,12 +363,12 @@ msgstr "" "sont déterminés à partir des ordres de passage du premier tour." #: draw/consumers.py:615 draw/consumers.py:755 draw/consumers.py:832 -#: draw/consumers.py:866 draw/consumers.py:991 draw/consumers.py:1089 +#: draw/consumers.py:866 draw/consumers.py:991 draw/consumers.py:1095 msgid "Your turn!" msgstr "À votre tour !" #: draw/consumers.py:616 draw/consumers.py:756 draw/consumers.py:992 -#: draw/consumers.py:1090 +#: draw/consumers.py:1096 msgid "It's your turn to draw a problem!" msgstr "C'est à vous de tirer un problème !" @@ -439,17 +439,27 @@ msgstr "" msgid "This is only available for the final tournament." msgstr "Cela n'est possible que pour la finale." -#: draw/consumers.py:1029 +#: draw/consumers.py:1030 +#, python-brace-format msgid "" -"The draw of the round 2 is starting. The passage order is determined from " -"the ranking of the first round, in order to mix the teams between the two " -"days." +"The draw of the round {round} is starting. The passage order is determined " +"from the ranking of the first round, in order to mix the teams between the " +"two days." msgstr "" -"Le tirage au sort du tour 2 commence. L'ordre de passage est déterminé à " +"Le tirage au sort du tour {round} commence. L'ordre de passage est déterminé à " "partir du classement du premier tour, afin de mélanger les équipes entre les " "deux jours." -#: draw/consumers.py:1039 +#: draw/consumers.py:1034 +#, python-brace-format +msgid "" +"The draw of the round {round} is starting. The passage order is another time " +"randomly drawn." +msgstr "" +"Le tirage au sort du tour {round} commence. L'ordre de passage est à nouveau tiré " +"au hasard." + +#: draw/consumers.py:1043 msgid "The draw of the second round is starting!" msgstr "Le tirage au sort du deuxième tour commence !" @@ -866,11 +876,11 @@ msgstr "Opp" #: draw/templates/draw/tournament_content.html:331 #: draw/templates/draw/tournament_content.html:337 #: draw/templates/draw/tournament_content.html:339 -#: draw/templates/draw/tournament_content.html:350 -#: draw/templates/draw/tournament_content.html:352 -#: draw/templates/draw/tournament_content.html:359 -#: draw/templates/draw/tournament_content.html:366 -#: draw/templates/draw/tournament_content.html:373 +#: draw/templates/draw/tournament_content.html:347 +#: draw/templates/draw/tournament_content.html:354 +#: draw/templates/draw/tournament_content.html:361 +#: draw/templates/draw/tournament_content.html:368 +#: draw/templates/draw/tournament_content.html:370 msgctxt "Role abbreviation" msgid "Obs" msgstr "Obs" @@ -2847,17 +2857,17 @@ msgstr "L'utilisateur⋅rice suivant n'est pas inscrit⋅e en tant que juré⋅e msgid "Notes were successfully uploaded." msgstr "Les notes ont bien été envoyées." -#: participation/views.py:1902 +#: participation/views.py:1904 #, python-brace-format msgid "Notation sheets of pool {pool} of {tournament}.zip" msgstr "Feuilles de notations pour la poule {pool} du tournoi {tournament}.zip" -#: participation/views.py:1907 +#: participation/views.py:1909 #, python-brace-format msgid "Notation sheets of {tournament}.zip" msgstr "Feuilles de notation de {tournament}.zip" -#: participation/views.py:2074 +#: participation/views.py:2076 msgid "You can't upload a written review after the deadline." msgstr "Vous ne pouvez pas envoyer de note de synthèse après la date limite."