3 from __future__ import with_statement
4 from __future__ import division
8 from PyQt4 import QtCore
11 import telepathy as _telepathy
12 import util.tp_utils as telepathy_utils
13 telepathy = _telepathy
17 import util.misc as misc_utils
20 _moduleLogger = logging.getLogger(__name__)
23 class _FakeSignaller(object):
32 class _MissedCallWatcher(QtCore.QObject):
34 callMissed = QtCore.pyqtSignal()
37 QtCore.QObject.__init__(self)
38 self._isStarted = False
39 self._isSupported = True
41 self._newChannelSignaller = telepathy_utils.NewChannelSignaller(self._on_new_channel)
42 self._outstandingRequests = []
45 def isSupported(self):
46 return self._isSupported
50 return self._isStarted
54 _moduleLogger.info("voicemail monitor already started")
57 self._newChannelSignaller.start()
59 _moduleLogger.exception("Missed call detection not supported")
60 self._newChannelSignaller = _FakeSignaller()
61 self._isSupported = False
62 self._isStarted = True
65 if not self._isStarted:
66 _moduleLogger.info("voicemail monitor stopped without starting")
68 _moduleLogger.info("Stopping voicemail refresh")
69 self._newChannelSignaller.stop()
71 # I don't want to trust whether the cancel happens within the current
72 # callback or not which could be the deciding factor between invalid
73 # iterators or infinite loops
74 localRequests = [r for r in self._outstandingRequests]
75 for request in localRequests:
76 localRequests.cancel()
78 self._isStarted = False
80 @misc_utils.log_exception(_moduleLogger)
81 def _on_new_channel(self, bus, serviceName, connObjectPath, channelObjectPath, channelType):
82 if channelType != telepathy.interfaces.CHANNEL_TYPE_STREAMED_MEDIA:
85 conn = telepathy.client.Connection(serviceName, connObjectPath)
87 chan = telepathy.client.Channel(serviceName, channelObjectPath)
88 except dbus.exceptions.UnknownMethodException:
89 _moduleLogger.exception("Client might not have implemented a deprecated method")
91 missDetection = telepathy_utils.WasMissedCall(
92 bus, conn, chan, self._on_missed_call, self._on_error_for_missed
94 self._outstandingRequests.append(missDetection)
96 @misc_utils.log_exception(_moduleLogger)
97 def _on_missed_call(self, missDetection):
98 _moduleLogger.info("Missed a call")
99 self.callMissed.emit()
100 self._outstandingRequests.remove(missDetection)
102 @misc_utils.log_exception(_moduleLogger)
103 def _on_error_for_missed(self, missDetection, reason):
104 _moduleLogger.debug("Error: %r claims %r" % (missDetection, reason))
105 self._outstandingRequests.remove(missDetection)
108 class _DummyMissedCallWatcher(QtCore.QObject):
110 callMissed = QtCore.pyqtSignal()
113 QtCore.QObject.__init__(self)
114 self._isStarted = False
117 def isSupported(self):
122 return self._isStarted
125 self._isStarted = True
128 if not self._isStarted:
129 _moduleLogger.info("voicemail monitor stopped without starting")
131 _moduleLogger.info("Stopping voicemail refresh")
132 self._isStarted = False
135 if telepathy is not None:
136 MissedCallWatcher = _MissedCallWatcher
138 MissedCallWatcher = _DummyMissedCallWatcher
141 if __name__ == "__main__":