summaryrefslogtreecommitdiff
path: root/sunshine
diff options
context:
space:
mode:
Diffstat (limited to 'sunshine')
-rw-r--r--sunshine/capabilities.py37
-rw-r--r--sunshine/channel/contact_list.py7
-rw-r--r--sunshine/channel/group.py4
-rw-r--r--sunshine/channel/text.py4
-rw-r--r--sunshine/channel_manager.py140
-rw-r--r--sunshine/connection.py11
6 files changed, 172 insertions, 31 deletions
diff --git a/sunshine/capabilities.py b/sunshine/capabilities.py
index d5276cd..0424b74 100644
--- a/sunshine/capabilities.py
+++ b/sunshine/capabilities.py
@@ -153,7 +153,7 @@ class SunshineCapabilities(telepathy.server.ConnectionInterfaceCapabilities,
cc_ret = dbus.Dictionary({}, signature='ua(a{sv}as)')
for handle in contacts_handles:
ctype = telepathy.CHANNEL_TYPE_TEXT
- if handle in self._caps:
+ if handle in self._caps and ctype in self._caps[handle]:
old_gen, old_spec = self._caps[handle][ctype]
else:
old_gen = 0
@@ -171,6 +171,30 @@ class SunshineCapabilities(telepathy.server.ConnectionInterfaceCapabilities,
self.CapabilitiesChanged(ret)
self.ContactCapabilitiesChanged(cc_ret)
+# def add_create_capability(self, contact_handle):
+# """Add the create capability for self handle."""
+# ret = []
+# cc_ret = dbus.Dictionary({}, signature='ua(a{sv}as)')
+#
+# ctype = telepathy.CHANNEL_TYPE_TEXT
+# if handle in self._caps:
+# old_gen, old_spec = self._caps[handle][ctype]
+# else:
+# old_gen = 0
+# old_spec = 0
+# new_gen = old_gen
+# new_gen |= telepathy.CONNECTION_CAPABILITY_FLAG_CREATE
+#
+# diff = (int(handle), ctype, old_gen, new_gen, old_spec, old_spec)
+# ret.append(diff)
+#
+# # ContactCapabilities
+# self._contact_caps.setdefault(handle, []).append(self.text_chat_class)
+# cc_ret[handle] = self._contact_caps[handle]
+#
+# self.CapabilitiesChanged(ret)
+# self.ContactCapabilitiesChanged(cc_ret)
+
def _update_capabilities(self, contact):
handle = SunshineHandleFactory(self, 'contact',
contact.account, contact.network_id)
@@ -234,12 +258,17 @@ class SunshineCapabilities(telepathy.server.ConnectionInterfaceCapabilities,
contacts list."""
handles = set([self._self_handle])
for contact in self.profile.contacts:
- handle = SunshineHandleFactory(self, 'contact',
- str(contact), None)
- handles.add(handle)
+ handle = SunshineHandleFactory(self, 'contact',
+ str(contact.uin), None)
+ handles.add(handle)
self.add_text_capabilities(handles)
# These caps were updated before we were online.
for caps in self._update_capabilities_calls:
self.UpdateCapabilities(caps)
self._update_capabilities_calls = []
+
+ def updateCapabilitiesCalls(self):
+ # These caps were updated before we were online.
+ for caps in self._update_capabilities_calls:
+ self.UpdateCapabilities(caps)
diff --git a/sunshine/channel/contact_list.py b/sunshine/channel/contact_list.py
index 63bcaa4..e942a03 100644
--- a/sunshine/channel/contact_list.py
+++ b/sunshine/channel/contact_list.py
@@ -124,9 +124,9 @@ class SunshineListChannel(
telepathy.server.ChannelInterfaceGroup):
"Abstract Contact List channels"
- def __init__(self, connection, manager, props):
+ def __init__(self, connection, manager, props, object_path=None):
self._conn_ref = weakref.ref(connection)
- telepathy.server.ChannelTypeContactList.__init__(self, connection, manager, props)
+ telepathy.server.ChannelTypeContactList.__init__(self, connection, manager, props, object_path=None)
telepathy.server.ChannelInterfaceGroup.__init__(self)
self._populate(connection)
@@ -184,6 +184,9 @@ class SunshineListChannel(
if ad: added.add(handle)
if lp: local_pending.add(handle)
if rp: remote_pending.add(handle)
+ #self._conn_ref()._populate_capabilities()
+ #capabilities for self handle
+ self._conn_ref().contactAdded(self._conn_ref().GetSelfHandle())
self.MembersChanged('', added, (), local_pending, remote_pending, 0,
telepathy.CHANNEL_GROUP_CHANGE_REASON_NONE)
diff --git a/sunshine/channel/group.py b/sunshine/channel/group.py
index 6094092..375d07a 100644
--- a/sunshine/channel/group.py
+++ b/sunshine/channel/group.py
@@ -37,12 +37,12 @@ logger = logging.getLogger('Sunshine.GroupChannel')
class SunshineGroupChannel(SunshineListChannel):
- def __init__(self, connection, manager, props):
+ def __init__(self, connection, manager, props, object_path=None):
self.__pending_add = []
self.__pending_remove = []
self.conn = connection
self.groups = {}
- SunshineListChannel.__init__(self, connection, manager, props)
+ SunshineListChannel.__init__(self, connection, manager, props, object_path=object_path)
self.GroupFlagsChanged(telepathy.CHANNEL_GROUP_FLAG_CAN_ADD |
telepathy.CHANNEL_GROUP_FLAG_CAN_REMOVE, 0)
@async
diff --git a/sunshine/channel/text.py b/sunshine/channel/text.py
index 34c2269..9d01f74 100644
--- a/sunshine/channel/text.py
+++ b/sunshine/channel/text.py
@@ -34,14 +34,14 @@ logger = logging.getLogger('Sunshine.TextChannel')
class SunshineTextChannel(telepathy.server.ChannelTypeText):
- def __init__(self, conn, manager, conversation, props):
+ def __init__(self, conn, manager, conversation, props, object_path=None):
_, surpress_handler, handle = manager._get_type_requested_handle(props)
self._recv_id = 0
self._conn_ref = weakref.ref(conn)
self.conn = conn
self.handle = handle
- telepathy.server.ChannelTypeText.__init__(self, conn, manager, props)
+ telepathy.server.ChannelTypeText.__init__(self, conn, manager, props, object_path=None)
def Send(self, message_type, text):
if message_type == telepathy.CHANNEL_TEXT_MESSAGE_TYPE_NORMAL:
diff --git a/sunshine/channel_manager.py b/sunshine/channel_manager.py
index cd02197..f067b6c 100644
--- a/sunshine/channel_manager.py
+++ b/sunshine/channel_manager.py
@@ -19,6 +19,7 @@
import logging
import weakref
+from string import ascii_letters, digits
import dbus
import telepathy
@@ -29,57 +30,160 @@ from sunshine.channel.text import SunshineTextChannel, SunshineRoomTextChannel
#from sunshine.channel.media import SunshineMediaChannel
from sunshine.handle import SunshineHandleFactory
+#from butterfly.Channel_Interface_Conference import CHANNEL_INTERFACE_CONFERENCE
+
__all__ = ['SunshineChannelManager']
logger = logging.getLogger('Sunshine.ChannelManager')
+_ASCII_ALNUM = ascii_letters + digits
+
+# copy/pasted from tp-glib's libtpcodegen
+def escape_as_identifier(identifier):
+ """Escape the given string to be a valid D-Bus object path or service
+ name component, using a reversible encoding to ensure uniqueness.
+
+ The reversible encoding is as follows:
+
+ * The empty string becomes '_'
+ * Otherwise, each non-alphanumeric character is replaced by '_' plus
+ two lower-case hex digits; the same replacement is carried out on
+ the first character, if it's a digit
+ """
+ # '' -> '_'
+ if not identifier:
+ return '_'
+
+ # A bit of a fast path for strings which are already OK.
+ # We deliberately omit '_' because, for reversibility, that must also
+ # be escaped.
+ if (identifier.strip(_ASCII_ALNUM) == '' and
+ identifier[0] in ascii_letters):
+ return identifier
+
+ # The first character may not be a digit
+ if identifier[0] not in ascii_letters:
+ ret = ['_%02x' % ord(identifier[0])]
+ else:
+ ret = [identifier[0]]
+
+ # Subsequent characters may be digits or ASCII letters
+ for c in identifier[1:]:
+ if c in _ASCII_ALNUM:
+ ret.append(c)
+ else:
+ ret.append('_%02x' % ord(c))
+
+ return ''.join(ret)
+
class SunshineChannelManager(telepathy.server.ChannelManager):
+ __text_channel_id = 1
+ __media_channel_id = 1
+
def __init__(self, connection):
telepathy.server.ChannelManager.__init__(self, connection)
- fixed = {telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_TEXT,
- telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_CONTACT)}
- self._implement_channel_class(telepathy.CHANNEL_TYPE_TEXT,
- self._get_text_channel, fixed, [])
-
- fixed = {telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_TEXT,
- telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_ROOM)}
- self._implement_channel_class(telepathy.CHANNEL_TYPE_TEXT,
- self._get_text_channel, fixed, [])
- fixed = {telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_CONTACT_LIST}
- self._implement_channel_class(telepathy.CHANNEL_TYPE_CONTACT_LIST,
- self._get_list_channel, fixed, [])
+ classes = [
+ ({telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_TEXT,
+ telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_CONTACT)},
+ [telepathy.CHANNEL_INTERFACE + '.TargetHandle',
+ telepathy.CHANNEL_INTERFACE + '.TargetID']),
+
+ ({telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_TEXT,
+ telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_ROOM)},
+# [
+# CHANNEL_INTERFACE_CONFERENCE + '.InitialChannels',
+# CHANNEL_INTERFACE_CONFERENCE + '.InitialInviteeHandles',
+# CHANNEL_INTERFACE_CONFERENCE + '.InitialInviteeIDs',
+# CHANNEL_INTERFACE_CONFERENCE + '.InitialMessage',
+# CHANNEL_INTERFACE_CONFERENCE + '.SupportsNonMerges']
+ [telepathy.CHANNEL_INTERFACE + '.TargetHandle',
+ telepathy.CHANNEL_INTERFACE + '.TargetID']),
+ ]
+ self.implement_channel_classes(telepathy.CHANNEL_TYPE_TEXT, self._get_text_channel, classes)
+
+ classes = [
+ ({telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_CONTACT_LIST,
+ telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_GROUP)},
+ [telepathy.CHANNEL_INTERFACE + '.TargetHandle',
+ telepathy.CHANNEL_INTERFACE + '.TargetID']),
+
+ ({telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_CONTACT_LIST,
+ telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_LIST)},
+ [telepathy.CHANNEL_INTERFACE + '.TargetHandle',
+ telepathy.CHANNEL_INTERFACE + '.TargetID'])
+ ]
+ self.implement_channel_classes(telepathy.CHANNEL_TYPE_CONTACT_LIST, self._get_list_channel, classes)
+
+# classes = [
+# ({telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_STREAMED_MEDIA,
+# telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_CONTACT)},
+# [telepathy.CHANNEL_INTERFACE + '.TargetHandle',
+# telepathy.CHANNEL_INTERFACE + '.TargetID',
+# telepathy.CHANNEL_TYPE_STREAMED_MEDIA + '.InitialAudio',
+# telepathy.CHANNEL_TYPE_STREAMED_MEDIA + '.InitialVideo'])
+# ]
+# self.implement_channel_classes(telepathy.CHANNEL_TYPE_STREAMED_MEDIA, self._get_media_channel, classes)
+#
+# fixed = {telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_TEXT,
+# telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_CONTACT)}
+# self._implement_channel_class(telepathy.CHANNEL_TYPE_TEXT,
+# self._get_text_channel, fixed, [])
+#
+# fixed = {telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_TEXT,
+# telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_ROOM)}
+# self._implement_channel_class(telepathy.CHANNEL_TYPE_TEXT,
+# self._get_text_channel, fixed, [])
+#
+# fixed = {telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_CONTACT_LIST}
+# self._implement_channel_class(telepathy.CHANNEL_TYPE_CONTACT_LIST,
+# self._get_list_channel, fixed, [])
# fixed = {telepathy.CHANNEL_INTERFACE + '.ChannelType': telepathy.CHANNEL_TYPE_STREAMED_MEDIA,
# telepathy.CHANNEL_INTERFACE + '.TargetHandleType': dbus.UInt32(telepathy.HANDLE_TYPE_CONTACT)}
# self._implement_channel_class(telepathy.CHANNEL_TYPE_STREAMED_MEDIA,
# self._get_media_channel, fixed, [telepathy.CHANNEL_INTERFACE + '.TargetHandle'])
-
def _get_list_channel(self, props):
_, surpress_handler, handle = self._get_type_requested_handle(props)
+ logger.debug('New contact list channel')
+
if handle.get_type() == telepathy.HANDLE_TYPE_GROUP:
- channel = SunshineGroupChannel(self._conn, self, props)
- logger.debug('New group channel')
+ path = "RosterChannel/Group/%s" % escape_as_identifier(handle.get_name())
+ channel = SunshineGroupChannel(self._conn, self, props, object_path=path)
else:
channel = SunshineContactListChannelFactory(self._conn,
self, handle, props)
- logger.debug('New contact list channel: %s' % (handle.name))
return channel
+
+# def _get_list_channel(self, props):
+# _, surpress_handler, handle = self._get_type_requested_handle(props)
+#
+# if handle.get_type() == telepathy.HANDLE_TYPE_GROUP:
+# channel = SunshineGroupChannel(self._conn, self, props)
+# logger.debug('New group channel')
+# else:
+# channel = SunshineContactListChannelFactory(self._conn,
+# self, handle, props)
+# logger.debug('New contact list channel: %s' % (handle.name))
+# return channel
def _get_text_channel(self, props, conversation=None):
_, surpress_handler, handle = self._get_type_requested_handle(props)
+ path = "TextChannel%d" % self.__text_channel_id
+ self.__text_channel_id += 1
+
if handle.get_type() == telepathy.HANDLE_TYPE_CONTACT:
logger.debug('New text channel for contact handle, name: %s, id: %s, type: %s' % (handle.name, handle.id, handle.type))
- channel = SunshineTextChannel(self._conn, self, conversation, props)
+ channel = SunshineTextChannel(self._conn, self, conversation, props, object_path=path)
return channel
elif handle.get_type() == telepathy.HANDLE_TYPE_ROOM:
logger.debug('New text channel for room handle, name: %s, id: %s, type: %s' % (handle.name, handle.id, handle.type))
- channel = SunshineRoomTextChannel(self._conn, self, conversation, props)
+ channel = SunshineRoomTextChannel(self._conn, self, conversation, props, object_path=path)
return channel
else:
raise telepathy.NotImplemented('Unknown handle for text channel.')
diff --git a/sunshine/connection.py b/sunshine/connection.py
index cbfbd4c..87bda75 100644
--- a/sunshine/connection.py
+++ b/sunshine/connection.py
@@ -288,6 +288,9 @@ class SunshineConnection(telepathy.server.Connection,
SunshinePresence.__init__(self)
SunshineAvatars.__init__(self)
SunshineContacts.__init__(self)
+ SunshineCapabilities.__init__(self)
+
+ self.updateCapabilitiesCalls()
self.set_self_handle(SunshineHandleFactory(self, 'self'))
@@ -361,6 +364,9 @@ class SunshineConnection(telepathy.server.Connection,
#if reactor.running:
# reactor.stop()
+ def GetInterfaces(self):
+ return self._interfaces
+
def RequestHandles(self, handle_type, names, sender):
logger.info("Method RequestHandles called, handle type: %s, names: %s" % (str(handle_type), str(names)))
self.check_connected()
@@ -503,7 +509,6 @@ class SunshineConnection(telepathy.server.Connection,
self.makeTelepathyGroupChannels()
SunshineAliasing.__init__(self)
- SunshineCapabilities.__init__(self)
self._status = telepathy.CONNECTION_STATUS_CONNECTED
self.StatusChanged(telepathy.CONNECTION_STATUS_CONNECTED,
@@ -528,12 +533,12 @@ class SunshineConnection(telepathy.server.Connection,
self.makeTelepathyGroupChannels()
SunshineAliasing.__init__(self)
- SunshineCapabilities.__init__(self)
self._status = telepathy.CONNECTION_STATUS_CONNECTED
self.StatusChanged(telepathy.CONNECTION_STATUS_CONNECTED,
telepathy.CONNECTION_STATUS_REASON_REQUESTED)
- self._populate_capabilities()
+ #self._populate_capabilities()
+ #self.contactAdded(self.GetSelfHandle())
def on_loginFailed(self, response):
logger.info("Login failed: ", response)