- researcher.py/factchecker.py: TimeoutError wird nach oben durchgereicht statt vom breiten except Exception geschluckt zu werden - orchestrator.py: Built-in TimeoutError zu TRANSIENT_ERRORS hinzugefuegt (war nur asyncio.TimeoutError, aber claude_client wirft TimeoutError) - config.py: CLAUDE_TIMEOUT von 300s auf 420s erhoeht Vorher: Timeout fuehrte zu "0 Artikel" ohne Retry (8 Timeouts seit 28.02.) Nachher: Timeout loest bis zu 3 Retries aus (sofort, +2min, +5min) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
75 Zeilen
3.3 KiB
Python
75 Zeilen
3.3 KiB
Python
"""Konfiguration für den OSINT Lagemonitor."""
|
|
import os
|
|
from zoneinfo import ZoneInfo
|
|
|
|
# Zeitzone für alle Anwendungs-Timestamps (DB, Logs, UI)
|
|
TIMEZONE = ZoneInfo("Europe/Berlin")
|
|
|
|
# Pfade
|
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
DATA_DIR = os.path.join(BASE_DIR, "data")
|
|
LOG_DIR = os.path.join(BASE_DIR, "logs")
|
|
STATIC_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "static")
|
|
DB_PATH = os.path.join(DATA_DIR, "osint.db")
|
|
|
|
# JWT
|
|
JWT_SECRET = os.environ.get("JWT_SECRET")
|
|
if not JWT_SECRET:
|
|
raise RuntimeError("JWT_SECRET Umgebungsvariable muss gesetzt sein")
|
|
JWT_ALGORITHM = "HS256"
|
|
JWT_EXPIRE_HOURS = 24
|
|
|
|
# Claude CLI
|
|
CLAUDE_PATH = os.environ.get("CLAUDE_PATH", "/home/claude-dev/.claude/local/claude")
|
|
CLAUDE_TIMEOUT = 420 # Sekunden (Claude mit WebSearch braucht oft 2-4 Min)
|
|
# Claude Modelle
|
|
CLAUDE_MODEL_FAST = "claude-haiku-4-5-20251001" # Für einfache Aufgaben (Feed-Selektion)
|
|
|
|
# Ausgabesprache (Lagebilder, Faktenchecks, Zusammenfassungen)
|
|
OUTPUT_LANGUAGE = "Deutsch"
|
|
|
|
# RSS-Feeds (Fallback, primär aus DB geladen)
|
|
RSS_FEEDS = {
|
|
"deutsch": [
|
|
{"name": "tagesschau", "url": "https://www.tagesschau.de/index~rss2.xml"},
|
|
{"name": "ZDF heute", "url": "https://www.zdf.de/rss/zdf/nachrichten"},
|
|
{"name": "Spiegel", "url": "https://www.spiegel.de/schlagzeilen/index.rss"},
|
|
{"name": "Zeit", "url": "https://newsfeed.zeit.de/index"},
|
|
{"name": "FAZ", "url": "https://www.faz.net/rss/aktuell/"},
|
|
{"name": "Süddeutsche", "url": "https://rss.sueddeutsche.de/rss/Topthemen"},
|
|
{"name": "NZZ", "url": "https://www.nzz.ch/recent.rss"},
|
|
{"name": "Deutsche Welle", "url": "https://rss.dw.com/rdf/rss-de-all"},
|
|
],
|
|
"international": [
|
|
{"name": "Reuters", "url": "https://www.reutersagency.com/feed/"},
|
|
{"name": "AP News", "url": "https://rsshub.app/apnews/topics/apf-topnews"},
|
|
{"name": "BBC World", "url": "https://feeds.bbci.co.uk/news/world/rss.xml"},
|
|
{"name": "Al Jazeera", "url": "https://www.aljazeera.com/xml/rss/all.xml"},
|
|
{"name": "France24", "url": "https://www.france24.com/en/rss"},
|
|
],
|
|
"behoerden": [
|
|
{"name": "BMI", "url": "https://www.bmi.bund.de/SiteGlobals/Functions/RSSFeed/BMI/RSSNewsfeed/RSSNewsfeed_Nachrichten.xml"},
|
|
{"name": "Europol", "url": "https://www.europol.europa.eu/rss.xml"},
|
|
],
|
|
}
|
|
|
|
# Ausgeschlossene Quellen (Fallback, primär aus DB geladen)
|
|
EXCLUDED_SOURCES = ["bild.de", "bild", "twitter", "x.com", "facebook", "instagram", "tiktok", "reddit"]
|
|
|
|
# SMTP (E-Mail-Versand für Magic Links und Einladungen)
|
|
SMTP_HOST = os.environ.get("SMTP_HOST", "")
|
|
SMTP_PORT = int(os.environ.get("SMTP_PORT", "587"))
|
|
SMTP_USER = os.environ.get("SMTP_USER", "")
|
|
SMTP_PASSWORD = os.environ.get("SMTP_PASSWORD", "")
|
|
SMTP_FROM_EMAIL = os.environ.get("SMTP_FROM_EMAIL", "noreply@intelsight.de")
|
|
SMTP_FROM_NAME = os.environ.get("SMTP_FROM_NAME", "AegisSight Monitor")
|
|
SMTP_USE_TLS = os.environ.get("SMTP_USE_TLS", "true").lower() == "true"
|
|
|
|
# Quellenvielfalt: Domain-Begrenzungen
|
|
MAX_FEEDS_PER_DOMAIN = 3 # Max. Feeds pro Domain bei Feed-Selektion
|
|
MAX_ARTICLES_PER_DOMAIN_RSS = 10 # Max. Artikel pro Domain nach RSS-Fetch
|
|
|
|
# Magic Link
|
|
MAGIC_LINK_EXPIRE_MINUTES = 10
|
|
MAGIC_LINK_BASE_URL = os.environ.get("MAGIC_LINK_BASE_URL", "https://osint.intelsight.de")
|