from channels.generic.websocket import WebsocketConsumer from .models import * import json from django.template.loader import render_to_string from asgiref.sync import async_to_sync import threading class OnlineUserConsumer(WebsocketConsumer): def connect(self): self.user = self.scope['user'] existing_connection = Connection.objects.filter(user=self.user).last() if existing_connection: self.connection = existing_connection self.connection.online = True self.connection.disconnected = False self.connection.save() else: self.connection = Connection.objects.create(user=self.user, online=True) async_to_sync(self.channel_layer.group_add)( 'online_users', self.channel_name ) self.accept() self.modify_online_user() def disconnect(self, close_code): self.last_seen = datetime.now() self.connection.disconnected = True self.connection.save() timer_thread = threading.Timer(10, self.check_disconnect_status) timer_thread.start() def check_disconnect_status(self): connection = Connection.objects.filter(user=self.user).last() if connection.disconnected: self.connection.last_seen = self.last_seen self.connection.online = False self.connection.save() self.modify_online_user() def modify_online_user(self): connections = Connection.objects.all() online_connections = connections.filter(online=True) offline_connections = connections.filter(online=False, last_seen__isnull=False).order_by('-last_seen')[:5] sorted_connections = list(online_connections) + list(offline_connections) online_users_ids = [connection.user.id for connection in online_connections] customer_connections = [] staff_connections = [] customer_connections = [connection for connection in sorted_connections if hasattr(connection.user, 'customerprofile')] staff_connections = [connection for connection in sorted_connections if hasattr(connection.user, 'staffprofile')] event = { 'type': 'online_user_connection_handler', 'staff_connections': staff_connections, 'customer_connections': customer_connections, 'online_users_ids': online_users_ids } async_to_sync(self.channel_layer.group_send)( 'online_users', event ) def online_user_connection_handler(self, event): context = { 'staff_connections': event['staff_connections'], 'customer_connections': event['customer_connections'], } html = render_to_string("details_templates/partials/recently-online.html", context=context) self.send(text_data=json.dumps({ 'event_type': 'online_user_status', 'html': html, 'online_users_ids': event.get('online_users_ids', []) })) class NewStatusConsumer(WebsocketConsumer): def connect(self): self.user = self.scope['user'] async_to_sync(self.channel_layer.group_add)( "new_status_group", self.channel_name ) self.accept() def disconnect(self, close_code): async_to_sync(self.channel_layer.group_discard)( "new_status_group", self.channel_name ) def new_status_event(self, event): is_online = Connection.objects.all().filter(user=self.user, online=True) status_id = event['status_id'] status = Status.objects.get(id=status_id) context = {'status': status, 'new': True, 'is_online': is_online,} html = render_to_string("details_templates/partials/new-status-activity.html", context) self.send(text_data=json.dumps({ 'event_type': 'new_status', 'html': html, })) class UpdateStatusesTimeConsumer(WebsocketConsumer): def connect(self): self.user = self.scope['user'] async_to_sync(self.channel_layer.group_add)( "new_statuses_time_group", self.channel_name ) self.accept() def disconnect(self, close_code): async_to_sync(self.channel_layer.group_discard)( "new_statuses_time_group", self.channel_name ) def receive(self, text_data): data = json.loads(text_data) connections = Connection.objects.filter(online=True) online_users_ids = [connection.user.id for connection in connections] if data.get('event_type') == 'update_statuses_time': event = { 'type': 'modify_status_time_handler', 'online_users_ids': online_users_ids, } async_to_sync(self.channel_layer.group_send)( "new_statuses_time_group", event ) def modify_status_time_handler(self, event): today = datetime.now().date() latest_statuses = Status.objects.filter(date_time__date=today).order_by('-id') context = {'latest_statuses': latest_statuses} html = render_to_string("details_templates/partials/recent-activities.html", context) self.send(text_data=json.dumps({ 'event_type': 'update_statuses_time', 'html': html, 'online_users_ids': event.get('online_users_ids', []) }))