diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2010-03-30 15:51:56 +0100 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2010-03-30 15:51:56 +0100 |
commit | fbbb71a170876d87358a84c06011d76bc8b0d960 (patch) | |
tree | db0467de4022699cd8947cd1729a4f4d444aada0 | |
parent | 478a16906b4cb3fd1c870a9bf5161e84865d10c9 (diff) | |
parent | 89ac7165248cd95e0e15084bbaaeb7bbeab7d9d0 (diff) |
Merge branch 'contactcaps'
-rw-r--r-- | butterfly/capabilities.py | 136 | ||||
-rw-r--r-- | butterfly/contacts.py | 7 |
2 files changed, 134 insertions, 9 deletions
diff --git a/butterfly/capabilities.py b/butterfly/capabilities.py index e03184c..829d72f 100644 --- a/butterfly/capabilities.py +++ b/butterfly/capabilities.py @@ -23,6 +23,9 @@ import telepathy import papyon import papyon.event +from telepathy._generated.Connection_Interface_Contact_Capabilities \ + import ConnectionInterfaceContactCapabilities + from butterfly.util.decorator import async from butterfly.handle import ButterflyHandleFactory @@ -32,12 +35,46 @@ logger = logging.getLogger('Butterfly.Capabilities') class ButterflyCapabilities( telepathy.server.ConnectionInterfaceCapabilities, + ConnectionInterfaceContactCapabilities, papyon.event.ContactEventInterface): + text_chat_class = \ + ({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']) + + audio_chat_class = \ + ({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']) + + av_chat_class = \ + ({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']) + + def __init__(self): telepathy.server.ConnectionInterfaceCapabilities.__init__(self) + ConnectionInterfaceContactCapabilities.__init__(self) papyon.event.ContactEventInterface.__init__(self, self.msn_client) - dbus_interface = telepathy.CONNECTION_INTERFACE_CAPABILITIES + + # handle -> list(RCC) + self._contact_caps = {} + self._video_clients = [] + self._update_capabilities_calls = [] def AdvertiseCapabilities(self, add, remove): #for caps, specs in add: @@ -52,6 +89,58 @@ class ButterflyCapabilities( return telepathy.server.ConnectionInterfaceCapabilities.\ AdvertiseCapabilities(self, add, remove) + def GetContactCapabilities(self, handles): + if 0 in handles: + raise telepathy.InvalidHandle('Contact handle list contains zero') + + ret = dbus.Dictionary({}, signature='ua(a{sv}as)') + for i in handles: + handle = self.handle(telepathy.HANDLE_TYPE_CONTACT, i) + ret[handle] = self._contact_caps[handle] + + return ret + + def UpdateCapabilities(self, caps): + if self._state != telepathy.CONNECTION_STATUS_CONNECTED: + self._update_capabilities_calls.append(caps) + return + + # butterfly voip is disabled, so + return + + # We only care about voip. + for client, classes, capabilities in caps: + video = False + for channel_class in classes: + # Does this client support video? + if channel_class[telepathy.CHANNEL_INTERFACE + '.ChannelType'] == \ + telepathy.CHANNEL_TYPE_STREAMED_MEDIA: + video = True + self._video_clients.append(client) + else: + # *Did* it used to support video? + if client in self._video_clients: + self._video_clients.remove(client) + + changed = False + + # We've got no more clients that support video; remove the cap. + if not video and not self._video_clients: + self._self_handle.profile.client_id.has_webcam = False + changed = True + + # We want video. + if video and not self._self_handle.profile.client_id.has_webcam: + self._self_handle.profile.client_id.has_webcam = True + self._self_handle.profile.client_id.supports_rtc_video = True + changed = True + + # Signal. + if changed: + updated = dbus.Dictionary({self._self_handle: self._contact_caps[self._self_handle]}, + signature='ua(a{sv}as)') + self.ContactCapabilitiesChanged(updated) + # papyon.event.ContactEventInterface def on_contact_client_capabilities_changed(self, contact): self._update_capabilities(contact) @@ -68,6 +157,7 @@ class ButterflyCapabilities( def add_text_capabilities(self, contacts_handles): """Add the create capability for text channel to these contacts.""" ret = [] + cc_ret = dbus.Dictionary({}, signature='ua(a{sv}as)') for handle in contacts_handles: ctype = telepathy.CHANNEL_TYPE_TEXT if handle in self._caps: @@ -81,30 +171,55 @@ class ButterflyCapabilities( 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 = ButterflyHandleFactory(self, 'contact', contact.account, contact.network_id) ctype = telepathy.CHANNEL_TYPE_STREAMED_MEDIA - new_gen, new_spec = self._get_capabilities(contact) + new_gen, new_spec, rcc = self._get_capabilities(contact) if handle in self._caps: old_gen, old_spec = self._caps[handle][ctype] else: old_gen = 0 old_spec = 0 - if old_gen == new_gen and old_spec == new_spec: + if old_gen != new_gen or old_spec != new_spec: + diff = (int(handle), ctype, old_gen, new_gen, old_spec, new_spec) + self.CapabilitiesChanged([diff]) + + if rcc is None: + return + + self._contact_caps.setdefault(handle, []) + + if rcc in self._contact_caps[handle]: return - diff = (int(handle), ctype, old_gen, new_gen, old_spec, new_spec) - self.CapabilitiesChanged([diff]) + if self.audio_chat_class in self._contact_caps[handle]: + self._contact_caps[handle].remove(self.audio_chat_class) + + if self.audio_chat_class in self._contact_caps[handle]: + self._contact_caps[handle].remove(self.audio_chat_class) + + self._contact_caps[handle].append(rcc) + + ret = dbus.Dictionary({handle: self._contact_caps[handle]}, + signature='ua(a{sv}as)') + self.ContactCapabilitiesChanged(ret) def _get_capabilities(self, contact): gen_caps = 0 spec_caps = 0 + rcc = None + caps = contact.client_capabilities #if caps.supports_sip_invite: #gen_caps |= telepathy.CONNECTION_CAPABILITY_FLAG_CREATE @@ -114,14 +229,17 @@ class ButterflyCapabilities( #if caps.has_webcam: #spec_caps |= telepathy.CHANNEL_MEDIA_CAPABILITY_VIDEO + #rcc = self.av_chat_class + #else: + #rcc = self.audio_chat_class - return gen_caps, spec_caps + return gen_caps, spec_caps, rcc @async def _populate_capabilities(self): """ Add the capability to create text channels to all contacts in our contacts list.""" - handles = set() + handles = set([self._self_handle]) for contact in self.msn_client.address_book.contacts: if contact.is_member(papyon.Membership.FORWARD): handle = ButterflyHandleFactory(self, 'contact', @@ -129,3 +247,7 @@ class ButterflyCapabilities( 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 = [] diff --git a/butterfly/contacts.py b/butterfly/contacts.py index 62696cb..3bf71f6 100644 --- a/butterfly/contacts.py +++ b/butterfly/contacts.py @@ -39,7 +39,8 @@ class ButterflyContacts( telepathy.CONNECTION_INTERFACE_SIMPLE_PRESENCE : 'presence', telepathy.CONNECTION_INTERFACE_ALIASING : 'alias', telepathy.CONNECTION_INTERFACE_AVATARS : 'token', - telepathy.CONNECTION_INTERFACE_CAPABILITIES : 'caps' + telepathy.CONNECTION_INTERFACE_CAPABILITIES : 'caps', + telepathy.CONNECTION_INTERFACE_CONTACT_CAPABILITIES : 'capabilities' } def __init__(self): @@ -77,7 +78,9 @@ class ButterflyContacts( telepathy.CONNECTION_INTERFACE_AVATARS : lambda x: self.GetKnownAvatarTokens(x).items(), telepathy.CONNECTION_INTERFACE_CAPABILITIES : - lambda x: self.GetCapabilities(x).items() + lambda x: self.GetCapabilities(x).items(), + telepathy.CONNECTION_INTERFACE_CONTACT_CAPABILITIES : + lambda x: self.GetContactCapabilities(x).items() } #Hold handles if needed |