Improving logging
[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                 _moduleLogger.info("Added: %r, Removed: %r" % (len(added), len(removed)))
94                 connection = self._conn
95                 handlesAdded = [
96                         handle.create_handle(connection, "contact", contactId, phoneNumber)
97                         for contactId in added
98                         for (phoneType, phoneNumber) in addressbook.get_contact_details(contactId)
99                 ]
100                 handlesRemoved = [
101                         handle.create_handle(connection, "contact", contactId, phoneNumber)
102                         for contactId in removed
103                         for (phoneType, phoneNumber) in addressbook.get_contact_details(contactId)
104                 ]
105                 message = ""
106                 actor = 0
107                 reason = telepathy.CHANNEL_GROUP_CHANGE_REASON_NONE
108                 self.MembersChanged(
109                         message,
110                         handlesAdded, handlesRemoved,
111                         (), (),
112                         actor,
113                         reason,
114                 )
115
116
117 def create_contact_list_channel(connection, manager, props, h):
118         if h.get_name() == 'subscribe':
119                 # The group of contacts for whom you receive presence
120                 ChannelClass = AllContactsListChannel
121         elif h.get_name() == 'publish':
122                 # The group of contacts who may receive your presence
123                 ChannelClass = AllContactsListChannel
124         elif h.get_name() == 'hide':
125                 # A group of contacts who are on the publish list but are temporarily
126                 # disallowed from receiving your presence
127                 # This doesn't make sense to support
128                 _moduleLogger.warn("Unsuported type %s" % h.get_name())
129         elif h.get_name() == 'allow':
130                 # A group of contacts who may send you messages
131                 # @todo Allow-List would be cool to support
132                 _moduleLogger.warn("Unsuported type %s" % h.get_name())
133         elif h.get_name() == 'deny':
134                 # A group of contacts who may not send you messages
135                 # @todo Deny-List would be cool to support
136                 _moduleLogger.warn("Unsuported type %s" % h.get_name())
137         elif h.get_name() == 'stored':
138                 # On protocols where the user's contacts are stored, this contact list
139                 # contains all stored contacts regardless of subscription status.
140                 ChannelClass = AllContactsListChannel
141         else:
142                 raise TypeError("Unknown list type : " + h.get_name())
143         return ChannelClass(connection, manager, props, h)
144
145