diff --git a/web_check.py b/web_check.py index 718ec83..4a86f4a 100644 --- a/web_check.py +++ b/web_check.py @@ -17,9 +17,11 @@ load_dotenv() ADMIN_USER = os.getenv("ADMIN_USER") ADMIN_PW = os.getenv("ADMIN_PW") NTFY_BASE = os.getenv("NTFY_BASE") +SIGNAL_NUMBER = os.getenv("SIGNAL_NUMBER") +SIGNAL_GROUPE_ID = os.getenv("SIGNAL_GROUPE_ID") DEBUG_LOG = os.getenv("DEBUG_LOG", "false").lower() == "true" MIN_RELEVANZ_SCORE = int(os.getenv("MIN_RELEVANZ_SCORE", "30")) -GEMINI_MODEL = "gemini-2.5-flash-lite" +GEMINI_MODEL = "gemini-3-flash-preview" GEMINI_SESSION = "1" NTFY = "true" SIGNAL = "true" @@ -63,7 +65,7 @@ conn.commit() def analysiere_mit_gemini(text): """KI-Analyse: Bewertet NUR den Text laut V8 (inkl. Begründung).""" sicherer_text = text[:5000] - anweisung = f"WICHTIG: Analysiere NUR den folgenden Text laut deinen Panda-Regeln (V8).\n\nTEXT:\n{sicherer_text}" + anweisung = f"WICHTIG: Analysiere NUR den folgenden Text laut deinen Regeln @gemini_instructions.md .\n\nTEXT:\n{sicherer_text}" befehl = ["gemini", "-m", GEMINI_MODEL, "-r", GEMINI_SESSION, "-p", anweisung] try: @@ -71,17 +73,34 @@ def analysiere_mit_gemini(text): befehl, capture_output=True, text=True, encoding="utf-8", timeout=300 ) antwort_roh = prozess.stdout.strip() + if DEBUG_LOG: + # Logge die rohe Ausgabe vom gemini CLI, um das Problem einzugrenzen + debug(f"Raw KI output: {antwort_roh}") + start = antwort_roh.find("{") ende = antwort_roh.rfind("}") + 1 if start != -1 and ende != -1: - return json.loads(antwort_roh[start:ende]) - return { - "relevant": False, - "relevanz_score": 0, - "begruendung_score": "Fehler: Kein JSON gefunden", - } + parsed_json = json.loads(antwort_roh[start:ende]) + if DEBUG_LOG: + # Logge das geparste JSON-Dictionary + debug(f"Parsed KI result: {parsed_json}") + return parsed_json + else: + # Falls keine gültige JSON-Struktur gefunden wird, logge dies und gib ein Fehler-Dictionary zurück + if DEBUG_LOG: + debug( + f"No valid JSON structure found in KI output. Raw output: {antwort_roh}" + ) + return { + "relevant": False, + "relevanz_score": 0, + "begruendung_score": "Fehler: Kein JSON gefunden", + } except Exception as e: print(f" [!] KI-Fehler: {e}") + if DEBUG_LOG: + # Logge die Exception für Debugging + debug(f"Exception during KI analysis: {e}") return { "relevant": False, "relevanz_score": 0, @@ -89,7 +108,54 @@ def analysiere_mit_gemini(text): } -def sende_public(titel, nachricht, klick_url, tags, priority=3): +def sende_signal(titel, nachricht, signal_number, signal_group_id): + """Sendet eine Benachrichtigung über Signal direkt vom lokalen System.""" + if not signal_number or not signal_group_id: + print( + " [!] Signal-Benachrichtigung kann nicht gesendet werden: SIGNAL_NUMBER oder SIGNAL_GROUPE_ID nicht gesetzt." + ) + return + + # Nachricht formatieren: Titel in der ersten Zeile, Nachricht in der nächsten + message_content = f"{titel}\n{nachricht}" + + # Befehl für die direkte Ausführung lokal + # Der Config-Pfad muss hier dem Pfad entsprechen, den Sie bei der Registrierung verwendet haben + cmd = [ + "signal-cli", + "--config", + "/root/.local/share/signal-cli", + "-u", + signal_number, + "send", + "-m", + message_content, + "-g", + signal_group_id, + ] + + debug(f"Executing Signal command locally: {' '.join(cmd)}") + + try: + process_result = subprocess.run( + cmd, capture_output=True, text=True, encoding="utf-8", timeout=30 + ) + + if process_result.returncode == 0: + print(" [SUCCESS] Signal-Nachricht erfolgreich gesendet.") + else: + print( + f" [!] Fehler beim Senden der Signal-Nachricht: {process_result.stderr}" + ) + sende_admin( + "Signal Sende-Fehler", + f"Fehler beim Senden der Signal-Nachricht: {process_result.stderr}", + ) + except Exception as e: + print(f" [!] Unerwarteter Fehler beim Senden der Signal-Nachricht: {e}") + + +def sende_ntfy(titel, nachricht, klick_url, tags, priority=3): """Sendet Push-Nachricht an ntfy.""" if NTFY == "true": if not NTFY_BASE: @@ -227,13 +293,26 @@ def verarbeite_website(url): debug( f"KI-Analyse-Ergebnis (JSON): {json.dumps(analyse, indent=2, ensure_ascii=False)}" ) - sende_public( - titel=analyse.get("titel", "Polit-Update"), - nachricht=analyse.get("nachricht", "Neu auf der Seite"), - klick_url=link, - priority=analyse.get("priority", 3), - tags=analyse.get("tags", "panda_face"), - ) + + # Sende NTFY Benachrichtigung, wenn konfiguriert + if NTFY == "true": + sende_ntfy( + titel=analyse.get("titel", "Polit-Update"), + nachricht=analyse.get("nachricht", "Neu auf der Seite"), + klick_url=link, + priority=analyse.get("priority", 3), + tags=analyse.get("tags", "panda_face"), + ) + + # Sende Signal Benachrichtigung, wenn konfiguriert + if SIGNAL == "true": + sende_signal( + titel=analyse.get("titel", "Polit-Update"), + nachricht=analyse.get("nachricht", "Neu auf der Seite"), + signal_number=SIGNAL_NUMBER, + signal_group_id=SIGNAL_GROUPE_ID, + ) + else: debug( f"Überspringe Artikel (Score {score} < {MIN_RELEVANZ_SCORE}). Begründung: {begruendung}" @@ -280,15 +359,32 @@ def verarbeite_website(url): f" [!] RELEVANT (Score: {score}): {analyse.get('titel')}" ) if DEBUG_LOG: - debug(f"KI-Analyse-Ergebnis (JSON): {json.dumps(analyse, indent=2, ensure_ascii=False)}") - debug(f"Begründung: {begruendung}") - sende_public( - analyse.get("titel"), - analyse.get("nachricht"), - target_url, - analyse.get("tags"), - analyse.get("priority"), - ) + debug( + f"KI-Analyse-Ergebnis (JSON): {json.dumps(analyse, indent=2, ensure_ascii=False)}" + ) + + # Sende NTFY Benachrichtigung, wenn konfiguriert + if NTFY == "true": + sende_ntfy( + titel=analyse.get("titel", "Polit-Update"), + nachricht=analyse.get( + "nachricht", "Neu auf der Seite" + ), + klick_url=target_url, + tags=analyse.get("tags"), + priority=analyse.get("priority"), + ) + + # Sende Signal Benachrichtigung, wenn konfiguriert + if SIGNAL == "true": + sende_signal( + titel=analyse.get("titel", "Polit-Update"), + nachricht=analyse.get( + "nachricht", "Neu auf der Seite" + ), + signal_number=SIGNAL_NUMBER, + signal_group_id=SIGNAL_GROUPE_ID, + ) else: debug( f"Überspringe Änderung (Score {score} < {MIN_RELEVANZ_SCORE}). Begründung: {begruendung}"