76 lines
2.6 KiB
Python
76 lines
2.6 KiB
Python
# Copyright (C) 2024 by Animath
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from channels.generic.websocket import AsyncJsonWebsocketConsumer
|
|
from django.contrib.auth.models import User
|
|
from registration.models import Registration
|
|
|
|
from .models import Channel
|
|
|
|
|
|
class ChatConsumer(AsyncJsonWebsocketConsumer):
|
|
"""
|
|
This consumer manages the websocket of the chat interface.
|
|
"""
|
|
async def connect(self) -> None:
|
|
"""
|
|
This function is called when a new websocket is trying to connect to the server.
|
|
We accept only if this is a user of a team of the associated tournament, or a volunteer
|
|
of the tournament.
|
|
"""
|
|
if '_fake_user_id' in self.scope['session']:
|
|
self.scope['user'] = await User.objects.aget(pk=self.scope['session']['_fake_user_id'])
|
|
|
|
# Fetch the registration of the current user
|
|
user = self.scope['user']
|
|
if user.is_anonymous:
|
|
# User is not authenticated
|
|
await self.close()
|
|
return
|
|
|
|
reg = await Registration.objects.aget(user_id=user.id)
|
|
self.registration = reg
|
|
|
|
# Accept the connection
|
|
await self.accept()
|
|
|
|
async def disconnect(self, close_code) -> None:
|
|
"""
|
|
Called when the websocket got disconnected, for any reason.
|
|
:param close_code: The error code.
|
|
"""
|
|
if self.scope['user'].is_anonymous:
|
|
# User is not authenticated
|
|
return
|
|
|
|
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.
|
|
"""
|
|
match content['type']:
|
|
case 'fetch_channels':
|
|
await self.fetch_channels()
|
|
case unknown:
|
|
print("Unknown message type:", unknown)
|
|
|
|
async def fetch_channels(self) -> None:
|
|
user = self.scope['user']
|
|
|
|
read_channels = await Channel.get_accessible_channels(user, 'read')
|
|
write_channels = await Channel.get_accessible_channels(user, 'write')
|
|
print([channel async for channel in write_channels.all()])
|
|
message = {
|
|
'type': 'fetch_channels',
|
|
'channels': [
|
|
{
|
|
'id': channel.id,
|
|
'name': channel.name,
|
|
'read_access': True,
|
|
'write_access': await write_channels.acontains(channel),
|
|
}
|
|
async for channel in read_channels.all()
|
|
]
|
|
}
|
|
await self.send_json(message)
|