Écoute des notifications libnotify entrantes à l'aide de DBus

9

J'essaie de filtrer chaque notification via espeak. Cependant, je n'arrive pas à trouver un moyen d'obtenir le corps de notification à partir d'un script python, ou même quel signal_name écouter.

bus.add_signal_receiver(espeak,
                    dbus_interface="org.freedesktop.Notifications",
                    signal_name="??")

Essayer de google pour cela semble seulement donner des résultats impliquant la création de nouvelles notifications, donc je suis complètement perdu maintenant.

N'importe qui peut m'aider avec ça?

En bref, ce que je veux, c'est écouter les notifications entrantes en utilisant python, et obtenir l'attribut "body" de la notification.

manmachine
la source
1
Il semble qu'une notification ne produit pas de signal, c'est-à-dire qu'elle dbus-monitor "type='signal',interface='org.freedesktop.Notifications'"ne montre rien mais qu'elle dbus-monitor "interface='org.freedesktop.Notifications'"affiche des notifications (le type est 'method_call' et non 'signal').
jfs

Réponses:

11

Pour garder cela à jour: à partir de dbus 1.5, quelque chose d'un paramètre supplémentaire est requis lors de l'ajout d'une chaîne de correspondance avec bus.add_match_string_non_blockingpour s'assurer que nous recevons tout.

Le code résultant serait le suivant:

import glib
import dbus
from dbus.mainloop.glib import DBusGMainLoop

def notifications(bus, message):
    print [arg for arg in message.get_args_list()]

DBusGMainLoop(set_as_default=True)

bus = dbus.SessionBus()
bus.add_match_string_non_blocking("eavesdrop=true, interface='org.freedesktop.Notifications', member='Notify'")
bus.add_message_filter(notifications)

mainloop = glib.MainLoop()
mainloop.run()
joost
la source
Si je veux appeler une autre méthode dbus différente dans le filtre de notification, cela ne fonctionne pas. Tout ce que je reçois unable to connect to session bus: Operation was cancelled. Nous passons busau filtre.
Khurshid Alam
1
Sur mon installation Python (Python 3, Ubuntu), j'avais besoin from gi.repository import GLib as glibde faire ce travail.
Owen
6

Par notifications, vous entendez les "bulles OSD" que certains logiciels envoient, comme le changement de volume, le chat IM, etc.? Vous voulez créer un programme python pour les capturer?

Eh bien, Ask Ubuntu n'est pas l'AQ d'un programmeur, et le développement de logiciels est un peu au-delà de la portée, mais voici un petit code que j'ai fait capturer des bulles de notification:

import glib
import dbus
from dbus.mainloop.glib import DBusGMainLoop

def notifications(bus, message):
    if message.get_member() == "Notify":
        print [arg for arg in message.get_args_list()]

DBusGMainLoop(set_as_default=True)

bus = dbus.SessionBus()
bus.add_match_string_non_blocking("interface='org.freedesktop.Notifications'")
bus.add_message_filter(notifications)

mainloop = glib.MainLoop()
mainloop.run()

Laissez cela s'exécuter dans un terminal, puis ouvrez une autre fenêtre de terminal et testez-le:

notify-send --icon=/usr/share/pixmaps/debian-logo.png "My Title" "Some text body"

Et le programme affichera ceci:

[dbus.String(u'notify-send'), dbus.UInt32(0L), dbus.String(u'/usr/share/pixmaps/debian-logo.png'), dbus.String(u'My Title'), dbus.String(u'Some text body'),...

Comme vous l'avez peut-être deviné, message.get_args_list()[0]est l'expéditeur, [2] pour l'icône, [3] pour le résumé et [4] pour le corps du texte.

Pour la signification des autres champs, consultez les documents officiels de spécifications

MestreLion
la source
Il semble que cela ne fonctionne plus à partir du 16/04. La réponse de Joost ci-dessous le résout.
Catskul
3

J'ai eu du mal à faire fonctionner les autres exemples, mais j'y suis finalement arrivé. Voici un exemple de travail:

import glib
import dbus
from dbus.mainloop.glib import DBusGMainLoop

def print_notification(bus, message):
  keys = ["app_name", "replaces_id", "app_icon", "summary",
          "body", "actions", "hints", "expire_timeout"]
  args = message.get_args_list()
  if len(args) == 8:
    notification = dict([(keys[i], args[i]) for i in range(8)])
    print notification["summary"], notification["body"]

loop = DBusGMainLoop(set_as_default=True)
session_bus = dbus.SessionBus()
session_bus.add_match_string("type='method_call',interface='org.freedesktop.Notifications',member='Notify',eavesdrop=true")
session_bus.add_message_filter(print_notification)

glib.MainLoop().run()

Si vous souhaitez voir un exemple de travail plus détaillé, je vous recommande de consulter Notifications.py dans le projet recent_notifications .

kzar
la source