I had a crazy idea this afternoon.
One of the things when writing a D-Bus service in Python is that you
have to know the type signatures of the methods to pass to the
dbus.service.method decorator. This is something that's very easy to
typo, also something that's already stored in the spec.
Instead, why not generate a decorator for each signal and method in the
Telepathy spec?
For example:
@telepathy.decorators.Telepathy.Client.Observer.ObserveChannels
def ObserveChannels(self, account, connection, channels, dispatch_operation,
requests_satisfied, observer_info):
print "Incoming channels on %s:" % (connection)
for object, props in channels:
print " - %s :: %s" % (props[CHANNEL + '.ChannelType'],
props[CHANNEL + '.TargetID'])
Here is a hacked up version that I did to implement an Observer:
class Decorators(object):
methods = {
'org.freedesktop.DBus.Properties.GetAll': [ 's', 'a{sv}' ],
'org.freedesktop.DBus.Properties.Get': [ 'ss', 'v' ],
'org.freedesktop.Telepathy.Client.Observer.ObserveChannels': [
'ooa(oa{sv})oaoa{sv}', '' ],
}
def __init__(self, namespace):
self._namespace = namespace
def __getattr__(self, key):
return Decorators('%s.%s' % (self._namespace, key))
def __call__(self, func):
iface = self._namespace.rsplit('.', 1)[0]
in_sig, out_sig = self.methods[self._namespace]
return dbus.service.method(dbus_interface=iface,
in_signature=in_sig,
out_signature=out_sig)(func)
def __str__(self):
return self._namespace
decorators = Decorators('org.freedesktop')
Complete example attached. Thoughts?
--
Danielle Madeley
Collabora Ltd., Melbourne, Australia
http://www.collabora.co.uk/
import dbus.glib
import gobject
import telepathy
from telepathy.interfaces import CLIENT, \
CLIENT_OBSERVER, \
CHANNEL
class Decorators(object):
methods = {
'org.freedesktop.DBus.Properties.GetAll': [ 's', 'a{sv}' ],
'org.freedesktop.DBus.Properties.Get': [ 'ss', 'v' ],
'org.freedesktop.Telepathy.Client.Observer.ObserveChannels': [ 'ooa(oa{sv})oaoa{sv}', '' ],
}
def __init__(self, namespace):
self._namespace = namespace
def __getattr__(self, key):
return Decorators('%s.%s' % (self._namespace, key))
def __call__(self, func):
iface = self._namespace.rsplit('.', 1)[0]
in_sig, out_sig = self.methods[self._namespace]
return dbus.service.method(dbus_interface=iface,
in_signature=in_sig,
out_signature=out_sig)(func)
def __str__(self):
return self._namespace
decorators = Decorators('org.freedesktop')
class ExampleObserver(dbus.service.Object):
properties = {
CLIENT: {
'Interfaces': [ CLIENT_OBSERVER ],
},
CLIENT_OBSERVER: {
'ObserverChannelFilter': dbus.Array([
dbus.Dictionary({
}, signature='sv')
], signature='a{sv}')
},
}
def __init__(self, client_name):
bus_name = '.'.join ([CLIENT, client_name])
object_path = '/' + bus_name.replace('.', '/')
bus_name = dbus.service.BusName(bus_name, bus=dbus.SessionBus())
dbus.service.Object.__init__(self, bus_name, object_path)
self.nameref = bus_name
@decorators.DBus.Properties.GetAll
def GetAll(self, interface):
print "GetAll", interface
if interface in self.properties:
return self.properties[interface]
else:
return {}
@decorators.DBus.Properties.Get
def Get(self, interface, property):
print "Get", interface, property
if interface in self.properties and \
property in self.properties[interface]:
return self.properties[interface][property]
else:
return 0
@decorators.Telepathy.Client.Observer.ObserveChannels
def ObserveChannels(self, account, connection, channels, dispatch_operation,
requests_satisfied, observer_info):
print "Incoming channels on %s:" % (connection)
for object, props in channels:
print " - %s :: %s" % (props[CHANNEL + '.ChannelType'],
props[CHANNEL + '.TargetID'])
def start():
ExampleObserver("ExampleObserver")
return False
if __name__ == '__main__':
gobject.timeout_add(0, start)
loop = gobject.MainLoop()
loop.run()
_______________________________________________
telepathy mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/telepathy