"""Single Source of Truth für Quellen-Kategorien und -Typen. Wird vom Backend über GET /api/sources/meta exportiert. Frontend (sources.js, source-health.js, dashboard.html) lädt diese beim Init und befüllt damit Filter-Dropdowns und Label-Lookups. """ from typing import TypedDict class CategoryEntry(TypedDict): key: str label: str class TypeEntry(TypedDict): key: str label: str SOURCE_CATEGORIES: list[CategoryEntry] = [ {"key": "nachrichtenagentur", "label": "Nachrichtenagentur"}, {"key": "oeffentlich-rechtlich", "label": "Öffentlich-Rechtlich"}, {"key": "qualitaetszeitung", "label": "Qualitätszeitung"}, {"key": "behoerde", "label": "Behörde"}, {"key": "fachmedien", "label": "Fachmedien"}, {"key": "think-tank", "label": "Think-Tank"}, {"key": "international", "label": "International"}, {"key": "regional", "label": "Regional"}, {"key": "boulevard", "label": "Boulevard"}, {"key": "sonstige", "label": "Sonstige"}, {"key": "cybercrime", "label": "Cybercrime / Hacktivismus"}, {"key": "cybercrime-leaks", "label": "Cybercrime / Leaks"}, {"key": "ukraine-russland-krieg", "label": "Ukraine-Russland-Krieg"}, {"key": "irankonflikt", "label": "Irankonflikt"}, {"key": "osint-international", "label": "OSINT International"}, {"key": "extremismus-deutschland", "label": "Extremismus Deutschland"}, {"key": "russische-staatspropaganda", "label": "Russische Staatspropaganda"}, {"key": "russische-opposition", "label": "Russische Opposition / Exilmedien"}, {"key": "syrien-nahost", "label": "Syrien / Nahost"}, ] SOURCE_TYPES: list[TypeEntry] = [ {"key": "rss_feed", "label": "RSS-Feed"}, {"key": "web_source", "label": "Webquelle"}, {"key": "telegram_channel", "label": "Telegram-Kanal"}, {"key": "podcast_feed", "label": "Podcast-Feed"}, {"key": "excluded", "label": "Ausgeschlossen"}, ] def get_meta() -> dict: """Vollständige Meta-Information für Frontend-Konsumenten.""" return { "categories": SOURCE_CATEGORIES, "types": SOURCE_TYPES, } def category_label(key: str) -> str: """Lookup: Kategorie-Key -> Label. Fallback: Key selbst.""" for c in SOURCE_CATEGORIES: if c["key"] == key: return c["label"] return key def type_label(key: str) -> str: """Lookup: Typ-Key -> Label. Fallback: Key selbst.""" for t in SOURCE_TYPES: if t["key"] == key: return t["label"] return key