From b804c9dd8f81073104b79b86cd37ad0571848c2a Mon Sep 17 00:00:00 2001 From: emile Date: Fri, 12 Jul 2024 09:47:02 +0300 Subject: [PATCH] new; --- osinaweb/db.sqlite3 | Bin 1560576 -> 1560576 bytes osinaweb/static/js/tickets/tickets-room.js | 2 +- .../__pycache__/consumers.cpython-310.pyc | Bin 7137 -> 7702 bytes osinaweb/support/consumers.py | 122 ++++++++---------- 4 files changed, 55 insertions(+), 69 deletions(-) diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index b8f93ba2850f3c80f11f25862da7648e180804c8..6c272bc86460f8f451a7a5919ad9cdbbb9b1a6ad 100644 GIT binary patch delta 234 zcmZoz5Z|yMeu6Zk^h6nFM(K?SiJFYln-6KWAJSw5VkRJF24WT!L?>~p zD>jO=F*q`EG8h>cndlmr>lzv<7?@d^m{}QE>KU1vnwy$PTQ`bLPwWvDZU5B`!eZNh Jb&IpP001~uOMCzT delta 227 zcmZoz5Z|yMeu6Zkwr&)gp4cNQ+WxB>gvGZ1>K12n0RV2Y BOKboD diff --git a/osinaweb/static/js/tickets/tickets-room.js b/osinaweb/static/js/tickets/tickets-room.js index 8736bd93..0a794b5e 100644 --- a/osinaweb/static/js/tickets/tickets-room.js +++ b/osinaweb/static/js/tickets/tickets-room.js @@ -63,7 +63,7 @@ function app(socket) { function initializeWebSocket() { const ticketId = document.getElementById('ticketId').textContent.trim(); - const wsUrl = `wss://${window.location.host}/ws/ticketroom/${ticketId}/`; + const wsUrl = `ws://${window.location.host}/ws/ticketroom/${ticketId}/`; const socket = new WebSocket(wsUrl); socket.onopen = () => { diff --git a/osinaweb/support/__pycache__/consumers.cpython-310.pyc b/osinaweb/support/__pycache__/consumers.cpython-310.pyc index 05c2d41ed37e05f9d5ce2e43e43b6d396cdbecfe..c4b4a2e5bedb2c63209e6e616fdf9b764252e0c4 100644 GIT binary patch literal 7702 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 diff --git a/osinaweb/support/consumers.py b/osinaweb/support/consumers.py index 71ab0ec1..2e233f54 100644 --- a/osinaweb/support/consumers.py +++ b/osinaweb/support/consumers.py @@ -11,65 +11,59 @@ import json from django.template.loader import render_to_string from asgiref.sync import async_to_sync +from channels.generic.websocket import AsyncWebsocketConsumer +from django.shortcuts import get_object_or_404 +from datetime import datetime +from asgiref.sync import sync_to_async +import json -class TicketRoomConsumer(WebsocketConsumer): - def connect(self): +class TicketRoomConsumer(AsyncWebsocketConsumer): + async def connect(self): self.user = self.scope['user'] self.ticket_id = self.scope['url_route']['kwargs']['ticket_id'] - self.ticket = get_object_or_404(Ticket, id=self.ticket_id) + self.ticket = await sync_to_async(get_object_or_404)(Ticket, id=self.ticket_id) self.ticket_number = self.ticket.ticket_number - existing_connection = TicketConnection.objects.filter(ticket=self.ticket, user=self.user, terminated_at__isnull=True).delete() - TicketConnection.objects.create( + await sync_to_async(TicketConnection.objects.filter(ticket=self.ticket, user=self.user, terminated_at__isnull=True).delete)() + await sync_to_async(TicketConnection.objects.create)( ticket=self.ticket, user=self.user, date=datetime.now() ) - staff_profile = StaffProfile.objects.filter(user=self.user).first() + + staff_profile = await sync_to_async(StaffProfile.objects.filter(user=self.user).first)() if staff_profile: - if not TicketStaff.objects.filter(staff=staff_profile, ticket=self.ticket).exists(): - TicketStaff.objects.create( + if not await sync_to_async(TicketStaff.objects.filter(staff=staff_profile, ticket=self.ticket).exists)(): + await sync_to_async(TicketStaff.objects.create)( staff=staff_profile, ticket=self.ticket, date_added=datetime.now() ) - async_to_sync(self.channel_layer.group_add)( - self.ticket_number, self.channel_name - ) - self.accept() - self.modify_online_user() + await self.channel_layer.group_add(self.ticket_number, self.channel_name) + await self.accept() + await self.modify_online_user() + async def disconnect(self, close_code): + await sync_to_async(TicketConnection.objects.filter(ticket=self.ticket, user=self.user).update)(terminated_at=datetime.now()) + await self.channel_layer.group_discard(self.ticket_number, self.channel_name) + await self.modify_online_user() - def disconnect(self, close_code): - TicketConnection.objects.filter( - ticket=self.ticket, - user=self.user, - ).update(terminated_at=datetime.now()) - async_to_sync(self.channel_layer.group_discard)( - self.ticket_number, self.channel_name - ) - self.modify_online_user() - - def receive(self, text_data): + async def receive(self, text_data): text_data_json = json.loads(text_data) event_type = text_data_json.get('event_type') - + if event_type == 'typing': event = { 'type': 'typing_handler', 'user': self.scope['user'] } - async_to_sync(self.channel_layer.group_send)( - self.ticket_number, event - ) + await self.channel_layer.group_send(self.ticket_number, event) elif event_type == 'stop_typing': event = { 'type': 'stop_typing_handler', } - async_to_sync(self.channel_layer.group_send)( - self.ticket_number, event - ) + await self.channel_layer.group_send(self.ticket_number, event) elif event_type == 'update_reaction': reaction = text_data_json['reaction'] update_id = text_data_json['update_id'] @@ -79,13 +73,11 @@ class TicketRoomConsumer(WebsocketConsumer): 'reaction': reaction, 'user': self.scope['user'] } - async_to_sync(self.channel_layer.group_send)( - self.ticket_number, event - ) + await self.channel_layer.group_send(self.ticket_number, event) else: body = text_data_json['description'] file_paths = text_data_json['filePath'] - ticketupdate = TicketUpdate.objects.create( + ticketupdate = await sync_to_async(TicketUpdate.objects.create)( added_by=self.user, description=body, ticket=self.ticket, @@ -96,94 +88,88 @@ class TicketRoomConsumer(WebsocketConsumer): ticket_update=ticketupdate, file_path=file_path ) - ticket_attachment.save() + await sync_to_async(ticket_attachment.save)() event = { 'type': 'update_handler', 'update_id': ticketupdate.id } - async_to_sync(self.channel_layer.group_send)( - self.ticket_number, event - ) + await self.channel_layer.group_send(self.ticket_number, event) - def update_handler(self, event): + async def update_handler(self, event): update_id = event['update_id'] - update = TicketUpdate.objects.get(id=update_id) + update = await sync_to_async(TicketUpdate.objects.get)(id=update_id) context = { 'update': update, 'user': self.user } - - - html = render_to_string("details_templates/partials/new-ticket-message.html", context=context) - self.send(text_data=json.dumps({ + html = await sync_to_async(render_to_string)("details_templates/partials/new-ticket-message.html", context=context) + await self.send(text_data=json.dumps({ 'event_type': 'update', 'html': html })) - def typing_handler(self, event): + async def typing_handler(self, event): context = { 'user': event['user'] } - html = render_to_string("details_templates/partials/typing-message.html", context=context) - self.send(text_data=json.dumps({ + html = await sync_to_async(render_to_string)("details_templates/partials/typing-message.html", context=context) + await self.send(text_data=json.dumps({ 'event_type': 'typing', 'html': html })) - def stop_typing_handler(self, event): - self.send(text_data=json.dumps({ + async def stop_typing_handler(self, event): + await self.send(text_data=json.dumps({ 'event_type': 'stop_typing' })) - def reaction_handler(self, event): + async def reaction_handler(self, event): update_id = event['update_id'] reaction = event['reaction'] user = self.user - update = TicketUpdate.objects.get(id=update_id) - existing_reaction = TicketUpdateReaction.objects.filter(ticket_update=update, customer=user).first() + update = await sync_to_async(TicketUpdate.objects.get)(id=update_id) + existing_reaction = await sync_to_async(TicketUpdateReaction.objects.filter)(ticket_update=update, customer=user).first() new_reaction = None if existing_reaction: - # If the existing reaction type is equal to the new reaction, delete it if existing_reaction.reaction == reaction: - existing_reaction.delete() + await sync_to_async(existing_reaction.delete)() else: - # If not, delete all previous reactions and add a new one - TicketUpdateReaction.objects.filter(ticket_update=update, customer=user).delete() - new_reaction = TicketUpdateReaction.objects.create( + await sync_to_async(TicketUpdateReaction.objects.filter)(ticket_update=update, customer=user).delete() + new_reaction = await sync_to_async(TicketUpdateReaction.objects.create)( ticket_update=update, reaction=reaction, customer=user ) else: - # If there's no existing reaction, simply add the new one - new_reaction = TicketUpdateReaction.objects.create( + new_reaction = await sync_to_async(TicketUpdateReaction.objects.create)( ticket_update=update, reaction=reaction, customer=user ) - self.send(text_data=json.dumps({ + await self.send(text_data=json.dumps({ 'event_type': 'reaction', 'update_id': update_id, 'reaction': new_reaction.reaction if new_reaction else None })) - def modify_online_user(self): + async def modify_online_user(self): + connections = await sync_to_async(TicketConnection.objects.filter)(ticket=self.ticket, terminated_at__isnull=True) event = { 'type': 'user_connection_handler', 'user': self.user, + 'connections': connections, } - async_to_sync(self.channel_layer.group_send)( - self.ticket_number, event - ) + await self.channel_layer.group_send(self.ticket_number, event) - def user_connection_handler(self, event): + async def user_connection_handler(self, event): context = { + 'connections': event['connections'], 'user': event['user'] } - html = render_to_string("details_templates/partials/ticket-online-users.html", context=context) - self.send(text_data=json.dumps({ + html = await sync_to_async(render_to_string)("details_templates/partials/ticket-online-users.html", context=context) + await self.send(text_data=json.dumps({ 'event_type': 'user_status', 'html': html }))