""" Offline-Konfiguration für MYP-System =================================== Konfiguriert das System für den Offline-Betrieb ohne Internetverbindung. Stellt Fallback-Lösungen für internetabhängige Funktionen bereit. """ import os import logging from typing import Dict, List, Optional from utils.logging_config import get_logger logger = get_logger("offline_config") # ===== OFFLINE-MODUS KONFIGURATION ===== OFFLINE_MODE = True # Produktionseinstellung - System läuft offline # ===== OFFLINE-KOMPATIBILITÄT PRÜFUNGEN ===== def check_internet_connectivity() -> bool: """ Prüft ob eine Internetverbindung verfügbar ist. Im Offline-Modus gibt immer False zurück. Returns: bool: True wenn Internet verfügbar, False im Offline-Modus """ if OFFLINE_MODE: return False # In einem echten Online-Modus könnte hier eine echte Prüfung stehen try: import socket socket.create_connection(("8.8.8.8", 53), timeout=3) return True except OSError: return False def is_oauth_available() -> bool: """ Prüft ob OAuth-Funktionalität verfügbar ist. Returns: bool: False im Offline-Modus """ return not OFFLINE_MODE and check_internet_connectivity() def is_email_sending_available() -> bool: """ Prüft ob E-Mail-Versand verfügbar ist. Returns: bool: False im Offline-Modus (nur Logging) """ return not OFFLINE_MODE and check_internet_connectivity() def is_cdn_available() -> bool: """ Prüft ob CDN-Links verfügbar sind. Returns: bool: False im Offline-Modus (lokale Fallbacks verwenden) """ return not OFFLINE_MODE and check_internet_connectivity() # ===== CDN FALLBACK-KONFIGURATION ===== CDN_FALLBACKS = { # Chart.js CDN -> Lokale Datei "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.0/chart.min.js": "/static/js/charts/chart.min.js", "https://cdn.jsdelivr.net/npm/chart.js": "/static/js/charts/chart.min.js", # FontAwesome (bereits lokal verfügbar) "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css": "/static/fontawesome/css/all.min.css", # Weitere CDN-Fallbacks können hier hinzugefügt werden } def get_local_asset_path(cdn_url: str) -> Optional[str]: """ Gibt den lokalen Pfad für eine CDN-URL zurück. Args: cdn_url: URL des CDN-Assets Returns: str: Lokaler Pfad oder None wenn kein Fallback verfügbar """ return CDN_FALLBACKS.get(cdn_url) def replace_cdn_links(html_content: str) -> str: """ Ersetzt CDN-Links durch lokale Fallbacks im HTML-Inhalt. Args: html_content: HTML-Inhalt mit CDN-Links Returns: str: HTML-Inhalt mit lokalen Links """ if not OFFLINE_MODE: return html_content modified_content = html_content for cdn_url, local_path in CDN_FALLBACKS.items(): if cdn_url in modified_content: modified_content = modified_content.replace(cdn_url, local_path) logger.info(f"🔄 CDN-Link ersetzt: {cdn_url} -> {local_path}") return modified_content # ===== SECURITY POLICY ANPASSUNGEN ===== def get_offline_csp_policy() -> Dict[str, List[str]]: """ Gibt CSP-Policy für Offline-Modus zurück. Entfernt externe CDN-Domains aus der Policy. Returns: Dict: CSP-Policy ohne externe Domains """ if not OFFLINE_MODE: # Online-Modus: Originale Policy mit CDNs return { "script-src": [ "'self'", "'unsafe-inline'", "'unsafe-eval'", "https://cdn.jsdelivr.net", "https://unpkg.com", "https://cdnjs.cloudflare.com" ], "style-src": [ "'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://cdn.jsdelivr.net" ], "font-src": [ "'self'", "https://fonts.gstatic.com" ] } else: # Offline-Modus: Nur lokale Ressourcen return { "script-src": [ "'self'", "'unsafe-inline'", "'unsafe-eval'" ], "style-src": [ "'self'", "'unsafe-inline'" ], "font-src": [ "'self'" ], "img-src": [ "'self'", "data:" ] } # ===== OFFLINE-MODUS HILFSFUNKTIONEN ===== def log_offline_mode_status(): """Loggt den aktuellen Offline-Modus Status.""" if OFFLINE_MODE: logger.info("🌐 System läuft im OFFLINE-MODUS") logger.info(" ❌ OAuth deaktiviert") logger.info(" ❌ E-Mail-Versand deaktiviert (nur Logging)") logger.info(" ❌ CDN-Links werden durch lokale Dateien ersetzt") logger.info(" ✅ Alle Kernfunktionen verfügbar") else: logger.info("🌐 System läuft im ONLINE-MODUS") logger.info(" ✅ OAuth verfügbar") logger.info(" ✅ E-Mail-Versand verfügbar") logger.info(" ✅ CDN-Links verfügbar") def get_feature_availability() -> Dict[str, bool]: """ Gibt die Verfügbarkeit verschiedener Features zurück. Returns: Dict: Feature-Verfügbarkeit """ return { "oauth": is_oauth_available(), "email_sending": is_email_sending_available(), "cdn_resources": is_cdn_available(), "offline_mode": OFFLINE_MODE, "core_functionality": True, # Kernfunktionen immer verfügbar "printer_control": True, # Drucker-Steuerung immer verfügbar "job_management": True, # Job-Verwaltung immer verfügbar "user_management": True # Benutzer-Verwaltung immer verfügbar } # ===== STARTUP-FUNKTIONEN ===== def initialize_offline_mode(): """Initialisiert den Offline-Modus beim System-Start.""" log_offline_mode_status() if OFFLINE_MODE: logger.info("🔧 Initialisiere Offline-Modus-Anpassungen...") # Prüfe ob lokale Chart.js verfügbar ist chart_js_path = "static/js/charts/chart.min.js" if not os.path.exists(chart_js_path): logger.warning(f"⚠️ Lokale Chart.js nicht gefunden: {chart_js_path}") logger.warning(" Diagramme könnten nicht funktionieren") else: logger.info(f"✅ Lokale Chart.js gefunden: {chart_js_path}") # Prüfe weitere lokale Assets fontawesome_path = "static/fontawesome/css/all.min.css" if not os.path.exists(fontawesome_path): logger.warning(f"⚠️ Lokale FontAwesome nicht gefunden: {fontawesome_path}") else: logger.info(f"✅ Lokale FontAwesome gefunden: {fontawesome_path}") logger.info("✅ Offline-Modus erfolgreich initialisiert") # Beim Import automatisch initialisieren initialize_offline_mode()