Update app.py
Browse files
app.py
CHANGED
|
@@ -5,10 +5,13 @@ from sentiment_analyzer import NewsAnalyzer # Import new class
|
|
| 5 |
import time
|
| 6 |
from collections import Counter # For counting themes/impacts
|
| 7 |
|
| 8 |
-
#
|
|
|
|
| 9 |
print("Initializing Yahoo Finance News Analyzer...")
|
| 10 |
scraper = YahooFinanceScraper()
|
| 11 |
-
analyzer =
|
|
|
|
|
|
|
| 12 |
|
| 13 |
def get_sentiment_color(sentiment):
|
| 14 |
"""กำหนดสีตาม sentiment"""
|
|
@@ -20,12 +23,26 @@ def get_impact_color(impact):
|
|
| 20 |
colors = { "Opportunity": "🟢", "Risk": "🔴", "Neutral": "🟡" }
|
| 21 |
return colors.get(impact, "⚪")
|
| 22 |
|
|
|
|
| 23 |
def analyze_news(search_type, search_input, num_articles):
|
| 24 |
"""
|
| 25 |
ฟังก์ชันหลักในการวิเคราะห์ข่าว
|
| 26 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
try:
|
| 28 |
-
yield "กำลังดึงข่าว...", None,
|
| 29 |
|
| 30 |
if search_type == "Latest News":
|
| 31 |
news_list = scraper.get_latest_news(max_articles=int(num_articles))
|
|
@@ -44,11 +61,11 @@ def analyze_news(search_type, search_input, num_articles):
|
|
| 44 |
yield "❌ ไม่พบข่าว กรุณาลองใหม่อีกครั้ง", None, None
|
| 45 |
return
|
| 46 |
|
| 47 |
-
yield f"พบข่าว {len(news_list)} รายการ |
|
| 48 |
|
| 49 |
results = analyzer.analyze_batch(news_list)
|
| 50 |
|
| 51 |
-
#
|
| 52 |
total = len(results)
|
| 53 |
positive = sum(1 for r in results if r['sentiment'] == 'Positive')
|
| 54 |
negative = sum(1 for r in results if r['sentiment'] == 'Negative')
|
|
@@ -67,32 +84,30 @@ def analyze_news(search_type, search_input, num_articles):
|
|
| 67 |
|
| 68 |
summary = f"""## 📊 สรุปผลการวิเคราะห์
|
| 69 |
**ภาพรวม:** {overall} | **คะแนนเฉลี่ย:** {avg_score:.2f}/1.0
|
| 70 |
-
|
| 71 |
### การกระจาย Sentiment
|
| 72 |
- 🟢 Positive: {positive} ({positive/total*100:.1f}%)
|
| 73 |
- 🔴 Negative: {negative} ({negative/total*100:.1f}%)
|
| 74 |
- 🟡 Neutral: {neutral} ({neutral/total*100:.1f}%)
|
| 75 |
-
|
| 76 |
### 📌 สรุปหัวข้อ (Themes)
|
| 77 |
"""
|
| 78 |
for theme, count in theme_counts.most_common():
|
| 79 |
summary += f"- **{theme}:** {count} รายการ ({count/total*100:.1f}%)\n"
|
| 80 |
|
|
|
|
|
|
|
| 81 |
summary += "\n### ⚡ สรุปผลกระทบ (Impact)\n"
|
| 82 |
for impact, count in impact_counts.most_common():
|
| 83 |
emoji = get_impact_color(impact)
|
| 84 |
summary += f"- {emoji} **{impact}:** {count} รายการ ({count/total*100:.1f}%)\n"
|
| 85 |
-
|
| 86 |
-
summary += "
|
| 87 |
-
|
| 88 |
-
# Create detailed results
|
| 89 |
-
detailed_results = "## 📰 รายละเอียดแต่ละข่าว\n\n"
|
| 90 |
|
| 91 |
for i, result in enumerate(results, 1):
|
| 92 |
s_emoji = get_sentiment_color(result['sentiment'])
|
| 93 |
i_emoji = get_impact_color(result.get('impact', 'N/A'))
|
| 94 |
|
| 95 |
-
# --- MODIFIED: Reverted to *exact* original format + added Theme/Impact line ---
|
| 96 |
detailed_results += f"""### {i}. {s_emoji} {result['title']}
|
| 97 |
**Theme:** {result.get('theme', 'N/A')} | **Impact:** {i_emoji} {result.get('impact', 'N/A')}
|
| 98 |
**Sentiment:** {result['sentiment']} | **Score:** {result['score']:.2f}
|
|
@@ -101,9 +116,7 @@ def analyze_news(search_type, search_input, num_articles):
|
|
| 101 |
{result['summary'][:200]}{'...' if len(result['summary']) > 200 else ''}
|
| 102 |
[🔗 อ่านต่อ]({result['link']})
|
| 103 |
---"""
|
| 104 |
-
# --- End of MODIFIED block ---
|
| 105 |
|
| 106 |
-
# Create DataFrame for table view (Keeping new columns as they are useful)
|
| 107 |
df_data = []
|
| 108 |
for result in results:
|
| 109 |
df_data.append({
|
|
@@ -125,7 +138,7 @@ def analyze_news(search_type, search_input, num_articles):
|
|
| 125 |
error_msg = f"❌ เกิดข้อผิดพลาด: {str(e)}"
|
| 126 |
yield error_msg, None, error_msg
|
| 127 |
|
| 128 |
-
# ---
|
| 129 |
with gr.Blocks(title="Yahoo Finance News Analyzer", theme=gr.themes.Soft()) as demo:
|
| 130 |
gr.Markdown("""
|
| 131 |
# 📈 Yahoo Finance News Analyzer
|
|
|
|
| 5 |
import time
|
| 6 |
from collections import Counter # For counting themes/impacts
|
| 7 |
|
| 8 |
+
# --- MODIFIED BLOCK 1 ---
|
| 9 |
+
# เราจะโหลด Scraper (เบา) แต่จะยังไม่โหลด Analyzer (หนัก)
|
| 10 |
print("Initializing Yahoo Finance News Analyzer...")
|
| 11 |
scraper = YahooFinanceScraper()
|
| 12 |
+
analyzer = None # <-- ตั้งเป็น None ก่อน จะโหลดเมื่อถูกเรียกใช้ครั้งแรก
|
| 13 |
+
# --- END MODIFIED BLOCK ---
|
| 14 |
+
|
| 15 |
|
| 16 |
def get_sentiment_color(sentiment):
|
| 17 |
"""กำหนดสีตาม sentiment"""
|
|
|
|
| 23 |
colors = { "Opportunity": "🟢", "Risk": "🔴", "Neutral": "🟡" }
|
| 24 |
return colors.get(impact, "⚪")
|
| 25 |
|
| 26 |
+
|
| 27 |
def analyze_news(search_type, search_input, num_articles):
|
| 28 |
"""
|
| 29 |
ฟังก์ชันหลักในการวิเคราะห์ข่าว
|
| 30 |
"""
|
| 31 |
+
|
| 32 |
+
# --- MODIFIED BLOCK 2: LAZY LOADING ---
|
| 33 |
+
# ตรวจสอบว่า analyzer ถูกโหลดหรือยัง
|
| 34 |
+
global analyzer
|
| 35 |
+
if analyzer is None:
|
| 36 |
+
# ถ้ายัง ให้แสดงสถานะว่ากำลังโหลด
|
| 37 |
+
yield "⌛ กำลังโหลดโมเดล AI (ครั้งแรก)...", None, "⌛ กำลังโหลดโมเดล AI (ครั้งแรก)..."
|
| 38 |
+
print("Analyzer not loaded. Initializing NewsAnalyzer (lazy)...")
|
| 39 |
+
# นี่คือจุดที่จะโหลดโมเดล (ใช้เวลา 1-2 นาทีในครั้งแรก)
|
| 40 |
+
analyzer = NewsAnalyzer()
|
| 41 |
+
print("Analyzer loaded successfully.")
|
| 42 |
+
# --- END MODIFIED BLOCK ---
|
| 43 |
+
|
| 44 |
try:
|
| 45 |
+
yield "กำลังดึงข่าว...", None, "กำลังดึงข่าว..." # <-- แก้ไข Output ที่ 3 ด้วย
|
| 46 |
|
| 47 |
if search_type == "Latest News":
|
| 48 |
news_list = scraper.get_latest_news(max_articles=int(num_articles))
|
|
|
|
| 61 |
yield "❌ ไม่พบข่าว กรุณาลองใหม่อีกครั้ง", None, None
|
| 62 |
return
|
| 63 |
|
| 64 |
+
yield f"พบข่าว {len(news_list)} รายการ | กำลังวิเคราะห์...", None, f"พบข่าว {len(news_list)} รายการ | กำลังวิเคราะห์..."
|
| 65 |
|
| 66 |
results = analyzer.analyze_batch(news_list)
|
| 67 |
|
| 68 |
+
# (ส่วนที่เหลือของฟังก์ชันเหมือนเดิม)
|
| 69 |
total = len(results)
|
| 70 |
positive = sum(1 for r in results if r['sentiment'] == 'Positive')
|
| 71 |
negative = sum(1 for r in results if r['sentiment'] == 'Negative')
|
|
|
|
| 84 |
|
| 85 |
summary = f"""## 📊 สรุปผลการวิเคราะห์
|
| 86 |
**ภาพรวม:** {overall} | **คะแนนเฉลี่ย:** {avg_score:.2f}/1.0
|
|
|
|
| 87 |
### การกระจาย Sentiment
|
| 88 |
- 🟢 Positive: {positive} ({positive/total*100:.1f}%)
|
| 89 |
- 🔴 Negative: {negative} ({negative/total*100:.1f}%)
|
| 90 |
- 🟡 Neutral: {neutral} ({neutral/total*100:.1f}%)
|
| 91 |
+
---
|
| 92 |
### 📌 สรุปหัวข้อ (Themes)
|
| 93 |
"""
|
| 94 |
for theme, count in theme_counts.most_common():
|
| 95 |
summary += f"- **{theme}:** {count} รายการ ({count/total*100:.1f}%)\n"
|
| 96 |
|
| 97 |
+
summary += "\n---\n" # เพิ่มเส้นคั่น
|
| 98 |
+
|
| 99 |
summary += "\n### ⚡ สรุปผลกระทบ (Impact)\n"
|
| 100 |
for impact, count in impact_counts.most_common():
|
| 101 |
emoji = get_impact_color(impact)
|
| 102 |
summary += f"- {emoji} **{impact}:** {count} รายการ ({count/total*100:.1f}%)\n"
|
| 103 |
+
|
| 104 |
+
summary += "\n\n---\n\n## 📰 รายละเอียดแต่ละข่าว\n\n"
|
| 105 |
+
detailed_results = ""
|
|
|
|
|
|
|
| 106 |
|
| 107 |
for i, result in enumerate(results, 1):
|
| 108 |
s_emoji = get_sentiment_color(result['sentiment'])
|
| 109 |
i_emoji = get_impact_color(result.get('impact', 'N/A'))
|
| 110 |
|
|
|
|
| 111 |
detailed_results += f"""### {i}. {s_emoji} {result['title']}
|
| 112 |
**Theme:** {result.get('theme', 'N/A')} | **Impact:** {i_emoji} {result.get('impact', 'N/A')}
|
| 113 |
**Sentiment:** {result['sentiment']} | **Score:** {result['score']:.2f}
|
|
|
|
| 116 |
{result['summary'][:200]}{'...' if len(result['summary']) > 200 else ''}
|
| 117 |
[🔗 อ่านต่อ]({result['link']})
|
| 118 |
---"""
|
|
|
|
| 119 |
|
|
|
|
| 120 |
df_data = []
|
| 121 |
for result in results:
|
| 122 |
df_data.append({
|
|
|
|
| 138 |
error_msg = f"❌ เกิดข้อผิดพลาด: {str(e)}"
|
| 139 |
yield error_msg, None, error_msg
|
| 140 |
|
| 141 |
+
# --- (Interface Block: ไม่มีการเปลี่ยนแปลง) ---
|
| 142 |
with gr.Blocks(title="Yahoo Finance News Analyzer", theme=gr.themes.Soft()) as demo:
|
| 143 |
gr.Markdown("""
|
| 144 |
# 📈 Yahoo Finance News Analyzer
|