示例#1
0
class AboutDialog(QDialog, Ui_Dialog):
    def __init__(self, activeconfig):
        super(AboutDialog, self).__init__()
        self.setupUi(self)
        self.translator = QTranslator()
        self.setLanguage(activeconfig.language)

        setIcon(self)

        self.btnMascot.clicked.connect(self.nya)

    def setLanguage(self, language):
        if not self.translator.isEmpty():
            QApplication.removeTranslator(self.translator)
        self.translator.load(f':/l10n/about_{language.value}.qm')
        QApplication.installTranslator(self.translator)
        self.retranslateUi(self)

    def nya(self):
        i = self.stackedEggs.currentIndex()
        i += 1
        i %= 6
        self.stackedEggs.setCurrentIndex(i)
        if i != 0:
            pass
示例#2
0
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, activeConfig, *args, obj=None, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        # pure UI

        self.setupUi(self)

        setIcon(self)

        self.setupLanguageActions()

        # set the language of the UI by looking it up in the config
        self.activeConfig = activeConfig
        self.translator = QTranslator()

        self.file_dialog_translator = QTranslator()

        self.setLanguage(self.activeConfig.language)

        # setup initial values
        self.rngSource = RngSource.CSPRNG
        self.busy = False
        self.encProgress = 0
        self.decProgress = 0
        self.encText = ''
        self.decText = ''

        self.slotActionsIn()

    def slotActionsIn(self):
        # from here on: slotting
        # MENU
        self.actionClose.triggered.connect(closeApp)
        self.actionOpenHelpFile.triggered.connect(self.openHelpFile)
        self.actionOpenOnlineHelp.triggered.connect(self.openProjectWebsite)
        self.actionAbout.triggered.connect(self.about)
        self.actionGerman.triggered.connect(self.setLanguageGerman)
        self.actionEnglish.triggered.connect(self.setLanguageEnglish)
        self.actionReportBug.triggered.connect(self.reportBug)
        # ENCRYPTION
        self.btnAddInputFilesEnc.clicked.connect(self.addInputFilesEnc)
        self.btnRemoveInputFilesEnc.clicked.connect(self.removeInputFilesEnc)
        self.rbANU.clicked.connect(self.rngSourceChanged)
        self.rbCSPRNG.clicked.connect(self.rngSourceChanged)
        self.btnEncrypt.clicked.connect(self.startEncryption)
        # DECRYPTION
        self.btnAddInputFilesDec.clicked.connect(self.addInputFilesDec)
        self.btnRemoveInputFilesDec.clicked.connect(self.removeInputFilesDec)
        self.btnDecrypt.clicked.connect(self.startDecryption)

    def slotActionsOut(self):
        # from here on: slotting
        # MENU
        self.actionClose.triggered.disconnect(closeApp)
        self.actionOpenHelpFile.triggered.disconnect(self.openHelpFile)
        self.actionOpenOnlineHelp.triggered.disconnect(self.openProjectWebsite)
        self.actionAbout.triggered.disconnect(self.about)
        self.actionGerman.triggered.disconnect(self.setLanguageGerman)
        self.actionEnglish.triggered.disconnect(self.setLanguageEnglish)
        self.actionReportBug.triggered.disconnect(self.reportBug)
        # ENCRYPTION
        self.btnAddInputFilesEnc.clicked.disconnect(self.addInputFilesEnc)
        self.btnRemoveInputFilesEnc.clicked.disconnect(
            self.removeInputFilesEnc)
        self.rbANU.clicked.disconnect(self.rngSourceChanged)
        self.rbCSPRNG.clicked.disconnect(self.rngSourceChanged)
        self.btnEncrypt.clicked.disconnect(self.startEncryption)
        # DECRYPTION
        self.btnAddInputFilesDec.clicked.disconnect(self.addInputFilesDec)
        self.btnRemoveInputFilesDec.clicked.disconnect(
            self.removeInputFilesDec)
        self.btnDecrypt.clicked.disconnect(self.startDecryption)

    def setupLanguageActions(self):
        languageActionGroup = QActionGroup(self)
        languageActionGroup.addAction(self.actionEnglish)
        languageActionGroup.addAction(self.actionGerman)
        languageActionGroup.setExclusive(True)

    def openHelpFile(self):
        path = Path().absolute()
        url = f'file://{path}/help/user_manual_{self.activeConfig.language.value}.html'
        webbrowser.open(url, new=2)

    def openProjectWebsite(self):
        if self.activeConfig.language == Language.GERMAN:
            url = 'http://redneptun.net/lokkat/lokkat_de.html'
        else:
            url = 'http://redneptun.net/lokkat/lokkat_en.html'
        webbrowser.open(url, new=2)

    def setLanguageGerman(self):
        self.setLanguage(Language.GERMAN)

    def setLanguageEnglish(self):
        self.setLanguage(Language.ENGLISH)

    def setLanguage(self, language):
        # file dialog
        if not self.file_dialog_translator.isEmpty():
            QApplication.removeTranslator(self.file_dialog_translator)

        qmfile = "qtbase_" + QLocale.system().name().split('_')[0] + '.qm'
        self.file_dialog_translator.load(
            qmfile, QLibraryInfo.location(QLibraryInfo.TranslationsPath))
        QApplication.installTranslator(self.file_dialog_translator)

        # rest of app
        if language == Language.ENGLISH:
            self.actionEnglish.setChecked(True)

        elif language == Language.GERMAN:
            self.actionGerman.setChecked(True)

        else:
            # Fall back to english
            self.actionEnglish.setChecked(True)
            language = Language.ENGLISH

        self.activeConfig.language = language
        self.activeConfig.saveConfig()
        if not self.translator.isEmpty():
            QApplication.removeTranslator(self.translator)
        self.translator.load(
            f':/l10n/gui_{self.activeConfig.language.value}.qm')
        QApplication.installTranslator(self.translator)
        self.retranslateUi(self)
        self.resetEncText()
        self.resetDecText()

    def about(self):
        diag = AboutDialog(activeconfig=self.activeConfig)
        diag.exec()

    def reportBug(self):
        diag = ReportBugDialog(activeconfig=self.activeConfig)
        diag.exec()

    def addEncText(self, text):
        if text is not None and len(text) > 0:
            # if len(self.encText) > 0:
            #     self.encText += os.linesep
            # self.encText += text

            self.encText += '<p>'
            self.encText += text
            self.encText += '</p>'
            self.txtEncryptionResult.setText(self.encText)

    def resetEncText(self):
        self.encText = ''
        self.txtEncryptionResult.setText(self.encText)

    def addDecText(self, text):
        if text is not None and len(text) > 0:
            # if len(self.decText) > 0:
            #     self.decText += os.linesep
            # self.decText += text
            self.decText += '<p>'
            self.decText += text
            self.decText += '</p>'
            self.txtDecryptionResult.setText(self.decText)

    def resetDecText(self):
        self.decText = ''
        self.txtDecryptionResult.setText(self.decText)

    def setEncProgress(self, progress):
        self.encProgress = progress

    def setDecProgress(self, progress):
        self.decProgress = progress

    def updateProgressEnc(self):
        while 1:
            self.prgEnc.setValue(self.encProgress)
            time.sleep(0.1)
            if self.encProgress >= 100:
                time.sleep(3)
                break

    def updateProgressDec(self):
        while 1:
            self.prgDec.setValue(self.decProgress)
            time.sleep(0.1)
            if self.decProgress >= 100:
                time.sleep(3)
                break

    def addInputFilesEnc(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(
            self,
            tr(self.trWhichFilesEnc.text()),
            QDir.homePath(),
            tr(self.trWhichFilesEncFileTypes.text()),
            options=options)
        for path in files:
            if len(self.lsInputFilesEnc.findItems(path, Qt.MatchExactly)) == 0:
                self.lsInputFilesEnc.addItem(path)

        if len(files) > 0:
            self.resetEncText()

    def addInputFilesDec(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(
            self,
            tr(self.trWhichFilesDec.text()),
            QDir.homePath(),
            tr(self.trWhichFilesDecFileTypes.text()),
            options=options)
        for path in files:
            if len(self.lsInputFilesDec.findItems(path, Qt.MatchExactly)) == 0:
                self.lsInputFilesDec.addItem(path)

        if len(files) > 0:
            self.resetDecText()

    def removeInputFilesEnc(self):
        for item in self.lsInputFilesEnc.selectedItems():
            self.lsInputFilesEnc.takeItem(self.lsInputFilesEnc.row(item))
        if len(self.lsInputFilesEnc.selectedItems()) > 0:
            self.resetEncText()

    def removeInputFilesDec(self):
        for item in self.lsInputFilesDec.selectedItems():
            self.lsInputFilesDec.takeItem(self.lsInputFilesDec.row(item))
        if len(self.lsInputFilesDec.selectedItems()) > 0:
            self.resetDecText()

    def rngSourceChanged(self):
        if self.rbANU.isChecked():
            self.rngSource = RngSource.ANU
        elif self.rbCSPRNG.isChecked():
            self.rngSource = RngSource.CSPRNG
        else:
            self.rngSource = RngSource.CSPRNG

    def switchEncMode(self, busy=False, resetFiles=False):
        if self.busy != busy:
            self.setEncProgress(0)
            self.stackEnc.setCurrentIndex(1 if busy else 0)
            if not self.busy:
                self.resetEncText()
                self.setCursor(Qt.WaitCursor)
                self.slotActionsOut()
            else:
                if resetFiles:
                    clearList(self.lsInputFilesEnc)
                self.setCursor(Qt.ArrowCursor)
                self.slotActionsIn()
            self.busy = busy
            self.enableUserInput(not busy)

    def switchDecMode(self, busy=False, resetFiles=False):
        if self.busy != busy:
            self.setDecProgress(0)
            self.stackDec.setCurrentIndex(1 if busy else 0)
            if not self.busy:
                self.resetDecText()
                self.setCursor(Qt.WaitCursor)
                self.slotActionsOut()
            else:
                if resetFiles:
                    clearList(self.lsInputFilesDec)
                self.setCursor(Qt.ArrowCursor)
                self.slotActionsIn()

            self.busy = busy
            self.enableUserInput(not busy)

    def enableUserInput(self, enable):

        # FILE ACTIONS
        self.actionClose.setEnabled(enable)

        # LANGUAGES
        self.actionGerman.setEnabled(enable)
        self.actionEnglish.setEnabled(enable)

        # HELP ACTIONS
        self.actionOpenHelpFile.setEnabled(enable)
        self.actionOpenOnlineHelp.setEnabled(enable)
        self.actionAbout.setEnabled(enable)

        # ENCRYPT
        self.btnEncrypt.setEnabled(enable)
        self.btnAddInputFilesEnc.setEnabled(enable)
        self.btnRemoveInputFilesEnc.setEnabled(enable)
        self.rbANU.setEnabled(enable)
        self.rbCSPRNG.setEnabled(enable)

        # DECRYPT
        self.btnDecrypt.setEnabled(enable)
        self.btnAddInputFilesDec.setEnabled(enable)
        self.btnRemoveInputFilesDec.setEnabled(enable)

    def startEncryption(self):
        self.switchEncMode(busy=True)
        progressUpdateThread = threading.Thread(None, self.updateProgressEnc,
                                                None)
        progressUpdateThread.start()

        # getPaths
        plainPaths = getPathsFromList(self.lsInputFilesEnc)
        if len(plainPaths) == 0:
            self.addEncText(tr(self.trErrorNoEncFiles.text()))
            self.switchEncMode(busy=False)
            return

        self.addEncText(tr(self.trInfoLetsGo.text()))
        # get random bytes
        rndBytes = None
        if self.rngSource == RngSource.ANU:
            self.addEncText(tr(self.trRetrievingANUData.text()))
            total = sum(os.path.getsize(p) for p in plainPaths)
            if total > anuqrandom.MAX_LEN:
                self.addEncText(tr(self.trErrorTooBigForANU.text()))
                self.switchEncMode(busy=False, resetFiles=False)
                return
            anuResult = {'rnd': None, 'message': None}
            anuThread = threading.Thread(None, anuqrandom.getRandBytes, None,
                                         (total, anuResult))
            anuThread.start()
            anustep = 0.5
            anumax = 10
            while anuThread.isAlive():
                if self.encProgress <= anumax:
                    self.setEncProgress(self.encProgress + anustep)
                time.sleep(1)
                QCoreApplication.processEvents()
            anuMessage = anuResult['message']
            if anuMessage == anuqrandom.Message.INFO_SUCCESS:
                passed_time = anuResult['passed_time']
                output = tr(self.trInfoANUSuccess.text()).format(passed_time)
            elif anuMessage == anuqrandom.Message.ERROR_TOO_MUCH_DATA:
                output = tr(self.trErrorANUTooMuchData.text())
            elif anuMessage == anuqrandom.Message.ERROR_NO_CONNECTION:
                output = tr(self.trErrorANUNoConnection.text())
            else:
                output = tr(self.trErrorANUUnknown.text())
            self.addEncText(output)
            if anuResult['rnd'] is None:
                self.switchEncMode(busy=False)
                return
            else:
                rndBytes = anuResult['rnd']
        self.setEncProgress(10)

        # encrypt files
        encThread = threading.Thread(
            None, crypt.encryptPathsWithProgress, None,
            (plainPaths, self.setEncProgress, rndBytes, 90, 10))
        self.addEncText(tr(self.trInfoStartingEnc.text()))
        encThread.start()

        while encThread.is_alive():
            time.sleep(ENCDEC_SLEEP_TIME)
            QCoreApplication.processEvents()

        self.setEncProgress(100)
        time.sleep(1)

        self.addEncText(tr(self.trSuccessEnc.text()))
        self.addEncText(tr(self.trInfoAfterSuccess.text()))

        self.switchEncMode(busy=False, resetFiles=True)

    def startDecryption(self):
        self.switchDecMode(busy=True)
        progressUpdateThread = threading.Thread(None, self.updateProgressDec,
                                                None)
        progressUpdateThread.start()

        # get crypt paths
        cryptPaths = getPathsFromList(self.lsInputFilesDec)
        if len(cryptPaths) == 0:
            self.addDecText(tr(self.trErrorNoDecFiles.text()))
            self.switchDecMode(busy=False)
            return

        # get OTPs
        otpPaths = ['.'.join(p.split('.')[:-1]) + '.otp' for p in cryptPaths]
        missingOTPs = []
        for p in otpPaths:
            if not os.path.exists(p):
                missingOTPs.append(p)

        if len(missingOTPs) > 0:
            self.addDecText(tr(self.trErrorEncMissingKeys.text()))
            for p in missingOTPs:
                self.addDecText(p)

            self.addDecText(tr(self.trInfoDecryptExample.text()))
            self.switchDecMode(busy=False)
            return

        self.addDecText(tr(self.trInfoLetsGo.text()))

        # decrypt files
        decThread = threading.Thread(
            None, crypt.decryptPathsWithProgress, None,
            (cryptPaths, otpPaths, self.setDecProgress, 100, 0))
        self.addDecText(tr(self.trStartingDec.text()))
        decThread.start()

        while decThread.is_alive():
            time.sleep(ENCDEC_SLEEP_TIME)
            QCoreApplication.processEvents()

        self.setDecProgress(100)
        time.sleep(1)

        self.addDecText(tr(self.trSuccessDec.text()))
        self.switchDecMode(busy=False, resetFiles=True)