Exemplo n.º 1
0
    def __init__(self, master):
        self.master = master
        self.myQueue = queue.Queue()
        self.shared = SharedFlags()

        self.app = App(master, self.myQueue, self.shared)

        states = {
            States.WAITING: self.waitingForDevice,
            States.DETECTED: self.deviceDetected,
            States.SCANNING: self.scanning,
            States.SCAN_SELECTED: self.scanSelected,
            States.CLEAR: self.clearResults,
            States.INFECTED_FILES: self.infectedResults,
            States.REMOVE_SELECTED: self.removeSelected,
            States.INFECTED_HEAD: self.infectedHead,
            States.ERRORS: self.error,
        }

        self.detector = Detector()
        self.scanner = Scanner()
        self.machine = StateMachine(states, States.WAITING)

        self.running = True
        self.gifRunning = False
        self.machineThread = StoppableThread(target=self.machine.run)
        self.machineThread.start()
        self.periodicCall()
Exemplo n.º 2
0
class ThreadedClient(object):
    """
    Launch the main part of GUI and state machine thread.
    """

    def __init__(self, master):
        self.master = master
        self.myQueue = queue.Queue()
        self.shared = SharedFlags()

        self.app = App(master, self.myQueue, self.shared)

        states = {
            States.WAITING: self.waitingForDevice,
            States.DETECTED: self.deviceDetected,
            States.SCANNING: self.scanning,
            States.SCAN_SELECTED: self.scanSelected,
            States.CLEAR: self.clearResults,
            States.INFECTED_FILES: self.infectedResults,
            States.REMOVE_SELECTED: self.removeSelected,
            States.INFECTED_HEAD: self.infectedHead,
            States.ERRORS: self.error,
        }

        self.detector = Detector()
        self.scanner = Scanner()
        self.machine = StateMachine(states, States.WAITING)

        self.running = True
        self.gifRunning = False
        self.machineThread = StoppableThread(target=self.machine.run)
        self.machineThread.start()
        self.periodicCall()

    def periodicCall(self):
        """
        Check every 200ms if there is something new in the queue.
        """
        self.app.processIncoming()
        self.master.after(200, self.periodicCall)

    def newEvent(self, *args, **kwargs):
        self.myQueue.put(Event(*args, **kwargs))

    def waitingForDevice(self):
        """
        Initial state of machine handling function, monitors devices
        using detector method
        """
        print("State waiting")
        self.newEvent(hideWidget, widget=self.app.mainButton)
        self.scanner.reset()
        self.newEvent(self.app.setLabelMsg, label=self.app.info, text=msg.WAITING)
        self.newEvent(self.app.setLabelMsg, label=self.app.message, text="")
        try:
            self.detector.watchUsbMedia()
        except DetectionErrorException:
            logger.error(msg.DISKSTATS_ERROR)
            self.errorMsg = msg.DISKSTATS_ERROR
            return States.ERRORS
        return States.DETECTED

    def deviceDetected(self):
        """
        State machine handling function, prints detection message
        and asks user if new device is going to be scanned
        """
        print("State Detected")
        detectionLogEcho(self.detector.detectedDevice)
        if len(self.detector.detectedDevice["partitions"]) > 1:
            self.newEvent(self.app.setLabelMsg, label=self.app.info, text=msg.MULTIPARTITION)
        else:
            device = getDeviceName(self.detector.detectedDevice["partitions"][0])
            self.newEvent(self.app.setLabelMsg, label=self.app.info, text=msg.singlePartition(device))
        self.shared.buttonPushed.clear()
        self.newEvent(showWidget, widget=self.app.mainButton)
        if SELECT_FILES:
            self.newEvent(showWidget, widget=self.app.specialStateButton)
        self.newEvent(self.app.mainButton.config, text=msg.SCAN_BUTTON)
        self.newEvent(self.app.specialStateButton.config, text=msg.SCAN_SELECTED_BUTTON)
        self.shared.buttonPushed.wait()
        self.newEvent(hideWidget, widget=self.app.specialStateButton)
        self.newEvent(hideWidget, widget=self.app.mainButton)
        if self.shared.specialState.isSet():
            return States.SCAN_SELECTED
        return States.SCANNING

    def scanning(self):
        """
        State machine handling function, scans device after
        detection
        """
        print("State scanning")
        self.newEvent(self.app.setLabelMsg, label=self.app.info, text=msg.SCANNING)
        self.newEvent(showWidget, widget=self.app.waitingTransparent)
        if not self.gifRunning:
            self.gifRunning = True
            self.newEvent(self.app.waitingTransparent.runGif)
        try:
            self.scanner.handleNewDevice(self.detector.detectedDevice)
        except NoMountPointException:
            self.newEvent(hideWidget, widget=self.app.waitingTransparent)
            logger.error(msg.MOUNT_CALL_ERROR)
            self.errorMsg = msg.MOUNT_CALL_ERROR
            return States.ERRORS
        self.newEvent(self.app.setLabelMsg, label=self.app.info, text=msg.SCANNING_FINISHED)
        result = self.scanner.checkResults()
        self.newEvent(hideWidget, widget=self.app.waitingTransparent)
        if result == States.ERRORS:
            self.errorMsg = msg.CLAMSCAN_ERROR
        return result

    def scanSelected(self):
        """
        State machine handling function, scans only selected files 
        from device
        """
        print("State scanSelected")
        self.shared.buttonPushed.clear()
        self.newEvent(self.app.setLabelMsg, label=self.app.info, text=msg.SELECT_TO_SCAN)
        try:
            files = self.scanner.getAllFilesOnDevice(self.detector.detectedDevice)
            self.newEvent(self.app.addCheckBoxes, boxes=files)
            self.newEvent(showWidget, widget=self.app.processSelectedButton)
            self.newEvent(self.app.processSelectedButton.config, text=msg.SCAN_BUTTON)
            self.shared.buttonPushed.wait()
            self.newEvent(self.app.hideCheckBoxes)
            self.newEvent(hideWidget, widget=self.app.processSelectedButton)
            self.newEvent(self.app.setLabelMsg, label=self.app.info, text=msg.SCANNING)
            self.newEvent(showWidget, widget=self.app.waitingTransparent)
            self.newEvent(self.app.waitingTransparent.runGif)
            self.scanner.scanSelectedFiles(self.detector.detectedDevice, self.getCheckboxesFiles)
        except NoMountPointException:
            logger.error(msg.MOUNT_CALL_ERROR)
            self.newEvent(hideWidget, widget=self.app.waitingTransparent)
            self.errorMsg = msg.MOUNT_CALL_ERROR
            return States.ERRORS
        self.newEvent(hideWidget, widget=self.app.waitingTransparent)
        self.newEvent(self.app.setLabelMsg, label=self.app.info, text=msg.SCANNING_FINISHED)
        result = self.scanner.checkResults()
        if result == States.ERRORS:
            logger.error(msg.CLAMSCAN_ERROR)
            self.errorMsg = msg.CLAMSCAN_ERROR
        return result

    def clearResults(self):
        """
        State machine handling function, shows message when
        infected files were not found
        """
        print("State clearResults")
        self.shared.buttonPushed.clear()
        self.newEvent(showWidget, widget=self.app.message)
        self.newEvent(showWidget, widget=self.app.mainButton)
        self.newEvent(self.app.mainButton.config, text=msg.CONTINUE_BUTTON)
        self.newEvent(self.app.message.config, fg="green")
        self.newEvent(self.app.setLabelMsg, label=self.app.message, text=msg.CLEAN)
        self.shared.buttonPushed.wait()
        self.newEvent(self.app.message.config, fg="black")
        return States.WAITING

    def infectedHead(self):
        """
        State machine handling function, print message when head virus is
        found
        """

        self.newEvent(showWidget, widget=self.app.message)
        self.newEvent(self.app.message.config, fg="red")
        self.newEvent(self.app.setLabelMsg, label=self.app.message, text=msg.INFECTED_HEAD)
        time.sleep(10)
        self.newEvent(self.app.message.config, fg="black")
        return States.WAITING

    def infectedResults(self):
        """
        State machine handling function, shows infedted files
        summary and delete them.
        """
        print("State infectedResults")
        self.newEvent(showWidget, widget=self.app.message)
        self.shared.buttonPushed.clear()
        self.newEvent(showWidget, widget=self.app.mainButton)
        self.newEvent(self.app.mainButton.config, text=msg.DELETE_BUTTON)
        if SELECT_FILES:
            self.newEvent(showWidget, widget=self.app.specialStateButton)
        self.newEvent(self.app.specialStateButton.config, text=msg.REMOVE_SELECTED_BUTTON)
        self.newEvent(self.app.message.config, fg="red")
        part = getDeviceName(self.detector.detectedDevice["partitions"][0])
        infected = self.scanner.getScanSummary()
        self.newEvent(
            self.app.setLabelMsg, label=self.app.message, text=msg.INFECTED_FILES + "\n".join([x[1] for x in infected])
        )
        self.shared.buttonPushed.wait()
        self.newEvent(self.app.message.config, fg="black")
        if self.shared.specialState.isSet():
            self.newEvent(hideWidget, widget=self.app.mainButton)
            self.newEvent(hideWidget, widget=self.app.specialStateButton)
            return States.REMOVE_SELECTED
        self.newEvent(self.app.setLabelMsg, label=self.app.message, text=msg.DELETING)
        try:
            deleteFiles(infected)
        except FileNotFoundError:
            logger.error(msg.REMOVING_ERROR)
            self.errorMsg = msg.REMOVING_ERROR
            return States.ERRORS
        self.newEvent(self.app.setLabelMsg, label=self.app.message, text=msg.DELETED)
        time.sleep(5)
        return States.WAITING

    @property
    def getCheckboxesFiles(self):
        return [key for key, value in self.shared.checkBoxes.items() if value.isSet()]

    def removeSelected(self):
        """
        State machine handling function, removes only selected files
        """
        print("State removeSelected")
        self.shared.buttonPushed.clear()
        infected = self.scanner.getScanSummary()
        self.newEvent(self.app.setLabelMsg, label=self.app.info, text=msg.SELECT_TO_REMOVE)
        self.newEvent(hideWidget, widget=self.app.message)
        self.newEvent(self.app.addCheckBoxes, boxes=infected)
        self.newEvent(showWidget, widget=self.app.processSelectedButton)
        self.newEvent(self.app.processSelectedButton.config, text=msg.DELETE_BUTTON)
        self.shared.buttonPushed.wait()
        self.newEvent(hideWidget, widget=self.app.processSelectedButton)
        try:
            deleteFiles(self.getCheckboxesFiles)
        except FileNotFoundError:
            logger.error(msg.REMOVING_ERROR)
            self.errorMsg = msg.REMOVING_ERROR
            self.newEvent(self.app.hideCheckBoxes)
            return States.ERRORS
        self.newEvent(self.app.hideCheckBoxes)
        self.newEvent(showWidget, widget=self.app.message)
        self.newEvent(self.app.setLabelMsg, label=self.app.message, text=msg.DELETED)
        time.sleep(5)
        return States.WAITING

    def error(self):
        """
        State machine handling function, informs user about errors,
        which occurred during device processing
        """
        print("State error")
        self.newEvent(showWidget, widget=self.app.message)
        self.newEvent(self.app.message.config, fg="orange")
        self.newEvent(self.app.setLabelMsg, label=self.app.info, text=msg.ERRORS)
        self.newEvent(self.app.setLabelMsg, label=self.app.message, text=self.errorMsg)
        time.sleep(10)
        self.newEvent(self.app.message.config, fg="black")
        return States.WAITING

    def exitProgram(self):
        """
        App X button overriding function, stop child thread before exiting
        """
        self.machineThread.stop()
        self.app.shared.buttonPushed.set()
        self.app.shared.specialState.set()
        self.master.destroy()