import sys from lib.helpers import timing from PyQt5.QtCore import Qt, QTimer, pyqtSignal from PyQt5.QtGui import QColor, QPalette, QPixmap from ui import Dialog from ui.test_admin_permission import Test_Admin_Permission from ui.widget import Widget class Test_Test(Widget): ok = pyqtSignal(dict) ko = pyqtSignal(dict) def __init__(self, components=None, recipe=None, step=None): super().__init__() self.components = components self.recipe = recipe self.step = step # setup variables self.ok_counter = 0 self.ok_counter_limit = 1 # setup controls self.ok_timer = QTimer() self.ok_timer.setSingleShot(True) self.ok_timer.setInterval(2000) self.ok_timer.timeout.connect(self.emit_ok) self.ko_timer = QTimer() self.ko_timer.setSingleShot(True) self.ko_timer.setInterval(2000) self.ko_timer.timeout.connect(self.emit_ko) # setup save frame button self.last = None self.save_b.setEnabled(False) self.save_b.clicked.connect(self.save_last) # setup override self.admin_challenged = False self.override_b.clicked.connect(self.override) self.override_b.setEnabled(True) # setup vision staus gui self.status_imgs_full = { True: QPixmap("src/ui/imgs/success.png"), "": QPixmap("src/ui/imgs/neo.ico"), "warning": QPixmap("src/ui/imgs/warning.png"), False: QPixmap("src/ui/imgs/fail.png"), None: QPixmap("src/ui/imgs/wait.png"), } self.status_imgs_small = {k: i.scaled(32, 32, Qt.KeepAspectRatio, Qt.SmoothTransformation) for k, i in self.status_imgs_full.items()} self.status_palettes = { True: QPalette(), "": QPalette(), "warning": QPalette(), False: QPalette(), None: QPalette(), } self.status_palettes[True].setColor(QPalette.Base, Qt.green) self.status_palettes[False].setColor(QPalette.Base, Qt.red) self.status_palettes["warning"].setColor(QPalette.Base, QColor(255, 165, 0)) self.status_palettes[""].setColor(QPalette.Base, QColor(255, 255, 0)) self.visualize() def start(self, recipe=None, step=None): self.recipe = recipe self.step = step self.visualize() # start test self.start_time = timing() # TESTING if "--test" in sys.argv: if hasattr(self, "_test_overridden_test_"): del self._test_overridden_test_ # /TESTING def stop(self): pass def get(self, data=None, override=False, fail=False): if self.ok_timer.isActive() or self.ko_timer.isActive(): # avoid proccessing if test was completed return if data is None: data = self.last if self.last is not None else {} else: data_usable = [d is not None for d in reversed(data)] if not any(data_usable): data = self.last if self.last is not None else {} else: data = data[-data_usable.index(True) - 1] if not override: result_ok = data.get("results", {}).get("ok", None) else: result_ok = True self.last = { **data, "overridden": override, "duration": timing() - self.start_time, "ok": result_ok, } if fail: self.ok_counter = 0 elif override: self.ok_counter = self.ok_counter_limit else: if result_ok is True: self.ok_counter += 1 else: self.ok_counter = 0 # check if completed if fail: self.stop() self.ko_timer.start() elif self.ok_counter >= self.ok_counter_limit: self.stop() self.ok_timer.start() self.visualize(self.last) # TESTING if "--test" in sys.argv: if not hasattr(self, "_test_overridden_test_"): self._test_overridden_test_ = True self.override_b.click() # /TESTING def visualize(self, data=None, img=None): if data is None: data = {} overridden = data.get("overridden", False) results = data.get("results", None) self.save_b.setEnabled(self.last is not None) if overridden: self.state_l.setPixmap(self.status_imgs_small["warning"]) elif results is None: self.state_l.setPixmap(self.status_imgs_small[None]) elif results.get("ok", None) is True: self.state_l.setPixmap(self.status_imgs_small[True]) else: self.state_l.setPixmap(self.status_imgs_small[False]) self.ok_counter_pb.setMaximum(self.ok_counter_limit) self.ok_counter_pb.setValue(min(self.ok_counter, self.ok_counter_limit)) if self.ok_counter >= self.ok_counter_limit: self.ok_counter_pb.setPalette(self.status_palettes[True]) else: self.ok_counter_pb.setPalette(self.status_palettes[False]) if img is None: if overridden: self.img = self.status_imgs_full["warning"] elif results is None or results.get("ok", None) is None: self.img = self.status_imgs_full[None] elif results.get("ok", None) is False: self.img = self.status_imgs_full[False] else: self.img = self.status_imgs_full[None] else: self.img = img self.resizeEvent() def save_last(self): if self.last is None: return def resizeEvent(self, event=None): self.img_l.setPixmap(self.img.scaled(self.img_l.width(), self.img_l.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) def challenge_admin(self, info): if not self.admin_challenged: d = Dialog(parent=self) d.setCentralWidget(Test_Admin_Permission(info)) d.setModal(True) d.show() r = d.exec() if r == d.Accepted: self.admin_challenged = True elif r == d.Rejected: self.admin_challenged ^= False else: raise AssertionError("Bad admin challenge dialog return code") return self.admin_challenged def override(self): if self.challenge_admin("Si sta tentando di bypassare il test"): self.get(override=True) def emit_ok(self): self.ok.emit(self.last) def emit_ko(self): self.ko.emit(self.last)