Switching over to a copy-paste version of python-telepathy's channel manager
[theonering] / src / channel / contact_list.py
1 import logging
2
3 import telepathy
4
5 import util.go_utils as gobject_utils
6 import util.coroutines as coroutines
7 import gtk_toolbox
8 import handle
9
10
11 _moduleLogger = logging.getLogger("channel.contact_list")
12
13
14 class AbstractListChannel(
15                 telepathy.server.ChannelTypeContactList,
16                 telepathy.server.ChannelInterfaceGroup,
17         ):
18         "Abstract Contact List channels"
19
20         def __init__(self, connection, manager, props, h):
21                 self._manager = manager
22                 self._props = props
23
24                 telepathy.server.ChannelTypeContactList.__init__(self, connection, h)
25                 telepathy.server.ChannelInterfaceGroup.__init__(self)
26
27                 self._session = connection.session
28
29
30 class AllContactsListChannel(AbstractListChannel):
31         """
32         The group of contacts for whom you receive presence
33         """
34
35         def __init__(self, connection, manager, props, h):
36                 AbstractListChannel.__init__(self, connection, manager, props, h)
37
38                 self._callback = coroutines.func_sink(
39                         coroutines.expand_positional(
40                                 self._on_contacts_refreshed
41                         )
42                 )
43                 self._session.addressbook.updateSignalHandler.register_sink(
44                         self._callback
45                 )
46
47                 self.GroupFlagsChanged(0, 0)
48
49                 addressbook = connection.session.addressbook
50                 contacts = addressbook.get_contacts()
51                 self._process_refresh(addressbook, contacts, [])
52
53         @gtk_toolbox.log_exception(_moduleLogger)
54         def Close(self):
55                 self.close()
56
57         def close(self):
58                 self._session.addressbook.updateSignalHandler.unregister_sink(
59                         self._callback
60                 )
61                 self._callback = None
62
63                 telepathy.server.ChannelTypeContactList.Close(self)
64                 if self._manager.channel_exists(self._props):
65                         # Older python-telepathy requires doing this manually
66                         self._manager.remove_channel(self)
67                 self.remove_from_connection()
68
69         @gobject_utils.async
70         @gtk_toolbox.log_exception(_moduleLogger)
71         def _on_contacts_refreshed(self, addressbook, added, removed, changed):
72                 self._process_refresh(addressbook, added, removed)
73
74         def _process_refresh(self, addressbook, added, removed):
75                 connection = self._conn
76                 handlesAdded = [
77                         handle.create_handle(connection, "contact", contactId, phoneNumber)
78                         for contactId in added
79                         for (phoneType, phoneNumber) in addressbook.get_contact_details(contactId)
80                 ]
81                 handlesRemoved = [
82                         handle.create_handle(connection, "contact", contactId, phoneNumber)
83                         for contactId in removed
84                         for (phoneType, phoneNumber) in addressbook.get_contact_details(contactId)
85                 ]
86                 message = ""
87                 actor = 0
88                 reason = telepathy.CHANNEL_GROUP_CHANGE_REASON_NONE
89                 self.MembersChanged(
90                         message,
91                         handlesAdded, handlesRemoved,
92                         (), (),
93                         actor,
94                         reason,
95                 )
96
97
98 def create_contact_list_channel(connection, h):
99         if h.get_name() == 'subscribe':
100                 # The group of contacts for whom you receive presence
101                 ChannelClass = AllContactsListChannel
102         elif h.get_name() == 'publish':
103                 # The group of contacts who may receive your presence
104                 ChannelClass = AllContactsListChannel
105         elif h.get_name() == 'hide':
106                 # A group of contacts who are on the publish list but are temporarily
107                 # disallowed from receiving your presence
108                 # This doesn't make sense to support
109                 _moduleLogger.warn("Unsuported type %s" % h.get_name())
110         elif h.get_name() == 'allow':
111                 # A group of contacts who may send you messages
112                 # @todo Allow-List would be cool to support
113                 _moduleLogger.warn("Unsuported type %s" % h.get_name())
114         elif h.get_name() == 'deny':
115                 # A group of contacts who may not send you messages
116                 # @todo Deny-List would be cool to support
117                 _moduleLogger.warn("Unsuported type %s" % h.get_name())
118         elif h.get_name() == 'stored':
119                 # On protocols where the user's contacts are stored, this contact list
120                 # contains all stored contacts regardless of subscription status.
121                 ChannelClass = AllContactsListChannel
122         else:
123                 raise TypeError("Unknown list type : " + h.get_name())
124         return ChannelClass(connection, h)
125
126