1 # telepathy-python - Base classes defining the interfaces of the Telepathy framework
3 # Copyright (C) 2005, 2006 Collabora Limited
4 # Copyright (C) 2005, 2006 Nokia Corporation
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 from telepathy.constants import (CONNECTION_HANDLE_TYPE_NONE,
24 CHANNEL_TEXT_MESSAGE_TYPE_NORMAL,
27 from telepathy.errors import InvalidArgument
29 from telepathy.interfaces import (CHANNEL_INTERFACE,
30 CHANNEL_INTERFACE_DTMF,
31 CHANNEL_INTERFACE_GROUP,
32 CHANNEL_INTERFACE_HOLD,
33 CHANNEL_INTERFACE_PASSWORD,
34 CHANNEL_TYPE_CONTACT_LIST,
35 CHANNEL_TYPE_FILE_TRANSFER,
36 CHANNEL_TYPE_ROOM_LIST,
37 CHANNEL_TYPE_STREAMED_MEDIA,
39 MEDIA_SESSION_HANDLER,
42 from telepathy._generated.Channel import Channel as _Channel
44 from properties import DBusProperties
46 from handle import NoneHandle
48 class Channel(_Channel, DBusProperties):
50 def __init__(self, connection, manager, props, object_path=None):
52 Initialise the base channel object.
55 connection - the parent Connection object
56 props - initial channel properties
58 self._conn = connection
59 self._chan_manager = manager
61 object_path = self._conn.get_channel_path(object_path)
62 _Channel.__init__(self, self._conn._name, object_path)
64 self._type = props[CHANNEL_INTERFACE + '.ChannelType']
65 self._requested = props[CHANNEL_INTERFACE + '.Requested']
67 self._immutable_properties = dict()
69 tht = props.get(CHANNEL_INTERFACE + '.TargetHandleType', HANDLE_TYPE_NONE)
71 if tht == HANDLE_TYPE_NONE:
72 self._handle = NoneHandle()
74 self._handle = self._conn.get_handle_by_id(
75 props[CHANNEL_INTERFACE + '.TargetHandleType'],
76 props[CHANNEL_INTERFACE + '.TargetHandle'])
78 self._interfaces = set()
80 DBusProperties.__init__(self)
81 self._implement_property_get(CHANNEL_INTERFACE,
82 {'ChannelType': lambda: dbus.String(self.GetChannelType()),
83 'Interfaces': lambda: dbus.Array(self.GetInterfaces(), signature='s'),
84 'TargetHandle': lambda: dbus.UInt32(self._handle.get_id()),
85 'TargetHandleType': lambda: dbus.UInt32(self._handle.get_type()),
86 'TargetID': lambda: dbus.String(self._handle.get_name()),
87 'Requested': lambda: self._requested})
89 self._add_immutables({
90 'ChannelType': CHANNEL_INTERFACE,
91 'TargetHandle': CHANNEL_INTERFACE,
92 'Interfaces': CHANNEL_INTERFACE,
93 'TargetHandleType': CHANNEL_INTERFACE,
94 'TargetID': CHANNEL_INTERFACE,
95 'Requested': CHANNEL_INTERFACE
98 def _add_immutables(self, props):
99 self._immutable_properties.update(props)
102 """Despite its name, this function actually only returns immutable channel
105 for prop, iface in self._immutable_properties.items():
106 props[iface + '.' + prop] = \
107 self._prop_getters[iface][prop]()
110 @dbus.service.method(CHANNEL_INTERFACE, in_signature='', out_signature='')
113 self._chan_manager.remove_channel(self)
114 self._conn.remove_channel(self)
116 @dbus.service.method(CHANNEL_INTERFACE, in_signature='', out_signature='s')
117 def GetChannelType(self):
118 """ Returns the interface name for the type of this channel. """
121 @dbus.service.method(CHANNEL_INTERFACE, in_signature='', out_signature='uu')
123 """ Returns the handle type and number if this channel represents a
124 communication with a particular contact, room or server-stored list, or
125 zero if it is transient and defined only by its contents. """
126 return (self._handle.get_type(), self._handle.get_id())
128 @dbus.service.method(CHANNEL_INTERFACE, in_signature='', out_signature='as')
129 def GetInterfaces(self):
131 Get the optional interfaces implemented by the channel.
134 an array of the D-Bus interface names
136 return self._interfaces
138 from telepathy._generated.Channel_Type_Contact_List \
139 import ChannelTypeContactList as _ChannelTypeContactListIface
141 class ChannelTypeContactList(Channel, _ChannelTypeContactListIface):
142 __doc__ = _ChannelTypeContactListIface.__doc__
144 def __init__(self, connection, manager, props, object_path=None):
146 Initialise the channel.
149 connection - the parent Telepathy Connection object
151 Channel.__init__(self, connection, manager, props,
152 object_path=object_path)
155 from telepathy._generated.Channel_Type_File_Transfer \
156 import ChannelTypeFileTransfer as _ChannelTypeFileTransferIface
158 class ChannelTypeFileTransfer(Channel, _ChannelTypeFileTransferIface):
159 __doc__ = _ChannelTypeFileTransferIface.__doc__
161 def __init__(self, connection, manager, props, object_path=None):
163 Initialise the channel.
166 connection - the parent Telepathy Connection object
168 Channel.__init__(self, connection, manager, props,
169 object_path=object_path)
172 from telepathy._generated.Channel_Type_Streamed_Media \
173 import ChannelTypeStreamedMedia as _ChannelTypeStreamedMediaIface
175 class ChannelTypeStreamedMedia(Channel, _ChannelTypeStreamedMediaIface):
176 __doc__ = _ChannelTypeStreamedMediaIface.__doc__
178 def __init__(self, connection, manager, props, object_path=None):
180 Initialise the channel.
183 connection - the parent Telepathy Connection object
185 Channel.__init__(self, connection, manager, props,
186 object_path=object_path)
189 from telepathy._generated.Channel_Type_Room_List \
190 import ChannelTypeRoomList as _ChannelTypeRoomListIface
192 class ChannelTypeRoomList(Channel, _ChannelTypeRoomListIface):
193 __doc__ = _ChannelTypeRoomListIface.__doc__
195 def __init__(self, connection, manager, props, object_path=None):
197 Initialise the channel.
200 connection - the parent Telepathy Connection object
202 Channel.__init__(self, connection, manager, props,
203 object_path=object_path)
204 self._listing_rooms = False
207 self._add_immutables({'Server': CHANNEL_TYPE_ROOM_LIST})
209 @dbus.service.method(CHANNEL_TYPE_ROOM_LIST, in_signature='', out_signature='b')
210 def GetListingRooms(self):
211 return self._listing_rooms
213 @dbus.service.signal(CHANNEL_TYPE_ROOM_LIST, signature='b')
214 def ListingRooms(self, listing):
215 self._listing_rooms = listing
218 from telepathy._generated.Channel_Type_Text \
219 import ChannelTypeText as _ChannelTypeTextIface
221 class ChannelTypeText(Channel, _ChannelTypeTextIface):
222 __doc__ = _ChannelTypeTextIface.__doc__
224 def __init__(self, connection, manager, props, object_path=None):
226 Initialise the channel.
229 connection - the parent Telepathy Connection object
231 Channel.__init__(self, connection, manager, props,
232 object_path=object_path)
234 self._pending_messages = {}
235 self._message_types = [CHANNEL_TEXT_MESSAGE_TYPE_NORMAL]
237 @dbus.service.method(CHANNEL_TYPE_TEXT, in_signature='', out_signature='au')
238 def GetMessageTypes(self):
240 Return an array indicating which types of message may be sent on this
244 an array of integer message types as defined above
246 return self._message_types
248 @dbus.service.method(CHANNEL_TYPE_TEXT, in_signature='au', out_signature='')
249 def AcknowledgePendingMessages(self, ids):
251 Inform the channel that you have handled messages by displaying them to
252 the user (or equivalent), so they can be removed from the pending queue.
255 ids - the message to acknowledge
258 InvalidArgument (a given message ID was not found, no action taken)
261 if id not in self._pending_messages:
262 raise InvalidArgument("the given message ID was not found")
265 del self._pending_messages[id]
267 @dbus.service.method(CHANNEL_TYPE_TEXT, in_signature='b', out_signature='a(uuuuus)')
268 def ListPendingMessages(self, clear):
270 List the messages currently in the pending queue, and optionally
274 clear - a boolean indicating whether the queue should be cleared
277 an array of structs containing:
279 a unix timestamp indicating when the message was received
280 an integer handle of the contact who sent the message
281 an integer of the message type
282 a bitwise OR of the message flags
283 a string of the text of the message
286 for id in self._pending_messages.keys():
287 (timestamp, sender, type, flags, text) = self._pending_messages[id]
288 message = (id, timestamp, sender, type, flags, text)
289 messages.append(message)
291 del self._pending_messages[id]
292 messages.sort(cmp=lambda x,y:cmp(x[1], y[1]))
295 @dbus.service.signal(CHANNEL_TYPE_TEXT, signature='uuuuus')
296 def Received(self, id, timestamp, sender, type, flags, text):
297 self._pending_messages[id] = (timestamp, sender, type, flags, text)
300 from telepathy._generated.Channel_Interface_Chat_State \
301 import ChannelInterfaceChatState
304 from telepathy._generated.Channel_Interface_DTMF import ChannelInterfaceDTMF
307 from telepathy._generated.Channel_Interface_Group \
308 import ChannelInterfaceGroup as _ChannelInterfaceGroup
310 class ChannelInterfaceGroup(_ChannelInterfaceGroup, DBusProperties):
313 _ChannelInterfaceGroup.__init__(self)
314 DBusProperties.__init__(self)
316 self._implement_property_get(CHANNEL_INTERFACE_GROUP,
317 {'GroupFlags': lambda: dbus.UInt32(self.GetGroupFlags()),
318 'Members': lambda: dbus.Array(self.GetMembers(), signature='u'),
319 'RemotePendingMembers': lambda: dbus.Array(self.GetRemotePendingMembers(), signature='u'),
320 'SelfHandle': lambda: dbus.UInt32(self.GetSelfHandle())})
322 self._group_flags = 0
323 self._members = set()
324 self._local_pending = set()
325 self._remote_pending = set()
327 @dbus.service.method(CHANNEL_INTERFACE_GROUP, in_signature='', out_signature='u')
328 def GetGroupFlags(self):
329 return self._group_flags
331 @dbus.service.signal(CHANNEL_INTERFACE_GROUP, signature='uu')
332 def GroupFlagsChanged(self, added, removed):
333 self._group_flags |= added
334 self._group_flags &= ~removed
336 @dbus.service.method(CHANNEL_INTERFACE_GROUP, in_signature='', out_signature='au')
337 def GetMembers(self):
340 @dbus.service.method(CHANNEL_INTERFACE_GROUP, in_signature='', out_signature='u')
341 def GetSelfHandle(self):
342 self_handle = self._conn.GetSelfHandle()
343 if (self_handle in self._members or
344 self_handle in self._local_pending or
345 self_handle in self._remote_pending):
350 @dbus.service.method(CHANNEL_INTERFACE_GROUP, in_signature='', out_signature='au')
351 def GetLocalPendingMembers(self):
352 return self._local_pending
354 @dbus.service.method(CHANNEL_INTERFACE_GROUP, in_signature='', out_signature='au')
355 def GetRemotePendingMembers(self):
356 return self._remote_pending
358 @dbus.service.method(CHANNEL_INTERFACE_GROUP, in_signature='', out_signature='auauau')
359 def GetAllMembers(self):
360 return (self._members, self._local_pending, self._remote_pending)
362 @dbus.service.signal(CHANNEL_INTERFACE_GROUP, signature='sauauauauuu')
363 def MembersChanged(self, message, added, removed, local_pending, remote_pending, actor, reason):
365 self._members.update(added)
366 self._members.difference_update(removed)
368 self._local_pending.update(local_pending)
369 self._local_pending.difference_update(added)
370 self._local_pending.difference_update(removed)
372 self._remote_pending.update(remote_pending)
373 self._remote_pending.difference_update(added)
374 self._remote_pending.difference_update(removed)
377 from telepathy._generated.Channel_Interface_Hold import ChannelInterfaceHold
380 # ChannelInterfaceMediaSignalling is in telepathy.server.media
383 from telepathy._generated.Channel_Interface_Password \
384 import ChannelInterfacePassword as _ChannelInterfacePassword
386 class ChannelInterfacePassword(_ChannelInterfacePassword):
388 _ChannelInterfacePassword.__init__(self)
389 self._password_flags = 0
392 @dbus.service.method(CHANNEL_INTERFACE_PASSWORD, in_signature='', out_signature='u')
393 def GetPasswordFlags(self):
394 return self._password_flags
396 @dbus.service.signal(CHANNEL_INTERFACE_PASSWORD, signature='uu')
397 def PasswordFlagsChanged(self, added, removed):
398 self._password_flags |= added
399 self._password_flags &= ~removed
402 from telepathy._generated.Channel_Interface_Call_State import ChannelInterfaceCallState