使用DBus监听传入的libnotify通知


9

我正在尝试通过espeak过滤所有通知。但是,我似乎找不到从python脚本获取通知主体的方法,甚至找不到要监听的signal_name。

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 2012年

Answers:


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过滤器。
Khurshid Alam

1
在我的Python安装(Python 3,Ubuntu)上,我需要from gi.repository import GLib as glib完成这项工作。
欧文

6

所谓通知,是指某些软件发送的“ OSD气泡”,例如更改音量,IM聊天等?您想创建一个python程序来捕获那些程序吗?

好吧,Ask Ubuntu不是程序员的质量保证,并且软件开发超出了范围,但是这里有一些我确实捕获了通知气泡的代码:

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或之前的某个时间不再可用。Joost在下面的回答确实解决了该问题。
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()

如果您想查看更详细的工作示例,建议您查看last_notifications项目中的Notifications.py

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.