samirerty commited on
Commit
9e9ed87
·
verified ·
1 Parent(s): 4ed151b

Update app.py from anycoder

Browse files
Files changed (1) hide show
  1. app.py +492 -0
app.py ADDED
@@ -0,0 +1,492 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import time
3
+ import random
4
+ import re
5
+
6
+ # --- Sentiment Analysis Logic (Simulating the JS Model) ---
7
+ def analyze_sentiment(text):
8
+ """
9
+ Simulates the sentiment analysis model (Xenova/bert-base-multilingual-uncased-sentiment)
10
+ used in the JavaScript code.
11
+ """
12
+ positive_keywords = ['خوب', 'عالی', 'خوشحال', 'محشر', 'دوست', 'عشق', 'موفق', 'سالم', 'خنده', '🙂', '😊', '❤️', 'good', 'great', 'love']
13
+ negative_keywords = ['بد', 'غمگین', 'ترس', 'تنفر', 'مرگ', 'درد', 'خسته', 'مشکل', '😔', '😢', '😡', 'bad', 'sad', 'hate']
14
+
15
+ score = 0.5
16
+ label = "NEUTRAL" # 3 stars
17
+
18
+ text_lower = text.lower()
19
+
20
+ # Simple keyword matching for demo purposes
21
+ pos_count = sum(1 for word in positive_keywords if word in text_lower)
22
+ neg_count = sum(1 for word in negative_keywords if word in text_lower)
23
+
24
+ if pos_count > neg_count:
25
+ label = "POSITIVE" # 5 stars
26
+ score = random.uniform(0.7, 0.99)
27
+ elif neg_count > pos_count:
28
+ label = "NEGATIVE" # 1 star
29
+ score = random.uniform(0.7, 0.99)
30
+ else:
31
+ score = random.uniform(0.4, 0.6)
32
+
33
+ # Map to the star rating format used in the JS
34
+ if label == "POSITIVE":
35
+ star_label = "5 stars"
36
+ elif label == "NEGATIVE":
37
+ star_label = "1 star"
38
+ else:
39
+ star_label = "3 stars"
40
+
41
+ return [{"label": star_label, "score": score}]
42
+
43
+ def generate_ai_response(text):
44
+ """Generates a response based on sentiment, mimicking the JS logic."""
45
+ result = analyze_sentiment(text)
46
+ label = result[0]['label']
47
+ score = (result[0]['score'] * 100).toFixed(1) if isinstance(result[0]['score'], float) else f"{result[0]['score']*100:.1f}"
48
+
49
+ if label in ["5 stars", "4 stars", "POSITIVE"]:
50
+ return f"😊 خوشحالم که حالتان خوب است! (اطمینان: {score}%)"
51
+ elif label in ["1 star", "2 stars", "NEGATIVE"]:
52
+ return f"😔 متاسفم که اینطور احساس می‌کنید. امیدوارم روزتان بهتر شود. (اطمینان: {score}%)"
53
+ else:
54
+ return f"🤔 پیام شما دریافت شد. (اطمینان: {score}%)"
55
+
56
+ # --- Application Logic ---
57
+
58
+ def handle_login(username, password):
59
+ """Simulates PHP login logic."""
60
+ if not username or not password:
61
+ return gr.Warning("لطفاً نام کاربری و رمز عبور را وارد کنید."), None, gr.update(visible=True), gr.update(visible=False)
62
+
63
+ # Simulate loading
64
+ time.sleep(0.5)
65
+
66
+ # In a real app, check DB here. For demo, accept any non-empty input.
67
+ return (
68
+ gr.Info("ورود موفقیت‌آمیز بود!"),
69
+ {"username": username, "role": "user"}, # User State
70
+ gr.update(visible=False), # Hide Login
71
+ gr.update(visible=True) # Show Chat
72
+ )
73
+
74
+ def handle_register(full_name, email, username, password):
75
+ """Simulates PHP registration logic."""
76
+ if not all([full_name, email, username, password]):
77
+ return gr.Warning("لطفاً تمام فیلدها را پر کنید.")
78
+
79
+ return gr.Info("ثبت نام با موفقیت انجام شد. لطفاً وارد شوید.")
80
+
81
+ def handle_chat(message, history, user_state):
82
+ """Handles message sending and AI response."""
83
+ if not message:
84
+ return history, ""
85
+
86
+ # Add user message
87
+ history.append({"role": "user", "content": message})
88
+
89
+ # Simulate AI thinking time
90
+ time.sleep(0.5)
91
+
92
+ # Generate response
93
+ response = generate_ai_response(message)
94
+ history.append({"role": "assistant", "content": response})
95
+
96
+ return history, ""
97
+
98
+ def handle_logout():
99
+ """Resets the app to login state."""
100
+ return (
101
+ None, # Clear user state
102
+ [], # Clear history
103
+ gr.update(visible=True), # Show Login
104
+ gr.update(visible=False) # Hide Chat
105
+ )
106
+
107
+ # --- Mock Data for Sidebar ---
108
+ def get_online_users():
109
+ """Simulates fetching online users from database."""
110
+ users = [
111
+ {"name": "علی رضایی", "status": "online"},
112
+ {"name": "سارا محمدی", "status": "online"},
113
+ {"name": "رضا کریمی", "status": "offline"},
114
+ {"name": "مریم حسینی", "status": "online"},
115
+ {"name": "سیستم ادمین", "status": "online"},
116
+ ]
117
+ return users
118
+
119
+ # --- Custom CSS (Ported from your HTML) ---
120
+ custom_css = """
121
+ /*
122
+ * GLASSMORPHISM & MODERN UI STYLES
123
+ * Adapted for Gradio Components
124
+ */
125
+
126
+ :root {
127
+ --glass-bg: rgba(255, 255, 255, 0.05);
128
+ --glass-border: rgba(255, 255, 255, 0.1);
129
+ --glass-highlight: rgba(255, 255, 255, 0.1);
130
+ --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
131
+ --text-color: #ffffff;
132
+ --border-radius: 16px;
133
+ }
134
+
135
+ /* Force RTL and Font */
136
+ body, .gradio-container {
137
+ font-family: 'Vazirmatn', sans-serif !important;
138
+ direction: rtl !important;
139
+ text-align: right !important;
140
+ }
141
+
142
+ /* Main Background */
143
+ .gradio-container {
144
+ background: linear-gradient(-45deg, #0f0c29, #302b63, #24243e, #4a1c40);
145
+ background-size: 400% 400%;
146
+ animation: gradientBG 20s ease infinite;
147
+ color: var(--text-color);
148
+ }
149
+
150
+ @keyframes gradientBG {
151
+ 0% { background-position: 0% 50%; }
152
+ 50% { background-position: 100% 50%; }
153
+ 100% { background-position: 0% 50%; }
154
+ }
155
+
156
+ /* Login Panel Styling */
157
+ .login-panel {
158
+ background: var(--glass-bg);
159
+ backdrop-filter: blur(20px);
160
+ -webkit-backdrop-filter: blur(20px);
161
+ border: 1px solid var(--glass-border);
162
+ border-radius: 24px;
163
+ padding: 40px;
164
+ box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3);
165
+ max-width: 450px;
166
+ margin: auto;
167
+ }
168
+
169
+ /* Styling Tabs */
170
+ .tabs-container {
171
+ background: rgba(0, 0, 0, 0.2);
172
+ padding: 6px;
173
+ border-radius: 50px;
174
+ display: flex;
175
+ margin-bottom: 25px;
176
+ }
177
+
178
+ .tab-btn {
179
+ flex: 1;
180
+ background: transparent;
181
+ border: none;
182
+ color: rgba(255, 255, 255, 0.6);
183
+ padding: 10px;
184
+ border-radius: 50px;
185
+ cursor: pointer;
186
+ font-weight: 600;
187
+ transition: all 0.3s;
188
+ }
189
+
190
+ .tab-btn.selected {
191
+ background: var(--primary-gradient);
192
+ color: white;
193
+ box-shadow: 0 4px 15px rgba(118, 75, 162, 0.4);
194
+ }
195
+
196
+ /* Chat Interface Styling */
197
+ .chat-interface {
198
+ display: flex;
199
+ height: 80vh;
200
+ gap: 20px;
201
+ background: rgba(0,0,0,0.2);
202
+ border-radius: 24px;
203
+ border: 1px solid var(--glass-border);
204
+ padding: 20px;
205
+ backdrop-filter: blur(10px);
206
+ }
207
+
208
+ .chat-main {
209
+ flex: 1;
210
+ display: flex;
211
+ flex-direction: column;
212
+ gap: 15px;
213
+ }
214
+
215
+ .chat-sidebar {
216
+ width: 250px;
217
+ background: rgba(255, 255, 255, 0.03);
218
+ border-radius: 16px;
219
+ padding: 15px;
220
+ border: 1px solid var(--glass-border);
221
+ }
222
+
223
+ /* User List Item */
224
+ .user-item {
225
+ display: flex;
226
+ align-items: center;
227
+ gap: 10px;
228
+ padding: 10px;
229
+ border-radius: 8px;
230
+ margin-bottom: 8px;
231
+ background: rgba(255,255,255,0.02);
232
+ }
233
+
234
+ .user-status {
235
+ width: 8px;
236
+ height: 8px;
237
+ border-radius: 50%;
238
+ background: #555;
239
+ }
240
+
241
+ .user-status.online {
242
+ background: #00d2d3;
243
+ box-shadow: 0 0 8px #00d2d3;
244
+ }
245
+
246
+ /* Chatbot Bubbles Override */
247
+ .message.user {
248
+ background: var(--primary-gradient) !important;
249
+ align-self: flex-end !important;
250
+ border-bottom-left-radius: 4px !important;
251
+ border-bottom-right-radius: 16px !important;
252
+ }
253
+
254
+ .message.bot {
255
+ background: rgba(255, 255, 255, 0.1) !important;
256
+ align-self: flex-start !important;
257
+ border: 1px solid rgba(255, 255, 255, 0.1) !important;
258
+ border-bottom-left-radius: 16px !important;
259
+ border-bottom-right-radius: 4px !important;
260
+ }
261
+
262
+ /* Input Area */
263
+ .chat-input-area {
264
+ display: flex;
265
+ gap: 10px;
266
+ background: rgba(0,0,0,0.3);
267
+ padding: 10px;
268
+ border-radius: 16px;
269
+ border: 1px solid var(--glass-border);
270
+ }
271
+
272
+ /* Buttons */
273
+ .primary-btn {
274
+ background: var(--primary-gradient);
275
+ color: white;
276
+ border: none;
277
+ border-radius: 12px;
278
+ padding: 12px 24px;
279
+ font-weight: bold;
280
+ cursor: pointer;
281
+ transition: transform 0.2s;
282
+ }
283
+
284
+ .primary-btn:hover {
285
+ transform: translateY(-2px);
286
+ }
287
+
288
+ .secondary-btn {
289
+ background: rgba(255,255,255,0.1);
290
+ color: white;
291
+ border: 1px solid rgba(255,255,255,0.2);
292
+ border-radius: 12px;
293
+ padding: 8px 16px;
294
+ cursor: pointer;
295
+ }
296
+
297
+ /* Hide Gradio defaults we don't need */
298
+ #component-0 { /* This targets the main container wrapper often */
299
+ padding: 20px !important;
300
+ }
301
+
302
+ footer {
303
+ display: none !important;
304
+ }
305
+ """
306
+
307
+ # --- Gradio App Construction ---
308
+
309
+ with gr.Blocks(css=custom_css, title="چت روم هوشمند") as demo:
310
+
311
+ # Head for Fonts and Icons
312
+ gr.HTML("""
313
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
314
+ <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100;300;400;500;700;900&display=swap" rel="stylesheet">
315
+ """)
316
+
317
+ # Application State
318
+ user_state = gr.State(value=None) # Stores user info
319
+ chat_history = gr.State(value=[]) # Stores chat messages
320
+
321
+ # --- LOGIN / REGISTER SECTION ---
322
+ with gr.Column(elem_classes="login-panel", visible=True) as login_col:
323
+ gr.HTML("""
324
+ <div style="text-align: center; margin-bottom: 30px;">
325
+ <i class="fas fa-robot" style="font-size: 3rem; background: linear-gradient(to bottom right, #fff, #a29bfe); -webkit-background-clip: text; -webkit-text-fill-color: transparent; filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.2));"></i>
326
+ <h1 style="font-weight: 800; font-size: 2rem; margin: 10px 0 5px;">چت روم هوشمند</h1>
327
+ <p style="color: rgba(255, 255, 255, 0.7);">ورود به دنیای هوش مصنوعی</p>
328
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="font-size: 0.8rem; color: rgba(255, 255, 255, 0.5); text-decoration: none; border: 1px solid rgba(255, 255, 255, 0.1); padding: 4px 12px; border-radius: 20px; display: inline-block; margin-top: 10px;">
329
+ Built with anycoder
330
+ </a>
331
+ </div>
332
+ """)
333
+
334
+ with gr.Tabs(elem_classes="tabs-container") as auth_tabs:
335
+ with gr.Tab("ورود", id="login_tab"):
336
+ with gr.Column():
337
+ username = gr.Textbox(label="نام کاربری", placeholder="نام کاربری خود را وارد کنید", show_label=False, container=False)
338
+ password = gr.Textbox(label="رمز عبور", type="password", placeholder="رمز عبور خود را وارد کنید", show_label=False, container=False)
339
+ login_btn = gr.Button("ورود به سیستم", variant="primary", elem_classes="primary-btn", full_width=True)
340
+
341
+ with gr.Tab("ثبت نام", id="register_tab"):
342
+ with gr.Column():
343
+ reg_name = gr.Textbox(label="نام کامل", placeholder="نام و نام خانوادگی", show_label=False)
344
+ reg_email = gr.Textbox(label="ایمیل", placeholder="example@mail.com", show_label=False)
345
+ reg_user = gr.Textbox(label="نام کاربری", placeholder="نام کاربری دلخواه", show_label=False)
346
+ reg_pass = gr.Textbox(label="رمز عبور", type="password", placeholder="رمز عبور قوی انتخاب کنید", show_label=False)
347
+ register_btn = gr.Button("ثبت نام", variant="primary", elem_classes="primary-btn", full_width=True)
348
+
349
+ gr.HTML("""
350
+ <div style="margin-top: 25px; padding-top: 25px; border-top: 1px solid rgba(255, 255, 255, 0.1); color: rgba(255, 255, 255, 0.5); font-size: 0.8rem; text-align: center;">
351
+ <p><i class="fas fa-info-circle"></i> مدل‌های هوش مصنوعی در مرورگر اجرا می‌شوند</p>
352
+ </div>
353
+ """)
354
+
355
+ # --- CHAT INTERFACE SECTION ---
356
+ with gr.Column(elem_classes="chat-interface", visible=False) as chat_col:
357
+
358
+ # Sidebar: Users & Info
359
+ with gr.Column(elem_classes="chat-sidebar"):
360
+ gr.Markdown("## 👥 کاربران آنلاین")
361
+
362
+ # Room Selector (Simulating PHP room logic)
363
+ room_select = gr.Dropdown(
364
+ choices=["اتاق عمومی", "گفتگوی آزاد", "پشتیبانی فنی"],
365
+ value="اتاق عمومی",
366
+ label="اتاق گفتگو",
367
+ interactive=True
368
+ )
369
+
370
+ # User List (Dynamic HTML)
371
+ users_list_html = gr.HTML(value="")
372
+
373
+ gr.HTML("<hr style='border-color: rgba(255,255,255,0.1); margin: 15px 0;'>")
374
+
375
+ logout_btn = gr.Button("خروج از سیستم", elem_classes="secondary-btn", full_width=True, icon="fa-power-off")
376
+
377
+ # Main Chat Area
378
+ with gr.Column(elem_classes="chat-main"):
379
+ # Header
380
+ with gr.Row():
381
+ gr.HTML("""
382
+ <div style="display: flex; align-items: center; gap: 10px; color: white;">
383
+ <i class="fas fa-brain" style="font-size: 1.5rem; color: #a29bfe;"></i>
384
+ <div>
385
+ <h3 style="font-size: 1.1rem; margin:0;">دستیار هوشمند</h3>
386
+ <span style="font-size: 0.75rem; color: #00d2d3;">آماده</span>
387
+ </div>
388
+ </div>
389
+ """)
390
+
391
+ # Chatbot
392
+ chatbot = gr.Chatbot(
393
+ label=None,
394
+ show_label=False,
395
+ bubble_full_width=False,
396
+ height="auto",
397
+ elem_id="chatbot-area"
398
+ )
399
+
400
+ # Input Area
401
+ with gr.Row(elem_classes="chat-input-area"):
402
+ msg_input = gr.Textbox(
403
+ placeholder="پیام خود را بنویسید...",
404
+ show_label=False,
405
+ scale=4,
406
+ container=False,
407
+ autofocus=True
408
+ )
409
+ send_btn = gr.Button("ارسال", variant="primary", scale=1, elem_classes="primary-btn", icon="fa-paper-plane")
410
+
411
+ # --- Event Listeners ---
412
+
413
+ # 1. Login Logic
414
+ login_btn.click(
415
+ fn=handle_login,
416
+ inputs=[username, password],
417
+ outputs=[gr.Textbox(visible=False), user_state, login_col, chat_col] # Using dummy Textbox for toast output
418
+ )
419
+
420
+ # 2. Register Logic
421
+ register_btn.click(
422
+ fn=handle_register,
423
+ inputs=[reg_name, reg_email, reg_user, reg_pass],
424
+ outputs=[gr.Textbox(visible=False)]
425
+ )
426
+
427
+ # 3. Chat Logic
428
+ submit_event = msg_input.submit(
429
+ fn=handle_chat,
430
+ inputs=[msg_input, chat_history, user_state],
431
+ outputs=[chatbot, msg_input]
432
+ )
433
+
434
+ send_btn.click(
435
+ fn=handle_chat,
436
+ inputs=[msg_input, chat_history, user_state],
437
+ outputs=[chatbot, msg_input]
438
+ )
439
+
440
+ # 4. Logout Logic
441
+ logout_btn.click(
442
+ fn=handle_logout,
443
+ inputs=[],
444
+ outputs=[user_state, chat_history, login_col, chat_col]
445
+ )
446
+
447
+ # 5. Update User List (Simulated)
448
+ def update_users():
449
+ users = get_online_users()
450
+ html = ""
451
+ for u in users:
452
+ status_color = "#00d2d3" if u['status'] == 'online' else "#555"
453
+ status_text = "آنلاین" if u['status'] == 'online' else "آفلاین"
454
+ html += f"""
455
+ <div class="user-item">
456
+ <div class="user-status {u['status']}"></div>
457
+ <div style="flex:1">
458
+ <div style="font-size: 0.9rem;">{u['name']}</div>
459
+ <div style="font-size: 0.7rem; color: rgba(255,255,255,0.5);">{status_text}</div>
460
+ </div>
461
+ </div>
462
+ """
463
+ return html
464
+
465
+ # Load users on startup and periodically (simulated via render trigger or just once)
466
+ demo.load(update_users, outputs=users_list_html)
467
+
468
+ # --- Launch Configuration ---
469
+ demo.launch(
470
+ theme=gr.themes.Soft(
471
+ primary_hue="indigo",
472
+ secondary_hue="purple",
473
+ neutral_hue="slate",
474
+ font=gr.themes.GoogleFont("Vazirmatn"),
475
+ text_size="lg",
476
+ spacing_size="lg",
477
+ radius_size="md"
478
+ ).set(
479
+ body_background_fill="transparent", # Let our CSS handle the background
480
+ block_background_fill="transparent",
481
+ block_border_width="0px",
482
+ button_primary_background_fill="*primary_600",
483
+ button_primary_background_fill_hover="*primary_700",
484
+ block_title_text_weight="600",
485
+ input_background_fill="rgba(0,0,0,0.2)",
486
+ input_background_fill_dark="rgba(0,0,0,0.2)",
487
+ input_border_color="rgba(255,255,255,0.1)",
488
+ input_border_color_dark="rgba(255,255,255,0.1)",
489
+ input_radius="lg",
490
+ ),
491
+ footer_links=[{"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}]
492
+ )