ec390fff708b97f9c7271f26a34995a98efbb189
[theonering] / src / channel / contact_list.py
1 import weakref
2 import logging
3
4 import telepathy
5
6 import handle
7
8
9 def create_contact_list_channel(connection, h):
10         if h.get_name() == 'subscribe':
11                 channel_class = SubscribeListChannel
12         elif h.get_name() == 'publish':
13                 channel_class = PublishListChannel
14         elif h.get_name() == 'hide':
15                 logging.warn("Unsuported type %s" % h.get_name())
16         elif h.get_name() == 'allow':
17                 logging.warn("Unsuported type %s" % h.get_name())
18         elif h.get_name() == 'deny':
19                 logging.warn("Unsuported type %s" % h.get_name())
20         else:
21                 raise TypeError("Unknown list type : " + h.get_name())
22         return channel_class(connection, h)
23
24
25 class AbstractListChannel(
26                 telepathy.server.ChannelTypeContactList,
27                 telepathy.server.ChannelInterfaceGroup,
28         ):
29         "Abstract Contact List channels"
30
31         def __init__(self, connection, h):
32                 telepathy.server.ChannelTypeContactList.__init__(self, connection, h)
33                 telepathy.server.ChannelInterfaceGroup.__init__(self)
34
35                 self._conn_ref = weakref.ref(connection)
36
37         def GetLocalPendingMembersWithInfo(self):
38                 return []
39
40
41 class SubscribeListChannel(AbstractListChannel):
42         """
43         Subscribe List channel.
44
45         This channel contains the list of contact to whom the current used is
46         'subscribed', basically this list contains the contact for whom you are
47         supposed to receive presence notification.
48         """
49
50         def __init__(self, connection, h):
51                 AbstractListChannel.__init__(self, connection, h)
52                 self.GroupFlagsChanged(
53                         telepathy.CHANNEL_GROUP_FLAG_CAN_ADD |
54                         telepathy.CHANNEL_GROUP_FLAG_CAN_REMOVE,
55                         0,
56                 )
57
58         def AddMembers(self, contacts, message):
59                 addressBook = self._conn.gvoice_client
60                 for h in contacts:
61                         h = self._conn.handle(telepathy.HANDLE_TYPE_CONTACT, h)
62                         contact = h.contact
63                         if contact is None:
64                                 account = h.account
65                         else:
66                                 account = contact.account
67                         groups = list(h.pending_groups)
68                         h.pending_groups = set()
69                         addressBook.add_messenger_contact(account,
70                                         invite_message=message.encode('utf-8'),
71                                         groups=groups)
72
73         def RemoveMembers(self, contacts, message):
74                 addressBook = self._conn.gvoice_client
75                 for h in contacts:
76                         h = self._conn.handle(telepathy.HANDLE_TYPE_CONTACT, h)
77                         contact = h.contact
78                         addressBook.delete_contact(contact)
79
80
81 class PublishListChannel(AbstractListChannel):
82
83         def __init__(self, connection, h):
84                 AbstractListChannel.__init__(self, connection, h)
85                 self.GroupFlagsChanged(0, 0)
86
87         def AddMembers(self, contacts, message):
88                 addressBook = self._conn.gvoice_client
89                 for contactHandleId in contacts:
90                         contactHandle = self._conn.handle(telepathy.HANDLE_TYPE_CONTACT,
91                                                 contactHandleId)
92                         contact = contactHandle.contact
93                         addressBook.accept_contact_invitation(contact, False)
94
95         def RemoveMembers(self, contacts, message):
96                 addressBook = self._conn.gvoice_client
97                 for contactHandleId in contacts:
98                         contactHandle = self._conn.handle(telepathy.HANDLE_TYPE_CONTACT,
99                                                 contactHandleId)
100                         contact = contactHandle.contact
101
102         def GetLocalPendingMembersWithInfo(self):
103                 addressBook = self._conn.gvoice_client
104                 result = []
105                 for contact in addressBook.contacts:
106                         h = handle.create_handle(self._conn_ref(), 'contact',
107                                         contact.account, contact.network_id)
108                         result.append((h, h,
109                                         telepathy.CHANNEL_GROUP_CHANGE_REASON_INVITED,
110                                         contact.attributes.get('invite_message', '')))
111                 return result
112
113
114 class GroupChannel(AbstractListChannel):
115
116         def __init__(self, connection, h):
117                 self.__pending_add = []
118                 self.__pending_remove = []
119                 AbstractListChannel.__init__(self, connection, h)
120                 self.GroupFlagsChanged(
121                         telepathy.CHANNEL_GROUP_FLAG_CAN_ADD | telepathy.CHANNEL_GROUP_FLAG_CAN_REMOVE,
122                         0,
123                 )
124
125         def AddMembers(self, contacts, message):
126                 addressBook = self._conn.gvoice_client
127                 if self._handle.group is None:
128                         for contactHandleId in contacts:
129                                 contactHandle = self._conn.handle(telepathy.HANDLE_TYPE_CONTACT, contactHandleId)
130                                 logging.info("Adding contact %r to pending group %r" % (contactHandle, self._handle))
131                                 if contactHandleId in self.__pending_remove:
132                                         self.__pending_remove.remove(contactHandleId)
133                                 else:
134                                         self.__pending_add.append(contactHandleId)
135                         return
136                 else:
137                         for contactHandleId in contacts:
138                                 contactHandle = self._conn.handle(telepathy.HANDLE_TYPE_CONTACT, contactHandleId)
139                                 logging.info("Adding contact %r to group %r" % (contactHandle, self._handle))
140                                 contact = contactHandle.contact
141                                 group = self._handle.group
142                                 if contact is not None:
143                                         addressBook.add_contact_to_group(group, contact)
144                                 else:
145                                         contactHandle.pending_groups.add(group)
146
147         def RemoveMembers(self, contacts, message):
148                 addressBook = self._conn.gvoice_client
149                 if self._handle.group is None:
150                         for contactHandleId in contacts:
151                                 contactHandle = self._conn.handle(telepathy.HANDLE_TYPE_CONTACT, contactHandleId)
152                                 logging.info("Adding contact %r to pending group %r" % (contactHandle, self._handle))
153                                 if contactHandleId in self.__pending_add:
154                                         self.__pending_add.remove(contactHandleId)
155                                 else:
156                                         self.__pending_remove.append(contactHandleId)
157                         return
158                 else:
159                         for contactHandleId in contacts:
160                                 contactHandle = self._conn.handle(telepathy.HANDLE_TYPE_CONTACT, contactHandleId)
161                                 logging.info("Removing contact %r from pending group %r" % (contactHandle, self._handle))
162                                 contact = contactHandle.contact
163                                 group = self._handle.group
164                                 if contact is not None:
165                                         addressBook.delete_contact_from_group(group, contact)
166                                 else:
167                                         contactHandle.pending_groups.discard(group)
168
169         def Close(self):
170                 logging.debug("Deleting group %s" % self._handle.name)
171                 addressBook = self._conn.gvoice_client
172                 group = self._handle.group
173                 addressBook.delete_group(group)