summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <louis-francis.ratte-boulianne@collabora.co.uk>2010-10-28 16:38:38 -0400
committerLouis-Francis Ratté-Boulianne <louis-francis.ratte-boulianne@collabora.co.uk>2010-12-03 10:55:44 -0500
commit8a9fa626c7ee9183a6d275e8cb1134ee35c73eef (patch)
treed27bff11e56eaea54574415a359f3b3bb05e974f
parenta2d383a5a6beb9639a44331a33dc4f6025464ff3 (diff)
Add Protocol default implementation
Connection Managers have to populate Protocol properties (_english_name, _icon, etc.) in a child class. create_connection must be overridden. The method _implement_protocol must be called on the connection manager to add all known Protocol classes.
-rw-r--r--src/server/Makefile.am3
-rw-r--r--src/server/__init__.py1
-rw-r--r--src/server/conn.py5
-rw-r--r--src/server/connmgr.py7
-rw-r--r--src/server/protocol.py161
5 files changed, 173 insertions, 4 deletions
diff --git a/src/server/Makefile.am b/src/server/Makefile.am
index e6739ab..5d92dc2 100644
--- a/src/server/Makefile.am
+++ b/src/server/Makefile.am
@@ -9,7 +9,8 @@ server_PYTHON = \
handle.py \
__init__.py \
media.py \
- properties.py
+ properties.py \
+ protocol.py
clean-local:
rm -rf *.pyc *.pyo
diff --git a/src/server/__init__.py b/src/server/__init__.py
index 16167aa..94fb3dd 100644
--- a/src/server/__init__.py
+++ b/src/server/__init__.py
@@ -28,6 +28,7 @@ from telepathy.server.debug import *
from telepathy.server.handle import *
from telepathy.server.media import *
from telepathy.server.properties import *
+from telepathy.server.protocol import *
from telepathy._generated.Client_Observer import ClientObserver as Observer
from telepathy._generated.Client_Approver import ClientApprover as Approver
diff --git a/src/server/conn.py b/src/server/conn.py
index 9192829..dff738c 100644
--- a/src/server/conn.py
+++ b/src/server/conn.py
@@ -60,7 +60,7 @@ class Connection(_Connection, DBusProperties):
_secret_parameters = {}
_parameter_defaults = {}
- def __init__(self, proto, account, manager=None):
+ def __init__(self, proto, account, manager=None, protocol=None):
"""
Parameters:
proto - the name of the protcol this conection should be handling.
@@ -99,7 +99,8 @@ class Connection(_Connection, DBusProperties):
'Status': lambda: dbus.UInt32(self.GetStatus())
})
- self._proto = proto
+ self._proto = proto # Protocol name
+ self._protocol = protocol # Protocol object
self._status = CONNECTION_STATUS_DISCONNECTED
diff --git a/src/server/connmgr.py b/src/server/connmgr.py
index f087aae..bdf1dc6 100644
--- a/src/server/connmgr.py
+++ b/src/server/connmgr.py
@@ -41,7 +41,7 @@ class ConnectionManager(_ConnectionManager, DBusProperties):
self._interfaces = set()
self._connections = set()
- self._protos = {} # proto name => Connection class
+ self._protos = {} # proto name => Connection constructor
self._protocols = {} # proto name => Protocol object
DBusProperties.__init__(self)
@@ -86,6 +86,11 @@ class ConnectionManager(_ConnectionManager, DBusProperties):
self.connected(conn)
return (conn._name.get_name(), conn._object_path)
+ def _implement_protocol(self, name, protocol_class):
+ protocol = protocol_class(self)
+ self._protocols[name] = protocol
+ self._protos[name] = protocol.create_connection
+
@property
def _protocol_properties(self):
properties = {}
diff --git a/src/server/protocol.py b/src/server/protocol.py
new file mode 100644
index 0000000..fa20de4
--- /dev/null
+++ b/src/server/protocol.py
@@ -0,0 +1,161 @@
+# telepathy-python - Base classes defining the interfaces of the Telepathy framework
+#
+# Copyright (C) 2010 Collabora Limited
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import dbus
+import dbus.service
+
+from telepathy.constants import (CONN_MGR_PARAM_FLAG_REQUIRED,
+ CONN_MGR_PARAM_FLAG_SECRET,
+ CONN_MGR_PARAM_FLAG_HAS_DEFAULT)
+from telepathy.errors import InvalidArgument, NotImplemented
+from telepathy.interfaces import PROTOCOL
+from telepathy.server.properties import DBusProperties
+
+from telepathy._generated.Protocol import Protocol as _Protocol
+
+class Protocol(_Protocol, DBusProperties):
+
+ """ Class members to override in CM implementations : """
+
+ _english_name = ""
+ _icon = ""
+ _vcard_field = ""
+
+ # List of Requestable_Channel_Class struct
+ _requestable_channel_classe = []
+
+ _optional_parameters = {}
+ _mandatory_parameters = {}
+ _secret_parameters = {}
+ _parameter_defaults = {}
+
+
+ def __init__(self, connection_manager, proto):
+ escaped_name = proto.replace("-", "_")
+ bus_name = connection_manager._name
+ object_path = connection_manager._object_path + "/" + escaped_name
+
+ _Protocol.__init__(self, bus_name, object_path)
+
+ self._proto = proto
+ self._interfaces = set()
+
+ DBusProperties.__init__(self)
+ self._implement_property_get(PROTOCOL, {
+ 'EnglishName': lambda: self.english_name,
+ 'Icon': lambda: self.icon,
+ 'VCardField': lambda: self.vcard_field,
+ 'Interfaces': lambda: self.interfaces,
+ 'ConnectionInterfaces': lambda: self.connection_interfaces,
+ 'RequestableChannelClasses': lambda: self.requestable_channels,
+ 'Parameters': lambda: self.parameters
+ })
+
+ @property
+ def english_name(self):
+ return dbus.String(self._english_name)
+
+ @property
+ def icon(self):
+ return dbus.String(self._icon)
+
+ @property
+ def vcard_field(self):
+ return dbus.String(self._vcard_field)
+
+ @property
+ def interfaces(self):
+ return dbus.Array(self._interfaces, signature='s')
+
+ @property
+ def connection_interfaces(self):
+ return dbus.Array(self._supported_interfaces, signature='s')
+
+ @property
+ def requestable_channels(self):
+ return dbus.Array(self._requestable_channel_classes,
+ signature='(a{sv}as)')
+
+ @property
+ def parameters(self):
+ parameters = []
+
+ secret_parameters = self._secret_parameters
+ mandatory_parameters = self._mandatory_parameters
+ optional_parameters = self._optional_parameters
+ default_parameters = self._parameter_defaults
+
+ for parameter_name, parameter_type in mandatory_parameters.iteritems():
+ flags = CONN_MGR_PARAM_FLAG_REQUIRED
+ if parameter_name in secret_parameters:
+ flags |= CONN_MGR_PARAM_FLAG_SECRET
+ param = (parameter_name, flags, parameter_type, '')
+ parameters.append(param)
+
+ for parameter_name, parameter_type in optional_parameters.iteritems():
+ flags = 0
+ default = ''
+ if parameter_name in secret_parameters:
+ flags |= CONN_MGR_PARAM_FLAG_SECRET
+ if parameter_name in default_parameters:
+ flags |= CONN_MGR_PARAM_FLAG_HAS_DEFAULT
+ default = default_parameters[parameter_name]
+ param = (parameter_name, flags, parameter_type, default)
+ parameters.append(param)
+
+ return dbus.Array(parameters, signature='(susv)')
+
+ def check_parameters(self, parameters):
+ """
+ Validate and type check all of the provided parameters, and
+ check all mandatory parameters are present before creating a
+ new connection.
+ Sets defaults according to the defaults if the client has not
+ provided any.
+ """
+ for (parm, value) in parameters.iteritems():
+ if parm in self._mandatory_parameters.keys():
+ sig = self._mandatory_parameters[parm]
+ elif parm in self._optional_parameters.keys():
+ sig = self._optional_parameters[parm]
+ else:
+ raise InvalidArgument('unknown parameter name %s' % parm)
+
+ # we currently support strings, (u)int16/32 and booleans
+ if sig == 's':
+ if not isinstance(value, unicode):
+ raise InvalidArgument('incorrect type to %s parameter, got %s, expected a string' % (parm, type(value)))
+ elif sig in 'iunq':
+ if not isinstance(value, (int, long)):
+ raise InvalidArgument('incorrect type to %s parameter, got %s, expected an int' % (parm, type(value)))
+ elif sig == 'b':
+ if not isinstance(value, (bool, dbus.Boolean)):
+ raise InvalidArgument('incorrect type to %s parameter, got %s, expected an boolean' % (parm, type(value)))
+ else:
+ raise TypeError('unknown type signature %s in protocol parameters' % type)
+
+ for (parm, value) in self._parameter_defaults.iteritems():
+ if parm not in parameters:
+ parameters[parm] = value
+
+ missing = set(self._mandatory_parameters.keys()).difference(parameters.keys())
+ if missing:
+ raise InvalidArgument('required parameters %s not given' % missing)
+
+ def create_connection(self, connection_manager, parameters):
+ raise NotImplemented('no create_connection for %s' % self._proto)