mirror of
https://gitlab.com/animath/si/plateforme.git
synced 2025-06-21 15:18:26 +02:00
Translate draw messages
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
@ -122,6 +122,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
self.tournament = await Tournament.objects.filter(pk=self.tournament_id)\
|
||||
.prefetch_related('draw__current_round__current_pool__current_team__participation__team').aget()
|
||||
|
||||
translation.activate(settings.PREFERRED_LANGUAGE_CODE)
|
||||
|
||||
match content['type']:
|
||||
case 'set_language':
|
||||
# Update the translation language
|
||||
@ -233,8 +235,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
|
||||
{'tid': self.tournament_id, 'type': 'draw.notify',
|
||||
'title': 'Tirage au sort du TFJM²',
|
||||
'body': "Le tirage au sort du tournoi de "
|
||||
f"{self.tournament.name} a commencé !"})
|
||||
'body': _("The draw of tournament {tournament} started!")
|
||||
.format(tournament=self.tournament.name)})
|
||||
|
||||
async def draw_start(self, content) -> None:
|
||||
"""
|
||||
@ -403,8 +405,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
await self.channel_layer.group_send(
|
||||
f"team-{dup.participation.team.trigram}",
|
||||
{'tid': self.tournament_id, 'type': 'draw.notify', 'title': 'Tirage au sort du TFJM²',
|
||||
'body': 'Votre score de dé est identique à celui de une ou plusieurs équipes. '
|
||||
'Veuillez le relancer.'}
|
||||
'body': _("Your dice score is identical to the one of one or multiple teams. "
|
||||
"Please relaunch it.")}
|
||||
)
|
||||
# Alert the tournament
|
||||
await self.channel_layer.group_send(
|
||||
@ -448,7 +450,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
# We can add a joker team if there is not already a team in the pool that was in the same pool
|
||||
# in the first round, and such that the number of such jokers is exactly the free space of the current pool.
|
||||
# Exception: if there is one only pool with 5 teams, we exchange the first and the last teams of the pool.
|
||||
if not self.tournament.final:
|
||||
if not self.tournament.final and settings.TFJM_APP == "TFJM":
|
||||
tds_copy = sorted(tds, key=lambda td: (td.passage_index, -td.pool.letter,))
|
||||
jokers = [td for td in tds if td.passage_index == 4]
|
||||
round2 = await self.tournament.draw.round_set.filter(number=2).aget()
|
||||
@ -502,12 +504,11 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
await self.tournament.draw.current_round.asave()
|
||||
|
||||
# Display dice result in the header of the information alert
|
||||
msg = "Les résultats des dés sont les suivants : "
|
||||
msg += ", ".join(f"<strong>{td.participation.team.trigram}</strong> ({td.passage_dice})" for td in tds)
|
||||
msg += ". L'ordre de passage et les compositions des différentes poules sont affiché⋅es sur le côté. "
|
||||
msg += "Les ordres de passage pour le premier tour sont déterminés à partir des scores des dés, "
|
||||
msg += "dans l'ordre croissant. Pour le deuxième tour, les ordres de passage sont déterminés à partir "
|
||||
msg += "des ordres de passage du premier tour."
|
||||
trigrams = ", ".join(f"<strong>{td.participation.team.trigram}</strong> ({td.passage_dice})" for td in tds)
|
||||
msg = _("The dice results are the following: {trigrams}. "
|
||||
"The passage order and the compositions of the different pools are displayed on the side. "
|
||||
"The passage orders for the first round are determined from the dice scores, in increasing order. "
|
||||
"For the second round, the passage orders are determined from the passage orders of the first round.")
|
||||
self.tournament.draw.last_message = msg
|
||||
await self.tournament.draw.asave()
|
||||
|
||||
@ -610,8 +611,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
# Notify the team that it can draw a problem
|
||||
await self.channel_layer.group_send(f"team-{tds[0].participation.team.trigram}",
|
||||
{'tid': self.tournament_id, 'type': 'draw.notify',
|
||||
'title': "À votre tour !",
|
||||
'body': "C'est à vous de tirer un nouveau problème !"})
|
||||
'title': _("Your turn!"),
|
||||
'body': _("It's your turn to draw a problem!")})
|
||||
|
||||
async def select_problem(self, **kwargs):
|
||||
"""
|
||||
@ -631,7 +632,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
.prefetch_related('team').aget()
|
||||
# Ensure that the user can draws a problem at this time
|
||||
if participation.id != td.participation_id:
|
||||
return await self.alert("This is not your turn.", 'danger')
|
||||
return await self.alert(_("This is not your turn."), 'danger')
|
||||
|
||||
while True:
|
||||
# Choose a random problem
|
||||
@ -702,19 +703,20 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
.prefetch_related('team').aget()
|
||||
# Ensure that the user can accept a problem at this time
|
||||
if participation.id != td.participation_id:
|
||||
return await self.alert("This is not your turn.", 'danger')
|
||||
return await self.alert(_("This is not your turn."), 'danger')
|
||||
|
||||
td.accepted = td.purposed
|
||||
td.purposed = None
|
||||
await td.asave()
|
||||
|
||||
trigram = td.participation.team.trigram
|
||||
msg = f"L'équipe <strong>{trigram}</strong> a accepté le problème <strong>{td.accepted} : " \
|
||||
f"{settings.PROBLEMS[td.accepted - 1]}</strong>. "
|
||||
msg = _("The team <strong>{trigram}</strong> accepted the problem <string>{problem}</strong>: "
|
||||
"{problem_name}. ").format(trigram=trigram, problem=td.accepted,
|
||||
problem_name=settings.PROBLEMS[td.accepted - 1])
|
||||
if pool.size == 5 and await pool.teamdraw_set.filter(accepted=td.accepted).acount() < 2:
|
||||
msg += "Une équipe peut encore l'accepter."
|
||||
msg += _("One team more can accept this problem.")
|
||||
else:
|
||||
msg += "Plus personne ne peut l'accepter."
|
||||
msg += _("No team can accept this problem anymore.")
|
||||
self.tournament.draw.last_message = msg
|
||||
await self.tournament.draw.asave()
|
||||
|
||||
@ -749,8 +751,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
# Notify the team that it can draw a problem
|
||||
await self.channel_layer.group_send(f"team-{new_trigram}",
|
||||
{'tid': self.tournament_id, 'type': 'draw.notify',
|
||||
'title': "À votre tour !",
|
||||
'body': "C'est à vous de tirer un nouveau problème !"})
|
||||
'title': _("Your turn!"),
|
||||
'body': _("It's your turn to draw a problem!")})
|
||||
else:
|
||||
# Pool is ended
|
||||
await self.end_pool(pool)
|
||||
@ -808,8 +810,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
'problems': [td.accepted async for td in pool.team_draws],
|
||||
})
|
||||
|
||||
msg += f"<br><br>Le tirage de la poule {pool.get_letter_display()}{r.number} est terminé. " \
|
||||
f"Le tableau récapitulatif est en bas."
|
||||
msg += "<br><br>" + _("The draw of the pool {pool} is ended. The summary is below.") \
|
||||
.format(pool=f"{pool.get_letter_display()}{r.number}")
|
||||
self.tournament.draw.last_message = msg
|
||||
await self.tournament.draw.asave()
|
||||
|
||||
@ -826,8 +828,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
# Notify the team that it can draw a dice
|
||||
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
|
||||
{'tid': self.tournament_id, 'type': 'draw.notify',
|
||||
'title': "À votre tour !",
|
||||
'body': "C'est à vous de lancer le dé !"})
|
||||
'title': _("Your turn!"),
|
||||
'body': _("It's your turn to launch the dice!")})
|
||||
|
||||
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
|
||||
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
|
||||
@ -843,11 +845,11 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
"""
|
||||
msg = self.tournament.draw.last_message
|
||||
|
||||
if r.number < settings.NB_ROUNDS and not self.tournament.final:
|
||||
if r.number < settings.NB_ROUNDS and not self.tournament.final and settings.TFJM_APP == "TFJM":
|
||||
# Next round
|
||||
next_round = await self.tournament.draw.round_set.filter(number=r.number + 1).aget()
|
||||
self.tournament.draw.current_round = next_round
|
||||
msg += f"<br><br>Le tirage au sort du tour {r.number} est terminé."
|
||||
msg += "<br><br>" + _("The draw of the round {round} is ended.").format(round=r.number)
|
||||
self.tournament.draw.last_message = msg
|
||||
await self.tournament.draw.asave()
|
||||
|
||||
@ -860,8 +862,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
# Notify the team that it can draw a dice
|
||||
await self.channel_layer.group_send(f"team-{participation.team.trigram}",
|
||||
{'tid': self.tournament_id, 'type': 'draw.notify',
|
||||
'title': "À votre tour !",
|
||||
'body': "C'est à vous de lancer le dé !"})
|
||||
'title': _("Your turn!"),
|
||||
'body': _("It's your turn to launch the dice!")})
|
||||
|
||||
# Reorder dices
|
||||
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
|
||||
@ -888,9 +890,9 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
|
||||
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
|
||||
'visible': True})
|
||||
elif r.number == 1 and self.tournament.final:
|
||||
elif r.number == 1 and (self.tournament.final or settings.TFJM_APP == "ETEAM"):
|
||||
# For the final tournament, we wait for a manual update between the two rounds.
|
||||
msg += "<br><br>Le tirage au sort du tour 1 est terminé."
|
||||
msg += "<br><br>" + _("The draw of the first round is ended.")
|
||||
self.tournament.draw.last_message = msg
|
||||
await self.tournament.draw.asave()
|
||||
|
||||
@ -919,7 +921,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
.prefetch_related('team').aget()
|
||||
# Ensure that the user can reject a problem at this time
|
||||
if participation.id != td.participation_id:
|
||||
return await self.alert("This is not your turn.", 'danger')
|
||||
return await self.alert(_("This is not your turn."), 'danger')
|
||||
|
||||
# Add the problem to the rejected problems list
|
||||
problem = td.purposed
|
||||
@ -933,15 +935,16 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
|
||||
# Update messages
|
||||
trigram = td.participation.team.trigram
|
||||
msg = f"L'équipe <strong>{trigram}</strong> a refusé le problème <strong>{problem} : " \
|
||||
f"{settings.PROBLEMS[problem - 1]}</strong>. "
|
||||
msg = _("The team <strong>{trigram}</strong> refused the problem <strong>{problem}</strong>: "
|
||||
"{problem_name}.").format(trigram=trigram, problem=problem,
|
||||
problem_name=settings.PROBLEMS[problem - 1]) + " "
|
||||
if remaining >= 0:
|
||||
msg += f"Il lui reste {remaining} refus sans pénalité."
|
||||
msg += _("It remains {remaining} refusals without penalty.").format(remaining=remaining)
|
||||
else:
|
||||
if already_refused:
|
||||
msg += "Cela n'ajoute pas de pénalité."
|
||||
msg += _("This problem was already refused by this team.")
|
||||
else:
|
||||
msg += "Cela ajoute une pénalité de 25 % sur le coefficient de l'oral de la défense."
|
||||
msg += _("It adds a 25% penalty on the coefficient of the oral defense.")
|
||||
self.tournament.draw.last_message = msg
|
||||
await self.tournament.draw.asave()
|
||||
|
||||
@ -984,8 +987,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
# Notify the team that it can draw a problem
|
||||
await self.channel_layer.group_send(f"team-{new_trigram}",
|
||||
{'tid': self.tournament_id, 'type': 'draw.notify',
|
||||
'title': "À votre tour !",
|
||||
'body': "C'est à vous de tirer un nouveau problème !"})
|
||||
'title': _("Your turn!"),
|
||||
'body': _("It's your turn to draw a problem!")})
|
||||
|
||||
@ensure_orga
|
||||
async def export(self, **kwargs):
|
||||
@ -1022,17 +1025,17 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
|
||||
r2 = await self.tournament.draw.round_set.filter(number=2).aget()
|
||||
self.tournament.draw.current_round = r2
|
||||
msg = "Le tirage au sort pour le tour 2 va commencer. " \
|
||||
"L'ordre de passage est déterminé à partir du classement du premier tour, " \
|
||||
"de sorte à mélanger les équipes entre les deux jours."
|
||||
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.")
|
||||
self.tournament.draw.last_message = msg
|
||||
await self.tournament.draw.asave()
|
||||
|
||||
# Send notification to everyone
|
||||
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
|
||||
{'tid': self.tournament_id, 'type': 'draw.notify',
|
||||
'title': 'Tirage au sort du TFJM²',
|
||||
'body': "Le tirage au sort pour le second tour de la finale a commencé !"})
|
||||
'title': _("Draw") + " " + settings.APP_NAME,
|
||||
'body': _("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()
|
||||
@ -1082,8 +1085,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
|
||||
# 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': "À votre tour !",
|
||||
'body': "C'est à vous de tirer un nouveau problème !"})
|
||||
'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',
|
||||
|
@ -110,58 +110,61 @@ class Draw(models.Model):
|
||||
# Waiting for dices to determine pools and passage order
|
||||
if self.current_round.number == 1:
|
||||
# Specific information for the first round
|
||||
s += """Nous allons commencer le tirage des problèmes.<br>
|
||||
Vous pouvez à tout moment poser toute question si quelque chose
|
||||
n'est pas clair ou ne va pas.<br><br>
|
||||
Nous allons d'abord tirer les poules et l'ordre de passage
|
||||
pour le premier tour avec toutes les équipes puis pour chaque poule,
|
||||
nous tirerons l'ordre de tirage pour le tour et les problèmes.<br><br>"""
|
||||
s += """
|
||||
Les capitaines, vous pouvez désormais toustes lancer un dé 100,
|
||||
en cliquant sur le gros bouton. Les poules et l'ordre de passage
|
||||
lors du premier tour sera l'ordre croissant des dés, c'est-à-dire
|
||||
que le plus petit lancer sera le premier à passer dans la poule A."""
|
||||
s += _("We are going to start the problem draw.<br>"
|
||||
"You can ask any question if something is not clear or wrong.<br><br>"
|
||||
"We are going to first draw the pools and the passage order for the first round "
|
||||
"with all the teams, then for each pool, we will draw the draw order and the problems.")
|
||||
s += "<br><br>"
|
||||
s += _("The captains, you can now all throw a 100-sided dice, by clicking on the big dice button. "
|
||||
"The pools and the passage order during the first round will be the increasing order "
|
||||
"of the dices, ie. the smallest dice will be the first to pass in pool A.")
|
||||
case 'DICE_ORDER_POULE':
|
||||
# Waiting for dices to determine the choice order
|
||||
s += f"""Nous passons au tirage des problèmes pour la poule
|
||||
<strong>{self.current_round.current_pool}</strong>, entre les équipes
|
||||
<strong>{', '.join(td.participation.team.trigram
|
||||
for td in self.current_round.current_pool.teamdraw_set.all())}</strong>.
|
||||
Les capitaines peuvent lancer un dé 100 en cliquant sur le gros bouton
|
||||
pour déterminer l'ordre de tirage. L'équipe réalisant le plus gros score pourra
|
||||
tirer en premier."""
|
||||
s += _("We are going to start the problem draw for the pool <strong>{pool}</strong>, "
|
||||
"between the teams <strong>{teams}</strong>. "
|
||||
"The captains can throw a 100-sided dice by clicking on the big dice button "
|
||||
"to determine the order of draw. The team with the highest score will draw first.") \
|
||||
.format(pool=self.current_round.current_pool,
|
||||
teams=', '.join(td.participation.team.trigram
|
||||
for td in self.current_round.current_pool.teamdraw_set.all()))
|
||||
case 'WAITING_DRAW_PROBLEM':
|
||||
# Waiting for a problem draw
|
||||
td = self.current_round.current_pool.current_team
|
||||
s += f"""C'est au tour de l'équipe <strong>{td.participation.team.trigram}</strong>
|
||||
de choisir son problème. Cliquez sur l'urne au milieu pour tirer un problème au sort."""
|
||||
s += _("The team <strong>{trigram}</strong> is going to draw a problem. "
|
||||
"Click on the urn in the middle to draw a problem.") \
|
||||
.format(trigram=td.participation.team.trigram)
|
||||
case 'WAITING_CHOOSE_PROBLEM':
|
||||
# Waiting for the team that can accept or reject the problem
|
||||
td = self.current_round.current_pool.current_team
|
||||
s += f"""L'équipe <strong>{td.participation.team.trigram}</strong> a tiré le problème
|
||||
<strong>{td.purposed} : {settings.PROBLEMS[td.purposed - 1]}</strong>. """
|
||||
s += _("The team <strong>{trigram}</strong> drew the problem <strong>{problem}: "
|
||||
"{problem_name}</strong>.") \
|
||||
.format(trigram=td.participation.team.trigram,
|
||||
problem=td.purposed, problem_name=settings.PROBLEMS[td.purposed - 1]) + " "
|
||||
if td.purposed in td.rejected:
|
||||
# The problem was previously rejected
|
||||
s += """Elle a déjà refusé ce problème auparavant, elle peut donc le refuser sans pénalité et
|
||||
tirer un nouveau problème immédiatement, ou bien revenir sur son choix."""
|
||||
s += _("It already refused this problem before, so it can refuse it without penalty and "
|
||||
"draw a new problem immediately, or change its mind.")
|
||||
else:
|
||||
# The problem can be rejected
|
||||
s += "Elle peut décider d'accepter ou de refuser ce problème. "
|
||||
s += _("It can decide to accept or refuse this problem.") + " "
|
||||
if len(td.rejected) >= len(settings.PROBLEMS) - settings.RECOMMENDED_SOLUTIONS_COUNT:
|
||||
s += "Refuser ce problème ajoutera une nouvelle pénalité de 25 % sur le coefficient de l'oral de la défense."
|
||||
s += _("Refusing this problem will add a new penalty of 25% "
|
||||
"on the coefficient of the oral defense.")
|
||||
else:
|
||||
s += f"Il reste {len(settings.PROBLEMS) - settings.RECOMMENDED_SOLUTIONS_COUNT - len(td.rejected)} refus sans pénalité."
|
||||
s += _("There are still {remaining} refusals without penalty.").format(
|
||||
remaining=len(settings.PROBLEMS) - settings.RECOMMENDED_SOLUTIONS_COUNT - len(td.rejected))
|
||||
case 'WAITING_FINAL':
|
||||
# We are between the two rounds of the final tournament
|
||||
s += "Le tirage au sort pour le tour 2 aura lieu à la fin du premier tour. Bon courage !"
|
||||
s += _("The draw for the second round will take place at the end of the first round. Good luck!")
|
||||
case 'DRAW_ENDED':
|
||||
# The draw is ended
|
||||
s += "Le tirage au sort est terminé. Les solutions des autres équipes peuvent être trouvées dans l'onglet « Ma participation »."
|
||||
s += _("The draw is ended. The solutions of the other teams can be found in the tab "
|
||||
"\"My participation\".")
|
||||
|
||||
s += "<br><br>" if s else ""
|
||||
s += """Pour plus de détails sur le déroulement du tirage au sort,
|
||||
le règlement est accessible sur
|
||||
<a class="alert-link" href="https://tfjm.org/reglement">https://tfjm.org/reglement</a>."""
|
||||
rules_link = "https://tfjm.org/reglement" if settings.TFJM_APP == "TFJM" else "https://eteam.tfjm.org/rules/"
|
||||
s += _("For more details on the draw, the rules are available on "
|
||||
"<a class=\"alert-link\" href=\"{link}\">{link}</a>.").format(link=rules_link)
|
||||
return s
|
||||
|
||||
async def ainformation(self) -> str:
|
||||
|
Reference in New Issue
Block a user