import json from asgiref.sync import async_to_sync from channels.generic.websocket import WebsocketConsumer from django.contrib.auth.models import User from muzak.auth import get_user_from_token from channels.db import database_sync_to_async from playlist.models import Session, Track, Vote import random import logging class SessionConsumer(WebsocketConsumer): def connect(self): self.session_id = self.scope["url_route"]["kwargs"]["session_id"] self.session_name = f"session_{self.session_id}" self.logger = logging.getLogger(self.session_name) logging.basicConfig(filename=self.session_name+'.log', level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s', filemode='w') async_to_sync(self.channel_layer.group_add)( self.session_name, self.channel_name ) self.accept() def disconnect(self, close_code): # Leave room group async_to_sync(self.channel_layer.group_discard)( self.session_name, self.channel_name ) # Receive message from WebSocket def receive(self, text_data): user = self.scope["user"] # Waarschijnlijk altijd AnonymousUser #self.logger.info(self.scope) sessionId = self.scope["url_route"].get("kwargs", {}).get("session_id", None) text_data_json = json.loads(text_data) # Niet lachen, middleware is moeilijk oké? token = text_data_json.get("token") if token: user = get_user_from_token(token, log=False) session = Session.objects.get(session_id=sessionId) action = text_data_json.get("action", None) if action == "message": message = text_data_json["message"] # Send message to room group async_to_sync(self.channel_layer.group_send)( self.session_name, {"type": "chat.message", "message": str(user) + ": " + message} ) if action == "login": self.logger.info(f"Announced: {user}") async_to_sync(self.channel_layer.group_send)( self.session_name, {"type": "announce", "user": { "id": user.id, "username": user.username}} ) if action == "vote": points = text_data_json.get("points", None) track = session.current_track; try: vote = Vote.objects.get(user=user, track=track, session=session) vote.points = points self.logger.info(f"Updated vote for {track} by {user} to {points} points") vote.save() except Vote.DoesNotExist: vote = Vote.objects.create(user=user, track=track, points=points, session=session) self.logger.info(f"Created vote for {track} by {user} for {points} points") vote.save() except Exception as e: self.logger.error(f"Error voting on {track} by {user} for {points} points: {e}") if action == "pause": pass if action == "next": random.seed(session.seed) tracks = Track.objects.order_by("?") next = False if session.current_track: for track in tracks: if next: session.current_track = track break if session.current_track == track: next = True else: session.current_track = tracks.first() session.save() async_to_sync(self.channel_layer.group_send)( self.session_name, {"type": "announce.track"} ) def announce(self, event): user = event["user"] self.send(text_data=json.dumps({"joined": user})) def announce_track(self, event): self.send(text_data=json.dumps({"track": {}})) # Receive message from room group def chat_message(self, event): message = event["message"] self.logger.info(self.scope["user"]) # Send message to WebSocket self.send(text_data=json.dumps({"message": message}))