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()
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()