Nattapong Tapachoom commited on
Commit
28e39dc
·
1 Parent(s): 9161a49
Files changed (1) hide show
  1. app.py +199 -123
app.py CHANGED
@@ -263,152 +263,228 @@ def analyze_text(text: str, model_name: str) -> str:
263
 
264
  # Modern CSS with dark blue theme
265
  CUSTOM_CSS = """
266
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
267
- * {
268
- font-family: 'Inter', 'Noto Sans Thai', sans-serif !important;
269
- }
270
- .gradio-container {
271
- max-width: 1200px !important;
272
- margin: 0 auto !important;
273
- background: linear-gradient(135deg, #e0f7fa 0%, #b2f7ef 100%) !important;
274
  min-height: 100vh;
275
- padding: 20px;
276
- }
277
- .main-content, .glass-card {
278
- background: rgba(255,255,255,0.95) !important;
279
- backdrop-filter: blur(12px) !important;
280
- border-radius: 24px !important;
281
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08) !important;
282
- border: 1.5px solid #b2dfdb !important;
283
- overflow: hidden;
284
- color: #1a3c3d !important;
285
- }
286
- .glass-card:hover {
287
- transform: translateY(-2px) !important;
288
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12) !important;
289
  }
290
- .gr-button {
291
- background: linear-gradient(90deg, #26c6da 0%, #43e97b 100%) !important;
292
- border: none !important;
293
- border-radius: 12px !important;
294
- padding: 12px 24px !important;
295
- font-weight: 600 !important;
296
- text-transform: uppercase !important;
297
- letter-spacing: 0.5px !important;
298
- transition: all 0.3s ease !important;
299
- box-shadow: 0 4px 15px rgba(38, 198, 218, 0.13) !important;
300
- color: #fff !important;
301
  }
302
- .gr-button:hover {
303
- transform: translateY(-2px) !important;
304
- box-shadow: 0 6px 20px rgba(38, 198, 218, 0.18) !important;
305
  }
306
- .gr-button.secondary {
307
- background: linear-gradient(90deg, #b2f7ef 0%, #e0f7fa 100%) !important;
308
- color: #1a3c3d !important;
309
- box-shadow: 0 4px 15px rgba(178, 247, 239, 0.13) !important;
310
  }
311
- .gr-button.secondary:hover {
312
- box-shadow: 0 6px 20px rgba(178, 247, 239, 0.18) !important;
 
 
 
 
313
  }
314
- .gr-textbox textarea, .gr-textbox input {
315
- border-radius: 12px !important;
316
- border: 2px solid #b2dfdb !important;
317
- font-size: 16px !important;
318
- padding: 16px !important;
319
- transition: all 0.3s ease !important;
320
- background: #f8fffe !important;
321
- color: #1a3c3d !important;
322
  }
323
- .gr-textbox textarea:focus, .gr-textbox input:focus {
324
- border-color: #26c6da !important;
325
- box-shadow: 0 0 0 3px rgba(38, 198, 218, 0.13) !important;
326
- transform: scale(1.01) !important;
 
 
 
 
 
327
  }
328
- .gr-dropdown > div {
329
- border-radius: 12px !important;
330
- border: 2px solid #b2dfdb !important;
331
- background: #f8fffe !important;
332
- color: #1a3c3d !important;
 
 
 
 
 
333
  }
334
- .gr-dropdown > div:focus-within {
335
- border-color: #26c6da !important;
336
- box-shadow: 0 0 0 3px rgba(38, 198, 218, 0.13) !important;
 
337
  }
338
- .gr-panel, .gr-form, .gr-box {
339
- border-radius: 16px !important;
340
- border: none !important;
341
- background: transparent !important;
342
  }
343
- ::-webkit-scrollbar {
344
- width: 8px;
 
 
 
 
 
 
345
  }
346
- ::-webkit-scrollbar-track {
347
- background: #e0f7fa;
348
- border-radius: 4px;
 
 
 
 
 
 
 
349
  }
350
- ::-webkit-scrollbar-thumb {
351
- background: #26c6da;
352
- border-radius: 4px;
 
 
 
 
 
353
  }
354
- ::-webkit-scrollbar-thumb:hover {
355
- background: #43e97b;
 
 
 
356
  }
357
- @keyframes slideIn {
358
- from {
359
- opacity: 0;
360
- transform: translateY(20px);
361
- }
362
- to {
363
- opacity: 1;
364
- transform: translateY(0);
365
- }
366
  }
367
- .gr-column, .gr-row {
368
- animation: slideIn 0.6s ease-out !important;
 
369
  }
370
- .gr-examples {
371
- border-radius: 16px !important;
372
- overflow: hidden !important;
373
  }
374
- .gr-examples .gr-button {
375
- background: #e0f7fa !important;
376
- border: 1px solid #b2dfdb !important;
377
- margin: 4px !important;
378
- font-size: 14px !important;
379
- text-transform: none !important;
380
- letter-spacing: normal !important;
381
- color: #1a3c3d !important;
382
- }
383
- .gr-examples .gr-button:hover {
384
- background: #b2f7ef !important;
385
- transform: scale(1.02) !important;
386
  }
387
  """
388
 
389
  # Create the modern Gradio interface
390
- with gr.Blocks(
391
- theme=gr.themes.Glass(
392
- primary_hue="blue",
393
- secondary_hue="indigo",
394
- neutral_hue="slate",
395
- font=["Inter", "Noto Sans Thai", "sans-serif"]
396
- ),
397
- css=CUSTOM_CSS,
398
- title="🧠 AI Thai Sentiment Analyzer - วิเคราะห์ความรู้สึกภาษาไทย"
399
- ) as demo:
400
-
401
- # Header with dark blue design
402
  gr.HTML("""
403
- <div style="text-align: center; padding: 40px 0 30px 0;">
404
- <div style="display: inline-block; background: #e0f7fa; padding: 20px 40px; border-radius: 20px; border: 1.5px solid #b2dfdb; margin-bottom: 20px; box-shadow: 0 4px 16px #b2dfdb55;">
405
- <h1 style="font-size: 3.5em; margin: 0; color: #1a3c3d; font-weight: 800; text-shadow: 0 4px 8px #b2dfdb55; display: flex; align-items: center; justify-content: center; gap: 20px;">
406
- <span style="font-size: 1.2em;">🧠</span>
407
- Thai Sentiment AI
408
- </h1>
409
- <p style="font-size: 1.4em; color: #26c6da; margin: 10px 0 0 0; font-weight: 400; text-shadow: 0 2px 4px #b2dfdb33;">
410
- ระบบวิเคราะห์ความรู้สึกภาษาไทยด้วย AI ที่ทันสมัยและแม่นยำ
411
- </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
412
  </div>
413
  </div>
414
  """)
 
263
 
264
  # Modern CSS with dark blue theme
265
  CUSTOM_CSS = """
266
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
267
+ * { font-family: 'Inter', 'Noto Sans Thai', sans-serif !important; }
268
+ body, .gradio-container {
269
+ background: linear-gradient(135deg, #181f2a 0%, #232e3c 100%) !important;
 
 
 
 
270
  min-height: 100vh;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
  }
272
+ .main-uxui-card {
273
+ background: #232e3c !important;
274
+ border-radius: 20px;
275
+ box-shadow: 0 6px 32px rgba(0,0,0,0.22);
276
+ border: 1.5px solid #2d3a4d;
277
+ padding: 32px 28px 28px 28px;
278
+ margin: 0 0 32px 0;
279
+ color: #e3e8ef !important;
280
+ transition: box-shadow 0.2s;
 
 
281
  }
282
+ .main-uxui-card:hover {
283
+ box-shadow: 0 12px 36px rgba(0,0,0,0.28);
 
284
  }
285
+ .main-uxui-header {
286
+ text-align: center;
287
+ margin-bottom: 32px;
 
288
  }
289
+ .main-uxui-header h1 {
290
+ font-size: 2.8em;
291
+ color: #e3e8ef;
292
+ font-weight: 800;
293
+ margin-bottom: 0.2em;
294
+ letter-spacing: 0.5px;
295
  }
296
+ .main-uxui-header p {
297
+ color: #7da2e3;
298
+ font-size: 1.25em;
299
+ margin-top: 0;
300
+ margin-bottom: 0.5em;
 
 
 
301
  }
302
+ .main-uxui-section-title {
303
+ font-size: 1.18em;
304
+ color: #7da2e3;
305
+ font-weight: 700;
306
+ margin-bottom: 12px;
307
+ letter-spacing: 0.2px;
308
+ display: flex;
309
+ align-items: center;
310
+ gap: 8px;
311
  }
312
+ .main-uxui-btn {
313
+ font-size: 1.13em;
314
+ padding: 0.9em 2.7em;
315
+ border-radius: 13px;
316
+ font-weight: 600;
317
+ background: linear-gradient(90deg, #2563eb 0%, #1e293b 100%);
318
+ color: #f8fafc !important;
319
+ border: none;
320
+ box-shadow: 0 2px 8px #1e253355;
321
+ transition: all 0.2s;
322
  }
323
+ .main-uxui-btn:hover {
324
+ filter: brightness(1.08);
325
+ box-shadow: 0 6px 18px #1e253377;
326
+ transform: translateY(-2px) scale(1.03);
327
  }
328
+ .main-uxui-btn.secondary {
329
+ background: #232e3c;
330
+ color: #7da2e3 !important;
331
+ border: 1.5px solid #2d3a4d;
332
  }
333
+ .main-uxui-input, .main-uxui-dropdown {
334
+ font-size: 1.13em;
335
+ border-radius: 10px;
336
+ border: 1.5px solid #2d3a4d;
337
+ background: #1e2533;
338
+ color: #e3e8ef;
339
+ padding: 14px;
340
+ margin-bottom: 10px;
341
  }
342
+ .main-uxui-dropdown { min-width: 220px; }
343
+ .main-uxui-output {
344
+ background: #1e2533;
345
+ border-radius: 14px;
346
+ border: 1.5px solid #2d3a4d;
347
+ color: #e3e8ef;
348
+ padding: 22px 18px;
349
+ font-size: 1.08em;
350
+ min-height: 180px;
351
+ margin-bottom: 0;
352
  }
353
+ .main-uxui-legend {
354
+ background: #232e3c;
355
+ border-radius: 16px;
356
+ border: 1.5px solid #2d3a4d;
357
+ color: #7da2e3;
358
+ padding: 24px 18px;
359
+ margin-top: 32px;
360
+ font-size: 1.05em;
361
  }
362
+ .main-uxui-legend .legend-row {
363
+ display: flex;
364
+ gap: 24px;
365
+ flex-wrap: wrap;
366
+ margin-top: 12px;
367
  }
368
+ .main-uxui-legend .legend-item {
369
+ flex: 1 1 180px;
370
+ background: #1e2533;
371
+ border-radius: 10px;
372
+ padding: 16px 10px;
373
+ margin-bottom: 10px;
374
+ text-align: center;
375
+ border: 1px solid #2d3a4d;
 
376
  }
377
+ .main-uxui-legend .legend-item strong {
378
+ color: #e3e8ef;
379
+ font-size: 1.08em;
380
  }
381
+ .main-uxui-legend .legend-item small {
382
+ color: #7da2e3;
 
383
  }
384
+ @media (max-width: 900px) {
385
+ .main-uxui-card { padding: 16px 6px; }
386
+ .main-uxui-header h1 { font-size: 2em; }
387
+ .main-uxui-section-title { font-size: 1em; }
 
 
 
 
 
 
 
 
388
  }
389
  """
390
 
391
  # Create the modern Gradio interface
392
+ with gr.Blocks(css=CUSTOM_CSS, title="🧠 AI Thai Sentiment Analyzer - วิเคราะห์ความรู้สึกภาษาไทย") as demo:
 
 
 
 
 
 
 
 
 
 
 
393
  gr.HTML("""
394
+ <div class='main-uxui-header'>
395
+ <h1>🧠 Thai Sentiment Analyzer</h1>
396
+ <p>AI วิเคราะห์ความรู้สึกภาษาไทยและหลายภาษา <br>ใช้งานง่าย รองรับหลายโมเดล</p>
397
+ </div>
398
+ """)
399
+ with gr.Row():
400
+ with gr.Column(scale=1):
401
+ gr.HTML("""
402
+ <div class='main-uxui-card'>
403
+ <div class='main-uxui-section-title'>
404
+ <span>🤖</span> เลือกโมเดล AI
405
+ </div>
406
+ """)
407
+ model_dropdown = gr.Dropdown(
408
+ choices=[choice[1] for choice in MODEL_LIST],
409
+ value="🏆 MultiSent E5 Pro - แนะนำ (ความแม่นยำสูงสุด)",
410
+ label="",
411
+ show_label=False,
412
+ elem_classes=["main-uxui-dropdown"]
413
+ )
414
+ gr.HTML("""
415
+ <div class='main-uxui-section-title' style='margin-top:28px;'>
416
+ <span>💡</span> วิธีใช้งาน
417
+ </div>
418
+ <ul style='color:#7da2e3; font-size:1em; line-height:1.7; margin-bottom:0; padding-left:18px;'>
419
+ <li>พิมพ์ข้อความภาษาไทยหรือภาษาอื่นที่ต้องการวิเคราะห์</li>
420
+ <li>แยกประโยคด้วยจุด (.) หรือขึ้นบรรทัดใหม่</li>
421
+ <li>รองรับการวิเคราะห์หลายประโยคพร้อมกัน</li>
422
+ <li>ผลลัพธ์จะแสดงความม���่นใจและสรุปภาพรวม</li>
423
+ </ul>
424
+ </div>
425
+ """)
426
+ with gr.Column(scale=2):
427
+ gr.HTML("""
428
+ <div class='main-uxui-card'>
429
+ <div class='main-uxui-section-title'>
430
+ <span>✍️</span> ข้อความที่ต้องการวิเคราะห์
431
+ </div>
432
+ """)
433
+ text_input = gr.Textbox(
434
+ lines=7,
435
+ placeholder="ตัวอย่าง: วันนี้อากาศดีมาก ฉันรู้สึกมีความสุขมาก สีฟ้าสวยจริงๆ\nแต่การจราจรติดมาก น่าเบื่อจริงๆ\nโดยรวมแล้วก็โอเคนะ",
436
+ label="",
437
+ show_label=False,
438
+ elem_classes=["main-uxui-input"]
439
+ )
440
+ with gr.Row():
441
+ analyze_btn = gr.Button("🔍 วิเคราะห์ข้อความ", elem_classes=["main-uxui-btn"])
442
+ clear_btn = gr.Button("🗑️ ล้างข้อความ", elem_classes=["main-uxui-btn", "secondary"])
443
+ output_box = gr.HTML("""
444
+ <div class='main-uxui-output'>
445
+ <div style='text-align:center; color:#7da2e3; font-size:1.2em;'>
446
+ <div style='font-size:2.5em; margin-bottom:10px;'>🤖</div>
447
+ พร้อมวิเคราะห์ความรู้สึก<br>ใส่ข้อความแล้วกดปุ่ม "วิเคราะห์ข้อความ"
448
+ </div>
449
+ </div>
450
+ """)
451
+ gr.HTML("""
452
+ <div class='main-uxui-card' style='margin-top:0;'>
453
+ <div class='main-uxui-section-title'><span>✨</span> ตัวอย่างข้อความ</div>
454
+ </div>
455
+ """)
456
+ examples = gr.Examples(
457
+ examples=[
458
+ ["วันนี้อากาศดีมาก ฉันรู้สึกมีความสุขมาก สีฟ้าสวยจริงๆ"],
459
+ ["ฉันไม่ชอบอาหารนี้เลย รสชาติแปลกมาก เค็มเกินไป"],
460
+ ["วันนี้เป็นยังไงบ้าง?\nเรียนหนังสือกันไหม?\nมีงานอะไรให้ช่วยไหม?"],
461
+ ["บริการดีมาก พนักงานใจดีและเป็นกันเอง\nแต่ของมีราคาแพงไปหน่อย\nโดยรวมแล้วพอใจครับ แนะนำให้เพื่อนมาลอง"],
462
+ ["เมื่อไหร่จะได้เจอกันอีก คิดถึงมากเลย\nแต่ตอนนี้ต้องทำงานหนักก่อน เพื่ออนาคตที่ดี"]
463
+ ],
464
+ inputs=[text_input],
465
+ label="",
466
+ examples_per_page=5
467
+ )
468
+ gr.HTML("""
469
+ <div class='main-uxui-legend'>
470
+ <div class='main-uxui-section-title'><span>🎯</span> คำอธิบายผลการวิเคราะห์</div>
471
+ <div class='legend-row'>
472
+ <div class='legend-item'>
473
+ <div style='font-size:28px;'>😊</div>
474
+ <strong>Positive</strong><br><small>ความรู้สึกเชิงบวก<br>ดี, สุข, ชอบ</small>
475
+ </div>
476
+ <div class='legend-item'>
477
+ <div style='font-size:28px;'>😢</div>
478
+ <strong>Negative</strong><br><small>ความรู้สึกเชิงลบ<br>เศร้า, โกรธ, ไม่ชอบ</small>
479
+ </div>
480
+ <div class='legend-item'>
481
+ <div style='font-size:28px;'>😐</div>
482
+ <strong>Neutral</strong><br><small>ความรู้สึกเป็นกลาง<br>ปกติ, พอใช้ได้</small>
483
+ </div>
484
+ <div class='legend-item'>
485
+ <div style='font-size:28px;'>🤔</div>
486
+ <strong>Question</strong><br><small>ประโยคคำถาม<br>อะไร, ไหน, เมื่อไหร่</small>
487
+ </div>
488
  </div>
489
  </div>
490
  """)