Example #1
0
class QApplicationRunner(QObject):
    """ Application runner starts application in own thread """
    def __init__(self):
        QObject.__init__(self)
        self._thread = QThread()
        self.moveToThread(self._thread)
        self._thread.started.connect(self.start)
        self._ev = Event()
        self._app = None
        self._thread.start()

    @Slot()
    def start(self):
        self.app = Application()
        self._ev.set()
        self.app.exec_()

    def exit(self):
        self.app.exit() # perform polite disposal of resources
        if self._thread.isRunning():
            self._thread.wait(1000) # wait 1 sec
            self._thread.terminate() # no-way

    @property
    def app(self):
        if not self._ev.isSet():
            self._ev.wait()
        return self._app
    @app.setter
    def app(self, app):
        self._app = app
Example #2
0
class QWebPageRunner(QObject):
    """ Web page runner starts WebPage instances in one separate thread and implements custom event loop. """
    #FIXME: consider using QEventLoop instead
    def __init__(self, app):
        QObject.__init__(self)
        self._thread = QThread()
        self.moveToThread(self._thread)
        self._thread.started.connect(self.start)
        self._destroying = Event()
        self._destroying.clear()
        self._result = None
        self._commandQueue = Queue()
        self._app = app
        self._thread.start()

    @Slot()
    def start(self):
        try:
            while not self._destroying.is_set():
                self._app.processEvents()
                try:
                    cmd = self._commandQueue.get(timeout=0.1)
                    args = ()
                    if isinstance(cmd, tuple):
                        if not len(cmd):
                            continue
                        args = cmd[1:]
                        cmd = cmd[0]
                    if isinstance(cmd, NewPage):
                        args = (self._app,)
                    if isinstance(cmd, Command):
                        cmd(*args)
                    else:
                        raise ValueError('Unknown command %s(%s).' % (cmd, args))
                except Empty:
                    pass
        except Exception as e:
            logger.exception(e)

    def exit(self):
        self._destroying.set()
        if self._thread.isRunning():
            self._thread.wait(1000) # wait 1 sec
            self._thread.terminate() # no-way

    def invoke(self, cmd, *args):
        if isinstance(cmd, type) and issubclass(cmd, Command):
            cmd = cmd()
        if not isinstance(cmd, Command):
            cmd = Command(cmd)
        cmd.event.clear()
        self._commandQueue.put((cmd,)+args)
        while not cmd.event.is_set():
            self._app.processEvents()
            cmd.event.wait(0.1)
        return cmd.result
class Progress(QWidget, ProgressGui.Ui_Progress):
    # Signals
    completeProcessSig = Signal(str)
    endProcessEarlySig = Signal()

    """
    --------------------------------------------------------------------------------------------------------------------
    Constructor method
    --------------------------------------------------------------------------------------------------------------------
    """
    def __init__(self,
                 mode,
                 algo_type,
                 key,
                 keysize,
                 ciphertext_file_path,
                 plaintext_file_path,
                 parent=None):
        super(Progress, self).__init__(parent)
        self.setupUi(self)
        self.setWindowTitle(ApplicationStrings.APPLICATION_NAME)
        self.setFixedSize(500, 135)

        # set values from those passed in
        self.mode = mode
        self.algo_type = algo_type
        self.key = key
        self.keysize = keysize
        self.ciphertext_file_path = ciphertext_file_path
        self.plaintext_file_path = plaintext_file_path

        # create empty holders
        self.init_vector = None
        self.cipher = None
        self.cipher_process = None
        self.monitor_progress_thread = None
        self.progress_monitor = None

        # create Values to be shared between processes
        self.end_process_early = Value('i', 0)
        self.percent_done = Value('d', 0.0)
        self.pause_requested = Value('i', 0)
        self.paused = Value('i', 0)
        self.pause_sig_sent = Value('i', 0)

        # connect cancel btn signal and slot
        self.cancel_btn.clicked.connect(self.requestPause)
        # create the Value objects shared between processes
        self.setGuiValues()
        # create the initialization vector
        self.createInitVector()
        # create an instance of the appropriate cipher
        self.createCipher()
        # create and setup the monitor class
        self.setupMonitor()
        # create the Process that the Cipher will run in
        self.createCipherProcess()

    """
    --------------------------------------------------------------------------------------------------------------------
    Set the Gui Labels from data passed into constructor
    --------------------------------------------------------------------------------------------------------------------
    """
    def setGuiLabels(self):
        if self.mode == 'encryption':
            self.title_label.setText('Encrypting File: %s' \
                                     % self.plaintext_file_path[:3]+'.../'+self.plaintext_file_path.split('/')[-1])
        elif self.mode == 'decryption':
            self.title_label.setText('Decrypting File: %s' \
                                     % self.ciphertext_file_path[:3]+'.../'+self.ciphertext_file_path.split('/')[-1])
        self.key_label.setText('Key: %s' % binascii.hexlify(self.key).decode())
        self.progress_bar.reset()

    """
    --------------------------------------------------------------------------------------------------------------------
    Create the Initialization vector
    --------------------------------------------------------------------------------------------------------------------
    """
    def createInitVector(self):
        if kr.getFromKeyring('iv_source', 'admin') is None:
            self.init_vector = 1
        else:
            self.init_vector = int(kr.getFromKeyring('iv_source', 'admin')) + 1
        kr.saveToKeyring('iv_source', 'admin', str(self.init_vector))
        self.init_vector = hashlib.sha256(str(self.init_vector).encode('utf-8')).hexdigest()
        self.init_vector = bytearray.fromhex(self.init_vector)[:16]

    """
    --------------------------------------------------------------------------------------------------------------------
    Create the Cipher Algorithm
    --------------------------------------------------------------------------------------------------------------------
    """
    def createCipher(self):
        if self.algo_type == 'aes':
            self.cipher = AesCipher(self.keysize,
                                    self.plaintext_file_path,
                                    self.ciphertext_file_path,
                                    self.init_vector,
                                    self.key)
        elif self.algo_type == '3es':
            print('3es')
        elif self.algo_type == 'des':
            print('des')

    """
    --------------------------------------------------------------------------------------------------------------------
    Setup the monitor class and move to its own thread
    --------------------------------------------------------------------------------------------------------------------
    """
    def setupMonitor(self):
        self.monitor_progress_thread = QThread()
        self.progress_monitor = ProgressMonitor(self.percent_done,
                                               self.paused,
                                               self.pause_sig_sent,
                                               self.end_process_early)
        self.progress_monitor.moveToThread(self.monitor_progress_thread)
        # connect signals and slots
        self.monitor_progress_thread.started.connect(self.progress_monitor.beginMonitoring)
        self.progress_monitor.updateProcessSig.connect(self.update)
        self.progress_monitor.endProcessEarlySig.connect(self.endEarly)
        self.progress_monitor.endProcessSig.connect(self.complete)
        self.progress_monitor.pauseSig.connect(self.showCancelMessage)

    """
    --------------------------------------------------------------------------------------------------------------------
    Create the Cipher Process and set the target to the appropriate method in the Cipher instance
    --------------------------------------------------------------------------------------------------------------------
    """
    def createCipherProcess(self):
        if self.mode == 'encryption':
            self.cipher_process = Process(target=self.cipher.encrypt, args=(self.percent_done,
                                                                            self.pause_requested,
                                                                            self.paused))
        elif self.mode == 'decryption':
            self.cipher_process = Process(target=self.cipher.decrypt, args=(self.percent_done,
                                                                            self.pause_requested,
                                                                            self.paused))

    """
    --------------------------------------------------------------------------------------------------------------------
    Begin the encryption/decryption process and start the monitoring thread
    --------------------------------------------------------------------------------------------------------------------
    """
    def begin(self):
        self.monitor_progress_thread.start()
        self.cipher_process.start()

    """
    --------------------------------------------------------------------------------------------------------------------
    Update the progress bar with values from the encryption/decryption process
    --------------------------------------------------------------------------------------------------------------------
    """
    def update(self, percent_done):
        self.progress_bar.setValue(percent_done)

    """
    --------------------------------------------------------------------------------------------------------------------
    request the process to pause
    --------------------------------------------------------------------------------------------------------------------
    """
    def requestPause(self):
        self.pause_requested.value = 1

    """
    --------------------------------------------------------------------------------------------------------------------
    show the cancel message
    --------------------------------------------------------------------------------------------------------------------
    """
    def showCancelMessage(self):
        msgBox = QMessageBox()
        msgBox.setText("Are You Sure You Want To Cancel %s" % self.mode)
        msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        msgBox.setDefaultButton(QMessageBox.Cancel)
        ret = msgBox.exec_()

        if ret == QMessageBox.Ok:
            self.end_process_early.value = 1
        elif ret == QMessageBox.Cancel:
            self.paused.value = 0
            self.pause_requested.value = 0
            self.pause_sig_sent.value = 0
            self.pause_requested.value = 0

    """
    --------------------------------------------------------------------------------------------------------------------
    Complete encryption / decryption when done
    --------------------------------------------------------------------------------------------------------------------
    """
    def complete(self):
        self.cipher = None
        # terminate the update progress thread
        self.monitor_progress_thread.terminate()
        while self.monitor_progress_thread.isRunning():
            time.sleep(0.01)
        # terminate the cipher process
        self.cipher_process.terminate()
        while self.cipher_process.is_alive():
            time.sleep(0.01)
        self.close()
        # create the filepath to send back to the message box
        fp = ''
        if self.mode == 'encryption':
            fp = self.ciphertext_file_path
        elif self.mode == 'decryption':
            fp = self.plaintext_file_path
        # emit Signal
        self.completeProcessSig.emit(fp)

    """
    --------------------------------------------------------------------------------------------------------------------
    Cancel the encryption / decryption before completion
    --------------------------------------------------------------------------------------------------------------------
    """
    def endEarly(self):
        self.cipher = None
        # terminate the update progress thread
        self.monitor_progress_thread.terminate()
        while self.monitor_progress_thread.isRunning():
            time.sleep(0.01)
        # terminate the cipher process
        self.cipher_process.terminate()
        while self.cipher_process.is_alive():
            time.sleep(0.01)
        self.close()
        # emit Signal
        self.endProcessEarlySig.emit()