From a7725c9d7589773de7c068f11ca63b95f99ccfcc Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 15 Jul 2008 19:33:01 +0100 Subject: Alter dbus.server.Server API to have pseudo-signals By either appending to a list of callbacks, or subclassing and providing a method, you can be notified when connections are added or removed. Inspired by the DBusServer patch from Huang Peng. --- dbus/server.py | 48 ++++++++++++++++++++++++++++++++++++++++++++---- test/test-server.py | 24 +++++++++++++----------- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/dbus/server.py b/dbus/server.py index 2cf11c8..d690e1a 100644 --- a/dbus/server.py +++ b/dbus/server.py @@ -32,7 +32,8 @@ class Server(_Server): other applications. This class is not useful to instantiate directly: you must subclass it and - provide an implementation of the _on_new_connection method. + either extend the method connection_added, or append to the + list on_connection_added. :Since: 0.82.5 """ @@ -57,19 +58,58 @@ class Server(_Server): return super(Server, cls).__new__(cls, address, connection_class, mainloop, auth_mechanisms) + def __init__(self, *args, **kwargs): + + self.__connections = {} + + self.on_connection_added = [] + """A list of callbacks to invoke when a connection is added. + They receive two arguments: this Server and the new Connection.""" + + self.on_connection_removed = [] + """A list of callbacks to invoke when a connection becomes + disconnected. They receive two arguments: this Server and the removed + Connection.""" + + # This method name is hard-coded in _dbus_bindings._Server. + # This is not public API. def _on_new_connection(self, conn): + conn.call_on_disconnection(self.connection_removed) + self.connection_added(conn) + + def connection_added(self, conn): """Respond to the creation of a new Connection. + This base-class implementation just invokes the callbacks in + the on_connection_added attribute. + :Parameters: `conn` : dbus.connection.Connection - A D-Bus connection. + A D-Bus connection which has just been added. The type of this parameter is whatever was passed to the Server constructor as the ``connection_class``. """ - raise NotImplementedError('Subclasses of Server must implement ' - '_on_new_connection') + if self.on_connection_added: + for cb in self.on_connection_added: + cb(conn) + + def connection_removed(self, conn): + """Respond to the disconnection of a Connection. + This base-class implementation just invokes the callbacks in + the on_connection_removed attribute. + + :Parameters: + `conn` : dbus.connection.Connection + A D-Bus connection which has just become disconnected. + + The type of this parameter is whatever was passed + to the Server constructor as the ``connection_class``. + """ + if self.on_connection_removed: + for cb in self.on_connection_removed: + cb(conn) address = property(_Server.get_address) id = property(_Server.get_id) diff --git a/test/test-server.py b/test/test-server.py index aef27c9..b909d84 100755 --- a/test/test-server.py +++ b/test/test-server.py @@ -26,22 +26,23 @@ class TestService(dbus.service.Object): return ''.join(text) -class TestServer(dbus.server.Server): - def __init__(self, *args, **kwargs): - super(TestServer, self).__init__(*args, **kwargs) - self.__connections = list() - - def _on_new_connection(self, conn): - print 'new connection: %r' % conn - self.__connections.append(conn) - TestService(conn) - pin, pout = os.pipe() child = os.fork() if 0 == child: DBusGMainLoop(set_as_default=True) - server = TestServer('unix:tmpdir=/tmp') + server = dbus.server.Server('unix:tmpdir=/tmp') + + def new_connection(conn): + print "new connection, %r" % conn + TestService(conn) + + def connection_gone(conn): + print "goodbye, %r" % conn + + # Instantiate a TestService every time a connection is created + server.on_connection_added.append(new_connection) + server.on_connection_removed.append(connection_gone) os.write(pout, server.address) os.close(pout) @@ -72,3 +73,4 @@ else: text = line.strip() print 'reverse(%s): %s' % (text, object.reverse(text)) + client.close() -- cgit v1.2.1