web-dev-qa-db-fra.com

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

Je tente de filtrer chaque notification à travers espeak. Cependant, je n'arrive pas à trouver le moyen d'obtenir le corps de la notification à partir d'un script python, ni même le nom du signal à é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.

Quelqu'un peut m'aider avec ça?

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

9
manmachine

Pour garder cela à jour: à partir de dbus 1.5, un paramètre supplémentaire est requis lors de l'ajout d'une chaîne de correspondance avec bus.add_match_string_non_blocking pour 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()
11
joost

Par notifications, vous entendez les "bulles OSD" envoyées par certains logiciels, telles que la modification du volume, la discussion en ligne, etc.? Vous voulez créer un programme python pour les capturer?

Ask Ubuntu n’est pas l’assurance qualité du programmeur, et le développement logiciel dépasse un peu la portée, mais voici un petit code que j’ai capturé:

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-le en cours d'exécution 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 va sortir 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, cochez la documentation officielle de la spécification

6
MestreLion

J'ai eu du mal à faire fonctionner l'un des autres exemples, mais je suis arrivé à la fin. 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 voulez voir un exemple de travail plus détaillé, je vous recommande de regarder Notifications.py dans les recent_notifications projet.

3
kzar