MarfinF commited on
Commit
627279c
ยท
1 Parent(s): a596074

debug websocket

Browse files
Files changed (1) hide show
  1. backend/app.py +35 -182
backend/app.py CHANGED
@@ -1,188 +1,41 @@
1
- import asyncio
2
  from fastapi import FastAPI, WebSocket
3
- from fastapi.staticfiles import StaticFiles
4
- from fastapi.responses import FileResponse
5
- import uvicorn
6
- import json
7
- from transformers import pipeline
8
- from collections import deque
9
- from collections import defaultdict
10
- import math
11
- import sys
12
- import random
13
- import os
14
- from fastapi.middleware.cors import CORSMiddleware
15
-
16
-
17
- sys.path.append(".")
18
 
19
  app = FastAPI()
20
 
21
- # app.mount("/", StaticFiles(directory="frontend", html=True), name="frontend")
22
-
23
- app.add_middleware(
24
- CORSMiddleware,
25
- allow_origins=["*"], # Bisa diubah ke domain spesifik untuk keamanan
26
- allow_credentials=True,
27
- allow_methods=["*"],
28
- allow_headers=["*"],
29
- )
30
-
31
-
32
- # ๐Ÿ”น Load Emotion Detection Model
33
- emotion_classifier = pipeline(
34
- "zero-shot-classification",
35
- model="MarfinF/marfin_emotion",
36
- framework="pt"
37
- )
38
-
39
- # ๐Ÿ”น Emotion-to-Mood Mapping
40
- emotion_to_mood = {
41
- "senang": "happy",
42
- "sedih": "sad",
43
- "marah": "excited",
44
- "takut": "relaxed",
45
- "cinta": "romantic"
46
- }
47
-
48
- # ๐Ÿ”น WebSocket Clients
49
- clients = {}
50
- chat_history = deque(maxlen=4)
51
-
52
- mood_to_genre = {
53
- "happy": "pop",
54
- "sad": "acoustic",
55
- "excited": "rock",
56
- "intense": "cinematic",
57
- "romantic": "rnb",
58
- "chill": "chill"
59
- }
60
-
61
- # ๐Ÿ”น Detect Emotion
62
- def detect_emotion(text):
63
- labels = ["takut", "marah", "sedih", "senang", "cinta"]
64
- result = emotion_classifier(text, candidate_labels=labels)
65
- top_emotion = result['labels'][0]
66
- top_scores = result['scores'][0]
67
- return top_emotion, top_scores
68
-
69
- # ๐Ÿ”น Get Music Recommendations
70
- def get_recommendations_by_mood(mood):
71
- genre_folder = mood_to_genre.get(mood, "pop")
72
- folder_path = f"music/{genre_folder}"
73
- print("folder path")
74
- print(folder_path)
75
-
76
- # Check if folder exists
77
- if not os.path.exists(folder_path):
78
- return []
79
- print("folder exist")
80
-
81
- # List and shuffle songs
82
- songs = [f"music/{genre_folder}/{song}" for song in os.listdir(folder_path) if song.endswith(".mp3")]
83
- random.shuffle(songs)
84
- return songs[:3] # Return top 3 shuffled songs
85
-
86
- def softmax(scores):
87
- exp_scores = [math.exp(score) for score in scores]
88
- total = sum(exp_scores)
89
- return [exp_score / total for exp_score in exp_scores]
90
-
91
- # ๐Ÿ”น Broadcast User List
92
- async def broadcast_user_list():
93
- user_list = list(clients.keys())
94
- message = json.dumps({
95
- "type": "user_list",
96
- "users": user_list
97
- })
98
- for client in clients.values():
99
- await client.send_text(message)
100
-
101
- # ๐Ÿ”น Periodic Music Recommender every 30 seconds
102
- async def periodic_recommendation():
103
- while True:
104
- user_list = list(clients.keys())
105
- if len(user_list) >= 2:
106
- await asyncio.sleep(10)
107
- if clients: # Only run if someone is connected
108
- if len(chat_history) > 0:
109
- # 1. Detect emotion dan ambil (label, score)
110
- print("chat history")
111
- print(chat_history)
112
- emotions = [detect_emotion(msg) for msg in chat_history]
113
- print("Detected Emotions:", emotions)
114
-
115
- # 2. Group by emotion + sum score
116
- emotion_score_sum = defaultdict(float)
117
- for label, score in emotions:
118
- emotion_score_sum[label] += score
119
-
120
- # 3. Softmax
121
- labels = list(emotion_score_sum.keys())
122
- scores = list(emotion_score_sum.values())
123
- softmax_scores = softmax(scores)
124
-
125
- # 4. Pair label + softmax_score
126
- softmax_result = list(zip(labels, softmax_scores))
127
- print("Softmax Result:", softmax_result)
128
-
129
- # 5. Dominant emotion
130
- most_common_emotion = max(softmax_result, key=lambda x: x[1])[0]
131
- print("Dominant Emotion:", most_common_emotion)
132
- mood = emotion_to_mood.get(most_common_emotion, "chill")
133
- music_recommendations = get_recommendations_by_mood(mood)
134
- else:
135
- music_recommendations = ["chill"] # default if no chat
136
-
137
- recommendation_response = {
138
- "recommendations": music_recommendations,
139
- "genre": mood_to_genre.get(mood, "pop")
140
- }
141
-
142
- for client in clients.values():
143
- await client.send_text(json.dumps(recommendation_response))
144
- else:
145
- await asyncio.sleep(2)
146
- await broadcast_user_list()
147
-
148
- # ๐Ÿ”น Start periodic task
149
- @app.on_event("startup")
150
- async def start_recommender():
151
- asyncio.create_task(periodic_recommendation())
152
-
153
- # ๐Ÿ”น WebSocket Endpoint
154
- @app.websocket("/chat/{username}")
155
- async def chat_endpoint(websocket: WebSocket, username: str):
156
  await websocket.accept()
157
- clients[username] = websocket
158
- print(f"{username} joined")
159
-
160
- await broadcast_user_list()
161
-
162
- try:
163
- while True:
164
- data = await websocket.receive_text()
165
- message_data = json.loads(data)
166
-
167
- chat_history.append(message_data["message"])
168
- response = {
169
- "username": message_data["username"],
170
- "message": message_data["message"]
171
- }
172
-
173
- # Broadcast message to all clients
174
- for client in clients.values():
175
- await client.send_text(json.dumps(response))
176
-
177
- except Exception as e:
178
- print(f"{username} disconnected: {e}")
179
- del clients[username]
180
- await broadcast_user_list()
181
-
182
- @app.get("/frontend")
183
- def read_root():
184
- print("frontend")
185
- return FileResponse("frontend/index.html")
186
 
187
- if __name__ == "__main__":
188
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
 
1
  from fastapi import FastAPI, WebSocket
2
+ from fastapi.responses import HTMLResponse
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  app = FastAPI()
5
 
6
+ html = """
7
+ <!DOCTYPE html>
8
+ <html>
9
+ <head>
10
+ <title>WebSocket Chat</title>
11
+ </head>
12
+ <body>
13
+ <h1>WebSocket Chat</h1>
14
+ <textarea id="messages" rows="10" cols="30"></textarea><br>
15
+ <input id="messageInput" type="text"><button onclick="sendMessage()">Send</button>
16
+ <script>
17
+ let ws = new WebSocket("wss://" + location.host + "/ws");
18
+ ws.onmessage = function(event) {
19
+ document.getElementById("messages").value += event.data + "\\n";
20
+ };
21
+ function sendMessage() {
22
+ let input = document.getElementById("messageInput");
23
+ ws.send(input.value);
24
+ input.value = "";
25
+ }
26
+ </script>
27
+ </body>
28
+ </html>
29
+ """
30
+
31
+ @app.get("/")
32
+ async def get():
33
+ return HTMLResponse(html)
34
+
35
+ @app.websocket("/ws")
36
+ async def websocket_endpoint(websocket: WebSocket):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  await websocket.accept()
38
+ while True:
39
+ data = await websocket.receive_text()
40
+ await websocket.send_text(f"Message received: {data}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41