Прослуховування вхідних повідомлень libnotify за допомогою DBus


9

Я намагаюся фільтрувати кожне сповіщення за допомогою espeak. Однак, я не можу знайти спосіб отримати орган сповіщення зі сценарію python або навіть яке саме ім'я_для_слухати.

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

Спроба google для цього лише здається, що дає результати, пов’язані зі створенням нових сповіщень, тому я зараз повністю втрачена.

Хтось може мені в цьому допомогти?

Коротше кажучи, я хочу прослухати вхідні сповіщення за допомогою python та отримати атрибут "body" сповіщення.


1
Здається, сповіщення не видає сигнал, тобто dbus-monitor "type='signal',interface='org.freedesktop.Notifications'"не показує нічого, але не dbus-monitor "interface='org.freedesktop.Notifications'"показує сповіщення (тип "method_call", а не "сигнал").
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()

Якщо я хочу викликати інший метод dbus всередині фільтра сповіщень, він не працює. Все, що я отримую unable to connect to session bus: Operation was cancelled. Ми проходимо busдо фільтра.
Хуршид Алам

1
На моїй установці Python (Python 3, Ubuntu) мені потрібно from gi.repository import GLib as glibбуло зробити цю роботу.
Оуен

6

Під сповіщеннями ви маєте на увазі "бульбашки екранного меню", які надсилається деяким програмним забезпеченням, наприклад, зміна гучності, чат чату тощо? Ви хочете створити програму 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] для тексту тексту.

Для значення інших полів перевірте документи офіційних специфікацій


Схоже, це більше не працює з 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 у проекті нещодавніх повідомлень .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.