예제 #1
0
class RenameGui(BaseWindow, QtGui.QMainWindow):
    renameCompleted = QtCore.pyqtSignal()

    def __init__(self, session, parent=None):
        super(RenameGui, self).__init__(parent)

        self.session = session

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.renameUser.clicked.connect(self.renameUser)

        self.progressIndicator = QProgressBar(self.ui.statusBar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)
        self.ui.statusBar.addWidget(self.progressIndicator)

        self.renameCompleted.connect(self.renameCompletedSlot)

        self.uiTranslate()

    def uiTranslate(self):
        self.setWindowTitle(strings["renameWindowTitle"])
        self.ui.newUsername.setPlaceholderText(strings["newUsernameBoxHint"])
        self.ui.renameUser.setText(strings["renameUserButtonText"])

    def renameCompletedSlot(self):
        self.progressIndicator.setVisible(False)
        self.showMessageBox.emit(strings["renameSuccessText"])

    def renameUser(self):
        self.progressIndicator.setVisible(True)

        def renameThread():
            newUsername = self.ui.newUsername.text()
            if newUsername == "":
                self.showMessageBox.emit(strings["missingFieldsErrorText"])
                return
            try:
                oldUsername = self.session.username
                self.session.renameUser(newUsername)
                for message in sharedData.messages:
                    if message.sender == oldUsername:
                        message.sender = newUsername
                    elif message.receiver == oldUsername:
                        message.receiver = newUsername
                storeMessages(self.session.username, sharedData.messages)
                storeToken(self.session.username, self.session.token)
                storeKey(self.session.username, self.session.public, self.session.private)
                storeMessages(oldUsername, None)
                storeToken(oldUsername, None)
                storeKey(oldUsername, None, None)
                self.renameCompleted.emit()
            except SecureMessagingException as error:
                self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
                return

        Thread(target=renameThread).start()
예제 #2
0
class ForgotPasswordUi(BaseWindow, QtGui.QMainWindow):
    requestSendingCompleted = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(ForgotPasswordUi, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.forgot.clicked.connect(self.forgot)
        self.ui.forgot.setDefault(True)
        self.shortcut = QtGui.QShortcut(QtGui.QKeySequence("Return"), self)
        self.shortcut.activated.connect(self.forgot)
        self.shortcut2 = QtGui.QShortcut(QtGui.QKeySequence("Up"), self)
        self.shortcut2.activated.connect(self.focusUp)
        self.shortcut2 = QtGui.QShortcut(QtGui.QKeySequence("Down"), self)
        self.shortcut2.activated.connect(self.focusDown)

        self.progressIndicator = QProgressBar(self.ui.statusBar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)
        self.ui.statusBar.addWidget(self.progressIndicator)

        self.requestSendingCompleted.connect(self.requestSendingCompleteSlot)

        self.uiTranslate()

    def uiTranslate(self):
        self.setWindowTitle(strings["forgotPasswordWindowTitle"])
        self.ui.username.setPlaceholderText(strings["usernameBoxHint"])
        self.ui.email.setPlaceholderText(strings["emailBoxHint"])
        self.ui.forgot.setText(strings["forgotPasswordButtonText"])

    def requestSendingCompleteSlot(self):
        self.progressIndicator.setVisible(False)
        self.showMessageBox.emit(strings["forgotSuccessText"])

    def focusUp(self):
        self.ui.username.setFocus()

    def focusDown(self):
        self.ui.email.setFocus()

    def forgot(self):
        self.progressIndicator.setVisible(True)

        def requestSenderThread():
            if self.ui.username.text() and self.ui.email.text():
                try:
                    requestRecovery(self.ui.username.text(), self.ui.email.text())
                    self.requestSendingCompleted.emit()
                except SecureMessagingException as error:
                    self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
            else:
                self.showMessageBox.emit(strings["missingFieldsErrorText"])

        Thread(target=requestSenderThread).start()
예제 #3
0
class AddUserGui(BaseWindow):
    addUserCompleted = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(AddUserGui, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.adduser.clicked.connect(self.adduser)

        self.progressIndicator = QProgressBar(self.ui.statusBar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)
        self.ui.statusBar.addWidget(self.progressIndicator)

        self.addUserCompleted.connect(self.addUserCompletedSlot)

        self.uiTranslate()

    def uiTranslate(self):
        self.setWindowTitle(strings["registerUserWindowTitle"])
        self.ui.username.setPlaceholderText(strings["usernameBoxHint"])
        self.ui.password.setPlaceholderText(strings["passwordBoxHint"])
        self.ui.email.setPlaceholderText(strings["emailBoxHint"])
        self.ui.confirm.setPlaceholderText(strings["confirmPasswordBoxHint"])
        self.ui.adduser.setText(strings["registerUserButtonText"])

    def addUserCompletedSlot(self):
        self.progressIndicator.setVisible(False)
        self.showMessageBox.emit(strings["registrationSuccessText"])

    def adduser(self):
        self.progressIndicator.setVisible(True)

        def addUserThread():
            name = self.ui.username.text()
            password = self.ui.password.text()
            confirm = self.ui.confirm.text()
            email = self.ui.email.text()
            if name == "" or password == "" or email == "":
                self.showMessageBox.emit(strings["missingFieldsErrorText"])
                return
            if password != confirm:
                self.showMessageBox.emit(strings["passwordsDontMatchErrorText"])
                return
            try:
                addUser(name, email, password)
                self.addUserCompleted.emit()
            except SecureMessagingException as error:
                self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
                return

        Thread(target=addUserThread).start()
예제 #4
0
class MainWinGui(QtGui.QMainWindow):
    progressIndeterminate = QtCore.pyqtSignal()
    progressSet = QtCore.pyqtSignal(int)
    progressStop = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(MainWinGui, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.myName.setText(getStoredName() or "")

        self.ui.myName.textEdited.connect(self.nameChanged)

        self.communicator = Communicator(self)
        self.communicator.peersUpdated.connect(self.refreshPeers)
        self.communicator.fileReceived.connect(self.fileReceived)

        self.ui.refreshPeersButton.clicked.connect(self.discoverPeers)
        self.ui.peerList.itemClicked.connect(self.peerSelected)

        self.progressIndeterminate.connect(self.progressIndeterminateSlot)
        self.progressSet.connect(self.progressSetSlot)
        self.progressStop.connect(self.progressStopSlot)

        self.progressIndicator = QProgressBar(self.ui.statusbar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)
        self.ui.statusbar.addWidget(self.progressIndicator)

    def nameChanged(self, newName):
        storeName(newName)
        self.communicator.updateName(newName)

    def progressStart(self):
        self.progressIndicator.setVisible(True)

    def progressSetSlot(self, value):
        self.progressStart()
        self.progressIndicator.setMaximum(100)
        self.progressIndicator.setValue(value)

    def progressIndeterminateSlot(self):
        self.progressStart()
        self.progressIndicator.setMaximum(0)

    def progressStopSlot(self):
        self.progressIndicator.setVisible(False)

    def show(self):
        super(MainWinGui, self).show()
        self.refreshPeers()
        self.discoverPeers()

    def discoverPeers(self):
        self.communicator.discoverPeers()

    def refreshPeers(self):
        self.ui.peerList.clear()
        for peer in self.communicator.peers:
            peer = self.communicator.peers[peer]
            peerName = QListWidgetItem(self.ui.peerList)
            peerName.peer = peer
            nameFont = QtGui.QFont()
            nameFont.setPointSize(14)
            peerDetails = QListWidgetItem(self.ui.peerList)
            peerDetails.peer = peer
            detailsFont = QtGui.QFont()
            detailsFont.setPointSize(10)
            name = peer.name
            details = ""
            if peer.publicKey is None:
                details += "Unpaired, "
            else:
                details += "Paired, "
            if peer.lastKnownIP is None:
                details += "unavailable"
            else:
                details += "available: " + peer.lastKnownIP
            peerName.setFont(nameFont)
            peerName.setText(name)
            peerDetails.setFont(detailsFont)
            peerDetails.setText(details)
            self.ui.peerList.addItem(peerName)
            self.ui.peerList.addItem(peerDetails)
            separatorItem = QListWidgetItem(self.ui.peerList)
            separatorItem.guid = peer.guid
            separatorItem.peer = None
            separatorItem.setFlags(QtCore.Qt.NoItemFlags)
            self.ui.peerList.addItem(separatorItem)

    def peerSelected(self, selectedItem):
        selectedItem.setSelected(False)
        if selectedItem.peer:
            PeerOptionsUi(self, selectedItem.peer, self.communicator).show()
        else:
            pass

    def sendFile(self, guid):
        fileName = QtGui.QFileDialog.getOpenFileName()
        if not fileName:
            return
        fileContents = open(fileName, "rb").read()
        basename = os.path.basename(fileName)
        self.communicator.sendFile(basename, fileContents, guid)

    def fileReceived(self, fileName, fileContents):
        fileName = QtGui.QFileDialog.getSaveFileName(directory=fileName)
        if not fileName:
            return
        with open(fileName, mode="wb") as file:
            file.write(fileContents)
예제 #5
0
class LoginWinGui(BaseWindow, QtGui.QMainWindow):
    loginComplete = QtCore.pyqtSignal(Session)

    def __init__(self, parent=None):
        super(LoginWinGui, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.login.clicked.connect(self.login)
        self.ui.login.setDefault(True)
        self.ui.adduser.triggered.connect(self.adduser)
        self.ui.forgot.triggered.connect(self.forgot)
        QtGui.QShortcut(QtGui.QKeySequence("Return"), self).activated.connect(self.login)
        QtGui.QShortcut(QtGui.QKeySequence("Enter"), self).activated.connect(self.login)
        QtGui.QShortcut(QtGui.QKeySequence("Up"), self).activated.connect(self.focusUp)
        QtGui.QShortcut(QtGui.QKeySequence("Down"), self).activated.connect(self.focusDown)
        self.progressIndicator = QProgressBar(self.ui.statusBar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)
        self.ui.statusBar.addWidget(self.progressIndicator)
        self.loginComplete.connect(self.loginCompleteSlot)

        self.uiTranslate()

    def uiTranslate(self):
        self.setWindowTitle(strings["loginWindowTitle"])
        self.ui.username.setPlaceholderText(strings["usernameBoxHint"])
        self.ui.password.setPlaceholderText(strings["passwordBoxHint"])
        self.ui.login.setText(strings["loginButtonText"])
        self.ui.adduser.setText(strings["registerUserWindowTitle"])
        self.ui.forgot.setText(strings["forgotPasswordWindowTitle"])
        self.ui.menuTools.setTitle(strings["toolsMenuText"])

    def loginCompleteSlot(self, session):
        self.progressIndicator.setVisible(False)
        self.mainWin = ConversationsWinGui(session)
        self.mainWin.windowClosed.connect(self.close)
        self.mainWin.loggedOut.connect(self.loggedOut)
        self.mainWin.show()
        self.hide()

    def loggedOut(self):
        self.show()
        self.mainWin.windowClosed.disconnect(self.close)
        self.mainWin.close()

    def onMainClose(self):
        pass

    def focusUp(self):
        self.ui.username.setFocus()

    def focusDown(self):
        self.ui.password.setFocus()

    def login(self):
        self.progressIndicator.setVisible(True)

        def loginThread():
            username = self.ui.username.text()
            password = self.ui.password.text()
            if username == "" or password == "":
                self.showMessageBox.emit(strings["missingFieldsErrorText"])
                return
            try:
                if storage.getToken(username) and storage.getKey(username):
                    token = storage.getToken(username)
                    public, private = storage.getKey(username)
                    newSession = Session(username, password, token, public, private)
                    storage.storeKey(newSession.username, newSession.public, newSession.private)
                else:
                    token, public, private = Session.requestNewToken(username, password)
                    newSession = Session(username, password, token, public, private)
                    storage.storeToken(newSession.username, token)
                    storage.storeKey(newSession.username, newSession.public, newSession.private)
                self.loginComplete.emit(newSession)
            except SecureMessagingException as error:
                if error.message == HTTPStrings.RESPONSE_UNAUTHORIZED:
                    storage.storeKey(username, None, None)
                    storage.storeToken(username, None)
                    loginThread()
                    return
                self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])

        Thread(target=loginThread).start()

    def adduser(self):
        addUserGui = AddUserGui(parent=self)
        addUserGui.show()

    def forgot(self):
        forgotUi = ForgotPasswordUi(parent=self)
        forgotUi.show()
예제 #6
0
class MainWinGui(BaseWindow, QtGui.QMainWindow):
    refreshDisplay = QtCore.pyqtSignal()
    sendCompleted = QtCore.pyqtSignal(Message)
    fileDownloadCompleted = QtCore.pyqtSignal(bytes, str)
    onClose = QtCore.pyqtSignal(str)

    def __init__(self, session, peerName, parent=None):
        super(MainWinGui, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.session = session
        self.peerName = peerName
        if peerName == "":
            self.ui.peerName.setVisible(False)
            self.ui.peer.setVisible(True)
            self.ui.peer.setText("")
            self.ui.peer.setFocus()
        else:
            self.ui.peerName.setVisible(True)
            self.ui.peer.setVisible(False)
            self.ui.peer.setText(peerName)
            self.ui.peerName.setText(peerName)
            self.ui.message.setFocus()

        self.ui.refresh.clicked.connect(self.refresh)
        self.ui.send.clicked.connect(self.send)
        self.ui.scrollBar = self.ui.display.verticalScrollBar()
        self.ui.display.setOpenLinks(False)
        self.ui.display.anchorClicked.connect(self.linkClicked)
        self.ui.display.anchorClicked.emit(QtCore.QUrl("UP"))

        self.refreshShortcut = QtGui.QShortcut(QtGui.QKeySequence("F5"), self)
        self.refreshShortcut.activated.connect(self.refresh)

        self.enterShortcut = QtGui.QShortcut(QtGui.QKeySequence("Enter"), self)
        self.returnShortcut = QtGui.QShortcut(QtGui.QKeySequence("Return"), self)
        self.enterShortcut.activated.connect(self.enterPressed)
        self.returnShortcut.activated.connect(self.enterPressed)
        self.ui.message.keyPressEvent = types.MethodType(keyPressEventReplacement, self.ui.message)

        self.ui.uploadFile.triggered.connect(self.uploadFile)

        self.ui.deleteMessages.triggered.connect(self.clearMessages)

        self.ui.stopSigning.triggered.connect(self.clearSigningSecret)

        self.ui.signMessages.triggered.connect(self.askForSigningSecret)

        self.ui.message.parentWindow = self

        self.refreshDisplay.connect(self.refreshDisplaySlot)
        self.sendCompleted.connect(self.sendCompletedSlot)
        self.fileDownloadCompleted.connect(self.fileDownloadCompletedSlot)

        self.progressIndicator = QProgressBar(self.ui.statusBar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)

        self.signatureIndicator = QLabel(self.ui.statusBar)

        self.ui.statusBar.addWidget(self.progressIndicator)
        self.ui.statusBar.addPermanentWidget(self.signatureIndicator)

        self.signingSecret = None

        self.uiTranslate()

        self.refresh()

    def uiTranslate(self):
        self.ui.peer.setPlaceholderText(strings["peerBoxHint"])
        self.ui.refresh.setText(strings["refreshButtonText"])
        self.ui.send.setText(strings["sendMessageButtonText"])
        self.ui.deleteMessages.setText(strings["deleteConversationButtonText"])
        self.setWindowTitle(strings["conversationWindowTitle"] + ": " + self.peerName)
        self.ui.menuTools.setTitle(strings["toolsMenuText"])
        self.ui.uploadFile.setText(strings["uploadFileButtonText"])
        self.ui.stopSigning.setText(strings["stopSigningButtonText"])
        self.ui.signMessages.setText(strings["signMessagesButtonText"])
        self.signatureIndicator.setText(strings["signatureIndicatorOffText"])

    def enterPressed(self):
        if self.ui.peer.hasFocus():
            self.ui.message.setFocus()

    def progressStart(self):
        self.progressIndicator.setVisible(True)

    def askForConfirmation(self, message):
        confirmationBox = QtGui.QMessageBox(parent=self, text=message)
        confirmationBox.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
        confirmationBox.setWindowTitle(strings["appName"])
        return confirmationBox.exec() == QtGui.QMessageBox.Yes

    def askForSigningSecret(self):
        response = QInputDialog.getText(
            self, strings["signatureSecretInputTitle"], strings["signatureSecretInputLabel"]
        )
        if response[1]:
            self.signingSecret = response[0].encode("utf-8")
            self.signatureIndicator.setText(strings["signatureIndicatorOnText"])

    def clearSigningSecret(self):
        self.signingSecret = None
        self.signatureIndicator.setText(strings["signatureIndicatorOffText"])

    def progressStop(self):
        self.progressIndicator.setVisible(False)

    def fileDownloadCompletedSlot(self, contents, fileName):
        self.progressStop()
        try:
            with open(fileName, mode="wb") as file:
                file.write(contents)
        except (SecureMessagingException, IOError) as error:
            self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
            return

    def sendCompletedSlot(self, message):
        sharedData.messages += [message]
        self.ui.message.clear()
        self.ui.peerName.setText(self.ui.peer.text())
        self.ui.peer.setVisible(False)
        self.ui.peerName.setVisible(True)
        self.peerName = self.ui.peer.text()
        self.setWindowTitle(strings["conversationWindowTitle"] + ": " + self.peerName)
        self.refresh()

    def show(self):
        super(MainWinGui, self).show()
        self.refreshDisplay.emit()

    def linkClicked(self, url):
        url = url.toString()
        if url == "UP":
            return
        if url.startswith("FILE"):
            messageId = url[len("FILE") :]
            messageId = int(messageId)
            message = sharedData.messages[messageId]
            fileName = QtGui.QFileDialog.getSaveFileName(directory=message.fileName)
            if fileName:
                self.progressStart()

                def fileDownloaderThread():
                    try:
                        fileContents = self.session.downloadFile(message)
                        self.fileDownloadCompleted.emit(fileContents, fileName)
                    except (SecureMessagingException, IOError) as error:
                        self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
                        return

                Thread(target=fileDownloaderThread).start()
        elif url.startswith("DEL_"):
            messageId = int(url[len("DEL_") :])
            if self.askForConfirmation(strings["confirmDeleteMessageText"]):
                sharedData.messages.pop(messageId)
                storeMessages(self.session.username, sharedData.messages)
                self.refreshDisplay.emit()
        elif url.startswith("SGN_"):
            messageId = int(url[len("SGN_") :])
            message = sharedData.messages[messageId]
            response = QInputDialog.getText(
                self, strings["signatureSecretInputTitle"], strings["signatureSecretInputLabel"]
            )
            if response[1]:
                if message.verifySignature(response[0].encode("utf-8")):
                    self.showMessageBox.emit(strings["signatureOkMessageText"])
                else:
                    self.showMessageBox.emit(strings["signatureBadMessageText"])

    def refreshDisplaySlot(self):
        outputText = '<table width="100%" cellpadding="5" border="" style="padding:15px;width:100%;">'
        peer = self.ui.peer.text()
        msgCount = -1
        for message in sharedData.messages:
            msgCount += 1
            if message.messagePeer != peer:
                continue
            contents = message.contents
            contents = escape(contents)
            if message.isFile:
                contents = (
                    '<a href ="FILE' + str(sharedData.messages.index(message)) + '">File: ' + message.fileName + "</a>"
                )
            if message.sender == self.session.username:
                outputText += '<tr style="background-color:#cadced;color:#000000"><td>'
            else:
                outputText += '<tr style="background-color:#FFFFFF;color:#000000"><td>'
            outputText += "<b>" + message.sender + "</b>&#10153;<b>" + message.receiver + "</b>"
            outputText += "<pre style='word-break:break-all;white-space:pre-wrap;font-family:Arial'>"
            outputText += contents
            outputText += "</pre>"
            outputText += (
                "<a style='text-decoration:none;color:#000000' href='"
                + "DEL_"
                + str(msgCount)
                + "'><font size='1'>&#9003;</font></a>"
            )
            if message.isSigned():
                outputText += (
                    "&emsp;<a style='text-decoration:none;color:#000000' href='"
                    + "SGN_"
                    + str(msgCount)
                    + "'><font size='1'>&#10004;</font></a>"
                )
            outputText += "<div style='font-size:small;' align='right'>" + message.getTimeStamp() + "</div>"
            outputText += "</td></tr>"
        outputText += "</table>"
        self.ui.display.setHtml(outputText)
        self.ui.display.verticalScrollBar().setValue(self.ui.display.verticalScrollBar().maximum())
        self.progressStop()

    def refresh(self):
        self.progressStart()

        def refreshThread():
            try:
                sharedData.messages += self.session.getMessages()
            except SecureMessagingException as error:
                self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
                return
            sharedData.messages = sorted(sharedData.messages, key=messageSort)
            sharedData.markAsRead(self.ui.peer.text())
            storeMessages(self.session.username, sharedData.messages)
            self.refreshDisplay.emit()

        Thread(target=refreshThread).start()

    def send(self):
        self.progressStart()

        def senderThread():
            peer = self.ui.peer.text()
            contents = self.ui.message.toPlainText()
            if peer == "" or contents == "":
                self.showMessageBox.emit(strings["missingPeerOrMessageErrorText"])
                return
            if peer == self.session.username:
                self.showMessageBox.emit(strings["cantSendMessageToSelfText"])
                return
            sharedData.messages = sorted(sharedData.messages, key=messageSort)
            try:
                self.session.sendMessage(contents, peer, signatureSecret=self.signingSecret)
            except SecureMessagingException as error:
                self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
                return
            self.sendCompleted.emit(Message(contents, self.session.username, peer, peer, self.session.timeDiff))

        Thread(target=senderThread).start()

    def uploadFile(self):
        peer = self.ui.peer.text()
        if peer == "":
            self.showMessageBox.emit(strings["missingPeerErrorText"])
            return
        if peer == self.session.username:
            self.showMessageBox.emit(strings["cantSendMessageToSelfText"])
            return
        fileName = QtGui.QFileDialog.getOpenFileName()
        if fileName:
            self.progressStart()

            def uploaderThread():
                try:
                    fileContents = open(fileName, "rb").read()
                    basename = os.path.basename(fileName)
                    fileType = mimetypes.guess_type("file://" + fileName)[0] or "application/octet-stream"
                    fileType = fileType.encode("ascii")
                    self.session.sendFile(basename, fileContents, peer, fileType)
                    self.sendCompleted.emit(Message(basename, self.session.username, peer, peer, self.session.timeDiff))
                except (SecureMessagingException, IOError) as error:
                    self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
                    return

            Thread(target=uploaderThread).start()

    def clearMessages(self):
        if self.peerName and self.askForConfirmation(strings["confirmDeleteConversationText"]):
            numberOfMessages = len(sharedData.messages)
            deletedMessages = 0
            for i in range(numberOfMessages):
                if sharedData.messages[i - deletedMessages].messagePeer == self.peerName:
                    sharedData.messages.pop(i - deletedMessages)
                    deletedMessages += 1
            storeMessages(self.session.username, sharedData.messages)
            self.refreshDisplay.emit()

    def closeEvent(self, event):
        self.onClose.emit(self.ui.peer.text())
        super(MainWinGui, self).closeEvent(event)
예제 #7
0
class ConversationsWinGui(BaseWindow, QtGui.QMainWindow):
    refreshList = QtCore.pyqtSignal()
    loggedOut = QtCore.pyqtSignal()
    windowClosed = QtCore.pyqtSignal()

    def __init__(self, session, parent=None):
        super(ConversationsWinGui, self).__init__(parent=parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.activeConversationWindows = {}
        self.newConversationWindow = None

        self.session = session
        sharedData.messages = getMessages(self.session.username) or []

        self.ui.refresh.clicked.connect(self.refresh)
        self.ui.logout.triggered.connect(self.logout)

        self.refreshShortcut = QtGui.QShortcut(QtGui.QKeySequence("F5"), self)
        self.refreshShortcut.activated.connect(self.refresh)

        self.setPeerShortcut = QtGui.QShortcut(QtGui.QKeySequence("Return"), self)
        self.setPeerShortcut.activated.connect(self.refresh)
        self.setPeerShortcut.setEnabled(False)

        self.refreshList.connect(self.refreshListSlot)

        self.ui.newConversation.clicked.connect(self.startNewConversation)

        self.ui.conversationsList.itemClicked.connect(self.conversationSelected)

        self.ui.unauthorizeClient.triggered.connect(self.unauthorize)

        self.ui.deleteMessages.triggered.connect(self.clearMessages)

        self.ui.setPassword.triggered.connect(self.setPassword)

        self.ui.markAllAsRead.triggered.connect(self.markAllAsRead)

        self.ui.renameUser.triggered.connect(self.renameUser)

        self.progressIndicator = QProgressBar(self.ui.statusBar)
        self.progressIndicator.setMinimumHeight(5)
        self.progressIndicator.setVisible(False)
        self.progressIndicator.setMaximum(0)
        self.progressIndicator.setMinimum(0)
        self.ui.statusBar.addWidget(self.progressIndicator)

        self.uiTranslate()

        self.refresh()

    def uiTranslate(self):
        self.ui.refresh.setText(strings["refreshButtonText"])
        self.ui.logout.setText(strings["logoutButtonText"])
        self.ui.unauthorizeClient.setText(strings["unauthorizeClientButtonText"])
        self.ui.deleteMessages.setText(strings["deleteAllMessagesButtonText"])
        self.ui.setPassword.setText(strings["setPasswordWindowTitle"])
        self.setWindowTitle(strings["appName"] + ": " + self.session.username)
        self.ui.newConversation.setText(strings["startNewConversationButtonText"])
        self.ui.menuTools.setTitle(strings["toolsMenuText"])
        self.ui.markAllAsRead.setText(strings["markAllAsReadButtonText"])
        self.ui.renameUser.setText(strings["renameUserButtonText"])

    def progressStart(self):
        self.progressIndicator.setVisible(True)

    def askForConfirmation(self, message):
        confirmationBox = QtGui.QMessageBox(parent=self, text=message)
        confirmationBox.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
        confirmationBox.setWindowTitle(strings["appName"])
        return confirmationBox.exec() == QtGui.QMessageBox.Yes

    def progressStop(self):
        self.progressIndicator.setVisible(False)

    def show(self):
        super(ConversationsWinGui, self).show()
        self.refreshList.emit()

    def refresh(self):
        self.progressStart()

        def refreshThread():
            try:
                sharedData.messages += self.session.getMessages()
            except SecureMessagingException as error:
                self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
                print(error)
                return
            sharedData.messages = sorted(sharedData.messages, key=messageSort)
            storeMessages(self.session.username, sharedData.messages)
            self.refreshList.emit()

        Thread(target=refreshThread).start()

    def refreshListSlot(self, refreshChildren=True):
        seenPeers = set()
        self.ui.conversationsList.clear()
        for message in reversed(sharedData.messages):
            if not message.messagePeer in seenPeers:
                seenPeers.add(message.messagePeer)
                peerName = QListWidgetItem(self.ui.conversationsList)
                nameFont = QtGui.QFont()
                contentsFont = QtGui.QFont()
                nameFont.setPointSize(14)
                if not message.read:
                    nameFont.setBold(True)
                    contentsFont.setBold(True)
                peerName.setFont(nameFont)
                peerName.setText(message.messagePeer)
                messageContents = QListWidgetItem(self.ui.conversationsList)
                if message.isFile:
                    contentLines = [message.fileName]
                elif not message.contents:
                    contentLines = [""]
                else:
                    contentLines = message.contents.splitlines(keepends=False)
                contentsFont.setPointSize(10)
                contents = contentLines[0]
                if len(contentLines) > 1:
                    contents += "\n" + contentLines[1]
                if len(contents) > 20:
                    contents = contents[:20]
                messageContents.setFont(contentsFont)
                messageContents.setText(contents)
                self.ui.conversationsList.addItem(peerName)
                self.ui.conversationsList.addItem(messageContents)
                separatorItem = QListWidgetItem(self.ui.conversationsList)
                separatorItem.setFlags(QtCore.Qt.NoItemFlags)
                self.ui.conversationsList.addItem(separatorItem)
        if refreshChildren:
            for peerName in self.activeConversationWindows:
                self.activeConversationWindows[peerName].refreshDisplay.emit()
        self.progressStop()

    def startNewConversation(self):
        if self.newConversationWindow:
            self.newConversationWindow.activateWindow()
            return
        self.newConversationWindow = MainWinGui(self.session, "")
        self.newConversationWindow.refreshDisplay.connect(self.refreshTriggeredInChild)
        self.newConversationWindow.onClose.connect(self.newConversationWindowClosed)
        self.newConversationWindow.sendCompleted.connect(self.conversationStarted)
        self.newConversationWindow.show()

    def conversationStarted(self, message):
        if message.messagePeer in self.activeConversationWindows:
            self.activeConversationWindows[message.messagePeer].close()
        self.newConversationWindow.onClose.disconnect(self.newConversationWindowClosed)
        self.newConversationWindow.sendCompleted.disconnect(self.conversationStarted)
        self.newConversationWindow.onClose.connect(lambda peerName: self.activeConversationWindows.pop(peerName))
        self.activeConversationWindows[message.messagePeer] = self.newConversationWindow
        self.newConversationWindow = None

    def newConversationWindowClosed(self, *args, **kwargs):
        self.newConversationWindow = None

    def conversationSelected(self, listItem):
        row = self.ui.conversationsList.indexFromItem(listItem).row()
        selectedPeer = ""
        if row % 3 == 0:
            selectedPeer += listItem.text()
        elif row % 3 == 1:
            selectedPeer += self.ui.conversationsList.item(row - 1).text()
        else:
            listItem.setSelected(False)
        if selectedPeer != "":
            if selectedPeer in self.activeConversationWindows:
                self.activeConversationWindows[selectedPeer].activateWindow()
            else:
                newWindow = MainWinGui(self.session, selectedPeer)
                self.activeConversationWindows[selectedPeer] = newWindow
                newWindow.onClose.connect(lambda peerName: self.activeConversationWindows.pop(peerName))
                newWindow.refreshDisplay.connect(self.refreshTriggeredInChild)
                newWindow.show()

    def refreshTriggeredInChild(self):
        self.refreshListSlot(False)

    def clearMessages(self):
        if self.askForConfirmation(strings["confirmDeleteAllMessagesText"]):
            sharedData.messages = []
            storeMessages(self.session.username, None)
            self.refreshList.emit()

    def setPassword(self):
        setPasswordUi = SetPasswordGui(self.session, parent=self)
        setPasswordUi.show()

    def renameUser(self):
        renameUi = RenameGui(self.session, parent=self)
        renameUi.show()

    def logout(self):
        self.session.logout()
        self.loggedOut.emit()

    def unauthorize(self):
        if self.askForConfirmation(strings["confirmUnauthorizeClientText"]):
            try:
                self.session.unauthorize()
            except SecureMessagingException as error:
                self.showMessageBox.emit(strings["errorText"] + responseTranslations[str(error)])
                return
            storeMessages(self.session.username, None)
            storeToken(self.session.username, None)
            storeKey(self.session.username, None, None)
            self.logout()

    def closeEvent(self, *args, **kwargs):
        windowsToClose = []
        for window in self.activeConversationWindows:
            windowsToClose += [self.activeConversationWindows[window]]
        for window in windowsToClose:
            window.close()
        if self.newConversationWindow:
            self.newConversationWindow.close()
        self.windowClosed.emit()

    def markAllAsRead(self):
        sharedData.markAsRead()
        storeMessages(self.session.username, sharedData.messages)
        self.refreshList.emit()