ce8722ef14420694e9cbc3b80f688e6f4ac53570
[theonering] / src / util / tp_utils.py
1 #!/usr/bin/env python
2
3 import logging
4 import pprint
5
6 import gobject
7 import dbus
8 import telepathy
9
10 import util.go_utils as gobject_utils
11 import gtk_toolbox
12
13
14 _moduleLogger = logging.getLogger("tp_utils")
15 DBUS_PROPERTIES = 'org.freedesktop.DBus.Properties'
16
17
18 class WasMissedCall(object):
19
20         def __init__(self, bus, conn, chan, on_success, on_error):
21                 self._on_success = on_success
22                 self._on_error = on_error
23
24                 self._requested = None
25                 self._didMembersChange = False
26                 self._didClose = False
27                 self._didReport = False
28
29                 self._timeoutId = gobject_utils.timeout_add_seconds(10, self._on_timeout)
30
31                 chan[telepathy.interfaces.CHANNEL_INTERFACE_GROUP].connect_to_signal(
32                         "MembersChanged",
33                         self._on_members_changed,
34                 )
35
36                 chan[telepathy.interfaces.CHANNEL].connect_to_signal(
37                         "Closed",
38                         self._on_closed,
39                 )
40
41                 chan[DBUS_PROPERTIES].GetAll(
42                         telepathy.interfaces.CHANNEL_INTERFACE,
43                         reply_handler = self._on_got_all,
44                         error_handler = self._on_got_all,
45                 )
46
47         def cancel(self):
48                 self._report_error("by request")
49
50         def _report_missed_if_ready(self):
51                 if self._didReport:
52                         pass
53                 elif self._requested is not None and (self._didMembersChange or self._didClose):
54                         if self._requested:
55                                 self._report_error("wrong direction")
56                         elif self._didClose:
57                                 self._report_success()
58                         else:
59                                 self._report_error("members added")
60                 else:
61                         if self._didClose:
62                                 self._report_error("closed too early")
63
64         def _report_success(self):
65                 assert not self._didReport
66                 self._didReport = True
67                 if self._timeoutId:
68                         gobject.source_remove(self._timeoutId)
69                         self._timeoutId = None
70                 self._on_success(self)
71
72         def _report_error(self, reason):
73                 assert not self._didReport
74                 self._didReport = True
75                 if self._timeoutId:
76                         gobject.source_remove(self._timeoutId)
77                         self._timeoutId = None
78                 self._on_error(self, reason)
79
80         @gtk_toolbox.log_exception(_moduleLogger)
81         def _on_got_all(self, properties):
82                 self._requested = properties["Requested"]
83                 self._report_missed_if_ready()
84
85         @gtk_toolbox.log_exception(_moduleLogger)
86         def _on_members_changed(self, message, added, removed, lp, rp, actor, reason):
87                 pprint.pprint((message, added, removed, lp, rp, actor, reason))
88                 if added:
89                         self._didMembersChange = True
90                         self._report_missed_if_ready()
91
92         @gtk_toolbox.log_exception(_moduleLogger)
93         def _on_closed(self):
94                 self._didClose = True
95                 self._report_missed_if_ready()
96
97         @gtk_toolbox.log_exception(_moduleLogger)
98         def _on_error(self, *args):
99                 self._report_error(args)
100
101         @gtk_toolbox.log_exception(_moduleLogger)
102         def _on_timeout(self):
103                 self._report_error("timeout")
104                 return False
105
106
107 class NewChannelSignaller(object):
108
109         def __init__(self, on_new_channel):
110                 self._sessionBus = dbus.SessionBus()
111                 self._on_user_new_channel = on_new_channel
112
113         def start(self):
114                 self._sessionBus.add_signal_receiver(
115                         self._on_new_channel,
116                         "NewChannel",
117                         "org.freedesktop.Telepathy.Connection",
118                         None,
119                         None
120                 )
121
122         def stop(self):
123                 self._sessionBus.remove_signal_receiver(
124                         self._on_new_channel,
125                         "NewChannel",
126                         "org.freedesktop.Telepathy.Connection",
127                         None,
128                         None
129                 )
130
131         @gtk_toolbox.log_exception(_moduleLogger)
132         def _on_new_channel(
133                 self, channelObjectPath, channelType, handleType, handle, supressHandler
134         ):
135                 connObjectPath = channelObjectPath.rsplit("/", 1)[0]
136                 serviceName = connObjectPath[1:].replace("/", ".")
137                 conn = telepathy.client.Connection(serviceName, connObjectPath)
138                 chan = telepathy.client.Channel(serviceName, channelObjectPath)
139                 self._on_user_new_channel(self._sessionBus, conn, chan, channelType)