Bump to -13 to include fixes found through dbus-monitor to get calls to work
[theonering] / src / channel / contact_list.py
1 import logging
2
3 import telepathy
4
5 import util.coroutines as coroutines
6 import gtk_toolbox
7 import handle
8
9
10 _moduleLogger = logging.getLogger("channel.contact_list")
11
12
13 class AllContactsListChannel(
14                 telepathy.server.ChannelTypeContactList,
15                 telepathy.server.ChannelInterfaceGroup,
16         ):
17         """
18         The group of contacts for whom you receive presence
19         """
20
21         def __init__(self, connection, manager, props, h):
22                 try:
23                         # HACK Older python-telepathy way
24                         telepathy.server.ChannelTypeContactList.__init__(self, connection, h)
25                         self._requested = props[telepathy.interfaces.CHANNEL_INTERFACE + '.Requested']
26                         self._implement_property_get(
27                                 telepathy.interfaces.CHANNEL_INTERFACE,
28                                 {"Requested": lambda: self._requested}
29                         )
30                 except TypeError:
31                         # HACK Newer python-telepathy way
32                         telepathy.server.ChannelTypeContactList.__init__(self, connection, manager, props)
33                 telepathy.server.ChannelInterfaceGroup.__init__(self)
34
35                 self.__manager = manager
36                 self.__props = props
37                 self.__session = connection.session
38
39                 # HACK Older python-telepathy doesn't provide this
40                 self._immutable_properties = {
41                         'ChannelType': telepathy.server.interfaces.CHANNEL_INTERFACE,
42                         'TargetHandle': telepathy.server.interfaces.CHANNEL_INTERFACE,
43                         'Interfaces': telepathy.server.interfaces.CHANNEL_INTERFACE,
44                         'TargetHandleType': telepathy.server.interfaces.CHANNEL_INTERFACE,
45                         'TargetID': telepathy.server.interfaces.CHANNEL_INTERFACE,
46                         'Requested': telepathy.server.interfaces.CHANNEL_INTERFACE
47                 }
48
49                 self._callback = coroutines.func_sink(
50                         coroutines.expand_positional(
51                                 self._on_contacts_refreshed
52                         )
53                 )
54                 self.__session.addressbook.updateSignalHandler.register_sink(
55                         self._callback
56                 )
57
58                 self.GroupFlagsChanged(0, 0)
59
60                 addressbook = connection.session.addressbook
61                 contacts = addressbook.get_contacts()
62                 self._process_refresh(addressbook, contacts, [])
63
64         def get_props(self):
65                 # HACK Older python-telepathy doesn't provide this
66                 props = dict()
67                 for prop, iface in self._immutable_properties.items():
68                         props[iface + '.' + prop] = \
69                                 self._prop_getters[iface][prop]()
70                 return props
71
72         @gtk_toolbox.log_exception(_moduleLogger)
73         def Close(self):
74                 self.close()
75
76         def close(self):
77                 self.__session.addressbook.updateSignalHandler.unregister_sink(
78                         self._callback
79                 )
80                 self._callback = None
81
82                 telepathy.server.ChannelTypeContactList.Close(self)
83                 if self.__manager.channel_exists(self.__props):
84                         # HACK Older python-telepathy requires doing this manually
85                         self.__manager.remove_channel(self)
86                 self.remove_from_connection()
87
88         @gtk_toolbox.log_exception(_moduleLogger)
89         def _on_contacts_refreshed(self, addressbook, added, removed, changed):
90                 self._process_refresh(addressbook, added, removed)
91
92         def _process_refresh(self, addressbook, added, removed):
93                 connection = self._conn
94                 handlesAdded = [
95                         handle.create_handle(connection, "contact", contactId, phoneNumber)
96                         for contactId in added
97                         for (phoneType, phoneNumber) in addressbook.get_contact_details(contactId)
98                 ]
99                 handlesRemoved = [
100                         handle.create_handle(connection, "contact", contactId, phoneNumber)
101                         for contactId in removed
102                         for (phoneType, phoneNumber) in addressbook.get_contact_details(contactId)
103                 ]
104                 message = ""
105                 actor = 0
106                 reason = telepathy.CHANNEL_GROUP_CHANGE_REASON_NONE
107                 self.MembersChanged(
108                         message,
109                         handlesAdded, handlesRemoved,
110                         (), (),
111                         actor,
112                         reason,
113                 )
114
115
116 def create_contact_list_channel(connection, manager, props, h):
117         if h.get_name() == 'subscribe':
118                 # The group of contacts for whom you receive presence
119                 ChannelClass = AllContactsListChannel
120         elif h.get_name() == 'publish':
121                 # The group of contacts who may receive your presence
122                 ChannelClass = AllContactsListChannel
123         elif h.get_name() == 'hide':
124                 # A group of contacts who are on the publish list but are temporarily
125                 # disallowed from receiving your presence
126                 # This doesn't make sense to support
127                 _moduleLogger.warn("Unsuported type %s" % h.get_name())
128         elif h.get_name() == 'allow':
129                 # A group of contacts who may send you messages
130                 # @todo Allow-List would be cool to support
131                 _moduleLogger.warn("Unsuported type %s" % h.get_name())
132         elif h.get_name() == 'deny':
133                 # A group of contacts who may not send you messages
134                 # @todo Deny-List would be cool to support
135                 _moduleLogger.warn("Unsuported type %s" % h.get_name())
136         elif h.get_name() == 'stored':
137                 # On protocols where the user's contacts are stored, this contact list
138                 # contains all stored contacts regardless of subscription status.
139                 ChannelClass = AllContactsListChannel
140         else:
141                 raise TypeError("Unknown list type : " + h.get_name())
142         return ChannelClass(connection, manager, props, h)
143
144