1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2025-06-24 15:00:30 +02:00

Use a unique socket for the drawing system

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello
2023-05-11 17:07:53 +02:00
parent 8c41684993
commit 0c80385958
4 changed files with 979 additions and 829 deletions

View File

@ -42,35 +42,27 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
We accept only if this is a user of a team of the associated tournament, or a volunteer
of the tournament.
"""
# Get the tournament from the URL
self.tournament_id = self.scope['url_route']['kwargs']['tournament_id']
self.tournament = await Tournament.objects.filter(pk=self.tournament_id)\
.prefetch_related('draw__current_round__current_pool__current_team__participation__team').aget()
# Fetch participations from the tournament
self.participations = []
async for participation in self.tournament.participations.filter(valid=True).prefetch_related('team'):
self.participations.append(participation)
# Fetch the registration of the current user
user = self.scope['user']
reg = await Registration.objects.aget(user=user)
self.registration = reg
if reg.is_volunteer and not reg.is_admin and self.tournament not in reg.interesting_tournaments \
or not reg.is_volunteer and reg.team.participation.tournament != self.tournament:
# This user may not have access to the drawing session
await self.close()
return
# Accept the connection
await self.accept()
# Register to channel layers to get updates
await self.channel_layer.group_add(f"tournament-{self.tournament.id}", self.channel_name)
if not self.registration.is_volunteer:
if self.registration.participates:
await self.channel_layer.group_add(f"team-{self.registration.team.trigram}", self.channel_name)
participation = reg.team.participation
if participation.valid:
await self.channel_layer.group_add(f"tournament-{participation.tournament.id}", self.channel_name)
else:
await self.channel_layer.group_add(f"volunteer-{self.tournament.id}", self.channel_name)
tids = [t.id async for t in Tournament.objects.all()] \
if reg.is_admin else [t.id for t in reg.interesting_tournaments]
for tid in tids:
await self.channel_layer.group_add(f"tournament-{tid}", self.channel_name)
await self.channel_layer.group_add(f"volunteer-{tid}", self.channel_name)
async def disconnect(self, close_code) -> None:
"""
@ -78,25 +70,40 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
:param close_code: The error code.
"""
# Unregister from channel layers
await self.channel_layer.group_discard(f"tournament-{self.tournament.id}", self.channel_name)
if not self.registration.is_volunteer:
await self.channel_layer.group_discard(f"team-{self.registration.team.trigram}", self.channel_name)
participation = self.registration.team.participation
await self.channel_layer.group_discard(f"tournament-{participation.tournament.id}", self.channel_name)
else:
await self.channel_layer.group_discard(f"volunteer-{self.tournament.id}", self.channel_name)
async for tournament in Tournament.objects.all():
await self.channel_layer.group_discard(f"tournament-{tournament.id}", self.channel_name)
await self.channel_layer.group_discard(f"volunteer-{tournament.id}", self.channel_name)
async def alert(self, message: str, alert_type: str = 'info', **kwargs):
async def alert(self, message: str, alert_type: str = 'info', tid: int = -1, **kwargs):
"""
Send an alert message to the current user.
:param message: The body of the alert.
:param alert_type: The type of the alert, which is a bootstrap color (success, warning, info, danger,…)
:param tid: The tournament id. Default to -1, the current tournament.
"""
return await self.send_json({'type': 'alert', 'alert_type': alert_type, 'message': str(message)})
tid = tid if tid > 0 else self.tournament_id
return await self.send_json({'tid': tid, 'type': 'alert', 'alert_type': alert_type, 'message': str(message)})
async def receive_json(self, content, **kwargs):
"""
Called when the client sends us some data, parsed as JSON.
:param content: The sent data, decoded from JSON text. Must content a `type` field.
"""
# Get the tournament from the message
self.tournament_id = content['tid']
self.tournament = await Tournament.objects.filter(pk=self.tournament_id) \
.prefetch_related('draw__current_round__current_pool__current_team__participation__team').aget()
# Fetch participations from the tournament
self.participations = []
async for participation in self.tournament.participations.filter(valid=True).prefetch_related('team'):
self.participations.append(participation)
# Refresh tournament
self.tournament = await Tournament.objects.filter(pk=self.tournament_id)\
.prefetch_related('draw__current_round__current_pool__current_team__participation__team').aget()
@ -176,37 +183,42 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await TeamDraw.objects.acreate(participation=participation, round=r)
# Send to clients the different pools
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.send_poules',
'round': r.number,
'poules': [
{
'letter': pool.get_letter_display(),
'teams': await pool.atrigrams(),
}
async for pool in r.pool_set.order_by('letter').all()
]})
{
'tid': self.tournament_id,
'type': 'draw.send_poules',
'round': r.number,
'poules': [
{
'letter': pool.get_letter_display(),
'teams': await pool.atrigrams(),
}
async for pool in r.pool_set.order_by('letter').all()
]
})
draw.current_round = r1
await draw.asave()
# Make dice box visible
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': True})
await self.alert(_("Draw started!"), 'success')
# Update user interface
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.start', 'fmt': fmt, 'draw': draw})
{'tid': self.tournament_id, 'type': 'draw.start', 'fmt': fmt, 'draw': draw})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_info',
{'tid': self.tournament_id, 'type': 'draw.set_info',
'info': await self.tournament.draw.ainformation()})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_active', 'round': 1})
{'tid': self.tournament_id, 'type': 'draw.set_active', 'round': 1})
# Send notification to everyone
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.notify', 'title': 'Tirage au sort du TFJM²',
{'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é !"})
@ -216,7 +228,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
"""
await self.alert(_("The draw for the tournament {tournament} will start.")
.format(tournament=self.tournament.name), 'warning')
await self.send_json({'type': 'draw_start', 'fmt': content['fmt'],
await self.send_json({'tid': content['tid'], 'type': 'draw_start', 'fmt': content['fmt'],
'trigrams': [p.team.trigram for p in self.participations]})
@ensure_orga
@ -231,7 +243,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# All associated data will be deleted by cascade
await self.tournament.draw.adelete()
# Send information to all users
await self.channel_layer.group_send(f"tournament-{self.tournament.id}", {'type': 'draw_abort'})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'tid': self.tournament_id, 'type': 'draw_abort'})
async def draw_abort(self, content) -> None:
"""
@ -239,7 +252,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
"""
await self.alert(_("The draw for the tournament {tournament} is aborted.")
.format(tournament=self.tournament.name), 'danger')
await self.send_json({'type': 'abort'})
await self.send_json({'tid': content['tid'], 'type': 'abort'})
async def process_dice(self, trigram: str | None = None, **kwargs):
"""
@ -310,7 +323,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Send the dice result to all users
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}", {'type': 'draw.dice', 'team': trigram, 'result': res})
f"tournament-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.dice',
'team': trigram, 'result': res})
if state == 'DICE_SELECT_POULES' and \
not await TeamDraw.objects.filter(round_id=self.tournament.draw.current_round_id,
@ -364,19 +378,20 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await dup.asave()
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}",
{'type': 'draw.dice', 'team': dup.participation.team.trigram, 'result': None})
{'tid': self.tournament_id, 'type': 'draw.dice',
'team': dup.participation.team.trigram, 'result': None})
# Send notification to concerned teams
await self.channel_layer.group_send(
f"team-{dup.participation.team.trigram}",
{'type': 'draw.notify', 'title': 'Tirage au sort du TFJM²',
{'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.'}
)
# Alert the tournament
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}",
{'type': 'draw.alert',
{'tid': self.tournament_id, 'type': 'draw.alert',
'message': _('Dices from teams {teams} are identical. Please relaunch your dices.').format(
teams=', '.join(td.participation.team.trigram for td in dups)),
'alert_type': 'warning'})
@ -452,23 +467,26 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
for td in tds:
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}",
{'type': 'draw.dice', 'team': td.participation.team.trigram, 'result': None})
{'tid': self.tournament_id, 'type': 'draw.dice', 'team': td.participation.team.trigram, 'result': None})
# Hide dice interface
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': False})
# Display dice interface only for the teams in the first pool, and for volunteers
async for td in pool.teamdraw_set.prefetch_related('participation__team').all():
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
{'type': 'draw.dice_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': True})
# First send the second pool to have the good team order
r2 = await self.tournament.draw.round_set.filter(number=2).aget()
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.send_poules',
{'tid': self.tournament_id, 'type': 'draw.send_poules',
'round': r2.number,
'poules': [
{
@ -478,7 +496,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
async for pool in r2.pool_set.order_by('letter').all()
]})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.send_poules',
{'tid': self.tournament_id, 'type': 'draw.send_poules',
'round': r.number,
'poules': [
{
@ -490,10 +508,10 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Update information header and the active team on the recap menu
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_info',
{'tid': self.tournament_id, 'type': 'draw.set_info',
'info': await self.tournament.draw.ainformation()})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_active',
{'tid': self.tournament_id, 'type': 'draw.set_active',
'round': r.number,
'pool': pool.get_letter_display()})
@ -521,28 +539,30 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Update information header
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_info',
{'tid': self.tournament_id, 'type': 'draw.set_info',
'info': await self.tournament.draw.ainformation()})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_active',
{'tid': self.tournament_id, 'type': 'draw.set_active',
'round': r.number,
'pool': pool.get_letter_display(),
'team': pool.current_team.participation.team.trigram})
# Hide dice button to everyone
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': False})
# Display the box button to the first team and to volunteers
trigram = pool.current_team.participation.team.trigram
await self.channel_layer.group_send(f"team-{trigram}",
{'type': 'draw.box_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.box_visibility', 'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.box_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.box_visibility', 'visible': True})
# Notify the team that it can draw a problem
await self.channel_layer.group_send(f"team-{tds[0].participation.team.trigram}",
{'type': 'draw.notify', 'title': "À votre tour !",
{'tid': self.tournament_id, 'type': 'draw.notify',
'title': "À votre tour !",
'body': "C'est à vous de tirer un nouveau problème !"})
async def select_problem(self, **kwargs):
@ -585,20 +605,25 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Update interface
trigram = td.participation.team.trigram
await self.channel_layer.group_send(f"team-{trigram}",
{'type': 'draw.box_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.box_visibility',
'visible': False})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.box_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.box_visibility',
'visible': False})
await self.channel_layer.group_send(f"team-{trigram}",
{'type': 'draw.buttons_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.buttons_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': True})
await self.channel_layer.group_send(f"team-{self.tournament.id}",
{'type': 'draw.draw_problem', 'team': trigram, 'problem': problem})
{'tid': self.tournament_id, 'type': 'draw.draw_problem', 'team': trigram,
'problem': problem})
self.tournament.draw.last_message = ""
await self.tournament.draw.asave()
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_info',
{'tid': self.tournament_id, 'type': 'draw.set_info',
'info': await self.tournament.draw.ainformation()})
async def accept_problem(self, **kwargs):
@ -641,11 +666,13 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Send the accepted problem to the users
await self.channel_layer.group_send(f"team-{trigram}",
{'type': 'draw.buttons_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': False})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.buttons_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': False})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_problem',
{'tid': self.tournament_id, 'type': 'draw.set_problem',
'round': r.number,
'team': trigram,
'problem': td.accepted})
@ -659,13 +686,16 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
new_trigram = next_td.participation.team.trigram
await self.channel_layer.group_send(f"team-{new_trigram}",
{'type': 'draw.box_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.box_visibility',
'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.box_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.box_visibility',
'visible': True})
# Notify the team that it can draw a problem
await self.channel_layer.group_send(f"team-{new_trigram}",
{'type': 'draw.notify', 'title': "À votre tour !",
{'tid': self.tournament_id, 'type': 'draw.notify',
'title': "À votre tour !",
'body': "C'est à vous de tirer un nouveau problème !"})
else:
# Pool is ended
@ -674,10 +704,10 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
pool = r.current_pool
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_info',
{'tid': self.tournament_id, 'type': 'draw.set_info',
'info': await self.tournament.draw.ainformation()})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_active',
{'tid': self.tournament_id, 'type': 'draw.set_active',
'round': r.number,
'pool': pool.get_letter_display(),
'team': pool.current_team.participation.team.trigram
@ -715,6 +745,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Send the reordered pool
await self.channel_layer.group_send(f"tournament-{self.tournament.id}", {
'tid': self.tournament_id,
'type': 'draw.reorder_pool',
'round': r.number,
'pool': pool.get_letter_display(),
@ -736,14 +767,17 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
async for td in next_pool.team_draws.prefetch_related('participation__team').all():
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
{'type': 'draw.dice_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': True})
# Notify the team that it can draw a dice
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
{'type': 'draw.notify', 'title': "À votre tour !",
{'tid': self.tournament_id, 'type': 'draw.notify',
'title': "À votre tour !",
'body': "C'est à vous de lancer le dé !"})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': True})
else:
# Round is ended
await self.end_round(r)
@ -766,16 +800,18 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
for participation in self.participations:
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}",
{'type': 'draw.dice', 'team': participation.team.trigram, 'result': None})
{'tid': self.tournament_id, 'type': 'draw.dice',
'team': participation.team.trigram, 'result': None})
# Notify the team that it can draw a dice
await self.channel_layer.group_send(f"team-{participation.team.trigram}",
{'type': 'draw.notify', 'title': "À votre tour !",
{'tid': self.tournament_id, 'type': 'draw.notify',
'title': "À votre tour !",
'body': "C'est à vous de lancer le dé !"})
# Reorder dices
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.send_poules',
{'tid': self.tournament_id, 'type': 'draw.send_poules',
'round': r2.number,
'poules': [
{
@ -793,9 +829,11 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
async for td in p1.teamdraw_set.prefetch_related('participation__team').all():
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
{'type': 'draw.dice_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': True})
elif r.number == 1 and self.tournament.final:
# 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é."
@ -803,7 +841,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await self.tournament.draw.asave()
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.export_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.export_visibility',
'visible': True})
async def reject_problem(self, **kwargs):
"""
@ -854,11 +893,13 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Update interface
await self.channel_layer.group_send(f"team-{trigram}",
{'type': 'draw.buttons_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': False})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.buttons_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': False})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.reject_problem',
{'tid': self.tournament_id, 'type': 'draw.reject_problem',
'round': r.number, 'team': trigram, 'rejected': td.rejected})
if already_refused:
@ -873,22 +914,23 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
new_trigram = next_td.participation.team.trigram
await self.channel_layer.group_send(f"team-{new_trigram}",
{'type': 'draw.box_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.box_visibility', 'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.box_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.box_visibility', 'visible': True})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_info',
{'tid': self.tournament_id, 'type': 'draw.set_info',
'info': await self.tournament.draw.ainformation()})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_active',
{'tid': self.tournament_id, 'type': 'draw.set_active',
'round': r.number,
'pool': pool.get_letter_display(),
'team': new_trigram})
# Notify the team that it can draw a problem
await self.channel_layer.group_send(f"team-{new_trigram}",
{'type': 'draw.notify', 'title': "À votre tour !",
{'tid': self.tournament_id, 'type': 'draw.notify',
'title': "À votre tour !",
'body': "C'est à vous de tirer un nouveau problème !"})
@ensure_orga
@ -906,7 +948,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await pool.export()
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.export_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.export_visibility',
'visible': False})
@ensure_orga
async def continue_final(self, **kwargs):
@ -951,7 +994,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Send pools to users
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.send_poules',
{'tid': self.tournament_id, 'type': 'draw.send_poules',
'round': r2.number,
'poules': [
{
@ -965,27 +1008,31 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
for participation in self.participations:
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}",
{'type': 'draw.dice', 'team': participation.team.trigram, 'result': None})
{'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}",
{'type': 'draw.dice_visibility', 'visible': True})
{'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}",
{'type': 'draw.notify', 'title': "À votre tour !",
{'tid': self.tournament_id, 'type': 'draw.notify',
'title': "À votre tour !",
'body': "C'est à vous de tirer un nouveau problème !"})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.continue_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.continue_visibility',
'visible': False})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_info',
{'tid': self.tournament_id, 'type': 'draw.set_info',
'info': await self.tournament.draw.ainformation()})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_active',
{'tid': self.tournament_id, 'type': 'draw.set_active',
'round': r2.number,
'pool': r2.current_pool.get_letter_display()})
@ -1014,12 +1061,12 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await self.undo_order_dice()
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_info',
{'tid': self.tournament_id, 'type': 'draw.set_info',
'info': await self.tournament.draw.ainformation()})
r = self.tournament.draw.current_round
p = r.current_pool
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_active',
{'tid': self.tournament_id, 'type': 'draw.set_active',
'round': r.number,
'pool': p.get_letter_display() if p else None,
'team': p.current_team.participation.team.trigram
@ -1037,15 +1084,18 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await td.asave()
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.continue_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.continue_visibility',
'visible': False})
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
{'type': 'draw.buttons_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.buttons_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': True})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_problem',
{'tid': self.tournament_id, 'type': 'draw.set_problem',
'round': r.number,
'team': td.participation.team.trigram,
'problem': td.accepted})
@ -1061,13 +1111,15 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await td.asave()
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
{'type': 'draw.buttons_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': False})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.buttons_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': False})
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
{'type': 'draw.box_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.box_visibility', 'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.box_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.box_visibility', 'visible': True})
async def undo_process_problem(self):
"""
@ -1115,7 +1167,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await last_td.asave()
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_problem',
{'tid': self.tournament_id, 'type': 'draw.set_problem',
'round': r.number,
'team': last_td.participation.team.trigram,
'problem': last_td.accepted})
@ -1133,7 +1185,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await last_td.asave()
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.reject_problem',
{'tid': self.tournament_id, 'type': 'draw.reject_problem',
'round': r.number,
'team': last_td.participation.team.trigram,
'rejected': last_td.rejected})
@ -1143,9 +1195,11 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await r.current_pool.asave()
await self.channel_layer.group_send(f"team-{last_td.participation.team.trigram}",
{'type': 'draw.buttons_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.buttons_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': True})
else:
# Return to the dice choice
pool_tds = {td.id: td async for td in p.team_draws.prefetch_related('participation__team')}
@ -1166,7 +1220,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Reset the dice on the interface
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}", {'type': 'draw.dice',
f"tournament-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.dice',
'team': last_td.participation.team.trigram,
'result': None})
break
@ -1177,12 +1231,15 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Make dice box visible
for td in pool_tds.values():
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
{'type': 'draw.dice_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': True})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.box_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.box_visibility',
'visible': False})
async def undo_pool_dice(self):
"""
@ -1217,7 +1274,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Reset the dice on the interface
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}", {'type': 'draw.dice',
f"tournament-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.dice',
'team': last_td.participation.team.trigram,
'result': None})
break
@ -1236,15 +1293,18 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await td.asave()
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': False})
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
{'type': 'draw.buttons_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.buttons_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': True})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_problem',
{'tid': self.tournament_id, 'type': 'draw.set_problem',
'round': r.number,
'team': td.participation.team.trigram,
'problem': td.accepted})
@ -1258,12 +1318,12 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
async for td in r1.team_draws.prefetch_related('participation__team').all():
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}", {'type': 'draw.dice',
f"tournament-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.dice',
'team': td.participation.team.trigram,
'result': td.choice_dice})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.send_poules',
{'tid': self.tournament_id, 'type': 'draw.send_poules',
'round': r1.number,
'poules': [
{
@ -1281,15 +1341,18 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
await td.asave()
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': False})
await self.channel_layer.group_send(f"team-{td.participation.team.trigram}",
{'type': 'draw.buttons_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': True})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.buttons_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.buttons_visibility',
'visible': True})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.set_problem',
{'tid': self.tournament_id, 'type': 'draw.set_problem',
'round': r1.number,
'team': td.participation.team.trigram,
'problem': td.accepted})
@ -1308,14 +1371,16 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
async for td in r1.team_draws.prefetch_related('participation__team').all():
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}", {'type': 'draw.dice',
f"tournament-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.dice',
'team': td.participation.team.trigram,
'result': td.choice_dice})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': False})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': False})
await self.channel_layer.group_send(f"volunteer-{self.tournament.id}",
{'type': 'draw.continue_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.continue_visibility',
'visible': True})
else:
# Go to the dice order
async for r0 in self.tournament.draw.round_set.all():
@ -1349,19 +1414,20 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Reset the dice on the interface
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}", {'type': 'draw.dice',
f"tournament-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.dice',
'team': last_td.participation.team.trigram,
'result': None})
break
async for td in r.team_draws.prefetch_related('participation__team').all():
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}", {'type': 'draw.dice',
f"tournament-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.dice',
'team': td.participation.team.trigram,
'result': td.passage_dice})
await self.channel_layer.group_send(f"tournament-{self.tournament.id}",
{'type': 'draw.dice_visibility', 'visible': True})
{'tid': self.tournament_id, 'type': 'draw.dice_visibility',
'visible': True})
async def undo_order_dice(self):
"""
@ -1393,7 +1459,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
# Reset the dice on the interface
await self.channel_layer.group_send(
f"tournament-{self.tournament.id}", {'type': 'draw.dice',
f"tournament-{self.tournament.id}", {'tid': self.tournament_id, 'type': 'draw.dice',
'team': last_td.participation.team.trigram,
'result': None})
break
@ -1410,55 +1476,57 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
"""
Send a notification (with title and body) to the current user.
"""
await self.send_json({'type': 'notification', 'title': content['title'], 'body': content['body']})
await self.send_json({'tid': content['tid'], 'type': 'notification',
'title': content['title'], 'body': content['body']})
async def draw_set_info(self, content):
"""
Set the information banner to the current user.
"""
await self.send_json({'type': 'set_info', 'information': content['info']})
await self.send_json({'tid': content['tid'], 'type': 'set_info', 'information': content['info']})
async def draw_dice(self, content):
"""
Update the dice of a given team for the current user interface.
"""
await self.send_json({'type': 'dice', 'team': content['team'], 'result': content['result']})
await self.send_json({'tid': content['tid'], 'type': 'dice',
'team': content['team'], 'result': content['result']})
async def draw_dice_visibility(self, content):
"""
Update the visibility of the dice button for the current user.
"""
await self.send_json({'type': 'dice_visibility', 'visible': content['visible']})
await self.send_json({'tid': content['tid'], 'type': 'dice_visibility', 'visible': content['visible']})
async def draw_box_visibility(self, content):
"""
Update the visibility of the box button for the current user.
"""
await self.send_json({'type': 'box_visibility', 'visible': content['visible']})
await self.send_json({'tid': content['tid'], 'type': 'box_visibility', 'visible': content['visible']})
async def draw_buttons_visibility(self, content):
"""
Update the visibility of the accept/reject buttons for the current user.
"""
await self.send_json({'type': 'buttons_visibility', 'visible': content['visible']})
await self.send_json({'tid': content['tid'], 'type': 'buttons_visibility', 'visible': content['visible']})
async def draw_export_visibility(self, content):
"""
Update the visibility of the export button for the current user.
"""
await self.send_json({'type': 'export_visibility', 'visible': content['visible']})
await self.send_json({'tid': content['tid'], 'type': 'export_visibility', 'visible': content['visible']})
async def draw_continue_visibility(self, content):
"""
Update the visibility of the continue button for the current user.
"""
await self.send_json({'type': 'continue_visibility', 'visible': content['visible']})
await self.send_json({'tid': content['tid'], 'type': 'continue_visibility', 'visible': content['visible']})
async def draw_send_poules(self, content):
"""
Send the pools and the teams to the current user to update the interface.
"""
await self.send_json({'type': 'set_poules', 'round': content['round'],
await self.send_json({'tid': content['tid'], 'type': 'set_poules', 'round': content['round'],
'poules': content['poules']})
async def draw_set_active(self, content):
@ -1466,6 +1534,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
Update the user interface to highlight the current team.
"""
await self.send_json({
'tid': content['tid'],
'type': 'set_active',
'round': content.get('round', None),
'poule': content.get('pool', None),
@ -1476,20 +1545,20 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
"""
Send the accepted problem of a team to the current user.
"""
await self.send_json({'type': 'set_problem', 'round': content['round'],
await self.send_json({'tid': content['tid'], 'type': 'set_problem', 'round': content['round'],
'team': content['team'], 'problem': content['problem']})
async def draw_reject_problem(self, content):
"""
Send the rejected problems of a team to the current user.
"""
await self.send_json({'type': 'reject_problem', 'round': content['round'],
await self.send_json({'tid': content['tid'], 'type': 'reject_problem', 'round': content['round'],
'team': content['team'], 'rejected': content['rejected']})
async def draw_reorder_pool(self, content):
"""
Send the new order of a pool to the current user.
"""
await self.send_json({'type': 'reorder_poule', 'round': content['round'],
await self.send_json({'tid': content['tid'], 'type': 'reorder_poule', 'round': content['round'],
'poule': content['pool'], 'teams': content['teams'],
'problems': content['problems']})