Fixed student status websocket

This commit is contained in:
Keannu Bernasol 2023-09-18 19:18:44 +08:00
parent 295798b965
commit 18679541be

View file

@ -14,10 +14,13 @@ from djangochannelsrestframework.mixins import (
from djangochannelsrestframework.permissions import IsAuthenticated from djangochannelsrestframework.permissions import IsAuthenticated
from channels.layers import get_channel_layer from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync from asgiref.sync import async_to_sync
from django.contrib.gis.measure import Distance from django.contrib.gis.db.models.functions import Distance
from django.contrib.gis.geos import fromstr from django.contrib.gis.geos import fromstr
from .models import StudentStatus from .models import StudentStatus
from accounts.models import CustomUser from accounts.models import CustomUser
from django.contrib.auth.models import AnonymousUser
from rest_framework import generics, viewsets, exceptions
from channels.exceptions import DenyConnection
class StudentStatusConsumer( class StudentStatusConsumer(
@ -26,7 +29,7 @@ class StudentStatusConsumer(
GenericAsyncAPIConsumer, GenericAsyncAPIConsumer,
): ):
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
queryset = StudentStatus.objects.filter(active=True) queryset = StudentStatus.objects.none()
serializer_class = StudentStatusSerializer serializer_class = StudentStatusSerializer
async def send_status_update(self, event): async def send_status_update(self, event):
@ -34,19 +37,44 @@ class StudentStatusConsumer(
await self.send(text_data=json.dumps(data)) await self.send(text_data=json.dumps(data))
async def websocket_connect(self, message): async def websocket_connect(self, message):
await self.channel_layer.group_add('student_status_group', self.channel_name) if isinstance(self.scope['user'], AnonymousUser):
await self.accept() await self.close()
self.send_updates_task = asyncio.create_task(self.send_updates()) else:
student_status_isactive = await self.get_student_status()
if not student_status_isactive:
await self.close()
await self.channel_layer.group_add('student_status_group', self.channel_name)
await self.accept()
self.send_updates_task = asyncio.create_task(self.send_updates())
async def websocket_disconnect(self, message): async def websocket_disconnect(self, message):
# ... # ...
await self.channel_layer.group_discard('student_status_group', self.channel_name) if not isinstance(self.scope['user'], AnonymousUser):
self.send_updates_task.cancel() await self.channel_layer.group_discard('student_status_group', self.channel_name)
self.send_updates_task.cancel()
@database_sync_to_async
def get_student_status(self):
user = self.scope["user"]
user_status = StudentStatus.objects.filter(user=user).first()
return user_status.active
@database_sync_to_async @database_sync_to_async
def get_student_statuses(self): def get_student_statuses(self):
queryset = self.get_queryset()
user = self.scope['user'] user = self.scope['user']
user_status = StudentStatus.objects.filter(user=user).first()
user_status_active = StudentStatus.objects.filter(
user=user).values_list('active').first()
user_location = fromstr(
user_status.location, srid=4326)
if user_status.active is False:
queryset = StudentStatus.objects.none()
return StudentStatusSerializer(queryset, many=True).data
user_subject_names = user.subjects.values_list('subject', flat=True)
queryset = StudentStatus.objects.exclude(user=user).filter(active=True).filter(subject__name__in=user_subject_names).annotate(
distance=Distance('location', user_location)).filter(distance__lte=50)
return StudentStatusSerializer(queryset, many=True).data return StudentStatusSerializer(queryset, many=True).data
async def send_updates(self): async def send_updates(self):
@ -54,9 +82,9 @@ class StudentStatusConsumer(
while True: while True:
try: try:
print('attempting to get') # print('attempting to get')
data = await self.get_student_statuses() data = await self.get_student_statuses()
print(f"Sending update: {data}") # print(f"Sending update: {data}")
await channel_layer.group_send( await channel_layer.group_send(
'student_status_group', 'student_status_group',
{ {