File size: 6,940 Bytes
fd369a3
 
 
 
 
 
 
 
 
 
03786c1
fd369a3
164da59
fd369a3
 
 
8135f41
164da59
8135f41
 
fd369a3
bd3d2e8
fd369a3
164da59
fd369a3
03786c1
 
771fc8b
 
 
 
 
 
fd369a3
771fc8b
fd369a3
 
 
771fc8b
03786c1
164da59
bd3d2e8
164da59
8135f41
 
 
 
bd3d2e8
771fc8b
164da59
bd3d2e8
771fc8b
164da59
 
 
771fc8b
164da59
771fc8b
 
 
 
 
164da59
771fc8b
 
03786c1
164da59
771fc8b
03786c1
 
 
771fc8b
 
 
164da59
771fc8b
bd3d2e8
771fc8b
 
bd3d2e8
771fc8b
 
bd3d2e8
771fc8b
 
164da59
 
 
 
771fc8b
 
 
 
164da59
 
 
 
 
 
 
771fc8b
 
164da59
771fc8b
8135f41
771fc8b
164da59
03786c1
 
164da59
771fc8b
 
164da59
 
 
 
03786c1
 
 
771fc8b
164da59
03786c1
 
 
 
da3fca1
 
 
03786c1
 
 
164da59
03786c1
 
771fc8b
fd369a3
771fc8b
164da59
 
 
 
771fc8b
164da59
 
771fc8b
fd369a3
771fc8b
 
164da59
 
 
 
 
 
fd369a3
164da59
771fc8b
fd369a3
164da59
 
 
 
771fc8b
 
164da59
771fc8b
164da59
 
 
771fc8b
164da59
 
 
 
 
 
 
771fc8b
164da59
771fc8b
164da59
 
 
 
771fc8b
 
fd369a3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import gradio as gr
import requests
import pandas as pd
from transformers import pipeline
import torch
import time
import threading
import os
from datetime import datetime, timezone
from huggingface_hub import HfApi
import plotly.graph_objects as go

# --- KONFIGŪRACIJA ---
MODEL_NAME = "ProsusAI/finbert"
TARGET_DATASET = "Vycka12/Base"
HF_TOKEN = os.environ.get("HF_TOKEN")

# API Raktas ir URL (Griežtai nustatyti)
CRYPTOPANIC_API_KEY = "6c0f988f9e33170ccd183c6a14b34e8c2ad0867f"
CRYPTOPANIC_URL = "https://cryptopanic.com/api/developer/v2/posts/"

# Globalūs kintamieji
news_buffer = []
stats = {"bullish": 0, "bearish": 0, "neutral": 0, "overall": "Inicijuojama...", "status": "Startuoja..."}

# Krauname AI
print("⌛ Kraunamas AI modelis...")
try:
    sentiment_pipeline = pipeline("sentiment-analysis", model=MODEL_NAME)
    print("✅ AI paruoštas.")
except Exception as e:
    print(f"❌ AI ERROR: {e}")
    sentiment_pipeline = None

class SentimentSystem:
    def __init__(self):
        self.api = HfApi(token=HF_TOKEN)

    def fetch_and_analyze(self):
        global news_buffer, stats
        stats["status"] = "Gaunamos naujienos..."
        
        # Pataisyti parametrai - tik būtiniausi
        params = {
            "auth_token": CRYPTOPANIC_API_KEY,
            "kind": "news"
        }

        try:
            resp = requests.get(CRYPTOPANIC_URL, params=params, timeout=20)
            
            if resp.status_code == 200:
                data = resp.json()
                raw_news = data.get("results", [])
                
                if not raw_news:
                    stats["status"] = "⚠️ API grąžino tuščią sąrašą."
                    return
                
                temp_news = []
                pos, neg, neut = 0, 0, 0
                
                for item in raw_news:
                    title = item.get("title", "")
                    if not title: continue
                    
                    # AI Analizė
                    if sentiment_pipeline:
                        result = sentiment_pipeline(title[:512])[0]
                        label = result['label']
                        score = result['score']
                    else:
                        label, score = 'neutral', 0.5

                    # Emocijos
                    if label == 'positive': 
                        status, emo = "🟢 BULLISH", "🚀"
                        pos += 1
                    elif label == 'negative': 
                        status, emo = "🔴 BEARISH", "📉"
                        neg += 1
                    else: 
                        status, emo = "⚪ NEUTRAL", "➖"
                        neut += 1

                    # Laikas
                    pub_time = item.get("published_at", "")[:16].replace("T", " ")
                    
                    temp_news.append([emo, status, title, f"{round(score*100)}%", pub_time])

                stats["bullish"] = pos
                stats["bearish"] = neg
                stats["neutral"] = neut
                
                total = pos + neg + neut
                if total > 0:
                    ratio = (pos - neg) / total
                    if ratio > 0.2: stats["overall"] = "OPTIMIZMAS 📈"
                    elif ratio < -0.2: stats["overall"] = "BAIMĖ 📉"
                    else: stats["overall"] = "NEUTRALU ⚖️"
                
                news_buffer = temp_news
                stats["status"] = f"Atnaujinta: {datetime.now().strftime('%H:%M:%S')}"
            else:
                stats["status"] = f"❌ API Klaida: {resp.status_code}"
        except Exception as e:
            stats["status"] = f"❌ Klaida: {str(e)}"

    def create_gauge(self):
        total = stats["bullish"] + stats["bearish"] + stats["neutral"]
        val = 50
        if total > 0:
            # Formulė: 50 + (teigiami - neigiami) * koeficientas
            # Jei visi teigiami -> 100, visi neigiami -> 0
            net_sentiment = (stats["bullish"] - stats["bearish"]) / total
            val = 50 + (net_sentiment * 50)
        
        fig = go.Figure(go.Indicator(
            mode = "gauge+number",
            value = val,
            title = {'text': f"Rinkos Emocija: {stats['overall']}"},
            gauge = {
                'axis': {'range': [0, 100]},
                'bar': {'color': "black"},
                'steps': [
                    {'range': [0, 40], 'color': "#ff4b4b"},
                    {'range': [40, 60], 'color': "#ffffb2"},
                    {'range': [60, 100], 'color': "#00cc96"}
                ],
            }
        ))
        fig.update_layout(height=300, margin=dict(l=20, r=20, t=50, b=20))
        return fig

sys_analyzer = SentimentSystem()

def update_loop():
    # Pirmas paleidimas po 10 sek
    time.sleep(10)
    sys_analyzer.fetch_and_analyze()
    
    while True:
        # Atnaujiname kas 4 valandas (taupome limitą)
        time.sleep(14400)
        sys_analyzer.fetch_and_analyze()

def get_ui_data():
    gauge = sys_analyzer.create_gauge()
    cols = ["Emoji", "Verdiktas", "Antraštė", "Pasitikėjimas", "Laikas"]
    
    if not news_buffer:
        df = pd.DataFrame([["-", "-", "Kraunama...", "-", "-"]], columns=cols)
    else:
        df = pd.DataFrame(news_buffer, columns=cols)
    
    status_text = f"### 📊 Statistika\n**Būsena:** {stats['status']}\n**Geros:** {stats['bullish']} | **Blogos:** {stats['bearish']} | **Viso:** {stats['bullish']+stats['bearish']+stats['neutral']}"
    return gauge, df, status_text

# --- GRADIO UI ---
with gr.Blocks(title="Sentiment AI", theme=gr.themes.Soft()) as demo:
    gr.Markdown("# 🧠 Sentiment AI Analyzer")
    gr.Markdown("Analizuoja realias crypto naujienas naudodamas ProsusAI FinBERT modelį.")
    
    with gr.Row():
        with gr.Column():
            gauge_output = gr.Plot(label="Nuotaika")
        with gr.Column():
            status_output = gr.Markdown("Laukiama duomenų...")
            refresh_btn = gr.Button("🔄 Atnaujinti Dabar", variant="primary")

    gr.Markdown("### 📰 Naujienų srautas ir AI vertinimas")
    table_output = gr.Dataframe(interactive=False)

    # Eventai
    refresh_btn.click(fn=sys_analyzer.fetch_and_analyze).then(
        fn=get_ui_data, outputs=[gauge_output, table_output, status_output]
    )
    
    # Auto-start
    threading.Thread(target=update_loop, daemon=True).start()
    
    # UI atnaujinimas (tik vaizdo, ne duomenų siurbimo)
    demo.load(get_ui_data, outputs=[gauge_output, table_output, status_output])
    gr.Timer(5).tick(get_ui_data, outputs=[gauge_output, table_output, status_output])

if __name__ == "__main__":
    demo.launch(server_name="0.0.0.0", server_port=7860)