Прослушивание входящих уведомлений libnotify с использованием DBus

9

Я пытаюсь отфильтровать каждое уведомление через espeak. Однако я не могу найти способ получить тело уведомления из скрипта Python или даже какое имя_сигнала для прослушивания.

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

Попытка Google для этого только, кажется, дает результаты, связанные с созданием новых уведомлений, так что я совершенно потерян.

Кто-нибудь может мне помочь с этим?

Короче говоря, я хочу прослушивать входящие уведомления, используя python, и получать атрибут «body» уведомления.

manmachine
источник
1
Кажется, что уведомление не генерирует сигнал, т. Е. Ничего не dbus-monitor "type='signal',interface='org.freedesktop.Notifications'"показывает, а dbus-monitor "interface='org.freedesktop.Notifications'"показывает уведомления (тип «method_call», а не «signal»).
JFS

Ответы:

11

Чтобы поддерживать это в актуальном состоянии: начиная с версии dbus 1.5. При добавлении строки совпадения требуется дополнительный параметр, bus.add_match_string_non_blockingчтобы убедиться, что мы все получили.

Результирующий код будет следующим:

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
источник
Если я хочу вызвать другой метод dbus внутри фильтра уведомлений, он не работает. Все, что я получаю unable to connect to session bus: Operation was cancelled. Переходим busк фильтру.
Хуршид Алам
1
В моей установке Python (Python 3, Ubuntu) мне нужно from gi.repository import GLib as glibбыло сделать эту работу.
Оуэн
6

Под уведомлениями вы имеете в виду «пузыри OSD», которые посылает какое-либо программное обеспечение, например, изменение громкости, чат в чате и т. Д.? Вы хотите создать программу на Python, чтобы захватить их?

Ну, Ask Ubuntu - это не QA для программиста, и разработка программного обеспечения немного выходит за рамки, но вот небольшой код, который я сделал для захвата уведомлений:

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

Оставьте это работающим в терминале, затем откройте другое окно терминала и проверьте его:

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

И программа выведет это:

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

Как вы уже догадались, message.get_args_list()[0]это отправитель, [2] для значка, [3] для сводки и [4] для основного текста.

Для значения других полей, проверьте официальные документы спецификации

MestreLion
источник
Похоже, он больше не работает с 16.04 или раньше. Ответ Джуста ниже это исправляет.
Catskul
3

У меня были проблемы с тем, чтобы заставить работать какие-либо другие примеры, но в конце концов я попал туда. Вот рабочий пример:

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

Если вы хотите увидеть более подробный рабочий пример, я рекомендую посмотреть на Notifications.py в проекте недавних уведомлений .

kzar
источник