【问题标题】:How can i receive events from Skype via D-Bus using python?如何使用 python 通过 D-Bus 从 Skype 接收事件?
【发布时间】:2013-05-21 05:45:22
【问题描述】:

(我知道这类似于 Python and d-bus: How to set up main loop? ,但“答案”中没有完整的代码,我无法弄清楚我哪里出错了。这可能只是 Skype 中的一个变化)

这是我的程序:

import gobject
import dbus
import dbus.mainloop.glib
dbus_gmainloop = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
sessbus = dbus.SessionBus()
skype = sessbus.get_object('com.Skype.API', '/com/Skype')
skypec = sessbus.get_object('com.Skype.API', '/com/Skype/Client')
skype_iface = dbus.Interface(skype, dbus_interface='com.Skype.API')
skype_iface.Invoke("NAME py1")
# ... waits for user click in Skype ...
#==> dbus.String(u'OK')
skype_iface.Invoke("PROTOCOL 7")
#==> dbus.String(u'PROTOCOL 7')
def got_signal(sender, destination, member, interface, path):
  print "got_signal(sender=%s, dest=%s, member=%s, iface=%s, path=%s)" \
    % (sender, destination, member, interface, path)

skypec.connect_to_signal('Notify', got_signal, sender_keyword='sender', \
  destination_keyword='destination', member_keyword='member', \
  interface_keyword='interface', path_keyword='path')

mainloop = gobject.MainLoop()
mainloop.run()

运行时(例如python skype-call.py),它在向 Skype 发送NAME py1 命令后暂停并等待 Skype UI 中的交互式确认,然后继续。因此,skype_iface 对象显然至少在一定程度上是有效的。

但是,python 然后会发出以下错误:

ERROR:dbus.proxies:Introspect error on :1.152:/com/Skype/Client: dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UnknownObject: No such object path '/com/Skype/Client'

我还尝试了以下方法(而不是 connect_to_signal,就在最后开始 gobject 主循环之前):

def receiver(x, **kwargs):
  print "receiver(%s)" % (x,)

sessbus.add_signal_receiver(receiver, signal_name='Notify', \
  dbus_interface='com.Skype.API', bus_name='com.Skype.API', path='/com/Skype/Client')

虽然它没有抱怨,但它永远不会被调用。我尝试向 Skype 用户发送消息。什么样的事件应该触发它?

https://dev.skype.com/desktop-api-reference#DBUSUsage 的文档并不是很有帮助。

这是基于 Debian 7.0 多架构 (amd64/i386) 的 Skype for Linux 4.2.0.11。

【问题讨论】:

    标签: python skype dbus pygobject


    【解决方案1】:

    回头看http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html#exporting-methods-with-dbus-service-method,我试着以他们为例:

    import gobject
    import dbus
    from dbus.decorators import method
    import dbus.mainloop.glib
    import dbus.service
    
    dbus_gmainloop = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
    sessbus = dbus.SessionBus()
    
    class Example(dbus.service.Object):
        def __init__(self, bus):
            dbus.service.Object.__init__(self, bus, '/com/Skype/Client')
    
        @method(dbus_interface='com.Skype.API.Client', in_signature='s', \
                sender_keyword='sender', destination_keyword='dest', \
                rel_path_keyword='rel_path', path_keyword='path', \
                message_keyword='message', connection_keyword='conn')
        def Notify(self, s, sender=None, dest=None, rel_path=None, path=None, \
                   message=None, conn=None):
            print "Notify(%s, sender=%s, dest=%s, rel_path=%s, path=%s, message=%s, conn=%s)" \
                  % (s, sender, path, dest, message, rel_path, conn,)
    
    # make one:
    ex = Example(sessbus)
    
    skype = sessbus.get_object('com.Skype.API', '/com/Skype')
    skype_iface = dbus.Interface(skype, dbus_interface='com.Skype.API')
    skype_iface.Invoke("NAME py1")
    ##=> dbus.String(u'OK')
    skype_iface.Invoke("PROTOCOL 7")
    ##=> dbus.String(u'PROTOCOL 7')
    
    mainloop = gobject.MainLoop()
    mainloop.run()
    

    你瞧,我接到了Notify 电话:

    Notify(CONNSTATUS ONLINE, sender=:1.152, path=/com/Skype/Client, dest=:1.275, message=<dbus.lowlevel.MethodCallMessage path: /com/Skype/Client, iface: com.Skype.API.Client, member: Notify dest: :1.275>, rel_path=/, conn=<dbus._dbus.SessionBus (session) at 0x2118e90>)
    
    Notify(CURRENTUSERHANDLE ******, sender=:1.152, path=/com/Skype/Client, dest=:1.275, message=<dbus.lowlevel.MethodCallMessage path: /com/Skype/Client, iface: com.Skype.API.Client, member: Notify dest: :1.275>, rel_path=/, conn=<dbus._dbus.SessionBus (session) at 0x2118e90>)
    
    Notify(USERSTATUS ONLINE, sender=:1.152, path=/com/Skype/Client, dest=:1.275, message=<dbus.lowlevel.MethodCallMessage path: /com/Skype/Client, iface: com.Skype.API.Client, member: Notify dest: :1.275>, rel_path=/, conn=<dbus._dbus.SessionBus (session) at 0x2118e90>)
    

    显然,这不是一个结构良好的程序的一个很好的例子,但 d-bus 位似乎确实相互连接。

    【讨论】:

    【解决方案2】:

    我正在尝试调试相同的东西,也许我们可以一起解决一些问题(我也在使用 wheezy amd64,顺便说一句)...

    据我了解,com.Skype.API 似乎没有公开名为 /com/Skype/Client 的对象(d-feet 证实了这一点)。

    我使用dbus-monitor 监控总线,同时向我的Skype 帐户发送消息。在其他输出中,我得到了这个:

    method call sender=:1.43 -> dest=:1.132 serial=324 path=/com/Skype/Client; interface=com.Skype.API.Client; member=Notify
       string "CHAT #rshk-testuser1/$myusername;<hex-code-here> ACTIVITY_TIMESTAMP 1370647479"
    error sender=:1.132 -> dest=:1.43 error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=324
       string "Method "Notify" with signature "s" on interface "com.Skype.API.Client" doesn't exist
    "
    method call sender=:1.43 -> dest=:1.132 serial=325 path=/com/Skype/Client; interface=com.Skype.API.Client; member=Notify
       string "CHATMESSAGE 1538281 STATUS RECEIVED"
    error sender=:1.132 -> dest=:1.43 error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=325
       string "Method "Notify" with signature "s" on interface "com.Skype.API.Client" doesn't exist
    "
    

    所以,看起来有另一个名为 com.Skype.API.Client 的接口暴露了 /com/Skype/Client 对象,但由于某种原因,该接口无法访问..

    我查看了/etc/dbus-1/system.d/skype.conf,它只列出了com.Skype.API

    我对 dbus 不是很有经验,但我正在尝试进一步挖掘并了解问题所在..

    【讨论】:

    • 哦...我想知道是否在skype.conf 中添加一些东西是我们需要的。
    • 另外,我们应该弄清楚这是否仍然正确:“Skype 使用的 D-Bus 版本非常旧,与当前的守护进程和库不兼容。在他们更新之前,你不能使用它。” -- lists.freedesktop.org/archives/dbus/2006-November/006492.html -- 不喜欢,因为我们可以发送,但也许......
    猜你喜欢
    • 2019-08-17
    • 1970-01-01
    • 2017-04-04
    • 2013-01-16
    • 2020-02-18
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 2011-12-08
    相关资源
    最近更新 更多