3 from __future__ import with_statement
4 from __future__ import division
8 import util.qt_compat as qt_compat
9 QtCore = qt_compat.QtCore
12 import telepathy as _telepathy
13 import util.tp_utils as telepathy_utils
14 telepathy = _telepathy
18 import util.misc as misc_utils
21 _moduleLogger = logging.getLogger(__name__)
24 class _FakeSignaller(object):
33 class _MissedCallWatcher(QtCore.QObject):
35 callMissed = qt_compat.Signal()
38 QtCore.QObject.__init__(self)
39 self._isStarted = False
40 self._isSupported = True
42 self._newChannelSignaller = telepathy_utils.NewChannelSignaller(self._on_new_channel)
43 self._outstandingRequests = []
46 def isSupported(self):
47 return self._isSupported
51 return self._isStarted
55 _moduleLogger.info("voicemail monitor already started")
58 self._newChannelSignaller.start()
60 _moduleLogger.exception("Missed call detection not supported")
61 self._newChannelSignaller = _FakeSignaller()
62 self._isSupported = False
63 self._isStarted = True
66 if not self._isStarted:
67 _moduleLogger.info("voicemail monitor stopped without starting")
69 _moduleLogger.info("Stopping voicemail refresh")
70 self._newChannelSignaller.stop()
72 # I don't want to trust whether the cancel happens within the current
73 # callback or not which could be the deciding factor between invalid
74 # iterators or infinite loops
75 localRequests = [r for r in self._outstandingRequests]
76 for request in localRequests:
77 localRequests.cancel()
79 self._isStarted = False
81 @misc_utils.log_exception(_moduleLogger)
82 def _on_new_channel(self, bus, serviceName, connObjectPath, channelObjectPath, channelType):
83 if channelType != telepathy.interfaces.CHANNEL_TYPE_STREAMED_MEDIA:
86 conn = telepathy.client.Connection(serviceName, connObjectPath)
88 chan = telepathy.client.Channel(serviceName, channelObjectPath)
89 except dbus.exceptions.UnknownMethodException:
90 _moduleLogger.exception("Client might not have implemented a deprecated method")
92 missDetection = telepathy_utils.WasMissedCall(
93 bus, conn, chan, self._on_missed_call, self._on_error_for_missed
95 self._outstandingRequests.append(missDetection)
97 @misc_utils.log_exception(_moduleLogger)
98 def _on_missed_call(self, missDetection):
99 _moduleLogger.info("Missed a call")
100 self.callMissed.emit()
101 self._outstandingRequests.remove(missDetection)
103 @misc_utils.log_exception(_moduleLogger)
104 def _on_error_for_missed(self, missDetection, reason):
105 _moduleLogger.debug("Error: %r claims %r" % (missDetection, reason))
106 self._outstandingRequests.remove(missDetection)
109 class _DummyMissedCallWatcher(QtCore.QObject):
111 callMissed = qt_compat.Signal()
114 QtCore.QObject.__init__(self)
115 self._isStarted = False
118 def isSupported(self):
123 return self._isStarted
126 self._isStarted = True
129 if not self._isStarted:
130 _moduleLogger.info("voicemail monitor stopped without starting")
132 _moduleLogger.info("Stopping voicemail refresh")
133 self._isStarted = False
136 if telepathy is not None:
137 MissedCallWatcher = _MissedCallWatcher
139 MissedCallWatcher = _DummyMissedCallWatcher
142 if __name__ == "__main__":