+class VoicemailPlayer(object):
+
+ def __init__(self, app, session, errorLog):
+ self._app = app
+ self._session = session
+ self._errorLog = errorLog
+ self._token = None
+ self._session.voicemailAvailable.connect(self._on_voicemail_downloaded)
+ self._session.draft.recipientsChanged.connect(self._on_recipients_changed)
+
+ self._playButton = QtGui.QPushButton("Play")
+ self._playButton.clicked.connect(self._on_voicemail_play)
+ self._pauseButton = QtGui.QPushButton("Pause")
+ self._pauseButton.clicked.connect(self._on_voicemail_pause)
+ self._pauseButton.hide()
+ self._resumeButton = QtGui.QPushButton("Resume")
+ self._resumeButton.clicked.connect(self._on_voicemail_resume)
+ self._resumeButton.hide()
+ self._stopButton = QtGui.QPushButton("Stop")
+ self._stopButton.clicked.connect(self._on_voicemail_stop)
+ self._stopButton.hide()
+
+ self._downloadButton = QtGui.QPushButton("Download Voicemail")
+ self._downloadButton.clicked.connect(self._on_voicemail_download)
+ self._downloadLayout = QtGui.QHBoxLayout()
+ self._downloadLayout.addWidget(self._downloadButton)
+ self._downloadWidget = QtGui.QWidget()
+ self._downloadWidget.setLayout(self._downloadLayout)
+
+ self._playLabel = QtGui.QLabel("Voicemail")
+ self._saveButton = QtGui.QPushButton("Save")
+ self._saveButton.clicked.connect(self._on_voicemail_save)
+ self._playerLayout = QtGui.QHBoxLayout()
+ self._playerLayout.addWidget(self._playLabel)
+ self._playerLayout.addWidget(self._playButton)
+ self._playerLayout.addWidget(self._pauseButton)
+ self._playerLayout.addWidget(self._resumeButton)
+ self._playerLayout.addWidget(self._stopButton)
+ self._playerLayout.addWidget(self._saveButton)
+ self._playerWidget = QtGui.QWidget()
+ self._playerWidget.setLayout(self._playerLayout)
+
+ self._visibleWidget = None
+ self._layout = QtGui.QHBoxLayout()
+ self._layout.setContentsMargins(0, 0, 0, 0)
+ self._widget = QtGui.QWidget()
+ self._widget.setLayout(self._layout)
+ self._update_state()
+
+ @property
+ def toplevel(self):
+ return self._widget
+
+ def destroy(self):
+ self._session.voicemailAvailable.disconnect(self._on_voicemail_downloaded)
+ self._session.draft.recipientsChanged.disconnect(self._on_recipients_changed)
+ self._invalidate_token()
+
+ def _invalidate_token(self):
+ if self._token is not None:
+ self._token.invalidate()
+ self._token.error.disconnect(self._on_play_error)
+ self._token.stateChange.connect(self._on_play_state)
+ self._token.invalidated.connect(self._on_play_invalidated)
+
+ def _show_download(self, messageId):
+ if self._visibleWidget is self._downloadWidget:
+ return
+ self._hide()
+ self._layout.addWidget(self._downloadWidget)
+ self._visibleWidget = self._downloadWidget
+ self._visibleWidget.show()
+
+ def _show_player(self, messageId):
+ if self._visibleWidget is self._playerWidget:
+ return
+ self._hide()
+ self._layout.addWidget(self._playerWidget)
+ self._visibleWidget = self._playerWidget
+ self._visibleWidget.show()
+
+ def _hide(self):
+ if self._visibleWidget is None:
+ return
+ self._visibleWidget.hide()
+ self._layout.removeWidget(self._visibleWidget)
+ self._visibleWidget = None
+
+ def _update_play_state(self):
+ if self._token is not None and self._token.isValid:
+ self._playButton.setText("Stop")
+ else:
+ self._playButton.setText("Play")
+
+ def _update_state(self):
+ if self._session.draft.get_num_contacts() != 1:
+ self._hide()
+ return
+
+ (cid, ) = self._session.draft.get_contacts()
+ messageId = self._session.draft.get_message_id(cid)
+ if messageId is None:
+ self._hide()
+ return
+
+ if self._session.is_available(messageId):
+ self._show_player(messageId)
+ else:
+ self._show_download(messageId)
+ if self._token is not None:
+ self._token.invalidate()
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_voicemail_save(self, arg):
+ with qui_utils.notify_error(self._app.errorLog):
+ targetPath = QtGui.QFileDialog.getSaveFileName(None, caption="Save Voicemail", filter="Audio File (*.mp3)")
+ targetPath = unicode(targetPath)
+ if not targetPath:
+ return
+
+ (cid, ) = self._session.draft.get_contacts()
+ messageId = self._session.draft.get_message_id(cid)
+ sourcePath = self._session.voicemail_path(messageId)
+ import shutil
+ shutil.copy2(sourcePath, targetPath)
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_play_error(self, error):
+ with qui_utils.notify_error(self._app.errorLog):
+ self._app.errorLog.push_error(error)
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_play_invalidated(self):
+ with qui_utils.notify_error(self._app.errorLog):
+ self._playButton.show()
+ self._pauseButton.hide()
+ self._resumeButton.hide()
+ self._stopButton.hide()
+ self._invalidate_token()
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_play_state(self, state):
+ with qui_utils.notify_error(self._app.errorLog):
+ if state == self._token.STATE_PLAY:
+ self._playButton.hide()
+ self._pauseButton.show()
+ self._resumeButton.hide()
+ self._stopButton.show()
+ elif state == self._token.STATE_PAUSE:
+ self._playButton.hide()
+ self._pauseButton.hide()
+ self._resumeButton.show()
+ self._stopButton.show()
+ elif state == self._token.STATE_STOP:
+ self._playButton.show()
+ self._pauseButton.hide()
+ self._resumeButton.hide()
+ self._stopButton.hide()
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_voicemail_play(self, arg):
+ with qui_utils.notify_error(self._app.errorLog):
+ (cid, ) = self._session.draft.get_contacts()
+ messageId = self._session.draft.get_message_id(cid)
+ sourcePath = self._session.voicemail_path(messageId)
+
+ self._invalidate_token()
+ uri = "file://%s" % sourcePath
+ self._token = self._app.streamHandler.set_file(uri)
+ self._token.stateChange.connect(self._on_play_state)
+ self._token.invalidated.connect(self._on_play_invalidated)
+ self._token.error.connect(self._on_play_error)
+ self._token.play()
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_voicemail_pause(self, arg):
+ with qui_utils.notify_error(self._app.errorLog):
+ self._token.pause()
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_voicemail_resume(self, arg):
+ with qui_utils.notify_error(self._app.errorLog):
+ self._token.play()
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_voicemail_stop(self, arg):
+ with qui_utils.notify_error(self._app.errorLog):
+ self._token.stop()
+
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_voicemail_download(self, arg):
+ with qui_utils.notify_error(self._app.errorLog):
+ (cid, ) = self._session.draft.get_contacts()
+ messageId = self._session.draft.get_message_id(cid)
+ self._session.download_voicemail(messageId)
+ self._hide()
+
+ @qt_compat.Slot()
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_recipients_changed(self):
+ with qui_utils.notify_error(self._app.errorLog):
+ self._update_state()
+
+ @qt_compat.Slot(str, str)
+ @misc_utils.log_exception(_moduleLogger)
+ def _on_voicemail_downloaded(self, messageId, filepath):
+ with qui_utils.notify_error(self._app.errorLog):
+ self._update_state()
+
+
+class SMSEntryWindow(qwrappers.WindowWrapper):