Ascolto delle notifiche libnotify in arrivo tramite DBus


9

Sto tentando di filtrare ogni notifica tramite espeak. Tuttavia, non riesco a trovare un modo per ottenere il corpo della notifica da uno script Python o anche quale nome_del segnale ascoltare.

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

Cercare su Google per questo sembra solo produrre risultati che implicano la creazione di nuove notifiche, quindi ora mi sono completamente perso.

Qualcuno può aiutarmi con questo?

In breve, quello che voglio è ascoltare le notifiche in arrivo utilizzando Python e ottenere l'attributo "body" della notifica.


1
Sembra che una notifica non produca un segnale, cioè dbus-monitor "type='signal',interface='org.freedesktop.Notifications'"non mostri nulla ma dbus-monitor "interface='org.freedesktop.Notifications'"mostri notifiche (il tipo è 'method_call' non 'signal').
jfs,

Risposte:


11

Per tenerlo aggiornato: da dbus 1.5 è necessario un parametro aggiuntivo quando si aggiunge una stringa di corrispondenza con bus.add_match_string_non_blockingper assicurarsi che riceviamo tutto.

Il codice risultante sarebbe il seguente:

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()

Se voglio chiamare un altro metodo dbus diverso all'interno del filtro di notifica, non funziona. Tutto quello che ottengo unable to connect to session bus: Operation was cancelled. Stiamo passando busal filtro.
Khurshid Alam,

1
Nella mia installazione di Python (Python 3, Ubuntu) avevo bisogno from gi.repository import GLib as glibdi farlo funzionare.
Owen il

6

Per notifiche intendi le "bolle OSD" che alcuni software inviano, come la modifica del volume, la chat IM, ecc.? Vuoi creare un programma Python per catturarli?

Bene, Ask Ubuntu non è un QA di un programmatore e lo sviluppo del software è un po 'oltre lo scopo, ma ecco un piccolo codice che ho fatto per catturare le bolle di notifica:

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()

Lasciare questo in esecuzione in un terminale, quindi aprire un'altra finestra del terminale e testarlo:

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

E il programma produrrà questo:

[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'),...

Come avrai intuito, message.get_args_list()[0]è il mittente, [2] per l'icona, [3] per il riepilogo e [4] per il testo del corpo.

Per il significato degli altri campi, consultare i documenti ufficiali sulle specifiche


Sembra che non funzioni più a partire dal 16.04 o prima. La risposta di Joost qui sotto lo risolve.
Catskul,

3

Ho avuto problemi a far funzionare effettivamente uno degli altri esempi, ma alla fine ci sono arrivato. Ecco un esempio funzionante:

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()

Se vuoi vedere un esempio di lavoro più dettagliato, ti consiglio di dare un'occhiata a Notify.py nel progetto recent_notifications .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.