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

Reply via email to