"""Anruf-Benachrichtigung - KDE Plasma Notification mit Annehmen/Ablehnen.""" try: import dbus DBUS_VERFUEGBAR = True except ImportError: DBUS_VERFUEGBAR = False class AnrufBenachrichtigung: """KDE-Benachrichtigung mit Action-Buttons über D-Bus. Nutzt org.freedesktop.Notifications für native KDE Plasma Benachrichtigungen mit Annehmen/Ablehnen-Buttons. """ def __init__(self): self._notification_id = 0 self._callback_annehmen = None self._callback_ablehnen = None self._bus = None self._interface = None if not DBUS_VERFUEGBAR: return try: self._bus = dbus.SessionBus() proxy = self._bus.get_object( "org.freedesktop.Notifications", "/org/freedesktop/Notifications", ) self._interface = dbus.Interface( proxy, "org.freedesktop.Notifications" ) # Signal-Handler für Button-Klicks self._bus.add_signal_receiver( self._on_action, signal_name="ActionInvoked", dbus_interface="org.freedesktop.Notifications", ) # Signal wenn Notification geschlossen wird self._bus.add_signal_receiver( self._on_closed, signal_name="NotificationClosed", dbus_interface="org.freedesktop.Notifications", ) except dbus.DBusException: self._interface = None def anruf_anzeigen(self, anrufer, callback_annehmen=None, callback_ablehnen=None): """Benachrichtigung für eingehenden Anruf anzeigen. Args: anrufer: Anrufer-Nummer oder Name callback_annehmen: Funktion bei Klick auf "Annehmen" callback_ablehnen: Funktion bei Klick auf "Ablehnen" """ if not self._interface: return self._callback_annehmen = callback_annehmen self._callback_ablehnen = callback_ablehnen try: self._notification_id = self._interface.Notify( "SIP Softphone", # App-Name 0, # Replaces-ID (0 = neue Notification) "call-start", # Icon (Freedesktop-Icon-Name) f"Eingehender Anruf", # Titel f"Anruf von {anrufer}", # Text ["annehmen", "Annehmen", "ablehnen", "Ablehnen"], # Actions { "urgency": dbus.Byte(2), # Critical - bleibt stehen "category": "im.received", "desktop-entry": "sipwebapp", }, 0, # Timeout: 0 = kein Auto-Close (Critical) ) except dbus.DBusException: pass def schliessen(self): """Benachrichtigung schließen (z.B. wenn Anruf endet).""" if self._interface and self._notification_id: try: self._interface.CloseNotification(self._notification_id) except dbus.DBusException: pass self._notification_id = 0 self._callback_annehmen = None self._callback_ablehnen = None def _on_action(self, notif_id, action_id): """D-Bus Signal: Button wurde geklickt.""" if notif_id != self._notification_id: return if action_id == "annehmen" and self._callback_annehmen: self._callback_annehmen() elif action_id == "ablehnen" and self._callback_ablehnen: self._callback_ablehnen() self._notification_id = 0 def _on_closed(self, notif_id, reason): """D-Bus Signal: Notification wurde geschlossen.""" if notif_id == self._notification_id: self._notification_id = 0