Example #1
0
 def __init__(self, connect_addr):
     super(QMainWindow, self).__init__()
     
     self.ctx = zmq.Context()
     self.receiver = self.ctx.socket(zmq.SUB)
     self.receiver.connect(connect_addr)
     self.receiver.setsockopt(zmq.SUBSCRIBE, ''.encode())
     fd = self.receiver.getsockopt(zmq.FD)
     
     self.notifier = QSocketNotifier(fd, QSocketNotifier.Read, self)
     self.notifier.activated.connect(self.process_stuff)
     
     self.requests = {}
     
     self.services_views = {}
     self.services = SuperClient(self.ctx)
     
     self.__init_gui()
Example #2
0
class QtSpyWindow(QMainWindow):
    def __init__(self, connect_addr):
        super(QMainWindow, self).__init__()
        
        self.ctx = zmq.Context()
        self.receiver = self.ctx.socket(zmq.SUB)
        self.receiver.connect(connect_addr)
        self.receiver.setsockopt(zmq.SUBSCRIBE, ''.encode())
        fd = self.receiver.getsockopt(zmq.FD)
        
        self.notifier = QSocketNotifier(fd, QSocketNotifier.Read, self)
        self.notifier.activated.connect(self.process_stuff)
        
        self.requests = {}
        
        self.services_views = {}
        self.services = SuperClient(self.ctx)
        
        self.__init_gui()

    def __init_gui(self):
        self.resize(550, 700)
    
        layout = QHBoxLayout()
        layout2 = QVBoxLayout()
        layout3 = QVBoxLayout()
        
        widget = QWidget(self)
        widget.setLayout(layout)
        self.setCentralWidget(widget)
        
        layout.addLayout(layout3)
        
        self.tabs = QTabWidget(self)
        layout3.addWidget(self.tabs)
        
        self.history = []
        self.current_history_index = -1
        
        self.console = QLineEdit(self)
        self.console.setText('service.method(arg1, arg2, arg3=3)')
        self.console.returnPressed.connect(self.on_console_send)
        self.console.installEventFilter(self)
        self.console.setFocus()
        layout3.addWidget(self.console)

    def eventFilter(self, obj, event):
        if event.type() == QEvent.KeyPress:
            order = None
            if event.key() == Qt.Key_Up:
                order = self.get_history_up()
            elif event.key() == Qt.Key_Down:
                order = self.get_history_down()
            if not(order is None):
                self.console.setText(order)
                return True
        return obj.eventFilter(obj, event)

    def get_textedit(self, nom):
        if nom in self.services_views.keys():
            return self.services_views[nom]
        else:
            text = QTextBrowser(None)
            self.services_views[nom] = text
            self.tabs.addTab(text, nom.decode())
            return text

    def on_console_send(self, *args):
        order = self.console.text()
        #Le but est de recuperer le nom du service, la methode a appeler et les arguments
        #on decoupe d'abord en trois morceaux avec un regex
        res = re.findall(r"([a-zA-Z_\-]*\.)?([a-zA-Z0-9\-_]+) ?\((.*)\)", order)
        service = res[0][0]
        if service == '':
            service = self.tabs.tabText(self.tabs.currentIndex()) # TODO
        else:
            service = service[:-1]
        method = res[0][1]
        
        #Pour recuperer les arguments comme objets python on va utiliser eval
        #en remplaçant le dict 'locals' par un contenant seulement la fonctione 'identity'
        arguments = "a(%s)" % res[0][2]
        def identity(*args, **kwargs):
            return args, kwargs
        args, kwargs = eval(arguments,{'__builtin__':{}},{'a':identity})
        
        #Appel de la fonction, reset de la console et historique
        self.services.call(service, method, args, kwargs)
        self.console.setText('')
        self.add_to_history(order)
        
    def add_to_history(self, order):
        self.history.append(order)
        self.current_history_index = len(self.history) - 1

    def get_history_up(self):
        if self.current_history_index >= 0:
            order = self.history[self.current_history_index]
            self.current_history_index -= 1
            return order
        return None

    def get_history_down(self):
        if self.current_history_index+2 == len(self.history):
            self.current_history_index += 1
            return ''
        elif self.current_history_index+2 < len(self.history):
            self.current_history_index += 1
            return self.history[self.current_history_index+1]
        return None

    def process_stuff(self, sock):
        while self.receiver.getsockopt(zmq.EVENTS) & zmq.POLLIN:
            message = self.receiver.recv_multipart()
            from_, to, msg = message
            msg = json.loads(msg.decode())
            
            if 'data' in msg.keys() or 'error' in msg.keys():
                new_text = "<br/>"
                
                ans, req = msg, self.requests[msg["uid"]]
                new_text += "<i style='font-size: small'>%s</i> <b>%s : %s.%s(" % (time.strftime("%H:%M:%S", time.localtime()) ,to.decode(), from_.decode(), req["fct"])
                for arg in req["args"]:
                    new_text += "%s, " % arg
                for arg in req["kwargs"].items():
                    new_text += "%s=%s, " % arg
                if req["args"] or req["kwargs"]:
                    new_text = new_text[:-2]
                new_text += ")</b><br/>"
                if ans["error"] is None:
                    new_text += "<span style='color: green;'>%s</span>" % (htmlentities(ans["data"]))
                else:
                    new_text += "<span style='color: red;'>Error : %s<br/>Traceback : %s</span>" % (htmlentities(ans["error"]["error"]),
                                                                                                    htmlentities(ans["error"]["tb"]))
                
                self.get_textedit(from_).append(new_text)
                del self.requests[ans["uid"]]
            else:
                self.requests[msg["uid"]] = (msg)

        return True