import json from channels.generic.websocket import WebsocketConsumer from asgiref.sync import async_to_sync from channels_presence.models import Room from channels_presence.decorators import touch_presence, remove_presence from channels_presence.models import Presence import channels from django.contrib.auth.models import User from rest_framework.authtoken.models import Token class UsersConsumer(WebsocketConsumer): appconnect = False ''' CONNECT A WEBSOCKET Die Clients werden in Channel-Layer pro Agentur gepackt, damit gesendete Websocket-Nachrichten auch nur Clients innerhalb der Agentur treffen! ''' def connect(self): super().connect() pathcheck = self.scope["path"].split("/") loggeduser = "" # CHECK IF SOCKET COMES FROM APP OR FROM WEB #APP if(len(pathcheck) == 7 and len(pathcheck[5]) > 0): loggeduser = User.objects.get(pk=Token.objects.get(key=pathcheck[5]).user_id) self.appconnect = True else: loggeduser = self.scope["user"] # Jemand neues kommt online, daher einmal die Presence updaten Presence.objects.touch(self.channel_name) # Nutzer in Agenturraum und eigenen Raum hinzufügen Room.objects.add("agency_" + str(loggeduser.profile.agency.pk), self.channel_name, loggeduser) Room.objects.add("user_" + str(loggeduser.pk), self.channel_name, loggeduser) def disconnect(self, close_code): if(not self.appconnect): loggeduser = self.scope["user"] Room.objects.remove("agency_" + str(loggeduser.profile.agency.pk), self.channel_name) Presence.objects.touch(self.channel_name) else: pathcheck = self.scope["path"].split("/") loggeduser = User.objects.get(pk=Token.objects.get(key=pathcheck[5]).user_id) loggeduser = self.scope["user"] Room.objects.remove("agency_" + str(loggeduser.profile.agency.pk), self.channel_name) Room.objects.remove("user_" + str(loggeduser.pk), self.channel_name, loggeduser) Presence.objects.touch(self.channel_name) ''' def receive(self, text_data): loggeduser = self.scope["user"] async_to_sync(self.channel_layer.group_send)( 'allusers', { 'type': 'chat_message', 'message': 'von mainwebsocket.py' } ) ''' # WEBSOCKET-DATA-CONTENT def receive(self, text_data=None, bytes_data=None): if text_data == '"heartbeat"': Presence.objects.touch(self.channel_name) # UPDATET STANDARD def update_standard(self, event): self.send("standard_update") ''' Generelle FUnktion zum Weiterleiten von PUSH-Nachrichten an den einzelnen User. Die Infos werden dann in der Base.html zerlegt, die Nachrichten werden entweder in der signals.py vorbereitet oder (im seltensten Fall) direkt bei der Datenveränderung. ''' def pushhandler(self, event): self.send(event["pushtext"]) # NEW AGENCY NEWS def agency_newnews(self, event): self.send("pushnotification__news__" + event["pushtext"]) #self.send("Neue Agenturnews!") # SOMETHING IN PRESENCE CHANGED def update_presence_live(self, event): self.send("presence_update") class UsersChat(WebsocketConsumer): ''' CONNECT A WEBSOCKET Die Clients werden in Channel-Layer pro Agentur gepackt, damit gesendete Websocket-Nachrichten auch nur Clients innerhalb der Agentur treffen! ''' def connect(self): super().connect() pathcheck = self.scope["path"].split("/") loggeduser = "" # CHECK IF SOCKET COMES FROM APP OR FROM WEB #APP if(len(pathcheck) == 7 and len(pathcheck[5]) > 0): loggeduser = User.objects.get(pk=Token.objects.get(key=pathcheck[5]).user_id) self.appconnect = True else: loggeduser = self.scope["user"] roomname = "privatechat_" + str(self.scope["url_route"]["kwargs"]["creator"]) + "_" + str(self.scope["url_route"]["kwargs"]["single"]) channel_layer = channels.layers.get_channel_layer() Room.objects.add("user_" + str(loggeduser.pk), self.channel_name, loggeduser) Room.objects.add(roomname, self.channel_name, loggeduser) def disconnect(self, close_code): #self.channel_layer.group_discard(list(Room.objects.filter(room_channel_name=self.channel_name))[0].room_channel_name, self.channel_name) Presence.objects.touch(self.channel_name) Room.objects.remove("", self.channel_name) # WEBSOCKET-DATA-CONTENT def receive(self, text_data=None, bytes_data=None): datainfo = text_data.split("__") typinguserid = datainfo[1] if datainfo[0] == 'starttyping': channel_layer = channels.layers.get_channel_layer() async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'start_typing', 'typingname' : typinguserid}) elif datainfo[0] == 'stoptyping': channel_layer = channels.layers.get_channel_layer() async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'stop_typing'}) elif datainfo[0] == 'load': channel_layer = channels.layers.get_channel_layer() async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'reloadmessages'}) elif datainfo[0] == 'delmessage': channel_layer = channels.layers.get_channel_layer() async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'delmessage', 'messageid' : datainfo[1] }) def start_typing(self, event): useristyping = User.objects.get(pk=event["typingname"]) self.send("starttyping__" + str(useristyping.pk) + "_" + useristyping.first_name + " " + useristyping.last_name + " tippt...") def stop_typing(self, event): self.send("stoptyping") def reloadmessages(self, event): self.send("reloadmessages") # UPDATET STANDARD def update_standard(self, event): self.send("standard_update") # NEW AGENCY NEWS def agency_newnews(self, event): self.send("Neue Agenturnews!") def pushhandler(self, event): self.send(event["pushtext"]) # SOMETHING IN PRESENCE CHANGED def update_presence_live(self, event): self.send("presence_update") def delmessage(self, event): self.send("delete_message__" + event["messageid"]) class GroupChat(WebsocketConsumer): def connect(self): super().connect() pathcheck = self.scope["path"].split("/") loggeduser = "" # CHECK IF SOCKET COMES FROM APP OR FROM WEB #APP if(len(pathcheck) == 7 and len(pathcheck[5]) > 0): loggeduser = User.objects.get(pk=Token.objects.get(key=pathcheck[5]).user_id) self.appconnect = True else: loggeduser = self.scope["user"] roomname = "groupchat_" + str(self.scope["url_route"]["kwargs"]["chatid"]) channel_layer = channels.layers.get_channel_layer() Room.objects.add(roomname, self.channel_name, loggeduser) def disconnect(self, close_code): Presence.objects.touch(self.channel_name) Room.objects.remove("", self.channel_name) # WEBSOCKET-DATA-CONTENT def receive(self, text_data=None, bytes_data=None): datainfo = text_data.split("__") typinguserid = datainfo[1] print(datainfo[2]) if datainfo[0] == 'starttyping': channel_layer = channels.layers.get_channel_layer() async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'start_typing', 'typingname' : typinguserid}) elif datainfo[0] == 'stoptyping': channel_layer = channels.layers.get_channel_layer() async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'stop_typing'}) elif datainfo[0] == 'load': channel_layer = channels.layers.get_channel_layer() async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'reloadmessages'}) elif datainfo[0] == 'delmessage': channel_layer = channels.layers.get_channel_layer() async_to_sync(channel_layer.group_send)(datainfo[2], {'type' : 'delmessage', 'messageid' : datainfo[1] }) def start_typing(self, event): useristyping = User.objects.get(pk=event["typingname"]) self.send("starttyping__" + str(useristyping.pk) + "_" + useristyping.first_name + " " + useristyping.last_name + " tippt...") def stop_typing(self, event): self.send("stoptyping") def reloadmessages(self, event): self.send("reloadmessages") # UPDATET STANDARD def update_standard(self, event): self.send("standard_update") # NEW AGENCY NEWS def agency_newnews(self, event): self.send("Neue Agenturnews!") def pushhandler(self, event): self.send(event["pushtext"]) # SOMETHING IN PRESENCE CHANGED def update_presence_live(self, event): self.send("presence_update") def delmessage(self, event): self.send("delete_message__" + event["messageid"])