class Comm(): def __init__(self, address, port): self.block = 0 self.port = port self.delimiter = bytes('x', 'utf-8') self.address = address self.block = bytearray() self.initialize(address, port) def initialize(self, address, port): self.socket = QTcpSocket() self.socket.connectToHost(self.address, self.port) def decode(self, data): return data.decode('utf-8').replace('\x00', '').rsplit() def read(self): self.size = self.socket.bytesAvailable() self.block += self.socket.read(self.size) def get_data(self): if (self.delimiter in self.block): data = self.block[0:self.block.index(self.delimiter)] data = list(map(int, self.decode(data))) self.block = self.block[self.block.index(self.delimiter) + 1:-1] return data def send(self, data): self.socket.write(bytearray(data, 'utf-8')) def disconnect(self): self.socket.close()
def exchangeData(self): if not checkIPAddress(ip_line_edit.text()): raise Exception("ERROR IP-address format") tcp_socket = QTcpSocket() tcp_socket.connectToHost(ip_line_edit.text(), 80, QIODevice.ReadWrite) self.update.emit( f"Connecting to {tcp_socket.peerAddress().toString()}:{tcp_socket.peerPort()}" ) if not tcp_socket.waitForConnected(5000): raise Exception(f"ERROR connecting to {ip_line_edit.text()}:80") tcp_socket.waitForReadyRead(5000) arduino_state: bytes = b"" while tcp_socket.bytesAvailable() > 0: arduino_state += tcp_socket.readAll().data() print(arduino_state) arduino_state = arduino_state.decode() if ("+" not in arduino_state): raise Exception(f"ERROR incomplete read") self.updateState(arduino_state) tcp_socket.write((self.getState() + "+\n").encode("utf-8")) tcp_socket.flush() if tcp_socket.bytesToWrite() > 0: raise Exception(f"ERROR incomplete write") tcp_socket.disconnectFromHost() tcp_socket.close()
def get_ip_mac_pinged(ip): """ Returns a list [ip,mac,pinged] """ pinged = True mac = None sock = QTcpSocket() sock.connectToHost(ip, 80) sock.close() #ARP if pinged == True: if platform_system() == "Windows": CREATE_NO_WINDOW = 0x08000000 arpexit = subprocess.check_output( ["arp", "-a", ip], creationflags=CREATE_NO_WINDOW) for s in arpexit.split(b" "): if len(s) == 17 and s.find(b"-") != -1: mac = s.decode().replace("-", ":").upper() else: arpexit = subprocess.check_output(["arp", ip]) for s in arpexit.decode('utf-8').split(" "): if len(s) == 17 and s.find(":") != -1: mac = s.upper() return (ip, mac, pinged)
class TcpServer(QWidget, Ui_Form): def __init__(self): super(TcpServer, self).__init__() self.ui = Ui_Form() self.ui.setupUi(self) self.tcpServer = QTcpServer(self) #指定父对象自动回收空间 监听套接字 self.tcpSocket = QTcpSocket(self) #通信套接字 self.tcpServer.listen(QHostAddress.Any, 8888) #any默认绑定当前网卡的所有IP self.tcpServer.newConnection.connect(self.handleNewConnection) self.ui.sendButton.clicked.connect(self.sendMessage) self.ui.closeButton.clicked.connect(self.closeConnect) def handleNewConnection(self): self.tcpSocket = self.tcpServer.nextPendingConnection() #取出建立好链接的套接字 #获取对方IP和端口 ip = self.tcpSocket.peerAddress().toString() #获取对方的IP地址 port = self.tcpSocket.peerPort() #获取对方的端口号 self.ui.showText.setText("[{IP}:{Port}]".format(IP=ip, Port=port)) self.tcpSocket.readyRead.connect(self.showMessage) def sendMessage(self): # message = self.ui.sendEdit.toPlainText() # 获取编辑区内容 # self.request = QByteArray() #由于write函数的参数是QByteArray, bytes, bytearray所以在这里通过QByteArray来传递参数 # stream = QDataStream(self.request, QIODevice.WriteOnly) #创建数据流,和QByteArray关联,并且以只写的方式 # stream.setVersion(QDataStream.Qt_5_10) #设置数据流所对应的PyQt5版本 # stream.writeQString(message) #向数据流中写入数据,亦即向request中写入数据 # self.tcpSocket.write(self.request) # self.ui.sendEdit.clear() #每次数据发送后,将当前的输入text区域清空 message = self.ui.sendEdit.toPlainText() message = message.encode('utf-8') #encode()转换为bytes类型 self.tcpSocket.write(message) self.ui.sendEdit.clear() def showMessage(self): # stream = QDataStream(self.tcpSocket) #发送数据是以QByteArray数据类型发送过来的,所以接收数据也应该以此接收 # stream.setVersion(QDataStream.Qt_5_10) #发送和接收数据以相同的编码形式传输 # message = stream.readQString() #写入使用writeString, 对应读取使用readQString # self.ui.showText.append(message) message = QByteArray() message = self.tcpSocket.readAll() message = str(message, 'utf-8') self.ui.showText.setText(message) def closeConnect(self): self.tcpSocket.disconnectFromHost() self.tcpSocket.close()
class TcpClient(QWidget, Ui_Form): def __init__(self): super(TcpClient, self).__init__() self.ui = Ui_Form() self.ui.setupUi(self) self.tcpSocket = QTcpSocket(self) self.ui.connectButton.clicked.connect(self.buttonConnect) self.tcpSocket.connected.connect(self.sucessConnect) self.ui.sendButton.clicked.connect(self.sendMessage) self.tcpSocket.readyRead.connect(self.showMessage) self.ui.closeButton.clicked.connect(self.closeConnect) def buttonConnect(self): ip = self.ui.IPLineEdit.text() port = self.ui.portLineEdit.text() self.tcpSocket.connectToHost(QHostAddress(ip), int(port)) def sucessConnect(self): self.ui.showText.setText("成功和服务器建立连接") def sendMessage(self): message = self.ui.sendText.toPlainText() # self.communication = QByteArray() # stream = QDataStream(self.communication, QIODevice.WriteOnly) # stream.writeQString(message) # self.tcpSocket.write(self.communication) # self.ui.sendText.clear() message = message.encode(encoding='utf-8') self.tcpSocket.write(message) self.ui.sendText.clear() def showMessage(self): # stream = QDataStream(self.tcpSocket) # stream.setVersion(QDataStream.Qt_5_10) # message = stream.readQString() # self.ui.showText.append(message) self.message = QByteArray() self.message = self.tcpSocket.readAll() self.message = str(self.message, encoding='utf-8') #找遍世界,终于找到可用的方法 print(self.message) self.ui.showText.append(self.message) def closeConnect(self): self.tcpSocket.disconnectFromHost() self.tcpSocket.close()
class MyClientThread(QThread): def __init__(self, ip, port): super(MyClientThread, self).__init__() self.ip = ip self.port = port def run(self): print("新连接进入") self.clientSocket = QTcpSocket() self.clientSocket.connectToHost(QHostAddress(self.ip), self.port) clientSocketList.append((self.clientSocket, self.ip, self.port)) self.clientSocket.connected.connect(lambda: print("连接成功")) self.clientSocket.readyRead.connect(lambda:self.handle_read(self.clientSocket),Qt.DirectConnection) self.clientSocket.disconnected.connect(self.dealDisconnected,Qt.DirectConnection) self.exec() def handle_read(self,socket): msg = socket.readAll() print(msg) self.handle_write() def handle_write(self): for socket, ip, port in clientSocketList: socket.write("郑兵".encode("utf-8")) def handle_runing_single(self, str): print(str) def dealDisconnected(self): print("断开连接") self.clientSocket.disconnectFromHost() self.clientSocket.close() self.clientSocket.deleteLater() def winClose(self): print("主窗口关闭了") for socket,ip,port in clientSocketList: print(socket) # self.clientSocket.disconnectFromHost() # self.clientSocket.close() # self.deleteLater() clientSocketList.clear()
def run(self): tcpSocket = QTcpSocket() tcpSocket.disconnected.connect(tcpSocket.deleteLater) if not tcpSocket.setSocketDescriptor(self.sockDescriptor): print('setSocketDescriptor error') return block = QByteArray() out = QDataStream(block, QIODevice.WriteOnly) #out.setVersion(QDataStream.Qt_4_0) s = self.fortune + '\n' out.writeRawData(s.encode('utf-8')) #out.writeQString(s) tcpSocket.write(block) #等待数据发送完成 tcpSocket.waitForBytesWritten() tcpSocket.disconnectFromHost() tcpSocket.close()
def run(self): self.log.debug(f'Connection "{self.name}" is starting') def wait_and_read(n_bytes, wait_ms): "Convinience function that simplifies checking for stop events, etc." if sock.bytesAvailable() == 0: new_data = sock.waitForReadyRead(wait_ms) if not new_data: return None return sock.read(n_bytes) sock = QTcpSocket(None) # import pdb; pdb.set_trace() sock.setSocketDescriptor(self.socketDescriptor) sock.waitForConnected() while True: if sock.state() != sock.ConnectedState or self.need_to_stop(): self.log.debug(f'Connection "{self.name}" is stopping') break read_len = wait_and_read(4, 100) if not read_len: continue read_len = struct.unpack(">L", read_len)[0] if sock.bytesAvailable() == 0: sock.waitForReadyRead() data = sock.read(read_len) if not data: continue data = pickle.loads(data) record = logging.makeLogRecord(data) self.new_record.emit(record) sock.disconnectFromHost() sock.close() self.connection_finished.emit(int(self.socketDescriptor)) self.log.debug(f'Connection "{self.name}" has stopped')
class TcpC(QDialog, Ui_TcpClient): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget @type QWidget """ super(TcpC, self).__init__(parent) self.setupUi(self) self.TotalBytes = 0 self.bytesReceive = 0 self.fileNameSize = 0 self.bytesToReceive = 0 self.fileName = "" self.tcpClient = QTcpSocket(self) self.tcpPort = 7788 self.time = QTime() self.tcpClient.readyRead.connect(self.readMessage) self.tcpClient.error.connect(self.displayError) def setHostAddress(self, address): """ 设置服务器地址 """ self.hostAddress = address self.newConnect() def setFileName(self, file): """ 待接收文件的文件名 """ self.localFile = QFile(file) def closeEvent(self, event): """ 关闭事件 """ self.on_tcpClientCloseBtn_clicked() def newConnect(self): """ 连接服务器并开始计时 """ self.tcpClient.abort() self.tcpClient.connectToHost(self.hostAddress, self.tcpPort) self.time.start() def readMessage(self): """ 读取文件数据 """ receiver = QDataStream(self.tcpClient) receiver.setVersion(QDataStream.Qt_5_4) if self.bytesReceive <= 2: if self.tcpClient.bytesAvailable() >= 2 and self.fileNameSize == 0: self.TotalBytes = receiver.readInt64() self.fileNameSize = receiver.readInt64() self.bytesReceive += 2 if self.tcpClient.bytesAvailable() >= self.fileNameSize and self.fileNameSize != 0: self.fileName = receiver.readQString() self.bytesReceive += self.fileNameSize if not(self.localFile.open(QFile.WriteOnly)): QMessageBox.warning(self, "应用程序", "无法读取文件 {}:\n {}".format(self.fileName, self.localFile.errorString())) return else: return if self.bytesReceive < self.TotalBytes: self.bytesReceive += self.tcpClient.bytesAvailable() inBlock = self.tcpClient.readAll() self.localFile.write(inBlock) inBlock.resize(0) useTime = self.time.elapsed() / 1000 bytesReceived = self.bytesReceive / (1024*1024) speed = bytesReceived / useTime total = self.TotalBytes / (1024*1024) left = (total - bytesReceived) / speed if bytesReceived < 0.01: bytesReceived = self.bytesReceive / 1024 speed = bytesReceived / useTime / 1024 total = self.TotalBytes / 1024 if left > 0: msg = "已接收 {0:.2f} KB ({1:.2f}KB/s)\n共{2:.2f}KB.已用时:{3:.1f}秒\n估计剩余时间:{4:.1f}秒".format(bytesReceived, speed, total, useTime, left) else: msg = "已接收 {0:.2f} KB ({1:.2f}KB/s)\n共{2:.2f}KB.已用时:{3:.1f}秒\n".format(bytesReceived, speed, total, useTime) else: if left > 0: msg = "已接收 {0:.2f} MB ({1:.2f}MB/s)\n共{2:.2f}MB.已用时:{3:.1f}秒\n估计剩余时间:{4:.1f}秒".format(bytesReceived, speed, total, useTime, left) else: msg = "已接收 {0:.2f} MB ({1:.2f}MB/s)\n共{2:.2f}MB.已用时:{3:.1f}秒\n".format(bytesReceived, speed, total, useTime) self.progressBar.setMaximum(total) self.progressBar.setValue(bytesReceived) self.tcpClientStatuslabel.setText(msg) if self.bytesReceive == self.TotalBytes: self.localFile.close() self.tcpClient.close() self.tcpClientStatuslabel.setText("接收文件{}完毕".format(self.fileName)) self.tcpClientBtn.setEnabled(False) def displayError(self, socketError): """ 显示错误 """ if socketError == QAbstractSocket.RemoteHostClosedError: pass else: errorMsg = self.tcpClient.errorString() QMessageBox.warning(self, "应用程序", errorMsg) return @pyqtSlot() def on_tcpClientBtn_clicked(self): """ 取消接收 """ self.tcpClient.abort() if self.localFile.isOpen(): self.localFile.close() self.tcpClientBtn.setEnabled(False) @pyqtSlot() def on_tcpClientCloseBtn_clicked(self): """ 关闭 """ self.tcpClient.abort() if self.localFile.isOpen(): self.localFile.close() self.close() self.tcpClientBtn.setEnabled(True)
class WhiskerController(QObject, StatusMixin, WhiskerApi): # Whisker thread B finished = pyqtSignal() connected = pyqtSignal() disconnected = pyqtSignal() message_received = pyqtSignal(str, arrow.Arrow, int) event_received = pyqtSignal(str, arrow.Arrow, int) warning_received = pyqtSignal(str, arrow.Arrow, int) syntax_error_received = pyqtSignal(str, arrow.Arrow, int) error_received = pyqtSignal(str, arrow.Arrow, int) pingack_received = pyqtSignal(arrow.Arrow, int) def __init__(self, server: str, parent: QObject = None, connect_timeout_ms: int = 5000, read_timeout_ms: int = 500, name: str = "whisker_controller", sysevent_prefix: str = "sys_", **kwargs) -> None: super().__init__( # QObject parent=parent, # StatusMixin name=name, logger=log, # WhiskerApi whisker_immsend_get_reply_fn=self.get_immsock_response, sysevent_prefix=sysevent_prefix, # Anyone else? **kwargs) self.server = server self.connect_timeout_ms = connect_timeout_ms self.read_timeout_ms = read_timeout_ms self.immport = None self.code = None self.immsocket = None self.residual = '' @pyqtSlot(str, arrow.Arrow) @exit_on_exception def main_received(self, msg: str, timestamp: arrow.Arrow) -> None: gre = CompiledRegexMemory() # self.debug("main_received: {}".format(msg)) # 0. Ping has already been dealt with. # 1. Deal with immediate socket connection internally. if gre.search(IMMPORT_REGEX, msg): self.immport = int(gre.group(1)) return if gre.search(CODE_REGEX, msg): code = gre.group(1) self.immsocket = QTcpSocket(self) # noinspection PyUnresolvedReferences self.immsocket.disconnected.connect(self.disconnected) self.debug( "Connecting immediate socket to {}:{} with timeout {}".format( self.server, self.immport, self.connect_timeout_ms)) self.immsocket.connectToHost(self.server, self.immport) if not self.immsocket.waitForConnected(self.connect_timeout_ms): errmsg = "Immediate socket error {}".format( get_socket_error(self.immsocket)) self.error(errmsg) self.finish() self.debug("Connected immediate socket to " "{}:{}".format(self.server, self.immport)) disable_nagle(self.immsocket) self.command("Link {}".format(code)) self.connected.emit() return # 2. Get timestamp. (msg, whisker_timestamp) = split_timestamp(msg) # 3. Send the message to a general-purpose receiver self.message_received.emit(msg, timestamp, whisker_timestamp) # 4. Send the message to specific-purpose receivers. if gre.search(EVENT_REGEX, msg): event = gre.group(1) if self.process_backend_event(event): return self.event_received.emit(event, timestamp, whisker_timestamp) elif WARNING_REGEX.match(msg): self.warning_received.emit(msg, timestamp, whisker_timestamp) elif SYNTAX_ERROR_REGEX.match(msg): self.syntax_error_received.emit(msg, timestamp, whisker_timestamp) elif ERROR_REGEX.match(msg): self.error_received.emit(msg, timestamp, whisker_timestamp) elif msg == PING_ACK: self.pingack_received.emit(timestamp, whisker_timestamp) @pyqtSlot() @exit_on_exception def task_finished(self) -> None: self.debug("Task reports that it is finished") self.close_immsocket() self.finished.emit() def sendline_immsock(self, *args) -> None: msg = msg_from_args(*args) self.debug("Sending to server (IMM): {}".format(msg)) final_str = msg + EOL data_bytes = final_str.encode(ENCODING) self.immsocket.write(data_bytes) self.immsocket.waitForBytesWritten(INFINITE_WAIT) # http://doc.qt.io/qt-4.8/qabstractsocket.html self.immsocket.flush() def getline_immsock(self) -> str: """Get one line from the socket. Blocking.""" data = self.residual while EOL not in data: # self.debug("WAITING FOR DATA") # get more data from socket self.immsocket.waitForReadyRead(INFINITE_WAIT) # self.debug("DATA READY. READING IT.") newdata_bytearray = self.immsocket.readAll() # type: QByteArray newdata_str = newdata_bytearray.data().decode(ENCODING) data += newdata_str # self.debug("OK; HAVE READ DATA.") # self.debug("DATA: {}".format(repr(data))) eol_index = data.index(EOL) line = data[:eol_index] self.residual = data[eol_index + EOL_LEN:] self.debug("Reply from server (IMM): {}".format(line)) return line def get_immsock_response(self, *args) -> Optional[str]: if not self.is_connected(): self.error("Not connected") return None self.sendline_immsock(*args) reply = self.getline_immsock() return reply def is_connected(self) -> bool: return is_socket_connected(self.immsocket) # ... if the immediate socket is running, the main socket should be def close_immsocket(self) -> None: if is_socket_connected(self.immsocket): self.immsocket.close() def ping(self) -> None: # override WhiskerApi.ping() so we can emit a signal on success reply, whisker_timestamp = self._immresp_with_timestamp(PING) if reply == PING_ACK: timestamp = arrow.now() self.pingack_received.emit(timestamp, whisker_timestamp)
class WhiskerMainSocketListener(QObject, StatusMixin): # Whisker thread A finished = pyqtSignal() disconnected = pyqtSignal() line_received = pyqtSignal(str, arrow.Arrow) def __init__(self, server: str, port: int, parent: QObject = None, connect_timeout_ms: int = 5000, read_timeout_ms: int = 100, name: str = "whisker_mainsocket", **kwargs) -> None: super().__init__(parent=parent, name=name, logger=log, **kwargs) self.server = server self.port = port self.connect_timeout_ms = connect_timeout_ms self.read_timeout_ms = read_timeout_ms self.finish_requested = False self.residual = '' self.socket = None # Don't create the socket immediately; we're going to be moved to # another thread. @pyqtSlot() def start(self) -> None: # Must be separate from __init__, or signals won't be connected yet. self.finish_requested = False self.status("Connecting to {}:{} with timeout {} ms".format( self.server, self.port, self.connect_timeout_ms)) self.socket = QTcpSocket(self) # noinspection PyUnresolvedReferences self.socket.disconnected.connect(self.disconnected) self.socket.connectToHost(self.server, self.port) if not self.socket.waitForConnected(self.connect_timeout_ms): errmsg = "Socket error {}".format(get_socket_error(self.socket)) self.error(errmsg) self.finish() return self.debug("Connected to {}:{}".format(self.server, self.port)) disable_nagle(self.socket) # Main blocking loop while not self.finish_requested: # self.debug("ping") if self.socket.waitForReadyRead(self.read_timeout_ms): # data is now ready data = self.socket.readAll() # type: QByteArray # log.critical(repr(data)) # log.critical(repr(type(data))) # <class 'PyQt5.QtCore.QByteArray'> under PyQt5 # noqa # for PySide: # - readAll() returns a QByteArray; bytes() fails; str() is OK # strdata = str(data) # for PyQt5: # - readAll() returns a QByteArray again; # - however, str(data) looks like "b'Info: ...\\n'" strdata = data.data().decode(ENCODING) # this works # log.critical(repr(strdata)) self.process_data(strdata) self.finish() @pyqtSlot() @exit_on_exception def stop(self) -> None: self.debug("WhiskerMainSocketListener: stop") self.finish_requested = True def sendline_mainsock(self, msg: str) -> None: if not is_socket_connected(self.socket): self.error("Can't send through a closed socket") return self.debug("Sending to server (MAIN): {}".format(msg)) final_str = msg + EOL data_bytes = final_str.encode(ENCODING) self.socket.write(data_bytes) self.socket.flush() def finish(self) -> None: if is_socket_connected(self.socket): self.socket.close() self.finished.emit() def process_data(self, data: str) -> None: """ Adds the incoming data to any stored residual, splits it into lines, and sends each line on to the receiver. """ self.debug("incoming: {}".format(repr(data))) timestamp = arrow.now() data = self.residual + data fragments = data.split(EOL) lines = fragments[:-1] self.residual = fragments[-1] for line in lines: self.debug("incoming line: {}".format(line)) if line == PING: self.sendline_mainsock(PING_ACK) self.status("Ping received from server") return self.line_received.emit(line, timestamp)
class Dialog(QDialog): TotalBytes = 50 * 1024 * 1024 PayloadSize = 65536 def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.tcpServer = QTcpServer() self.tcpClient = QTcpSocket() self.bytesToWrite = 0 self.bytesWritten = 0 self.bytesReceived = 0 self.clientProgressBar = QProgressBar() self.clientStatusLabel = QLabel("Client ready") self.serverProgressBar = QProgressBar() self.serverStatusLabel = QLabel("Server ready") self.startButton = QPushButton("&Start") self.quitButton = QPushButton("&Quit") buttonBox = QDialogButtonBox() buttonBox.addButton(self.startButton, QDialogButtonBox.ActionRole) buttonBox.addButton(self.quitButton, QDialogButtonBox.RejectRole) self.startButton.clicked.connect(self.start) self.quitButton.clicked.connect(self.close) self.tcpServer.newConnection.connect(self.acceptConnection) self.tcpClient.connected.connect(self.startTransfer) self.tcpClient.bytesWritten.connect(self.updateClientProgress) self.tcpClient.error.connect(self.displayError) mainLayout = QVBoxLayout() mainLayout.addWidget(self.clientProgressBar) mainLayout.addWidget(self.clientStatusLabel) mainLayout.addWidget(self.serverProgressBar) mainLayout.addWidget(self.serverStatusLabel) mainLayout.addStretch(1) mainLayout.addSpacing(10) mainLayout.addWidget(buttonBox) self.setLayout(mainLayout) self.setWindowTitle("Loopback") def start(self): self.startButton.setEnabled(False) QApplication.setOverrideCursor(Qt.WaitCursor) self.bytesWritten = 0 self.bytesReceived = 0 while not self.tcpServer.isListening() and not self.tcpServer.listen(): ret = QMessageBox.critical(self, "Loopback", "Unable to start the test: %s." % self.tcpServer.errorString(), QMessageBox.Retry | QMessageBox.Cancel) if ret == QMessageBox.Cancel: return self.serverStatusLabel.setText("Listening") self.clientStatusLabel.setText("Connecting") self.tcpClient.connectToHost(QHostAddress(QHostAddress.LocalHost), self.tcpServer.serverPort()) def acceptConnection(self): self.tcpServerConnection = self.tcpServer.nextPendingConnection() self.tcpServerConnection.readyRead.connect(self.updateServerProgress) self.tcpServerConnection.error.connect(self.displayError) self.serverStatusLabel.setText("Accepted connection") self.tcpServer.close() def startTransfer(self): self.bytesToWrite = Dialog.TotalBytes - self.tcpClient.write(QByteArray(Dialog.PayloadSize, '@')) self.clientStatusLabel.setText("Connected") def updateServerProgress(self): self.bytesReceived += self.tcpServerConnection.bytesAvailable() self.tcpServerConnection.readAll() self.serverProgressBar.setMaximum(Dialog.TotalBytes) self.serverProgressBar.setValue(self.bytesReceived) self.serverStatusLabel.setText("Received %dMB" % (self.bytesReceived / (1024 * 1024))) if self.bytesReceived == Dialog.TotalBytes: self.tcpServerConnection.close() self.startButton.setEnabled(True) QApplication.restoreOverrideCursor() def updateClientProgress(self, numBytes): self.bytesWritten += numBytes if self.bytesToWrite > 0: self.bytesToWrite -= self.tcpClient.write(QByteArray( min(self.bytesToWrite, Dialog.PayloadSize), '@')) self.clientProgressBar.setMaximum(Dialog.TotalBytes) self.clientProgressBar.setValue(self.bytesWritten) self.clientStatusLabel.setText("Sent %dMB" % (self.bytesWritten / (1024 * 1024))) def displayError(self, socketError): if socketError == QTcpSocket.RemoteHostClosedError: return QMessageBox.information(self, "Network error", "The following error occured: %s." % self.tcpClient.errorString()) self.tcpClient.close() self.tcpServer.close() self.clientProgressBar.reset() self.serverProgressBar.reset() self.clientStatusLabel.setText("Client ready") self.serverStatusLabel.setText("Server ready") self.startButton.setEnabled(True) QApplication.restoreOverrideCursor()
class RedirectedIORunWrapper(): """Wrapper to run a script with redirected IO""" def __init__(self): self.__socket = None self.__redirected = False self.__procuuid = None def redirected(self): """True if streams are redirected""" return self.__redirected def main(self): """Run wrapper driver""" if '--' not in sys.argv: print("Unexpected arguments", file=sys.stderr) return 1 self.__procuuid, host, port, args = self.parseArgs() if self.__procuuid is None or host is None or port is None: print("Not enough arguments", file=sys.stderr) return 1 remoteAddress = self.resolveHost(host) self.connect(remoteAddress, port) sendJSONCommand(self.__socket, METHOD_PROC_ID_INFO, self.__procuuid, None) try: waitForIDEMessage(self.__socket, METHOD_PROLOGUE_CONTINUE, WAIT_CONTINUE_TIMEOUT) except Exception as exc: print(str(exc), file=sys.stderr) return 1 # Setup redirections stdoutOld = sys.stdout stderrOld = sys.stderr sys.stdout = OutStreamRedirector(self.__socket, True, self.__procuuid) sys.stderr = OutStreamRedirector(self.__socket, False, self.__procuuid) self.__redirected = True # Run the script retCode = 0 try: self.__runScript(args) except SystemExit as exc: if CLIENT_DEBUG: print(traceback.format_exc(), file=sys.__stderr__) if exc.code is None: retCode = 0 elif isinstance(exc.code, int): retCode = exc.code else: retCode = 1 print(str(exc.code), file=sys.stderr) except KeyboardInterrupt as exc: if CLIENT_DEBUG: print(traceback.format_exc(), file=sys.__stderr__) retCode = 1 print(traceback.format_exc(), file=sys.stderr) except Exception as exc: if CLIENT_DEBUG: print(traceback.format_exc(), file=sys.__stderr__) retCode = 1 print(traceback.format_exc(), file=sys.stderr) except: if CLIENT_DEBUG: print(traceback.format_exc(), file=sys.__stderr__) retCode = 1 print(traceback.format_exc(), file=sys.stderr) sys.stderr = stderrOld sys.stdout = stdoutOld self.__redirected = False # Send the return code back try: sendJSONCommand(self.__socket, METHOD_EPILOGUE_EXIT_CODE, self.__procuuid, {'exitCode': retCode}) except Exception as exc: print(str(exc), file=sys.stderr) self.close() return 1 self.close() return 0 def connect(self, remoteAddress, port): """Establishes a connection with the IDE""" self.__socket = QTcpSocket() if remoteAddress is None: self.__socket.connectToHost(QHostAddress.LocalHost, port) else: self.__socket.connectToHost(remoteAddress, port) if not self.__socket.waitForConnected(1000): raise Exception('Cannot connect to the IDE') self.__socket.setSocketOption(QAbstractSocket.KeepAliveOption, 1) self.__socket.setSocketOption(QAbstractSocket.LowDelayOption, 1) self.__socket.disconnected.connect(self.__onDisconnected) def __onDisconnected(self): """IDE dropped the socket""" sys.exit(0) def __runScript(self, arguments): """Runs the python script""" try: # In Py 2.x, the builtins were in __builtin__ builtins = sys.modules['__builtin__'] except KeyError: # In Py 3.x, they're in builtins builtins = sys.modules['builtins'] fileName = arguments[0] oldMainMod = sys.modules['__main__'] mainMod = imp.new_module('__main__') sys.modules['__main__'] = mainMod mainMod.__file__ = fileName mainMod.__builtins__ = builtins # Set sys.argv properly. oldArgv = sys.argv sys.argv = arguments # Without this imports of what is located at the script directory do # not work normCWD = os.path.normpath(os.getcwd()) normScriptDir = os.path.normpath(os.path.dirname(fileName)) sys.path.insert(0, os.getcwd()) if normCWD != normScriptDir: sys.path.insert(0, os.path.dirname(fileName)) with open(fileName, 'rb') as fileToRead: source = fileToRead.read() # We have the source. `compile` still needs the last line to be clean, # so make sure it is, then compile a code object from it. if not source or source[-1] != b'\n': source += b'\n' code = compile(source, fileName, "exec") exec(code, mainMod.__dict__) # Restore the old __main__ sys.modules['__main__'] = oldMainMod # Restore the old argv and path sys.argv = oldArgv def close(self): """Closes the connection if so""" try: if self.__socket: # Wait exit needed because otherwise IDE may get socket # disconnected before it has a chance to read the script # exit code. Wait for the explicit command to exit guarantees # that all the data will be received. waitForIDEMessage(self.__socket, METHOD_EPILOGUE_EXIT, WAIT_EXIT_COMMAND_TIMEOUT) finally: if self.__socket: self.__socket.close() self.__socket = None def input(self, prompt, echo): """Implements 'input' using the redirected input""" sendJSONCommand(self.__socket, METHOD_STDIN, self.__procuuid, { 'prompt': prompt, 'echo': echo }) params = waitForIDEMessage(self.__socket, METHOD_STDIN, 60 * 60 * 24 * 7) return params['input'] @staticmethod def resolveHost(host): """Resolves a hostname to an IP address""" try: host, _ = host.split("@@") family = socket.AF_INET6 except ValueError: # version = 'v4' family = socket.AF_INET return socket.getaddrinfo(host, None, family, socket.SOCK_STREAM)[0][4][0] @staticmethod def parseArgs(): """Parses the arguments""" host = None port = None procuuid = None args = sys.argv[1:] while args[0]: if args[0] in ['--host']: host = args[1] del args[0] del args[0] elif args[0] in ['--port']: port = int(args[1]) del args[0] del args[0] elif args[0] in ['--procuuid']: procuuid = args[1] del args[0] del args[0] elif args[0] == '--': del args[0] break return procuuid, host, port, args
class PulsedNMR(QMainWindow, Ui_PulsedNMR): rates = {0: 25.0e3, 1: 50.0e3, 2: 250.0e3, 3: 500.0e3, 4: 2500.0e3} def __init__(self): super(PulsedNMR, self).__init__() self.setupUi(self) self.rateValue.addItems(['25', '50', '250', '500', '2500']) # IP address validator rx = QRegExp( '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' ) self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variable self.idle = True # number of samples to show on the plot self.size = 50000 # buffer and offset for the incoming samples self.buffer = bytearray(8 * self.size) self.offset = 0 self.data = np.frombuffer(self.buffer, np.complex64) # create figure figure = Figure() figure.set_facecolor('none') self.axes = figure.add_subplot(111) self.canvas = FigureCanvas(figure) self.plotLayout.addWidget(self.canvas) # create navigation toolbar self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False) # remove subplots action actions = self.toolbar.actions() self.toolbar.removeAction(actions[7]) self.plotLayout.addWidget(self.toolbar) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from buttons and boxes self.startButton.clicked.connect(self.start) self.freqValue.valueChanged.connect(self.set_freq) self.awidthValue.valueChanged.connect(self.set_awidth) self.deltaValue.valueChanged.connect(self.set_delta) self.rateValue.currentIndexChanged.connect(self.set_rate) # set rate self.rateValue.setCurrentIndex(2) # create timer for the repetitions self.timer = QTimer(self) self.timer.timeout.connect(self.fire) def start(self): if self.idle: self.startButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) else: self.idle = True self.timer.stop() self.socket.close() self.offset = 0 self.startButton.setText('Start') self.startButton.setEnabled(True) def connected(self): self.idle = False self.set_freq(self.freqValue.value()) self.set_rate(self.rateValue.currentIndex()) self.set_awidth(self.awidthValue.value()) self.fire() self.timer.start(self.deltaValue.value()) self.startButton.setText('Stop') self.startButton.setEnabled(True) def read_data(self): size = self.socket.bytesAvailable() if self.offset + size < 8 * self.size: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.buffer[self.offset:8 * self.size] = self.socket.read(8 * self.size - self.offset) self.offset = 0 # plot the signal envelope self.curve.set_ydata(np.real(self.data)) self.canvas.draw() def display_error(self, socketError): if socketError == QAbstractSocket.RemoteHostClosedError: pass else: QMessageBox.information(self, 'PulsedNMR', 'Error: %s.' % self.socket.errorString()) self.startButton.setText('Start') self.startButton.setEnabled(True) def set_freq(self, value): if self.idle: return self.socket.write(struct.pack('<I', 0 << 28 | int(1.0e6 * value))) def set_rate(self, index): # time axis rate = float(PulsedNMR.rates[index]) time = np.linspace(0.0, (self.size - 1) * 1000.0 / rate, self.size) # reset toolbar self.toolbar.home() self.toolbar._views.clear() self.toolbar._positions.clear() # reset plot self.axes.clear() self.axes.grid() # plot zeros and get store the returned Line2D object self.curve, = self.axes.plot(time, np.zeros(self.size)) x1, x2, y1, y2 = self.axes.axis() # set y axis limits self.axes.axis((x1, x2, -0.1, 0.4)) self.axes.set_xlabel('time, ms') self.canvas.draw() # set repetition time minimum = self.size / rate * 2000.0 if minimum < 100.0: minimum = 100.0 self.deltaValue.setMinimum(minimum) self.deltaValue.setValue(minimum) if self.idle: return self.socket.write(struct.pack('<I', 1 << 28 | index)) def set_awidth(self, value): if self.idle: return self.socket.write(struct.pack('<I', 2 << 28 | int(1.0e1 * value))) def set_delta(self, value): if self.idle: return self.timer.stop() self.timer.start(value) def fire(self): if self.idle: return self.socket.write(struct.pack('<I', 3 << 28))
class IrcWidget(QWidget, Ui_IrcWidget): """ Class implementing the IRC window. @signal autoConnected() emitted after an automatic connection was initiated """ autoConnected = pyqtSignal() ServerDisconnected = 1 ServerConnected = 2 ServerConnecting = 3 def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(IrcWidget, self).__init__(parent) self.setupUi(self) from .IrcNetworkManager import IrcNetworkManager self.__ircNetworkManager = IrcNetworkManager(self) self.__leaveButton = QToolButton(self) self.__leaveButton.setIcon( UI.PixmapCache.getIcon("ircCloseChannel.png")) self.__leaveButton.setToolTip( self.tr("Press to leave the current channel")) self.__leaveButton.clicked.connect(self.__leaveChannel) self.__leaveButton.setEnabled(False) self.channelsWidget.setCornerWidget( self.__leaveButton, Qt.BottomRightCorner) self.channelsWidget.setTabsClosable(False) if not isMacPlatform(): self.channelsWidget.setTabPosition(QTabWidget.South) height = self.height() self.splitter.setSizes([height * 0.6, height * 0.4]) self.__channelList = [] self.__channelTypePrefixes = "" self.__userName = "" self.__identityName = "" self.__quitMessage = "" self.__nickIndex = -1 self.__nickName = "" self.__server = None self.__registering = False self.__connectionState = IrcWidget.ServerDisconnected self.__sslErrorLock = False self.__buffer = "" self.__userPrefix = {} self.__socket = None if SSL_AVAILABLE: self.__sslErrorHandler = E5SslErrorHandler(self) else: self.__sslErrorHandler = None self.__patterns = [ # :[email protected] PRIVMSG bar_ :some long message (re.compile(r":([^!]+)!([^ ]+)\sPRIVMSG\s([^ ]+)\s:(.*)"), self.__query), # :foo.bar.net COMMAND some message (re.compile(r""":([^ ]+)\s+([A-Z]+)\s+(.+)"""), self.__handleNamedMessage), # :foo.bar.net 123 * :info (re.compile(r""":([^ ]+)\s+(\d{3})\s+(.+)"""), self.__handleNumericMessage), # PING :ping message (re.compile(r"""PING\s+:(.*)"""), self.__ping), ] self.__prefixRe = re.compile(r""".*\sPREFIX=\((.*)\)([^ ]+).*""") self.__chanTypesRe = re.compile(r""".*\sCHANTYPES=([^ ]+).*""") ircPic = UI.PixmapCache.getPixmap("irc128.png") self.__emptyLabel = QLabel() self.__emptyLabel.setPixmap(ircPic) self.__emptyLabel.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter) self.channelsWidget.addTab(self.__emptyLabel, "") # all initialized, do connections now self.__ircNetworkManager.dataChanged.connect(self.__networkDataChanged) self.networkWidget.initialize(self.__ircNetworkManager) self.networkWidget.connectNetwork.connect(self.__connectNetwork) self.networkWidget.editNetwork.connect(self.__editNetwork) self.networkWidget.joinChannel.connect(self.joinChannel) self.networkWidget.nickChanged.connect(self.__changeNick) self.networkWidget.sendData.connect(self.__send) self.networkWidget.away.connect(self.__away) self.networkWidget.autoConnected.connect(self.autoConnected) def shutdown(self): """ Public method to shut down the widget. @return flag indicating successful shutdown (boolean) """ if self.__server: if Preferences.getIrc("AskOnShutdown"): ok = E5MessageBox.yesNo( self, self.tr("Disconnect from Server"), self.tr( """<p>Do you really want to disconnect from""" """ <b>{0}</b>?</p><p>All channels will be closed.""" """</p>""").format(self.__server.getName())) else: ok = True if ok: self.__connectNetwork("", False, True) else: ok = True if ok: self.__ircNetworkManager.close() return ok def autoConnect(self): """ Public method to initiate the IRC auto connection. """ self.networkWidget.autoConnect() def __connectNetwork(self, name, connect, silent): """ Private slot to connect to or disconnect from the given network. @param name name of the network to connect to (string) @param connect flag indicating to connect (boolean) @param silent flag indicating a silent connect/disconnect (boolean) """ if connect: network = self.__ircNetworkManager.getNetwork(name) if network: self.__server = network.getServer() self.__identityName = network.getIdentityName() identity = self.__ircNetworkManager.getIdentity( self.__identityName) if identity: self.__userName = identity.getIdent() self.__quitMessage = identity.getQuitMessage() if self.__server: useSSL = self.__server.useSSL() if useSSL and not SSL_AVAILABLE: E5MessageBox.critical( self, self.tr("SSL Connection"), self.tr( """An encrypted connection to the IRC""" """ network was requested but SSL is not""" """ available. Please change the server""" """ configuration.""")) return if useSSL: # create SSL socket self.__socket = QSslSocket(self) self.__socket.encrypted.connect( self.__hostConnected) self.__socket.sslErrors.connect( self.__sslErrors) else: # create TCP socket self.__socket = QTcpSocket(self) self.__socket.connected.connect( self.__hostConnected) self.__socket.hostFound.connect( self.__hostFound) self.__socket.disconnected.connect( self.__hostDisconnected) self.__socket.readyRead.connect( self.__readyRead) self.__socket.error.connect( self.__tcpError) self.__connectionState = IrcWidget.ServerConnecting if useSSL: self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Looking for server {0} (port {1})" " using an SSL encrypted connection" "...").format(self.__server.getName(), self.__server.getPort())) self.__socket.connectToHostEncrypted( self.__server.getName(), self.__server.getPort() ) else: self.networkWidget.addServerMessage( self.tr("Info"), self.tr( "Looking for server {0} (port {1})...") .format( self.__server.getName(), self.__server.getPort())) self.__socket.connectToHost( self.__server.getName(), self.__server.getPort()) else: if silent: ok = True else: ok = E5MessageBox.yesNo( self, self.tr("Disconnect from Server"), self.tr("""<p>Do you really want to disconnect from""" """ <b>{0}</b>?</p><p>All channels will be""" """ closed.</p>""") .format(self.__server.getName())) if ok: if self.__server is not None: self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Disconnecting from server {0}...").format( self.__server.getName())) elif name: self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Disconnecting from network {0}...").format( name)) else: self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Disconnecting from server.")) self.__closeAllChannels() self.__send("QUIT :" + self.__quitMessage) if self.__socket: self.__socket.flush() self.__socket.close() if self.__socket: # socket is still existing self.__socket.deleteLater() self.__socket = None self.__userName = "" self.__identityName = "" self.__quitMessage = "" def __editNetwork(self, name): """ Private slot to edit the network configuration. @param name name of the network to edit (string) """ from .IrcNetworkListDialog import IrcNetworkListDialog dlg = IrcNetworkListDialog(self.__ircNetworkManager, self) dlg.exec_() def __networkDataChanged(self): """ Private slot handling changes of the network and identity definitions. """ identity = self.__ircNetworkManager.getIdentity(self.__identityName) if identity: partMsg = identity.getPartMessage() for channel in self.__channelList: channel.setPartMessage(partMsg) def joinChannel(self, name, key=""): """ Public slot to join a channel. @param name name of the channel (string) @param key key of the channel (string) """ # step 1: check, if this channel is already joined for channel in self.__channelList: if channel.name() == name: return from .IrcChannelWidget import IrcChannelWidget channel = IrcChannelWidget(self) channel.setName(name) channel.setUserName(self.__nickName) identity = self.__ircNetworkManager.getIdentity(self.__identityName) if identity: channel.setPartMessage(identity.getPartMessage()) channel.setUserPrivilegePrefix(self.__userPrefix) channel.initAutoWho() channel.sendData.connect(self.__send) channel.sendCtcpRequest.connect(self.__sendCtcpRequest) channel.sendCtcpReply.connect(self.__sendCtcpReply) channel.channelClosed.connect(self.__closeChannel) channel.openPrivateChat.connect(self.__openPrivate) channel.awayCommand.connect(self.networkWidget.handleAwayCommand) channel.leaveChannels.connect(self.__leaveChannels) channel.leaveAllChannels.connect(self.__leaveAllChannels) self.channelsWidget.addTab(channel, name) self.__channelList.append(channel) self.channelsWidget.setCurrentWidget(channel) joinCommand = ["JOIN", name] if key: joinCommand.append(key) self.__send(" ".join(joinCommand)) self.__send("MODE " + name) emptyIndex = self.channelsWidget.indexOf(self.__emptyLabel) if emptyIndex > -1: self.channelsWidget.removeTab(emptyIndex) self.__leaveButton.setEnabled(True) self.channelsWidget.setTabsClosable(True) def __query(self, match): """ Private method to handle a new private connection. @param match reference to the match object @return flag indicating, if the message was handled (boolean) """ # group(1) sender user name # group(2) sender user@host # group(3) target nick # group(4) message if match.group(4).startswith("\x01"): return self.__handleCtcp(match) self.__openPrivate(match.group(1)) # the above call sets the new channel as the current widget channel = self.channelsWidget.currentWidget() channel.addMessage(match.group(1), match.group(4)) channel.setPrivateInfo( "{0} - {1}".format(match.group(1), match.group(2))) return True @pyqtSlot(str) def __openPrivate(self, name): """ Private slot to open a private chat with the given user. @param name name of the user (string) """ from .IrcChannelWidget import IrcChannelWidget channel = IrcChannelWidget(self) channel.setName(self.__nickName) channel.setUserName(self.__nickName) identity = self.__ircNetworkManager.getIdentity(self.__identityName) if identity: channel.setPartMessage(identity.getPartMessage()) channel.setUserPrivilegePrefix(self.__userPrefix) channel.setPrivate(True, name) channel.addUsers([name, self.__nickName]) channel.sendData.connect(self.__send) channel.sendCtcpRequest.connect(self.__sendCtcpRequest) channel.sendCtcpReply.connect(self.__sendCtcpReply) channel.channelClosed.connect(self.__closeChannel) channel.awayCommand.connect(self.networkWidget.handleAwayCommand) channel.leaveChannels.connect(self.__leaveChannels) channel.leaveAllChannels.connect(self.__leaveAllChannels) self.channelsWidget.addTab(channel, name) self.__channelList.append(channel) self.channelsWidget.setCurrentWidget(channel) @pyqtSlot() def __leaveChannel(self): """ Private slot to leave a channel and close the associated tab. """ channel = self.channelsWidget.currentWidget() channel.requestLeave() @pyqtSlot(list) def __leaveChannels(self, channelNames): """ Private slot to leave a list of channels and close their associated tabs. @param channelNames list of channels to leave @type list of str """ for channelName in channelNames: for channel in self.__channelList: if channel.name() == channelName: channel.leaveChannel() @pyqtSlot() def __leaveAllChannels(self): """ Private slot to leave all channels and close their tabs. """ while self.__channelList: channel = self.__channelList[0] channel.leaveChannel() def __closeAllChannels(self): """ Private method to close all channels. """ while self.__channelList: channel = self.__channelList.pop() self.channelsWidget.removeTab(self.channelsWidget.indexOf(channel)) channel.deleteLater() channel = None self.channelsWidget.addTab(self.__emptyLabel, "") self.__emptyLabel.show() self.__leaveButton.setEnabled(False) self.channelsWidget.setTabsClosable(False) def __closeChannel(self, name): """ Private slot handling the closing of a channel. @param name name of the closed channel (string) """ for channel in self.__channelList: if channel.name() == name: self.channelsWidget.removeTab( self.channelsWidget.indexOf(channel)) self.__channelList.remove(channel) channel.deleteLater() if self.channelsWidget.count() == 0: self.channelsWidget.addTab(self.__emptyLabel, "") self.__emptyLabel.show() self.__leaveButton.setEnabled(False) self.channelsWidget.setTabsClosable(False) @pyqtSlot(int) def on_channelsWidget_tabCloseRequested(self, index): """ Private slot to close a channel by pressing the close button of the channels widget. @param index index of the tab to be closed (integer) """ channel = self.channelsWidget.widget(index) channel.requestLeave() def __send(self, data): """ Private slot to send data to the IRC server. @param data data to be sent (string) """ if self.__socket: self.__socket.write( QByteArray("{0}\r\n".format(data).encode("utf-8"))) def __sendCtcpRequest(self, receiver, request, arguments): """ Private slot to send a CTCP request. @param receiver nick name of the receiver @type str @param request CTCP request to be sent @type str @param arguments arguments to be sent @type str """ request = request.upper() if request == "PING": arguments = "Eric IRC {0}".format( QDateTime.currentMSecsSinceEpoch()) self.__send("PRIVMSG {0} :\x01{1} {2}\x01".format( receiver, request, arguments)) def __sendCtcpReply(self, receiver, text): """ Private slot to send a CTCP reply. @param receiver nick name of the receiver @type str @param text text to be sent @type str """ self.__send("NOTICE {0} :\x01{1}\x01".format(receiver, text)) def __hostFound(self): """ Private slot to indicate the host was found. """ self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Server found,connecting...")) def __hostConnected(self): """ Private slot to log in to the server after the connection was established. """ self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Connected,logging in...")) self.networkWidget.setConnected(True) self.__registering = True serverPassword = self.__server.getPassword() if serverPassword: self.__send("PASS " + serverPassword) identity = self.__ircNetworkManager.getIdentity( self.__identityName) nick = self.networkWidget.getNickname() if not nick and identity: self.__nickIndex = 0 try: nick = identity.getNickNames()[self.__nickIndex] except IndexError: nick = "" if not nick: nick = self.__userName self.__nickName = nick self.networkWidget.setNickName(nick) if identity: realName = identity.getRealName() if not realName: realName = "eric IDE chat" self.__send("NICK " + nick) self.__send("USER " + self.__userName + " 0 * :" + realName) def __hostDisconnected(self): """ Private slot to indicate the host was disconnected. """ if self.networkWidget.isConnected(): self.__closeAllChannels() self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Server disconnected.")) self.networkWidget.setRegistered(False) self.networkWidget.setConnected(False) self.__server = None self.__nickName = "" self.__nickIndex = -1 self.__channelTypePrefixes = "" if self.__socket: self.__socket.deleteLater() self.__socket = None self.__connectionState = IrcWidget.ServerDisconnected self.__sslErrorLock = False def __readyRead(self): """ Private slot to read data from the socket. """ if self.__socket: self.__buffer += str( self.__socket.readAll(), Preferences.getSystem("IOEncoding"), 'replace') if self.__buffer.endswith("\r\n"): for line in self.__buffer.splitlines(): line = line.strip() if line: logging.debug("<IRC> %s", line) handled = False # step 1: give channels a chance to handle the message for channel in self.__channelList: handled = channel.handleMessage(line) if handled: break else: # step 2: try to process the message ourselves for patternRe, patternFunc in self.__patterns: match = patternRe.match(line) if match is not None: if patternFunc(match): break else: # Oops, the message wasn't handled self.networkWidget.addErrorMessage( self.tr("Message Error"), self.tr( "Unknown message received from server:" "<br/>{0}").format(line)) self.__updateUsersCount() self.__buffer = "" def __handleCtcpReply(self, match): """ Private method to handle a server message containing a CTCP reply. @param match reference to the match object """ if "!" in match.group(1): sender = match.group(1).split("!", 1)[0] try: ctcpCommand = match.group(3).split(":", 1)[1] except IndexError: ctcpCommand = match.group(3) ctcpCommand = ctcpCommand[1:].split("\x01", 1)[0] if " " in ctcpCommand: ctcpReply, ctcpArg = ctcpCommand.split(" ", 1) else: ctcpReply, ctcpArg = ctcpCommand, "" ctcpReply = ctcpReply.upper() if ctcpReply == "PING" and ctcpArg.startswith("Eric IRC "): # it is a response to a ping request pingDateTime = int(ctcpArg.split()[-1]) latency = QDateTime.currentMSecsSinceEpoch() - pingDateTime self.networkWidget.addServerMessage( self.tr("CTCP"), self.tr( "Received CTCP-PING response from {0} with latency" " of {1} ms.").format(sender, latency)) else: self.networkWidget.addServerMessage( self.tr("CTCP"), self.tr( "Received unknown CTCP-{0} response from {1}.") .format(ctcpReply, sender)) def __handleNamedMessage(self, match): """ Private method to handle a server message containing a message name. @param match reference to the match object @return flag indicating, if the message was handled (boolean) """ name = match.group(2) if name == "NOTICE": try: msg = match.group(3).split(":", 1)[1] except IndexError: msg = match.group(3) if msg.startswith("\x01"): self.__handleCtcpReply(match) return True if "!" in match.group(1): name = match.group(1).split("!", 1)[0] msg = "-{0}- {1}".format(name, msg) self.networkWidget.addServerMessage(self.tr("Notice"), msg) return True elif name == "MODE": self.__registering = False if ":" in match.group(3): # :foo MODE foo :+i name, modes = match.group(3).split(" :") sourceNick = match.group(1) if not self.isChannelName(name): if name == self.__nickName: if sourceNick == self.__nickName: msg = self.tr( "You have set your personal modes to" " <b>[{0}]</b>.").format(modes) else: msg = self.tr( "{0} has changed your personal modes to" " <b>[{1}]</b>.").format(sourceNick, modes) self.networkWidget.addServerMessage( self.tr("Mode"), msg, filterMsg=False) return True elif name == "PART": nick = match.group(1).split("!", 1)[0] if nick == self.__nickName: channel = match.group(3).split(None, 1)[0] self.networkWidget.addMessage( self.tr("You have left channel {0}.").format(channel)) return True elif name == "QUIT": # don't do anything with it here return True elif name == "NICK": # :[email protected] NICK :newnick oldNick = match.group(1).split("!", 1)[0] newNick = match.group(3).split(":", 1)[1] if oldNick == self.__nickName: self.networkWidget.addMessage( self.tr("You are now known as {0}.").format(newNick)) self.__nickName = newNick self.networkWidget.setNickName(newNick) else: self.networkWidget.addMessage( self.tr("User {0} is now known as {1}.").format( oldNick, newNick)) return True elif name == "PONG": nick = match.group(3).split(":", 1)[1] self.networkWidget.addMessage( self.tr("Received PONG from {0}").format(nick)) return True elif name == "ERROR": self.networkWidget.addErrorMessage( self.tr("Server Error"), match.group(3).split(":", 1)[1]) return True return False def __handleNumericMessage(self, match): """ Private method to handle a server message containing a numeric code. @param match reference to the match object @return flag indicating, if the message was handled (boolean) """ code = int(match.group(2)) if code < 400: return self.__handleServerReply( code, match.group(1), match.group(3)) else: return self.__handleServerError( code, match.group(1), match.group(3)) def __handleServerError(self, code, server, message): """ Private slot to handle a server error reply. @param code numerical code sent by the server (integer) @param server name of the server (string) @param message message sent by the server (string) @return flag indicating, if the message was handled (boolean) """ if code == 433: if self.__registering: self.__handleNickInUseLogin() else: self.__handleNickInUse() else: self.networkWidget.addServerMessage(self.tr("Error"), message) return True def __handleServerReply(self, code, server, message): """ Private slot to handle a server reply. @param code numerical code sent by the server (integer) @param server name of the server (string) @param message message sent by the server (string) @return flag indicating, if the message was handled (boolean) """ # determine message type if code in [1, 2, 3, 4]: msgType = self.tr("Welcome") elif code == 5: msgType = self.tr("Support") elif code in [250, 251, 252, 253, 254, 255, 265, 266]: msgType = self.tr("User") elif code in [372, 375, 376]: msgType = self.tr("MOTD") elif code in [305, 306]: msgType = self.tr("Away") else: msgType = self.tr("Info ({0})").format(code) # special treatment for some messages if code == 375: message = self.tr("Message of the day") elif code == 376: message = self.tr("End of message of the day") elif code == 4: parts = message.strip().split() message = self.tr( "Server {0} (Version {1}), User-Modes: {2}," " Channel-Modes: {3}" ).format(parts[1], parts[2], parts[3], parts[4]) elif code == 265: parts = message.strip().split() message = self.tr( "Current users on {0}: {1}, max. {2}").format( server, parts[1], parts[2]) elif code == 266: parts = message.strip().split() message = self.tr( "Current users on the network: {0}, max. {1}").format( parts[1], parts[2]) elif code == 305: message = self.tr("You are no longer marked as being away.") elif code == 306: message = self.tr("You have been marked as being away.") else: first, message = message.split(None, 1) if message.startswith(":"): message = message[1:] else: message = message.replace(":", "", 1) self.networkWidget.addServerMessage(msgType, message) if code == 1: # register with services after the welcome message self.__connectionState = IrcWidget.ServerConnected self.__registerWithServices() self.networkWidget.setRegistered(True) QTimer.singleShot(1000, self.__autoJoinChannels) elif code == 5: # extract the user privilege prefixes # ... PREFIX=(ov)@+ ... m = self.__prefixRe.match(message) if m: self.__setUserPrivilegePrefix(m.group(1), m.group(2)) # extract the channel type prefixes # ... CHANTYPES=# ... m = self.__chanTypesRe.match(message) if m: self.__setChannelTypePrefixes(m.group(1)) return True def __registerWithServices(self): """ Private method to register to services. """ identity = self.__ircNetworkManager.getIdentity(self.__identityName) if identity: service = identity.getServiceName() password = identity.getPassword() if service and password: self.__send("PRIVMSG " + service + " :identify " + password) def __autoJoinChannels(self): """ Private slot to join channels automatically once a server got connected. """ for channel in self.networkWidget.getNetworkChannels(): if channel.autoJoin(): name = channel.getName() key = channel.getKey() self.joinChannel(name, key) def __tcpError(self, error): """ Private slot to handle errors reported by the TCP socket. @param error error code reported by the socket (QAbstractSocket.SocketError) """ if error == QAbstractSocket.RemoteHostClosedError: # ignore this one, it's a disconnect if self.__sslErrorLock: self.networkWidget.addErrorMessage( self.tr("SSL Error"), self.tr( """Connection to server {0} (port {1}) lost while""" """ waiting for user response to an SSL error.""") .format(self.__server.getName(), self.__server.getPort())) self.__connectionState = IrcWidget.ServerDisconnected elif error == QAbstractSocket.HostNotFoundError: self.networkWidget.addErrorMessage( self.tr("Socket Error"), self.tr( "The host was not found. Please check the host name" " and port settings.")) elif error == QAbstractSocket.ConnectionRefusedError: self.networkWidget.addErrorMessage( self.tr("Socket Error"), self.tr( "The connection was refused by the peer. Please check the" " host name and port settings.")) elif error == QAbstractSocket.SslHandshakeFailedError: self.networkWidget.addErrorMessage( self.tr("Socket Error"), self.tr("The SSL handshake failed.")) else: if self.__socket: self.networkWidget.addErrorMessage( self.tr("Socket Error"), self.tr( "The following network error occurred:<br/>{0}") .format(self.__socket.errorString())) else: self.networkWidget.addErrorMessage( self.tr("Socket Error"), self.tr("A network error occurred.")) def __sslErrors(self, errors): """ Private slot to handle SSL errors. @param errors list of SSL errors (list of QSslError) """ ignored, defaultChanged = self.__sslErrorHandler.sslErrors( errors, self.__server.getName(), self.__server.getPort()) if ignored == E5SslErrorHandler.NotIgnored: self.networkWidget.addErrorMessage( self.tr("SSL Error"), self.tr( """Could not connect to {0} (port {1}) using an SSL""" """ encrypted connection. Either the server does not""" """ support SSL (did you use the correct port?) or""" """ you rejected the certificate.""") .format(self.__server.getName(), self.__server.getPort())) self.__socket.close() else: if defaultChanged: self.__socket.setSslConfiguration( QSslConfiguration.defaultConfiguration()) if ignored == E5SslErrorHandler.UserIgnored: self.networkWidget.addErrorMessage( self.tr("SSL Error"), self.tr( """The SSL certificate for the server {0} (port {1})""" """ failed the authenticity check. SSL errors""" """ were accepted by you.""") .format(self.__server.getName(), self.__server.getPort())) if self.__connectionState == IrcWidget.ServerConnecting: self.__socket.ignoreSslErrors() def __setUserPrivilegePrefix(self, prefix1, prefix2): """ Private method to set the user privilege prefix. @param prefix1 first part of the prefix (string) @param prefix2 indictors the first part gets mapped to (string) """ # PREFIX=(ov)@+ # o = @ -> @ircbot , channel operator # v = + -> +userName , voice operator for i in range(len(prefix1)): self.__userPrefix["+" + prefix1[i]] = prefix2[i] self.__userPrefix["-" + prefix1[i]] = "" def __ping(self, match): """ Private method to handle a PING message. @param match reference to the match object @return flag indicating, if the message was handled (boolean) """ self.__send("PONG " + match.group(1)) return True def __handleCtcp(self, match): """ Private method to handle a CTCP command. @param match reference to the match object @return flag indicating, if the message was handled (boolean) """ # group(1) sender user name # group(2) sender user@host # group(3) target nick # group(4) message if match.group(4).startswith("\x01"): ctcpCommand = match.group(4)[1:].split("\x01", 1)[0] if " " in ctcpCommand: ctcpRequest, ctcpArg = ctcpCommand.split(" ", 1) else: ctcpRequest, ctcpArg = ctcpCommand, "" ctcpRequest = ctcpRequest.lower() if ctcpRequest == "version": if Version.startswith("@@"): vers = "" else: vers = " " + Version msg = "Eric IRC client{0}, {1}".format(vers, Copyright) self.networkWidget.addServerMessage( self.tr("CTCP"), self.tr("Received Version request from {0}.").format( match.group(1))) self.__sendCtcpReply(match.group(1), "VERSION " + msg) elif ctcpRequest == "ping": self.networkWidget.addServerMessage( self.tr("CTCP"), self.tr( "Received CTCP-PING request from {0}," " sending answer.").format(match.group(1))) self.__sendCtcpReply( match.group(1), "PING {0}".format(ctcpArg)) elif ctcpRequest == "clientinfo": self.networkWidget.addServerMessage( self.tr("CTCP"), self.tr( "Received CTCP-CLIENTINFO request from {0}," " sending answer.").format(match.group(1))) self.__sendCtcpReply( match.group(1), "CLIENTINFO CLIENTINFO PING VERSION") else: self.networkWidget.addServerMessage( self.tr("CTCP"), self.tr( "Received unknown CTCP-{0} request from {1}.") .format(ctcpRequest, match.group(1))) return True return False def __updateUsersCount(self): """ Private method to update the users count on the channel tabs. """ for channel in self.__channelList: index = self.channelsWidget.indexOf(channel) self.channelsWidget.setTabText( index, self.tr("{0} ({1})", "channel name, users count").format( channel.name(), channel.getUsersCount())) def __handleNickInUseLogin(self): """ Private method to handle a 443 server error at login. """ self.__nickIndex += 1 try: identity = self.__ircNetworkManager.getIdentity( self.__identityName) if identity: nick = identity.getNickNames()[self.__nickIndex] self.__nickName = nick else: self.__connectNetwork("", False, True) self.__nickName = "" self.__nickIndex = -1 return except IndexError: self.networkWidget.addServerMessage( self.tr("Critical"), self.tr( "No nickname acceptable to the server configured" " for <b>{0}</b>. Disconnecting...") .format(self.__userName), filterMsg=False) self.__connectNetwork("", False, True) self.__nickName = "" self.__nickIndex = -1 return self.networkWidget.setNickName(nick) self.__send("NICK " + nick) def __handleNickInUse(self): """ Private method to handle a 443 server error. """ self.networkWidget.addServerMessage( self.tr("Critical"), self.tr("The given nickname is already in use.")) def __changeNick(self, nick): """ Private slot to use a new nick name. @param nick nick name to use (str) """ if nick and nick != self.__nickName: self.__send("NICK " + nick) def __setChannelTypePrefixes(self, prefixes): """ Private method to set the channel type prefixes. @param prefixes channel prefix characters (string) """ self.__channelTypePrefixes = prefixes def isChannelName(self, name): """ Public method to check, if the given name is a channel name. @param name name to check (string) @return flag indicating a channel name (boolean) """ if not name: return False if self.__channelTypePrefixes: return name[0] in self.__channelTypePrefixes else: return name[0] in "#&" def __away(self, isAway): """ Private slot handling the change of the away state. @param isAway flag indicating the current away state (boolean) """ if isAway and self.__identityName: identity = self.__ircNetworkManager.getIdentity( self.__identityName) if identity and identity.rememberAwayPosition(): for channel in self.__channelList: channel.setMarkerLine()
class MKSOutputDevice(NetworkedPrinterOutputDevice): def __init__(self, instance_id: str, address: str, properties: dict, **kwargs) -> None: super().__init__(device_id=instance_id, address=address, properties=properties, **kwargs) self._address = address self._port = 8080 self._key = instance_id self._properties = properties self._target_bed_temperature = 0 self._num_extruders = 1 self._hotend_temperatures = [0] * self._num_extruders self._target_hotend_temperatures = [0] * self._num_extruders self._monitor_view_qml_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "MonitorItem4x.qml") # self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "MonitorItem.qml") self.setPriority( 3 ) # Make sure the output device gets selected above local file output and Octoprint XD self._active_machine = CuraApplication.getInstance().getMachineManager( ).activeMachine self.setName(instance_id) self.setShortDescription( i18n_catalog.i18nc("@action:button", "Print over TFT")) self.setDescription( i18n_catalog.i18nc("@properties:tooltip", "Print over TFT")) self.setIconName("print") self.setConnectionText( i18n_catalog.i18nc("@info:status", "Connected to TFT on {0}").format(self._key)) Application.getInstance().globalContainerStackChanged.connect( self._onGlobalContainerChanged) self._socket = None self._gl = None self._command_queue = Queue() self._isPrinting = False self._isPause = False self._isSending = False self._gcode = None self._isConnect = False self._printing_filename = "" self._printing_progress = 0 self._printing_time = 0 self._start_time = 0 self._pause_time = 0 self.last_update_time = 0 self.angle = 10 self._connection_state_before_timeout = None self._sdFileList = False self.sdFiles = [] self._mdialog = None self._mfilename = None self._uploadpath = '' self._settings_reply = None self._printer_reply = None self._job_reply = None self._command_reply = None self._screenShot = None self._image_reply = None self._stream_buffer = b"" self._stream_buffer_start_index = -1 self._post_reply = None self._post_multi_part = None self._post_part = None self._last_file_name = None self._last_file_path = None self._progress_message = None self._error_message = None self._connection_message = None self.__additional_components_view = None self._update_timer = QTimer() self._update_timer.setInterval( 2000) # TODO; Add preference for update interval self._update_timer.setSingleShot(False) self._update_timer.timeout.connect(self._update) self._manager = QNetworkAccessManager() self._manager.finished.connect(self._onRequestFinished) self._preheat_timer = QTimer() self._preheat_timer.setSingleShot(True) self._preheat_timer.timeout.connect(self.cancelPreheatBed) self._exception_message = None self._output_controller = GenericOutputController(self) self._number_of_extruders = 1 self._camera_url = "" # Application.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged) CuraApplication.getInstance().getCuraSceneController( ).activeBuildPlateChanged.connect(self.CreateMKSController) def _onOutputDevicesChanged(self): Logger.log("d", "MKS _onOutputDevicesChanged") def connect(self): if self._socket is not None: self._socket.close() self._socket = QTcpSocket() self._socket.connectToHost(self._address, self._port) global_container_stack = CuraApplication.getInstance( ).getGlobalContainerStack() self.setShortDescription( i18n_catalog.i18nc( "@action:button", "Print over " + global_container_stack.getName())) self.setDescription( i18n_catalog.i18nc( "@properties:tooltip", "Print over " + global_container_stack.getName())) Logger.log("d", "MKS socket connecting ") # self._socket.waitForConnected(2000) self.setConnectionState( cast(ConnectionState, UnifiedConnectionState.Connecting)) self._setAcceptsCommands(True) self._socket.readyRead.connect(self.on_read) self._update_timer.start() def getProperties(self): return self._properties @pyqtSlot(str, result=str) def getProperty(self, key): key = key.encode("utf-8") if key in self._properties: return self._properties.get(key, b"").decode("utf-8") else: return "" @pyqtSlot(result=str) def getKey(self): return self._key @pyqtProperty(str, constant=True) def address(self): return self._properties.get(b"address", b"").decode("utf-8") @pyqtProperty(str, constant=True) def name(self): return self._properties.get(b"name", b"").decode("utf-8") @pyqtProperty(str, constant=True) def firmwareVersion(self): return self._properties.get(b"firmware_version", b"").decode("utf-8") @pyqtProperty(str, constant=True) def ipAddress(self): return self._address @pyqtSlot(float, float) def preheatBed(self, temperature, duration): self._setTargetBedTemperature(temperature) if duration > 0: self._preheat_timer.setInterval(duration * 1000) self._preheat_timer.start() else: self._preheat_timer.stop() @pyqtSlot() def cancelPreheatBed(self): self._setTargetBedTemperature(0) self._preheat_timer.stop() @pyqtSlot() def printtest(self): self.sendCommand("M104 S0\r\n M140 S0\r\n M106 S255") @pyqtSlot() def printer_state(self): if len(self._printers) <= 0: return "offline" return self.printers[0].state @pyqtSlot() def selectfile(self): if self._last_file_name: return True else: return False @pyqtSlot(str) def deleteSDFiles(self, filename): # filename = "几何图.gcode" self._sendCommand("M30 1:/" + filename) self.sdFiles.remove(filename) self._sendCommand("M20") @pyqtSlot(str) def printSDFiles(self, filename): self._sendCommand("M23 " + filename) self._sendCommand("M24") @pyqtSlot() def selectFileToUplload(self): preferences = Application.getInstance().getPreferences() preferences.addPreference("mkswifi/autoprint", "True") preferences.addPreference("mkswifi/savepath", "") filename, _ = QFileDialog.getOpenFileName( None, "choose file", preferences.getValue("mkswifi/savepath"), "Gcode(*.gcode;*.g;*.goc)") preferences.setValue("mkswifi/savepath", filename) self._uploadpath = filename if ".g" in filename.lower(): # Logger.log("d", "selectfile:"+filename) if filename in self.sdFiles: if self._mdialog: self._mdialog.close() self._mdialog = QDialog() self._mdialog.setWindowTitle("The " + filename[filename.rfind("/") + 1:] + " file already exists.") dialogvbox = QVBoxLayout() dialoghbox = QHBoxLayout() yesbtn = QPushButton("yes") nobtn = QPushButton("no") yesbtn.clicked.connect(lambda: self.renameupload(filename)) nobtn.clicked.connect(self.closeMDialog) content = QLabel( "The " + filename[filename.rfind("/") + 1:] + " file already exists. Do you want to rename and upload it?" ) self._mfilename = QLineEdit() self._mfilename.setText(filename[filename.rfind("/") + 1:]) dialoghbox.addWidget(yesbtn) dialoghbox.addWidget(nobtn) dialogvbox.addWidget(content) dialogvbox.addWidget(self._mfilename) dialogvbox.addLayout(dialoghbox) self._mdialog.setLayout(dialogvbox) self._mdialog.exec_() return if len(filename[filename.rfind("/") + 1:]) >= 30: if self._mdialog: self._mdialog.close() self._mdialog = QDialog() self._mdialog.setWindowTitle( "File name is too long to upload, please rename it.") dialogvbox = QVBoxLayout() dialoghbox = QHBoxLayout() yesbtn = QPushButton("yes") nobtn = QPushButton("no") yesbtn.clicked.connect(lambda: self.renameupload(filename)) nobtn.clicked.connect(self.closeMDialog) content = QLabel( "File name is too long to upload, please rename it.") self._mfilename = QLineEdit() self._mfilename.setText(filename[filename.rfind("/") + 1:]) dialoghbox.addWidget(yesbtn) dialoghbox.addWidget(nobtn) dialogvbox.addWidget(content) dialogvbox.addWidget(self._mfilename) dialogvbox.addLayout(dialoghbox) self._mdialog.setLayout(dialogvbox) self._mdialog.exec_() return if self.isBusy(): if self._exception_message: self._exception_message.hide() self._exception_message = Message( i18n_catalog.i18nc( "@info:status", "File cannot be transferred during printing.")) self._exception_message.show() return self.uploadfunc(filename) def closeMDialog(self): if self._mdialog: self._mdialog.close() def renameupload(self, filename): if self._mfilename and ".g" in self._mfilename.text().lower(): filename = filename[:filename. rfind("/")] + "/" + self._mfilename.text() if self._mfilename.text() in self.sdFiles: if self._mdialog: self._mdialog.close() self._mdialog = QDialog() self._mdialog.setWindowTitle("The " + filename[filename.rfind("/") + 1:] + " file already exists.") dialogvbox = QVBoxLayout() dialoghbox = QHBoxLayout() yesbtn = QPushButton("yes") nobtn = QPushButton("no") yesbtn.clicked.connect(lambda: self.renameupload(filename)) nobtn.clicked.connect(self.closeMDialog) content = QLabel( "The " + filename[filename.rfind("/") + 1:] + " file already exists. Do you want to rename and upload it?" ) self._mfilename = QLineEdit() self._mfilename.setText(filename[filename.rfind("/") + 1:]) dialoghbox.addWidget(yesbtn) dialoghbox.addWidget(nobtn) dialogvbox.addWidget(content) dialogvbox.addWidget(self._mfilename) dialogvbox.addLayout(dialoghbox) self._mdialog.setLayout(dialogvbox) self._mdialog.exec_() return if len(filename[filename.rfind("/") + 1:]) >= 30: if self._mdialog: self._mdialog.close() self._mdialog = QDialog() self._mdialog.setWindowTitle( "File name is too long to upload, please rename it.") dialogvbox = QVBoxLayout() dialoghbox = QHBoxLayout() yesbtn = QPushButton("yes") nobtn = QPushButton("no") yesbtn.clicked.connect(lambda: self.renameupload(filename)) nobtn.clicked.connect(self.closeMDialog) content = QLabel( "File name is too long to upload, please rename it.") self._mfilename = QLineEdit() self._mfilename.setText(filename[filename.rfind("/") + 1:]) dialoghbox.addWidget(yesbtn) dialoghbox.addWidget(nobtn) dialogvbox.addWidget(content) dialogvbox.addWidget(self._mfilename) dialogvbox.addLayout(dialoghbox) self._mdialog.setLayout(dialogvbox) self._mdialog.exec_() return if self.isBusy(): if self._exception_message: self._exception_message.hide() self._exception_message = Message( i18n_catalog.i18nc( "@info:status", "File cannot be transferred during printing.")) self._exception_message.show() return self._mdialog.close() self.uploadfunc(filename) def uploadfunc(self, filename): preferences = Application.getInstance().getPreferences() preferences.addPreference("mkswifi/autoprint", "True") preferences.addPreference("mkswifi/savepath", "") self._update_timer.stop() self._isSending = True self._preheat_timer.stop() single_string_file_data = "" try: f = open(self._uploadpath, "r") single_string_file_data = f.read() file_name = filename[filename.rfind("/") + 1:] self._last_file_name = file_name self._progress_message = Message( i18n_catalog.i18nc("@info:status", "Sending data to printer"), 0, False, -1, i18n_catalog.i18nc("@info:title", "Sending Data"), option_text=i18n_catalog.i18nc("@label", "Print jobs"), option_state=preferences.getValue("mkswifi/autoprint")) self._progress_message.addAction( "Cancel", i18n_catalog.i18nc("@action:button", "Cancel"), None, "") self._progress_message.actionTriggered.connect( self._cancelSendGcode) self._progress_message.optionToggled.connect( self._onOptionStateChanged) self._progress_message.show() self._post_multi_part = QHttpMultiPart(QHttpMultiPart.FormDataType) self._post_part = QHttpPart() self._post_part.setHeader( QNetworkRequest.ContentDispositionHeader, "form-data; name=\"file\"; filename=\"%s\"" % file_name) self._post_part.setBody(single_string_file_data.encode()) self._post_multi_part.append(self._post_part) post_request = QNetworkRequest( QUrl("http://%s/upload?X-Filename=%s" % (self._address, file_name))) post_request.setRawHeader(b'Content-Type', b'application/octet-stream') post_request.setRawHeader(b'Connection', b'keep-alive') self._post_reply = self._manager.post(post_request, self._post_multi_part) self._post_reply.uploadProgress.connect(self._onUploadProgress) self._post_reply.sslErrors.connect(self._onUploadError) self._gcode = None except IOError as e: Logger.log( "e", "An exception occurred in network connection: %s" % str(e)) self._progress_message.hide() self._error_message = Message( i18n_catalog.i18nc("@info:status", "Send file to printer failed.")) self._error_message.show() self._update_timer.start() except Exception as e: self._update_timer.start() self._progress_message.hide() Logger.log( "e", "An exception occurred in network connection: %s" % str(e)) @pyqtProperty("QVariantList") def getSDFiles(self): self._sendCommand("M20") return list(self.sdFiles) def _setTargetBedTemperature(self, temperature): if not self._updateTargetBedTemperature(temperature): return self._sendCommand(["M140 S%s" % temperature]) @pyqtSlot(str) def sendCommand(self, cmd): self._sendCommand(cmd) def _sendCommand(self, cmd): # Logger.log("d", "_sendCommand %s" % str(cmd)) if self._socket and self._socket.state() == 2 or self._socket.state( ) == 3: if isinstance(cmd, str): self._command_queue.put(cmd + "\r\n") elif isinstance(cmd, list): for eachCommand in cmd: self._command_queue.put(eachCommand + "\r\n") def disconnect(self): # self._updateJobState("") self._isConnect = False self.setConnectionState( cast(ConnectionState, UnifiedConnectionState.Closed)) if self._socket is not None: self._socket.readyRead.disconnect(self.on_read) self._socket.close() if self._progress_message: self._progress_message.hide() if self._error_message: self._error_message.hide() self._update_timer.stop() def isConnected(self): return self._isConnect def isBusy(self): return self._isPrinting or self._isPause def requestWrite(self, node, file_name=None, filter_by_machine=False, file_handler=None, **kwargs): self.writeStarted.emit(self) self._update_timer.stop() self._isSending = True # imagebuff = self._gl.glReadPixels(0, 0, 800, 800, self._gl.GL_RGB, # self._gl.GL_UNSIGNED_BYTE) active_build_plate = CuraApplication.getInstance( ).getMultiBuildPlateModel().activeBuildPlate scene = CuraApplication.getInstance().getController().getScene() gcode_dict = getattr(scene, "gcode_dict", None) if not gcode_dict: return self._gcode = gcode_dict.get(active_build_plate, None) # Logger.log("d", "mks ready for print") self.startPrint() def startPrint(self): global_container_stack = CuraApplication.getInstance( ).getGlobalContainerStack() if not global_container_stack: return if self._error_message: self._error_message.hide() self._error_message = None if self._progress_message: self._progress_message.hide() self._progress_message = None if self.isBusy(): self._error_message = Message( i18n_catalog.i18nc("@info:status", "Sending data to printer"), 0, False, -1, i18n_catalog.i18nc("@info:title", "Sending Data")) self._error_message.show() return job_name = Application.getInstance().getPrintInformation( ).jobName.strip() if job_name is "": job_name = "untitled_print" job_name = "cura_file" filename = "%s.gcode" % job_name if filename in self.sdFiles: if self._mdialog: self._mdialog.close() self._mdialog = QDialog() self._mdialog.setWindowTitle("The " + filename[filename.rfind("/") + 1:] + " file already exists.") dialogvbox = QVBoxLayout() dialoghbox = QHBoxLayout() yesbtn = QPushButton("yes") nobtn = QPushButton("no") yesbtn.clicked.connect(self.recheckfilename) nobtn.clicked.connect(self.closeMDialog) content = QLabel( "The " + filename[filename.rfind("/") + 1:] + " file already exists. Do you want to rename and upload it?") self._mfilename = QLineEdit() self._mfilename.setText(filename[filename.rfind("/") + 1:]) dialoghbox.addWidget(yesbtn) dialoghbox.addWidget(nobtn) dialogvbox.addWidget(content) dialogvbox.addWidget(self._mfilename) dialogvbox.addLayout(dialoghbox) self._mdialog.setLayout(dialogvbox) self._mdialog.exec_() return if len(filename[filename.rfind("/") + 1:]) >= 30: if self._mdialog: self._mdialog.close() self._mdialog = QDialog() self._mdialog.setWindowTitle( "File name is too long to upload, please rename it.") dialogvbox = QVBoxLayout() dialoghbox = QHBoxLayout() yesbtn = QPushButton("yes") nobtn = QPushButton("no") yesbtn.clicked.connect(self.recheckfilename) nobtn.clicked.connect(self.closeMDialog) content = QLabel( "File name is too long to upload, please rename it.") self._mfilename = QLineEdit() self._mfilename.setText(filename[filename.rfind("/") + 1:]) dialoghbox.addWidget(yesbtn) dialoghbox.addWidget(nobtn) dialogvbox.addWidget(content) dialogvbox.addWidget(self._mfilename) dialogvbox.addLayout(dialoghbox) self._mdialog.setLayout(dialogvbox) self._mdialog.exec_() return self._startPrint(filename) def recheckfilename(self): if self._mfilename and ".g" in self._mfilename.text().lower(): filename = self._mfilename.text() if filename in self.sdFiles: if self._mdialog: self._mdialog.close() self._mdialog = QDialog() self._mdialog.setWindowTitle("The " + filename[filename.rfind("/") + 1:] + " file already exists.") dialogvbox = QVBoxLayout() dialoghbox = QHBoxLayout() yesbtn = QPushButton("yes") nobtn = QPushButton("no") yesbtn.clicked.connect(self.recheckfilename) nobtn.clicked.connect(self.closeMDialog) content = QLabel( "The " + filename[filename.rfind("/") + 1:] + " file already exists. Do you want to rename and upload it?" ) self._mfilename = QLineEdit() self._mfilename.setText(filename[filename.rfind("/") + 1:]) dialoghbox.addWidget(yesbtn) dialoghbox.addWidget(nobtn) dialogvbox.addWidget(content) dialogvbox.addWidget(self._mfilename) dialogvbox.addLayout(dialoghbox) self._mdialog.setLayout(dialogvbox) self._mdialog.exec_() return if len(filename[filename.rfind("/") + 1:]) >= 30: if self._mdialog: self._mdialog.close() self._mdialog = QDialog() self._mdialog.setWindowTitle( "File name is too long to upload, please rename it.") dialogvbox = QVBoxLayout() dialoghbox = QHBoxLayout() yesbtn = QPushButton("yes") nobtn = QPushButton("no") yesbtn.clicked.connect(self.recheckfilename) nobtn.clicked.connect(self.closeMDialog) content = QLabel( "File name is too long to upload, please rename it.") self._mfilename = QLineEdit() self._mfilename.setText(filename[filename.rfind("/") + 1:]) dialoghbox.addWidget(yesbtn) dialoghbox.addWidget(nobtn) dialogvbox.addWidget(content) dialogvbox.addWidget(self._mfilename) dialogvbox.addLayout(dialoghbox) self._mdialog.setLayout(dialogvbox) self._mdialog.exec_() return if self.isBusy(): if self._exception_message: self._exception_message.hide() self._exception_message = Message( i18n_catalog.i18nc( "@info:status", "File cannot be transferred during printing.")) self._exception_message.show() return self._mdialog.close() self._startPrint(filename) def _messageBoxCallback(self, button): def delayedCallback(): if button == QMessageBox.Yes: self.startPrint() else: CuraApplication.getInstance().getController().setActiveStage( "PrepareStage") def _startPrint(self, file_name="cura_file.gcode"): self._preheat_timer.stop() self._screenShot = utils.take_screenshot() try: preferences = Application.getInstance().getPreferences() preferences.addPreference("mkswifi/autoprint", "True") preferences.addPreference("mkswifi/savepath", "") # CuraApplication.getInstance().showPrintMonitor.emit(True) self._progress_message = Message( i18n_catalog.i18nc("@info:status", "Sending data to printer"), 0, False, -1, i18n_catalog.i18nc("@info:title", "Sending Data"), option_text=i18n_catalog.i18nc("@label", "Print jobs"), option_state=preferences.getValue("mkswifi/autoprint")) self._progress_message.addAction( "Cancel", i18n_catalog.i18nc("@action:button", "Cancel"), None, "") self._progress_message.actionTriggered.connect( self._cancelSendGcode) self._progress_message.optionToggled.connect( self._onOptionStateChanged) self._progress_message.show() # job_name = Application.getInstance().getPrintInformation().jobName.strip() # if job_name is "": # job_name = "untitled_print" # job_name = "cura_file" # file_name = "%s.gcode" % job_name self._last_file_name = file_name Logger.log( "d", "mks: " + file_name + Application.getInstance(). getPrintInformation().jobName.strip()) single_string_file_data = "" if self._screenShot: single_string_file_data += utils.add_screenshot( self._screenShot, 50, 50, ";simage:") single_string_file_data += utils.add_screenshot( self._screenShot, 200, 200, ";;gimage:") single_string_file_data += "\r" last_process_events = time.time() for line in self._gcode: single_string_file_data += line if time.time() > last_process_events + 0.05: QCoreApplication.processEvents() last_process_events = time.time() self._post_multi_part = QHttpMultiPart(QHttpMultiPart.FormDataType) self._post_part = QHttpPart() # self._post_part.setHeader(QNetworkRequest.ContentTypeHeader, b'application/octet-stream') self._post_part.setHeader( QNetworkRequest.ContentDispositionHeader, "form-data; name=\"file\"; filename=\"%s\"" % file_name) self._post_part.setBody(single_string_file_data.encode()) self._post_multi_part.append(self._post_part) post_request = QNetworkRequest( QUrl("http://%s/upload?X-Filename=%s" % (self._address, file_name))) post_request.setRawHeader(b'Content-Type', b'application/octet-stream') post_request.setRawHeader(b'Connection', b'keep-alive') self._post_reply = self._manager.post(post_request, self._post_multi_part) self._post_reply.uploadProgress.connect(self._onUploadProgress) self._post_reply.sslErrors.connect(self._onUploadError) # Logger.log("d", "http://%s:80/upload?X-Filename=%s" % (self._address, file_name)) self._gcode = None except IOError as e: Logger.log( "e", "An exception occurred in network connection: %s" % str(e)) self._progress_message.hide() self._error_message = Message( i18n_catalog.i18nc("@info:status", "Send file to printer failed.")) self._error_message.show() self._update_timer.start() except Exception as e: self._update_timer.start() self._progress_message.hide() Logger.log( "e", "An exception occurred in network connection: %s" % str(e)) def _printFile(self): self._sendCommand("M23 " + self._last_file_name) self._sendCommand("M24") def _onUploadProgress(self, bytes_sent, bytes_total): if bytes_total > 0: new_progress = bytes_sent / bytes_total * 100 # Treat upload progress as response. Uploading can take more than 10 seconds, so if we don't, we can get # timeout responses if this happens. self._last_response_time = time.time() if new_progress > self._progress_message.getProgress(): self._progress_message.show( ) # Ensure that the message is visible. self._progress_message.setProgress(bytes_sent / bytes_total * 100) else: self._progress_message.setProgress(0) self._progress_message.hide() def _onUploadError(self, reply, sslerror): Logger.log("d", "Upload Error") def _setHeadPosition(self, x, y, z, speed): self._sendCommand("G0 X%s Y%s Z%s F%s" % (x, y, z, speed)) def _setHeadX(self, x, speed): self._sendCommand("G0 X%s F%s" % (x, speed)) def _setHeadY(self, y, speed): self._sendCommand("G0 Y%s F%s" % (y, speed)) def _setHeadZ(self, z, speed): self._sendCommand("G0 Z%s F%s" % (z, speed)) def _homeHead(self): self._sendCommand("G28 X Y") def _homeBed(self): self._sendCommand("G28 Z") def _moveHead(self, x, y, z, speed): self._sendCommand( ["G91", "G0 X%s Y%s Z%s F%s" % (x, y, z, speed), "G90"]) def _update(self): if self._socket is not None and (self._socket.state() == 2 or self._socket.state() == 3): _send_data = "M105\r\nM997\r\n" if self.isBusy(): _send_data += "M994\r\nM992\r\nM27\r\n" while self._command_queue.qsize() > 0: _queue_data = self._command_queue.get() if "M23" in _queue_data: self._socket.writeData(_queue_data.encode()) continue if "M24" in _queue_data: self._socket.writeData(_queue_data.encode()) continue _send_data += _queue_data # Logger.log("d", "_send_data: \r\n%s" % _send_data) self._socket.writeData(_send_data.encode()) self._socket.flush() # self._socket.waitForReadyRead() else: Logger.log("d", "MKS wifi reconnecting") self.disconnect() self.connect() def _setJobState(self, job_state): if job_state == "abort": command = "M26" elif job_state == "print": if self._isPause: command = "M25" else: command = "M24" elif job_state == "pause": command = "M25" if command: self._sendCommand(command) @pyqtSlot() def cancelPrint(self): self._sendCommand("M26") @pyqtSlot() def pausePrint(self): if self.printers[0].state == "paused": self._sendCommand("M24") else: self._sendCommand("M25") @pyqtSlot() def resumePrint(self): self._sendCommand("M25") def on_read(self): if not self._socket: self.disconnect() return try: if not self._isConnect: self._isConnect = True if self._connection_state != UnifiedConnectionState.Connected: self._sendCommand("M20") self.setConnectionState( cast(ConnectionState, UnifiedConnectionState.Connected)) self.setConnectionText( i18n_catalog.i18nc("@info:status", "TFT Connect succeed")) # ss = str(self._socket.readLine().data(), encoding=sys.getfilesystemencoding()) # while self._socket.canReadLine(): # ss = str(self._socket.readLine().data(), encoding=sys.getfilesystemencoding()) # ss_list = ss.split("\r\n") if not self._printers: self._createPrinterList() printer = self.printers[0] while self._socket.canReadLine(): s = str(self._socket.readLine().data(), encoding=sys.getfilesystemencoding()) # Logger.log("d", "mks recv: "+s) s = s.replace("\r", "").replace("\n", "") # if time.time() - self.last_update_time > 10 or time.time() - self.last_update_time<-10: # Logger.log("d", "mks time:"+str(self.last_update_time)+str(time.time())) # self._sendCommand("M20") # self.last_update_time = time.time() if "T" in s and "B" in s and "T0" in s: t0_temp = s[s.find("T0:") + len("T0:"):s.find("T1:")] t1_temp = s[s.find("T1:") + len("T1:"):s.find("@:")] bed_temp = s[s.find("B:") + len("B:"):s.find("T0:")] t0_nowtemp = float(t0_temp[0:t0_temp.find("/")]) t0_targettemp = float(t0_temp[t0_temp.find("/") + 1:len(t0_temp)]) t1_nowtemp = float(t1_temp[0:t1_temp.find("/")]) t1_targettemp = float(t1_temp[t1_temp.find("/") + 1:len(t1_temp)]) bed_nowtemp = float(bed_temp[0:bed_temp.find("/")]) bed_targettemp = float(bed_temp[bed_temp.find("/") + 1:len(bed_temp)]) # cura 3.4 new api printer.updateBedTemperature(bed_nowtemp) printer.updateTargetBedTemperature(bed_targettemp) extruder = printer.extruders[0] extruder.updateTargetHotendTemperature(t0_targettemp) extruder.updateHotendTemperature(t0_nowtemp) # self._number_of_extruders = 1 # extruder = printer.extruders[1] # extruder.updateHotendTemperature(t1_nowtemp) # extruder.updateTargetHotendTemperature(t1_targettemp) # only on lower 3.4 # self._setBedTemperature(bed_nowtemp) # self._updateTargetBedTemperature(bed_targettemp) # if self._num_extruders > 1: # self._setHotendTemperature(1, t1_nowtemp) # self._updateTargetHotendTemperature(1, t1_targettemp) # self._setHotendTemperature(0, t0_nowtemp) # self._updateTargetHotendTemperature(0, t0_targettemp) continue if printer.activePrintJob is None: print_job = PrintJobOutputModel( output_controller=self._output_controller) printer.updateActivePrintJob(print_job) else: print_job = printer.activePrintJob if s.startswith("M997"): job_state = "offline" if "IDLE" in s: self._isPrinting = False self._isPause = False job_state = 'idle' elif "PRINTING" in s: self._isPrinting = True self._isPause = False job_state = 'printing' elif "PAUSE" in s: self._isPrinting = False self._isPause = True job_state = 'paused' print_job.updateState(job_state) printer.updateState(job_state) # self._updateJobState(job_state) continue # print_job.updateState('idle') # printer.updateState('idle') if s.startswith("M994"): if self.isBusy() and s.rfind("/") != -1: self._printing_filename = s[s.rfind("/") + 1:s.rfind(";")] else: self._printing_filename = "" print_job.updateName(self._printing_filename) # self.setJobName(self._printing_filename) continue if s.startswith("M992"): if self.isBusy(): tm = s[s.find("M992") + len("M992"):len(s)].replace( " ", "") mms = tm.split(":") self._printing_time = int(mms[0]) * 3600 + int( mms[1]) * 60 + int(mms[2]) else: self._printing_time = 0 # Logger.log("d", self._printing_time) print_job.updateTimeElapsed(self._printing_time) # self.setTimeElapsed(self._printing_time) # print_job.updateTimeTotal(self._printing_time) # self.setTimeTotal(self._printing_time) continue if s.startswith("M27"): if self.isBusy(): self._printing_progress = float( s[s.find("M27") + len("M27"):len(s)].replace( " ", "")) totaltime = self._printing_time / self._printing_progress * 100 else: self._printing_progress = 0 totaltime = self._printing_time * 100 # Logger.log("d", self._printing_time) # Logger.log("d", totaltime) # self.setProgress(self._printing_progress) print_job.updateTimeTotal(self._printing_time) print_job.updateTimeElapsed(self._printing_time * 2 - totaltime) continue if 'Begin file list' in s: self._sdFileList = True self.sdFiles = [] self.last_update_time = time.time() continue if 'End file list' in s: self._sdFileList = False continue if self._sdFileList: s = s.replace("\n", "").replace("\r", "") if s.lower().endswith("gcode") or s.lower().endswith( "gco") or s.lower.endswith("g"): self.sdFiles.append(s) continue except Exception as e: print(e) def _updateTargetBedTemperature(self, temperature): if self._target_bed_temperature == temperature: return False self._target_bed_temperature = temperature self.targetBedTemperatureChanged.emit() return True def _updateTargetHotendTemperature(self, index, temperature): if self._target_hotend_temperatures[index] == temperature: return False self._target_hotend_temperatures[index] = temperature self.targetHotendTemperaturesChanged.emit() return True def _createPrinterList(self): printer = PrinterOutputModel( output_controller=self._output_controller, number_of_extruders=self._number_of_extruders) printer.updateName(self.name) self._printers = [printer] self.printersChanged.emit() def _onRequestFinished(self, reply): http_status_code = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) self._isSending = True self._update_timer.start() self._sendCommand("M20") preferences = Application.getInstance().getPreferences() preferences.addPreference("mkswifi/autoprint", "True") # preferences.addPreference("mkswifi/savepath", "") # preferences.setValue("mkswifi/autoprint", str(self._progress_message.getOptionState())) if preferences.getValue("mkswifi/autoprint"): self._printFile() if not http_status_code: return def _onOptionStateChanged(self, optstate): preferences = Application.getInstance().getPreferences() preferences.setValue("mkswifi/autoprint", str(optstate)) def _cancelSendGcode(self, message_id, action_id): self._update_timer.start() self._isSending = False self._progress_message.hide() self._post_reply.abort() def CreateMKSController(self): Logger.log("d", "Creating additional ui components for mkscontroller.") # self.__additional_components_view = CuraApplication.getInstance().createQmlComponent(self._monitor_view_qml_path, {"mkscontroller": self}) self.__additional_components_view = Application.getInstance( ).createQmlComponent(self._monitor_view_qml_path, {"manager": self}) # trlist = CuraApplication.getInstance()._additional_components # for comp in trlist: Logger.log("w", "create mkscontroller ") if not self.__additional_components_view: Logger.log("w", "Could not create ui components for tft35.") return def _onGlobalContainerChanged(self) -> None: self._global_container_stack = Application.getInstance( ).getGlobalContainerStack() definitions = self._global_container_stack.definition.findDefinitions( key="cooling") Logger.log("d", definitions[0].label)
class SmartHubComm(QObject): new_inouts = pyqtSignal(list, list, list, list, list, list, name = 'new_smhub_inouts') new_fullblock = pyqtSignal(str, name = 'new_smhub_raw') def __init__(self, parent=None): super(SmartHubComm, self).__init__(parent) self.smarthubIP = '198.17.154.164' self.router_dim = 20 self.min_smhub_status_size = 1000 self.msg_total = 0 self.smhub_status_block = "" self.raw_model_string = "" self.this_is_set_smhub_phase = False self.inportl = list(range(self.router_dim)) self.inlabell = ["Unknown"] * self.router_dim self.outportl = list(range(self.router_dim)) self.outlabell = ["Unknown"] * self.router_dim self.routein = list(range(self.router_dim)) self.routeout = list(range(self.router_dim)) self.new_fullblock.connect(self.parse_hub_data) self.new_inouts.connect(self.on_shdata_parsed) self.invoke_query_of_smhub() def invoke_query_of_smhub(self): self.sock = QTcpSocket() self.sock.error.connect(self.on_tcp_error) self.sock.readyRead.connect(self.on_ready_read) try: self.sock.connectToHost(self.smarthubIP, 9990) if not self.sock.waitForConnected(1000): errstr = "Error Communicating with SmartHub" print(errstr) except: print(self.sock.SocketError()) def on_shdata_parsed(self,inportl, inlabell, outportl, outlabell, routein, routeout): self.inportl = inportl self.inlabell = inlabell self.outportl = outportl self.outlabell = outlabell, self.routein = routein self.routeout = routeout def get_smhub_inouts(self): return(self.inportl, self.inlabell, self.outportl, self.outlabell, self.routein, self.routeout) def on_ready_read(self): instream = QTextStream(self.sock) inblock = () bytes_avail = self.sock.bytesAvailable() inblock = instream.readAll() self.smhub_status_block += inblock self.msg_total = self.msg_total + bytes_avail if self.msg_total >= self.min_smhub_status_size: self.sock.close() self.new_fullblock.emit(self.smhub_status_block) def parse_hub_data(self, fullblock): blocklist = () blocklist = fullblock.split('\n') ila = []; ola = []; vra = []; inportl = []; inlabell = [] outportl = []; outlabell = []; routein = []; routeout = [] modre = re.compile('^Model name') ilre = re.compile('^INPUT LABELS:$') olre = re.compile('^OUTPUT LABELS:$') vore = re.compile('^VIDEO OUTPUT ROUTING:$') modind = [i for i, item in enumerate (blocklist) if modre.match(item)][0] self.raw_model_string = str(blocklist[modind]) #print("Smarthub model:",self.raw_model_string) # Find lines starting the input label list, output label list, and routing list ilind = [i for i, item in enumerate (blocklist) if ilre.match(item)][0] olind = [i for i, item in enumerate (blocklist) if olre.match(item)][0] voind = [i for i, item in enumerate (blocklist) if vore.match(item)][0] # Read in the input and output label blocks, and the routing list for i in range((ilind+1), (ilind+(self.router_dim+1))): ila.append(blocklist[i]) for i in range((olind+1), (olind+(self.router_dim+1))): ola.append(blocklist[i]) # The routing list is just two numbers (input port and matched output port). for i in range((voind+1), (voind+(self.router_dim+1))): vra.append(blocklist[i]) # Parse the label lists and populate a data structure to hold the labels for i in range(0, len(ila) ): line = ila[i] #print line try: [port, label] = filter(None, line.split(' ')) except: try: [port, label1, label2] = line.split(' ') label = label1 + " " + label2 except: try: [port, label1, label2, label3] = line.split(' ') label = label1 + " " + label2 + " " + label3 except: [port, label1, label2, label3, label4] = line.split(' ') label = label1 + " " + label2 + " " + label3 + " " + label4 inportl.append(port) inlabell.append(label) for i in range(0, len(ola) ): line = ola[i] #print line try: [port, label] = filter(None, line.split(' ')) except: try: [port, label1, label2] = line.split(' ') label = label1 + " " + label2 except: try: [port, label1, label2, label3] = line.split(' ') label = label1 + " " + label2 + " " + label3 except: [port, label1, label2, label3, label4] = line.split(' ') label = label1 + " " + label2 + " " + label3 + " " + label4 outportl.append(port) outlabell.append(label) for i in range(0, len(vra) ): line = vra[i] try: [outport, inport] = line.split(' ') inport = int(inport) outport = int(outport) except: print("Failed to parse route line %d") % (i) routein.append(inport) routeout.append(outport) #print(routeout) self.new_inouts.emit(inportl, inlabell, outportl, outlabell, routein, routeout) def on_tcp_error(self, connect_error): if connect_error == QAbstractSocket.RemoteHostClosedError: print("ERROR: Remote host closed") elif connect_error == QAbstractSocket.HostNotFoundError: print("ERROR: Host was not found") elif connect_error == QAbstractSocket.ConnectionRefusedError: print("ERROR: The connection was refused by the peer") else: print("The following error occurred: %l" % self.sock.errorString()) def get_smarthub_model(self): return self.raw_model_string
class TcpServer(QWidget, Ui_MainWindow): def __init__(self): super(TcpServer, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.message = '' self.tcpServer = QTcpServer(self) # 指定父对象自动回收空间 监听套接字 self.tcpSocket = QTcpSocket(self) # 通信套接字 self.x1 = 0 self.y1 = 0 self.x2 = 0 self.y2 = 0 self.radio = '' self.R = 0 self.G = 0 self.B = 0 self.tcpServer.listen(QHostAddress.Any, 8888) # any默认绑定当前网卡的所有IP self.ui.showText.append( '服务器初始化成功,等待客户端链接... %s' % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))) self.tcpServer.newConnection.connect(self.handleNewConnection) # self.ui.sendButton.clicked.connect(self.sendMessage) self.ui.closeButton.clicked.connect(self.closeConnect) def paintEvent(self, e): qp = QPainter() qp.begin(self) qp.setBrush(QColor(int(self.R), int(self.G), int(self.B))) if self.radio == '矩形': qp.drawRect(430 + int(self.x1), 110 + int(self.y1), 0 + int(self.x2), 0 + int(self.y2)) elif self.radio == '圆形': qp.drawEllipse(430 + int(self.x1), 110 + int(self.y1), 0 + int(self.x2), 0 + int(self.y2)) else: qp.drawRect(430 + int(self.x1), 110 + int(self.y1), 0 + int(self.x2), 0 + int(self.y2)) qp.end() def handleNewConnection(self): self.tcpSocket = self.tcpServer.nextPendingConnection() # 取出建立好链接的套接字 # 获取对方IP和端口 ip = str(self.tcpSocket.peerAddress()) # 获取对方的IP地址 port = self.tcpSocket.peerPort() # 获取对方的端口号 print(ip, port, '成功') self.ui.showText.append( '客户端请求链接成功 %s' % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))) #self.ui.showText.append("[{IP}:{Port}]".format(IP=ip, Port=port)) self.tcpSocket.readyRead.connect(self.showMessage) def sendMessage(self): message = self.ui.sendEdit.toPlainText() # 获取编辑区内容 self.request = QByteArray( ) # 由于write函数的参数是QByteArray, bytes, bytearray所以在这里通过QByteArray来传递参数 stream = QDataStream( self.request, QIODevice.WriteOnly) # 创建数据流,和QByteArray关联,并且以只写的方式 stream.setVersion(QDataStream.Qt_5_10) # 设置数据流所对应的PyQt5版本 stream.writeQString(message) # 向数据流中写入数据,亦即向request中写入数据 self.tcpSocket.write(self.request) self.ui.sendEdit.clear() # 每次数据发送后,将当前的输入text区域清空 def showMessage(self): stream = QDataStream( self.tcpSocket) # 发送数据是以QByteArray数据类型发送过来的,所以接收数据也应该以此接收 stream.setVersion(QDataStream.Qt_5_10) # 发送和接收数据以相同的编码形式传输 self.message = stream.readQString( ) # 写入使用writeString, 对应读取使用readQString self.ui.showText.append( '%s %s' % (self.message, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))) message_list = self.message.split(',') self.radio = message_list[3][3:] self.x1 = message_list[4][3:] self.y1 = message_list[5][3:] self.x2 = message_list[6][3:] self.y2 = message_list[7][3:] self.R = message_list[-3][3:] self.G = message_list[-2][3:] self.B = message_list[-1][3:] print(message_list) def closeConnect(self): self.tcpSocket.disconnectFromHost() self.tcpSocket.close()
class MyWidget(QWidget, Ui_MyWidget): server_chinese_encoding = 'gbk' def __init__(self): super().__init__() super(Ui_MyWidget).__init__() self.remote_ip_addr = '127.0.0.1' self.remote_port = 9999 self.sock = QTcpSocket(self) self.isConnectedToServer = False self.textEdit = None self.lineEdit = None self.pushButton = None self.vBox = None self.setupUi(self) self.setupQtSignalConnections() def setupQtSignalConnections(self): self.pushButton.clicked.connect(self.push_button_event) self.sock.connected.connect(self.on_socket_connected) self.sock.disconnected.connect(self.on_socket_disconnected) self.sock.readyRead.connect(self.on_socket_receive) self.sock.bytesWritten.connect(self.on_socket_transmit) def add_message(self, message): self.textEdit.moveCursor(QTextCursor.End) self.textEdit.insertPlainText(message) def connect(self, remote_ip_addr: str = '127.0.0.1', remote_port: int = 9999) -> None: if self.isConnectedToServer: return self.remote_ip_addr = remote_ip_addr self.remote_port = remote_port self.sock.connectToHost(remote_ip_addr, remote_port) if not self.sock.waitForConnected(2500): msg = self.sock.errorString() raise ConnectionError(msg) def push_button_event(self): if not self.isConnectedToServer: # Error return txString = self.lineEdit.text() if len(txString) <= 0: msgBoxTitle = 'Warning' warning = 'You must enter a message!' QMessageBox.critical(self, msgBoxTitle, warning) self.add_message('{}\n'.format(warning)) return self.sock.write(txString.encode(self.server_chinese_encoding)) self.add_message('Wrote "{}"'.format(txString)) def on_socket_connected(self): self.isConnectedToServer = True self.lineEdit.setEnabled(True) self.pushButton.setEnabled(True) self.add_message('Connected to {} on port {}\n'.format( self.remote_ip_addr, self.remote_port)) def on_socket_disconnected(self): self.isConnectedToServer = False self.lineEdit.setEnabled(False) self.pushButton.setEnabled(False) self.add_message('Disconnected from server\n') def on_socket_receive(self): rxData = self.sock.readAll() unicodeMsg = rxData.data().decode(self.server_chinese_encoding) self.add_message('Received "{}"\n'.format(unicodeMsg)) def on_socket_transmit(self, numBytes): self.add_message(" ({} bytes)\n".format(numBytes)) # noinspection PyBroadException def disconnect(self): if not self.isConnectedToServer: return self.isConnectedToServer = False self.sock.close() self.lineEdit.setEnabled(False) self.pushButton.setEnabled(False)
class Window(QtWidgets.QWidget): def __init__(self): super(Window, self).__init__() # Worker button self.worker_button = QtWidgets.QPushButton('Worker', self) self.worker_button.clicked.connect(self.worker_handleButton) # AuthWorker button self.circu_button = QtWidgets.QPushButton('AuthWorker', self) self.circu_button.clicked.connect(self.circu_handleButton) # generate self.gen_button = QtWidgets.QPushButton('Generate', self) self.gen_button.clicked.connect(self.gen_handleButton) self.edit = QtWidgets.QLineEdit(self) self.edit.setReadOnly(True) layout = QtWidgets.QVBoxLayout(self) layout.addWidget(self.edit) layout.addWidget(self.worker_button) layout.addWidget(self.circu_button) layout.addWidget(self.gen_button) self.queue = Queue() self.data = np.zeros(3) # create thread self.thread = QtCore.QThread() self.gen_thread = QtCore.QThread() self.circu_thread = QtCore.QThread() # bind # ----------------- # target worker: Worker self.worker = Worker(self.queue) self.worker.moveToThread(self.thread) # target worker: Worker (generate) self.gen_worker = gen_Worker(self.queue) self.gen_worker.moveToThread(self.gen_thread) # target worker: circulation of workers self.circu_worker = intermedia(self.queue) self.circu_worker.moveToThread(self.circu_thread) # ----------------- # callback function self.worker.finished.connect(self.handleFinished) self.gen_worker.finished.connect(self.gen_handleFinished) self.circu_worker.finished.connect(self.circu_handleFinished) # QTcp self.tcpSocket = QTcpSocket(self) # self.blockSize = 0 # function 1: worker return # ----------------------------------------------- def handleFinished(self, ): # if SHOW: print("back to main: Worker") self.data = self.queue.get() self.thread.quit() self.thread.disconnect() text = "worker: %s" % self.data self.edit.setText(text) # self.queue.put(self.data) print("main get data: ", self.data, end='') print(", queue buffer: %d" % self.queue.qsize()) def worker_handleButton(self): # Worker if not self.thread.isRunning(): self.edit.clear() self.thread.started.connect(self.worker.run) self.thread.start() # ----------------------------------------------- # function 2: circulation # =============================================== def circu_handleFinished(self): # if SHOW: print("back to main: circulation") self.data = self.queue.get() self.circu_thread.quit() # self.circu_thread.disconnect() text = "circulation: %s" % self.data self.edit.setText(text) print("main get data: ", self.data, end='') print(", queue buffer: %d" % self.queue.qsize()) # send message to server print("Send data: ", self.data, " to server") self.tcpSocket.connectToHost('127.0.0.1', 8000, QIODevice.ReadWrite) self.tcpSocket.waitForConnected(1000) self.tcpSocket.write(self.data.tobytes()) # self.tcpSocket.readyRead.connect(self.dealCommunication) # self.tcpSocket.error.connect(self.displayError) self.tcpSocket.close() # restart # if not self.circu_thread.isRunning(): # self.edit.clear() # self.circu_thread.started.connect(self.circu_worker.circu_run) # self.circu_thread.start() def circu_handleButton(self): # intermedia & AuthWorker if self.queue.empty(): self.queue.put(self.data) if not self.circu_thread.isRunning(): self.edit.clear() self.circu_thread.started.connect(self.circu_worker.circu_run) self.circu_thread.start() # =============================================== # generate new data for function 2, but still affect function 1 # ----------------------------------------------- def gen_handleFinished(self): if SHOW: print("back to main: generation") self.data = self.queue.get() self.gen_thread.quit() self.gen_thread.disconnect() text = "generate: %s" % self.data self.edit.setText(text) self.data = self.queue.put(self.data) print("queue buffer: %d" % self.queue.qsize()) # self.gen_thread.start() def gen_handleButton(self): if not self.gen_thread.isRunning(): self.edit.clear() self.gen_thread.started.connect(self.gen_worker.generate) self.gen_thread.start() # ----------------------------------------------- def dealCommunication(self): instr = QDataStream(self.tcpSocket) instr.setVersion(QDataStream.Qt_5_0) if self.blockSize == 0: if self.tcpSocket.bytesAvailable() < 2: return self.blockSize = instr.readUInt16() if self.tcpSocket.bytesAvailable() < self.blockSize: return # Print response to terminal, we could use it anywhere else we wanted. print(str(instr.readString(), encoding='ascii')) def displayError(self, socketError): if socketError == QAbstractSocket.RemoteHostClosedError: pass else: print( self, "The following error occurred: %s." % self.tcpSocket.errorString())
class MyWidget(QWidget): server_chinese_encoding = 'gbk' def __init__(self): QWidget.__init__(self) self.sock = None self.isConnectedToServer = False self.textEdit = None self.lineEdit = None self.pushButton = None self.vBox = None self._create_widgets() def _create_widgets(self): self.textEdit = QTextEdit() self.textEdit.setReadOnly(True) p = self.textEdit.viewport().palette() p.setColor(self.textEdit.viewport().backgroundRole(), Qt.transparent) self.textEdit.viewport().setPalette(p) self.lineEdit = QLineEdit() self.lineEdit.setPlaceholderText("Enter message") self.lineEdit.setMaxLength(50) self.lineEdit.setEnabled(False) self.pushButton = QPushButton("Send") self.pushButton.setEnabled(False) self.vBox = QVBoxLayout(self) self.vBox.addWidget(self.textEdit) self.vBox.addWidget(self.lineEdit) self.vBox.addWidget(self.pushButton) self.setLayout(self.vBox) self.pushButton.released.connect(self.push_button_event) def add_message(self, message): self.textEdit.moveCursor(QTextCursor.End) self.textEdit.insertPlainText(message) self.textEdit.moveCursor(QTextCursor.End) def connect(self): if self.isConnectedToServer: return True self.sock = QTcpSocket(self) host_ip_addr = '192.168.1.150' port = 8080 self.sock.connectToHost(host_ip_addr, port) if not self.sock.waitForConnected(2500): msg = self.sock.errorString() self.add_message(msg + '\n') QMessageBox.critical(self, "Error", msg) return False self.sock.connected.connect(self.on_socket_connected) self.sock.disconnected.connect(self.on_socket_disconnected) self.sock.readyRead.connect(self.on_socket_receive) self.sock.bytesWritten.connect(self.on_socket_transmit) self.add_message("Connected to {} on port {}\n".format(host_ip_addr, port)) self.isConnectedToServer = True self.lineEdit.setEnabled(True) self.pushButton.setEnabled(True) return True def push_button_event(self): txString = self.lineEdit.text() #self.sock.write('hello my friend') if self.isConnectedToServer and len(txString) > 0: self.sock.write(txString.encode(self.server_chinese_encoding)) self.add_message("Wrote '" + txString + "'") else: self.add_message("You must enter a message\n") QMessageBox.critical(self, "Error", "You must enter a message") def on_socket_connected(self): pass def on_socket_disconnected(self): self.add_message("Disconnected from server\n") self.lineEdit.setEnabled(False) self.pushButton.setEnabled(False) def on_socket_receive(self): rxData = self.sock.readAll() self.add_message("Received '" + rxData.data().decode(self.server_chinese_encoding) + "'\n") def on_socket_transmit(self, numBytes): self.add_message(" (" + str(numBytes) + " bytes)\n") # noinspection PyBroadException def disconnect(self): if not self.isConnectedToServer: return try: self.sock.connected.disconncet() except: pass try: self.sock.disconnected.disconncet() except: pass try: self.sock.readyRead.disconncet() except: pass try: self.sock.bytesWritten.disconncet() except: pass self.sock.close() self.lineEdit.setEnabled(False) self.pushButton.setEnabled(False) self.isConnectedToServer = False
class Voltmeter(QtWidgets.QMainWindow, Ui_MainWindow): VOLTMETER_PORT = 5000 def __init__(self, parent=None): super(Voltmeter, self).__init__(parent) self.setupUi(self) self.needle = QwtDialSimpleNeedle(QwtDialSimpleNeedle.Arrow) self.Dial.setNeedle(self.needle) self.Dial.setValue(1.5) self.lcdNumber.display(1.5) self.actionQuit.triggered.connect(self.quit) self.connect_pb.clicked.connect(self.connect) self.calib = 3.3 / 256 self.client_socket = QTcpSocket(self) self.connected = False def connect(self): if self.connected: self.client_socket.close() self.connect_pb.setChecked(False) self.connect_pb.setText("Connect to Voltmeter") return print("Connecting") server_ip = str(self.ip_address_text.text()) port = self.VOLTMETER_PORT print("Server IP: ", server_ip) if server_ip.find('xxx') != -1: print("bad IP") QMessageBox.about( self, 'Bad Server IP', 'Please give a correct Server IP\n' 'IP is ' + server_ip) self.connect_pb.setChecked(False) return else: print("Connecting to " + server_ip + ":", port) self.client_socket.connectToHost(server_ip, port) self.client_socket.waitForConnected(1000) if self.client_socket.state() != QTcpSocket.ConnectedState: QMessageBox.warning( self, 'Connection failed', 'Please check IP address and port number\nIs the server running?' ) self.connect_pb.setChecked(False) return print("Connection established") self.client_socket.readyRead.connect(self.treatMeas) self.connect_pb.setText("Connected") def treatMeas(self): # get new values and display them msg = self.client_socket.readAll() newValue = int(bytes(msg).decode()) print("new value: ", newValue) response = 'ok\n' self.client_socket.write(bytes(response, encoding="ascii")) newVoltage = int(newValue) * self.calib print(newVoltage) self.lcdNumber.display(newVoltage) self.Dial.setValue(newVoltage) def quit(self): app.exit()
class IrcWidget(QWidget, Ui_IrcWidget): """ Class implementing the IRC window. @signal autoConnected() emitted after an automatic connection was initiated """ autoConnected = pyqtSignal() ServerDisconnected = 1 ServerConnected = 2 ServerConnecting = 3 def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(IrcWidget, self).__init__(parent) self.setupUi(self) from .IrcNetworkManager import IrcNetworkManager self.__ircNetworkManager = IrcNetworkManager(self) self.__leaveButton = QToolButton(self) self.__leaveButton.setIcon( UI.PixmapCache.getIcon("ircCloseChannel.png")) self.__leaveButton.setToolTip( self.tr("Press to leave the current channel")) self.__leaveButton.clicked.connect(self.__leaveChannel) self.__leaveButton.setEnabled(False) self.channelsWidget.setCornerWidget( self.__leaveButton, Qt.BottomRightCorner) self.channelsWidget.setTabsClosable(False) if not isMacPlatform(): self.channelsWidget.setTabPosition(QTabWidget.South) height = self.height() self.splitter.setSizes([height * 0.6, height * 0.4]) self.__channelList = [] self.__channelTypePrefixes = "" self.__userName = "" self.__identityName = "" self.__quitMessage = "" self.__nickIndex = -1 self.__nickName = "" self.__server = None self.__registering = False self.__connectionState = IrcWidget.ServerDisconnected self.__sslErrorLock = False self.__buffer = "" self.__userPrefix = {} self.__socket = None if SSL_AVAILABLE: self.__sslErrorHandler = E5SslErrorHandler(self) else: self.__sslErrorHandler = None self.__patterns = [ # :[email protected] PRIVMSG bar_ :some long message (re.compile(r":([^!]+)!([^ ]+)\sPRIVMSG\s([^ ]+)\s:(.*)"), self.__query), # :foo.bar.net COMMAND some message (re.compile(r""":([^ ]+)\s+([A-Z]+)\s+(.+)"""), self.__handleNamedMessage), # :foo.bar.net 123 * :info (re.compile(r""":([^ ]+)\s+(\d{3})\s+(.+)"""), self.__handleNumericMessage), # PING :ping message (re.compile(r"""PING\s+:(.*)"""), self.__ping), ] self.__prefixRe = re.compile(r""".*\sPREFIX=\((.*)\)([^ ]+).*""") self.__chanTypesRe = re.compile(r""".*\sCHANTYPES=([^ ]+).*""") ircPic = UI.PixmapCache.getPixmap("irc128.png") self.__emptyLabel = QLabel() self.__emptyLabel.setPixmap(ircPic) self.__emptyLabel.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter) self.channelsWidget.addTab(self.__emptyLabel, "") # all initialized, do connections now self.__ircNetworkManager.dataChanged.connect(self.__networkDataChanged) self.networkWidget.initialize(self.__ircNetworkManager) self.networkWidget.connectNetwork.connect(self.__connectNetwork) self.networkWidget.editNetwork.connect(self.__editNetwork) self.networkWidget.joinChannel.connect(self.__joinChannel) self.networkWidget.nickChanged.connect(self.__changeNick) self.networkWidget.sendData.connect(self.__send) self.networkWidget.away.connect(self.__away) self.networkWidget.autoConnected.connect(self.autoConnected) def shutdown(self): """ Public method to shut down the widget. @return flag indicating successful shutdown (boolean) """ if self.__server: if Preferences.getIrc("AskOnShutdown"): ok = E5MessageBox.yesNo( self, self.tr("Disconnect from Server"), self.tr( """<p>Do you really want to disconnect from""" """ <b>{0}</b>?</p><p>All channels will be closed.""" """</p>""").format(self.__server.getName())) else: ok = True if ok: self.__socket.blockSignals(True) self.__send("QUIT :" + self.__quitMessage) self.__socket.flush() self.__socket.close() self.__socket.deleteLater() self.__socket = None else: ok = True if ok: self.__ircNetworkManager.close() return ok def autoConnect(self): """ Public method to initiate the IRC auto connection. """ self.networkWidget.autoConnect() def __connectNetwork(self, name, connect, silent=False): """ Private slot to connect to or disconnect from the given network. @param name name of the network to connect to (string) @param connect flag indicating to connect (boolean) @keyparam silent flag indicating a silent connect/disconnect (boolean) """ if connect: network = self.__ircNetworkManager.getNetwork(name) if network: self.__server = network.getServer() self.__identityName = network.getIdentityName() identity = self.__ircNetworkManager.getIdentity( self.__identityName) self.__userName = identity.getIdent() self.__quitMessage = identity.getQuitMessage() if self.__server: useSSL = self.__server.useSSL() if useSSL and not SSL_AVAILABLE: E5MessageBox.critical( self, self.tr("SSL Connection"), self.tr( """An encrypted connection to the IRC""" """ network was requested but SSL is not""" """ available. Please change the server""" """ configuration.""")) return if useSSL: # create SSL socket self.__socket = QSslSocket(self) self.__socket.encrypted.connect(self.__hostConnected) self.__socket.sslErrors.connect(self.__sslErrors) else: # create TCP socket self.__socket = QTcpSocket(self) self.__socket.connected.connect(self.__hostConnected) self.__socket.hostFound.connect(self.__hostFound) self.__socket.disconnected.connect(self.__hostDisconnected) self.__socket.readyRead.connect(self.__readyRead) self.__socket.error.connect(self.__tcpError) self.__connectionState = IrcWidget.ServerConnecting if useSSL: self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Looking for server {0} (port {1})" " using an SSL encrypted connection" "...").format(self.__server.getName(), self.__server.getPort())) self.__socket.connectToHostEncrypted( self.__server.getName(), self.__server.getPort()) else: self.networkWidget.addServerMessage( self.tr("Info"), self.tr( "Looking for server {0} (port {1})...").format( self.__server.getName(), self.__server.getPort())) self.__socket.connectToHost(self.__server.getName(), self.__server.getPort()) else: if silent: ok = True else: ok = E5MessageBox.yesNo( self, self.tr("Disconnect from Server"), self.tr("""<p>Do you really want to disconnect from""" """ <b>{0}</b>?</p><p>All channels will be""" """ closed.</p>""") .format(self.__server.getName())) if ok: self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Disconnecting from server {0}...").format( self.__server.getName())) self.__closeAllChannels() self.__send("QUIT :" + self.__quitMessage) self.__socket and self.__socket.flush() self.__socket and self.__socket.close() self.__userName = "" self.__identityName = "" self.__quitMessage = "" def __editNetwork(self, name): """ Private slot to edit the network configuration. @param name name of the network to edit (string) """ from .IrcNetworkListDialog import IrcNetworkListDialog dlg = IrcNetworkListDialog(self.__ircNetworkManager, self) dlg.exec_() def __networkDataChanged(self): """ Private slot handling changes of the network and identity definitions. """ identity = self.__ircNetworkManager.getIdentity(self.__identityName) if identity: partMsg = identity.getPartMessage() for channel in self.__channelList: channel.setPartMessage(partMsg) def __joinChannel(self, name, key=""): """ Private slot to join a channel. @param name name of the channel (string) @param key key of the channel (string) """ # step 1: check, if this channel is already joined for channel in self.__channelList: if channel.name() == name: return from .IrcChannelWidget import IrcChannelWidget channel = IrcChannelWidget(self) channel.setName(name) channel.setUserName(self.__nickName) identity = self.__ircNetworkManager.getIdentity(self.__identityName) channel.setPartMessage(identity.getPartMessage()) channel.setUserPrivilegePrefix(self.__userPrefix) channel.initAutoWho() channel.sendData.connect(self.__send) channel.sendCtcpReply.connect(self.__sendCtcpReply) channel.channelClosed.connect(self.__closeChannel) channel.openPrivateChat.connect(self.__openPrivate) self.channelsWidget.addTab(channel, name) self.__channelList.append(channel) self.channelsWidget.setCurrentWidget(channel) joinCommand = ["JOIN", name] if key: joinCommand.append(key) self.__send(" ".join(joinCommand)) self.__send("MODE " + name) emptyIndex = self.channelsWidget.indexOf(self.__emptyLabel) if emptyIndex > -1: self.channelsWidget.removeTab(emptyIndex) self.__leaveButton.setEnabled(True) self.channelsWidget.setTabsClosable(True) def __query(self, match): """ Private method to handle a new private connection. @param match reference to the match object @return flag indicating, if the message was handled (boolean) """ # group(1) sender user name # group(2) sender user@host # group(3) target nick # group(4) message if match.group(4).startswith("\x01"): return self.__handleCtcp(match) self.__openPrivate(match.group(1)) # the above call sets the new channel as the current widget channel = self.channelsWidget.currentWidget() channel.addMessage(match.group(1), match.group(4)) channel.setPrivateInfo( "{0} - {1}".format(match.group(1), match.group(2))) return True @pyqtSlot(str) def __openPrivate(self, name): """ Private slot to open a private chat with the given user. @param name name of the user (string) """ from .IrcChannelWidget import IrcChannelWidget channel = IrcChannelWidget(self) channel.setName(self.__nickName) channel.setUserName(self.__nickName) identity = self.__ircNetworkManager.getIdentity(self.__identityName) channel.setPartMessage(identity.getPartMessage()) channel.setUserPrivilegePrefix(self.__userPrefix) channel.setPrivate(True, name) channel.addUsers([name, self.__nickName]) channel.sendData.connect(self.__send) channel.sendCtcpReply.connect(self.__sendCtcpReply) channel.channelClosed.connect(self.__closeChannel) self.channelsWidget.addTab(channel, name) self.__channelList.append(channel) self.channelsWidget.setCurrentWidget(channel) @pyqtSlot() def __leaveChannel(self): """ Private slot to leave a channel and close the associated tab. """ channel = self.channelsWidget.currentWidget() channel.requestLeave() def __closeAllChannels(self): """ Private method to close all channels. """ while self.__channelList: channel = self.__channelList.pop() self.channelsWidget.removeTab(self.channelsWidget.indexOf(channel)) channel.deleteLater() channel = None self.channelsWidget.addTab(self.__emptyLabel, "") self.__emptyLabel.show() self.__leaveButton.setEnabled(False) self.channelsWidget.setTabsClosable(False) def __closeChannel(self, name): """ Private slot handling the closing of a channel. @param name name of the closed channel (string) """ for channel in self.__channelList: if channel.name() == name: self.channelsWidget.removeTab( self.channelsWidget.indexOf(channel)) self.__channelList.remove(channel) channel.deleteLater() if self.channelsWidget.count() == 0: self.channelsWidget.addTab(self.__emptyLabel, "") self.__emptyLabel.show() self.__leaveButton.setEnabled(False) self.channelsWidget.setTabsClosable(False) @pyqtSlot(int) def on_channelsWidget_tabCloseRequested(self, index): """ Private slot to close a channel by pressing the close button of the channels widget. @param index index of the tab to be closed (integer) """ channel = self.channelsWidget.widget(index) channel.requestLeave() def __send(self, data): """ Private slot to send data to the IRC server. @param data data to be sent (string) """ if self.__socket: self.__socket.write( QByteArray("{0}\r\n".format(data).encode("utf-8"))) def __sendCtcpReply(self, receiver, text): """ Private slot to send a CTCP reply. @param receiver nick name of the receiver (string) @param text text to be sent (string) """ self.__send("NOTICE {0} :\x01{1}\x01".format(receiver, text)) def __hostFound(self): """ Private slot to indicate the host was found. """ self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Server found,connecting...")) def __hostConnected(self): """ Private slot to log in to the server after the connection was established. """ self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Connected,logging in...")) self.networkWidget.setConnected(True) self.__registering = True serverPassword = self.__server.getPassword() if serverPassword: self.__send("PASS " + serverPassword) nick = self.networkWidget.getNickname() if not nick: self.__nickIndex = 0 try: nick = self.__ircNetworkManager.getIdentity( self.__identityName).getNickNames()[self.__nickIndex] except IndexError: nick = "" if not nick: nick = self.__userName self.__nickName = nick self.networkWidget.setNickName(nick) realName = self.__ircNetworkManager.getIdentity( self.__identityName).getRealName() if not realName: realName = "eric IDE chat" self.__send("NICK " + nick) self.__send("USER " + self.__userName + " 0 * :" + realName) def __hostDisconnected(self): """ Private slot to indicate the host was disconnected. """ if self.networkWidget.isConnected(): self.__closeAllChannels() self.networkWidget.addServerMessage( self.tr("Info"), self.tr("Server disconnected.")) self.networkWidget.setRegistered(False) self.networkWidget.setConnected(False) self.__server = None self.__nickName = "" self.__nickIndex = -1 self.__channelTypePrefixes = "" self.__socket.deleteLater() self.__socket = None self.__connectionState = IrcWidget.ServerDisconnected self.__sslErrorLock = False def __readyRead(self): """ Private slot to read data from the socket. """ if self.__socket: self.__buffer += str( self.__socket.readAll(), Preferences.getSystem("IOEncoding"), 'replace') if self.__buffer.endswith("\r\n"): for line in self.__buffer.splitlines(): line = line.strip() if line: logging.debug("<IRC> " + line) handled = False # step 1: give channels a chance to handle the message for channel in self.__channelList: handled = channel.handleMessage(line) if handled: break else: # step 2: try to process the message ourselves for patternRe, patternFunc in self.__patterns: match = patternRe.match(line) if match is not None: if patternFunc(match): break else: # Oops, the message wasn't handled self.networkWidget.addErrorMessage( self.tr("Message Error"), self.tr( "Unknown message received from server:" "<br/>{0}").format(line)) self.__updateUsersCount() self.__buffer = "" def __handleNamedMessage(self, match): """ Private method to handle a server message containing a message name. @param match reference to the match object @return flag indicating, if the message was handled (boolean) """ name = match.group(2) if name == "NOTICE": try: msg = match.group(3).split(":", 1)[1] except IndexError: msg = match.group(3) if "!" in match.group(1): name = match.group(1).split("!", 1)[0] msg = "-{0}- {1}".format(name, msg) self.networkWidget.addServerMessage(self.tr("Notice"), msg) return True elif name == "MODE": self.__registering = False if ":" in match.group(3): # :detlev_ MODE detlev_ :+i name, modes = match.group(3).split(" :") sourceNick = match.group(1) if not self.isChannelName(name): if name == self.__nickName: if sourceNick == self.__nickName: msg = self.tr( "You have set your personal modes to" " <b>[{0}]</b>.").format(modes) else: msg = self.tr( "{0} has changed your personal modes to" " <b>[{1}]</b>.").format(sourceNick, modes) self.networkWidget.addServerMessage( self.tr("Mode"), msg, filterMsg=False) return True elif name == "PART": nick = match.group(1).split("!", 1)[0] if nick == self.__nickName: channel = match.group(3).split(None, 1)[0] self.networkWidget.addMessage( self.tr("You have left channel {0}.").format(channel)) return True elif name == "QUIT": # don't do anything with it here return True elif name == "NICK": # :[email protected] NICK :newnick oldNick = match.group(1).split("!", 1)[0] newNick = match.group(3).split(":", 1)[1] if oldNick == self.__nickName: self.networkWidget.addMessage( self.tr("You are now known as {0}.").format(newNick)) self.__nickName = newNick self.networkWidget.setNickName(newNick) else: self.networkWidget.addMessage( self.tr("User {0} is now known as {1}.").format( oldNick, newNick)) return True elif name == "ERROR": self.networkWidget.addErrorMessage( self.tr("Server Error"), match.group(3).split(":", 1)[1]) return True return False def __handleNumericMessage(self, match): """ Private method to handle a server message containing a numeric code. @param match reference to the match object @return flag indicating, if the message was handled (boolean) """ code = int(match.group(2)) if code < 400: return self.__handleServerReply( code, match.group(1), match.group(3)) else: return self.__handleServerError( code, match.group(1), match.group(3)) def __handleServerError(self, code, server, message): """ Private slot to handle a server error reply. @param code numerical code sent by the server (integer) @param server name of the server (string) @param message message sent by the server (string) @return flag indicating, if the message was handled (boolean) """ if code == 433: if self.__registering: self.__handleNickInUseLogin() else: self.__handleNickInUse() else: self.networkWidget.addServerMessage(self.tr("Error"), message) return True def __handleServerReply(self, code, server, message): """ Private slot to handle a server reply. @param code numerical code sent by the server (integer) @param server name of the server (string) @param message message sent by the server (string) @return flag indicating, if the message was handled (boolean) """ # determine message type if code in [1, 2, 3, 4]: msgType = self.tr("Welcome") elif code == 5: msgType = self.tr("Support") elif code in [250, 251, 252, 253, 254, 255, 265, 266]: msgType = self.tr("User") elif code in [372, 375, 376]: msgType = self.tr("MOTD") elif code in [305, 306]: msgType = self.tr("Away") else: msgType = self.tr("Info ({0})").format(code) # special treatment for some messages if code == 375: message = self.tr("Message of the day") elif code == 376: message = self.tr("End of message of the day") elif code == 4: parts = message.strip().split() message = self.tr( "Server {0} (Version {1}), User-Modes: {2}," " Channel-Modes: {3}")\ .format(parts[1], parts[2], parts[3], parts[4]) elif code == 265: parts = message.strip().split() message = self.tr( "Current users on {0}: {1}, max. {2}").format( server, parts[1], parts[2]) elif code == 266: parts = message.strip().split() message = self.tr( "Current users on the network: {0}, max. {1}").format( parts[1], parts[2]) elif code == 305: message = self.tr("You are no longer marked as being away.") elif code == 306: message = self.tr("You have been marked as being away.") else: first, message = message.split(None, 1) if message.startswith(":"): message = message[1:] else: message = message.replace(":", "", 1) self.networkWidget.addServerMessage(msgType, message) if code == 1: # register with services after the welcome message self.__connectionState = IrcWidget.ServerConnected self.__registerWithServices() self.networkWidget.setRegistered(True) QTimer.singleShot(1000, self.__autoJoinChannels) elif code == 5: # extract the user privilege prefixes # ... PREFIX=(ov)@+ ... m = self.__prefixRe.match(message) if m: self.__setUserPrivilegePrefix(m.group(1), m.group(2)) # extract the channel type prefixes # ... CHANTYPES=# ... m = self.__chanTypesRe.match(message) if m: self.__setChannelTypePrefixes(m.group(1)) return True def __registerWithServices(self): """ Private method to register to services. """ identity = self.__ircNetworkManager.getIdentity(self.__identityName) service = identity.getServiceName() password = identity.getPassword() if service and password: self.__send("PRIVMSG " + service + " :identify " + password) def __autoJoinChannels(self): """ Private slot to join channels automatically once a server got connected. """ for channel in self.networkWidget.getNetworkChannels(): if channel.autoJoin(): name = channel.getName() key = channel.getKey() self.__joinChannel(name, key) def __tcpError(self, error): """ Private slot to handle errors reported by the TCP socket. @param error error code reported by the socket (QAbstractSocket.SocketError) """ if error == QAbstractSocket.RemoteHostClosedError: # ignore this one, it's a disconnect if self.__sslErrorLock: self.networkWidget.addErrorMessage( self.tr("SSL Error"), self.tr( """Connection to server {0} (port {1}) lost while""" """ waiting for user response to an SSL error.""") .format(self.__server.getName(), self.__server.getPort())) self.__connectionState = IrcWidget.ServerDisconnected elif error == QAbstractSocket.HostNotFoundError: self.networkWidget.addErrorMessage( self.tr("Socket Error"), self.tr( "The host was not found. Please check the host name" " and port settings.")) elif error == QAbstractSocket.ConnectionRefusedError: self.networkWidget.addErrorMessage( self.tr("Socket Error"), self.tr( "The connection was refused by the peer. Please check the" " host name and port settings.")) elif error == QAbstractSocket.SslHandshakeFailedError: self.networkWidget.addErrorMessage( self.tr("Socket Error"), self.tr("The SSL handshake failed.")) else: if self.__socket: self.networkWidget.addErrorMessage( self.tr("Socket Error"), self.tr( "The following network error occurred:<br/>{0}") .format(self.__socket.errorString())) else: self.networkWidget.addErrorMessage( self.tr("Socket Error"), self.tr("A network error occurred.")) def __sslErrors(self, errors): """ Private slot to handle SSL errors. @param errors list of SSL errors (list of QSslError) """ ignored, defaultChanged = self.__sslErrorHandler.sslErrors( errors, self.__server.getName(), self.__server.getPort()) if ignored == E5SslErrorHandler.NotIgnored: self.networkWidget.addErrorMessage( self.tr("SSL Error"), self.tr( """Could not connect to {0} (port {1}) using an SSL""" """ encrypted connection. Either the server does not""" """ support SSL (did you use the correct port?) or""" """ you rejected the certificate.""") .format(self.__server.getName(), self.__server.getPort())) self.__socket.close() else: if defaultChanged: self.__socket.setSslConfiguration( QSslConfiguration.defaultConfiguration()) if ignored == E5SslErrorHandler.UserIgnored: self.networkWidget.addErrorMessage( self.tr("SSL Error"), self.tr( """The SSL certificate for the server {0} (port {1})""" """ failed the authenticity check. SSL errors""" """ were accepted by you.""") .format(self.__server.getName(), self.__server.getPort())) if self.__connectionState == IrcWidget.ServerConnecting: self.__socket.ignoreSslErrors() def __setUserPrivilegePrefix(self, prefix1, prefix2): """ Private method to set the user privilege prefix. @param prefix1 first part of the prefix (string) @param prefix2 indictors the first part gets mapped to (string) """ # PREFIX=(ov)@+ # o = @ -> @ircbot , channel operator # v = + -> +userName , voice operator for i in range(len(prefix1)): self.__userPrefix["+" + prefix1[i]] = prefix2[i] self.__userPrefix["-" + prefix1[i]] = "" def __ping(self, match): """ Private method to handle a PING message. @param match reference to the match object @return flag indicating, if the message was handled (boolean) """ self.__send("PONG " + match.group(1)) return True def __handleCtcp(self, match): """ Private method to handle a CTCP command. @param match reference to the match object @return flag indicating, if the message was handled (boolean) """ # group(1) sender user name # group(2) sender user@host # group(3) target nick # group(4) message if match.group(4).startswith("\x01"): ctcpCommand = match.group(4)[1:].split("\x01", 1)[0] if " " in ctcpCommand: ctcpRequest, ctcpArg = ctcpCommand.split(" ", 1) else: ctcpRequest, ctcpArg = ctcpCommand, "" ctcpRequest = ctcpRequest.lower() if ctcpRequest == "version": if Version.startswith("@@"): vers = "" else: vers = " " + Version msg = "Eric IRC client{0}, {1}".format(vers, Copyright) self.networkWidget.addServerMessage( self.tr("CTCP"), self.tr("Received Version request from {0}.").format( match.group(1))) self.__sendCtcpReply(match.group(1), "VERSION " + msg) elif ctcpRequest == "ping": self.networkWidget.addServerMessage( self.tr("CTCP"), self.tr( "Received CTCP-PING request from {0}," " sending answer.").format(match.group(1))) self.__sendCtcpReply( match.group(1), "PING {0}".format(ctcpArg)) elif ctcpRequest == "clientinfo": self.networkWidget.addServerMessage( self.tr("CTCP"), self.tr( "Received CTCP-CLIENTINFO request from {0}," " sending answer.").format(match.group(1))) self.__sendCtcpReply( match.group(1), "CLIENTINFO CLIENTINFO PING VERSION") else: self.networkWidget.addServerMessage( self.tr("CTCP"), self.tr( "Received unknown CTCP-{0} request from {1}.") .format(ctcpRequest, match.group(1))) return True return False def __updateUsersCount(self): """ Private method to update the users count on the channel tabs. """ for channel in self.__channelList: index = self.channelsWidget.indexOf(channel) self.channelsWidget.setTabText( index, self.tr("{0} ({1})", "channel name, users count").format( channel.name(), channel.getUsersCount())) def __handleNickInUseLogin(self): """ Private method to handle a 443 server error at login. """ self.__nickIndex += 1 try: nick = self.__ircNetworkManager.getIdentity(self.__identityName)\ .getNickNames()[self.__nickIndex] self.__nickName = nick except IndexError: self.networkWidget.addServerMessage( self.tr("Critical"), self.tr( "No nickname acceptable to the server configured" " for <b>{0}</b>. Disconnecting...") .format(self.__userName), filterMsg=False) self.__connectNetwork("", False, silent=True) self.__nickName = "" self.__nickIndex = -1 return self.networkWidget.setNickName(nick) self.__send("NICK " + nick) def __handleNickInUse(self): """ Private method to handle a 443 server error. """ self.networkWidget.addServerMessage( self.tr("Critical"), self.tr("The given nickname is already in use.")) def __changeNick(self, nick): """ Private slot to use a new nick name. @param nick nick name to use (str) """ if nick and nick != self.__nickName: self.__send("NICK " + nick) def __setChannelTypePrefixes(self, prefixes): """ Private method to set the channel type prefixes. @param prefixes channel prefix characters (string) """ self.__channelTypePrefixes = prefixes def isChannelName(self, name): """ Public method to check, if the given name is a channel name. @param name name to check (string) @return flag indicating a channel name (boolean) """ if not name: return False if self.__channelTypePrefixes: return name[0] in self.__channelTypePrefixes else: return name[0] in "#&" def __away(self, isAway): """ Private slot handling the change of the away state. @param isAway flag indicating the current away state (boolean) """ if isAway and self.__identityName: identity = self.__ircNetworkManager.getIdentity( self.__identityName) if identity.rememberAwayPosition(): for channel in self.__channelList: channel.setMarkerLine()
class SocketTest(QObject): def __init__(self, parent=None): super(SocketTest, self).__init__(parent) def init_socket(self): self.socket = QTcpSocket(self) def connected(): logger.info('connected , local port:{}'.format(self.socket.localPort())) # self.socket.write('f**k u'.encode(encoding='utf8')) def disconnect(): logger.info('disconnected') self.socket.connectToHost(IP, PORT) @pyqtSlot(QAbstractSocket.SocketError) def error(err): dict = { 0: 'QAbstractSocket::ConnectionRefusedError', 1: 'QAbstractSocket::RemoteHostClosedError', 2: 'QAbstractSocket::HostNotFoundError', 3: 'QAbstractSocket::SocketAccessError', 4: 'QAbstractSocket::SocketResourceError', 5: 'QAbstractSocket::SocketTimeoutError', 6: 'QAbstractSocket::DatagramTooLargeError', 7: 'QAbstractSocket::NetworkError', 8: 'QAbstractSocket::AddressInUseError', 9: 'QAbstractSocket::SocketAddressNotAvailableError', 10: 'QAbstractSocket::UnsupportedSocketOperationError', 12: 'QAbstractSocket::ProxyAuthenticationRequiredError', 13: 'QAbstractSocket::SslHandshakeFailedError', 11: 'QAbstractSocket::UnfinishedSocketOperationError', 14: 'QAbstractSocket::ProxyConnectionRefusedError', 15: 'QAbstractSocket::ProxyConnectionClosedError', 16: 'QAbstractSocket::ProxyConnectionTimeoutError', 17: 'QAbstractSocket::ProxyNotFoundError', 18: 'QAbstractSocket::ProxyProtocolError', 19: 'QAbstractSocket::OperationError', 20: 'QAbstractSocket::SslInternalError', 21: 'QAbstractSocket::SslInvalidUserDataError', 22: 'QAbstractSocket::TemporaryError', -1: 'QAbstractSocket::UnknownSocketError' } logger.info(dict[err]) @pyqtSlot(QAbstractSocket.SocketState) def _state_changed(state): # http://doc.qt.io/qt-5/qabstractsocket.html#SocketState-enum dict = { 0: 'QAbstractSocket::UnconnectedState', 1: 'QAbstractSocket::HostLookupState', 2: 'QAbstractSocket::ConnectingState', 3: 'QAbstractSocket::ConnectedState', 4: 'QAbstractSocket::BoundState', 6: 'QAbstractSocket::ClosingState', 5: 'QAbstractSocket::ListeningState' } logger.info(dict[state]) def ready_ready(): logger.info('ready read', end=': ') #logger.info(self.socket.readAll(q)) self.socket.close() @pyqtSlot(int) def bytes_written(bytes): logger.info('{} bytes send'.format(bytes)) #self.socket.connected.connect(connected) #self.socket.disconnected.connect(disconnect) self.socket.stateChanged.connect(_state_changed) self.socket.error.connect(error) # self.socket.readyRead.connect(ready_ready) # self.socket.bytesWritten.connect(bytes_written) self.socket.connectToHost(IP, PORT)
class TcpClient(QtCore.QThread): socketlist = [] socketInfo = {} signRecv = QtCore.pyqtSignal(str) signLog = QtCore.pyqtSignal(str) signFileBtn = QtCore.pyqtSignal(int) signFileBar = QtCore.pyqtSignal(int, int) signThread = QtCore.pyqtSignal(str, int, int, "QByteArray") signConfirm = QtCore.pyqtSignal(str) signFileSpeed = QtCore.pyqtSignal(str, str) def __init__(self, parent=None): super(TcpClient, self).__init__(parent) self.blockBytes = FileBlockSize # self.bytesReceive=0 self.fileBytes = 0 self.headSize = 0 self.flag = False # self.sendInit() self.signThread.connect(self.sendFile) self.signConfirm.connect(self.sendFileConfirm) def isconnect(self, ip): if ip in self.socketlist: return True return False def setIpPort(self, ip, port, ids, msgtype, msg): self.server_ip = ip self.server_port = port self.filename = msg self.msgtype = msgtype self.id = ids def slotTcpSendMsg(self, ips, ports, ids, types, msgs): # print("tcpclient send msg:",ips,ports,types,msgs) self.setIpPort(ips, ports, ids, types, msgs) if not self.isconnect(ips): self.tcpSocket = QTcpSocket() self.tcpSocket.connected.connect(self.connected) self.tcpSocket.readyRead.connect(self.readMessage) self.tcpSocket.error.connect(self.connError) self.tcpSocket.connectToHost(self.server_ip, int(self.server_port)) log_content = "connect to %s:%s ..." % (self.server_ip, self.server_port) self.signLog.emit(log_content) if not self.tcpSocket.waitForConnected(500): msg = self.tcpSocket.errorString() self.signLog.emit(msg) self.closeConnect() self.signFileBtn.emit(1) return self.socketlist.append(ips) self.socketInfo[ips] = self.tcpSocket return if ips in self.socketInfo.keys(): self.tcpSocket = self.socketInfo[ips] self.sendMessage() def connError(self): self.signLog.emit("connect error") self.closeConnect() def connected(self): self.sendMessage() def sendLocalMsg(self, filename): # self.sendInit() qheaer = self.getHeaderMsg(filename) self.sendHeaderMsg(qheaer) # self.sendInit() def sendMessage(self): if self.msgtype == 1: self.sendLocalMsg(self.filename) elif self.msgtype == 2: # log_content="connected,start to send file" # self.signLog.emit(log_content) self.sendMsgFile(self.filename) def sendMsgFile(self, filename): self.flag = True crthread = threading.Thread(target=self.readFile, args=(filename, self.blockBytes)) crthread.daemon = True # 设置随主线程退出 crthread.start() self.flag = False def readFile(self, filename, blockbytes): # print("send file",filename) info = QtCore.QFileInfo(filename) fname = info.fileName() localfile = QtCore.QFile(filename) localfile.open(QtCore.QFile.ReadOnly) totalFBytes = localfile.size() filecont = QByteArray() # filecont = self.localfile.read(min(totalFBytes,self.blockBytes)) fstream = QDataStream(localfile) fnum = math.ceil(float(totalFBytes) / self.blockBytes) # print("total",totalFBytes) # print("blockbytes",self.blockBytes) # print("fnum",fnum) i = 0 start_time = int(time.time()) tmp_time = start_time tmp_speed = "" tmp_total_time = "" while not fstream.atEnd(): readsize = min(totalFBytes, self.blockBytes) totalFBytes -= readsize filecont = fstream.readRawData(readsize) # print("send",i,readsize) self.signThread.emit(fname, i, readsize, filecont) i += 1 self.signFileBar.emit(fnum, i) self.flag = True while self.flag: if len(tmp_speed) > 0: self.signFileSpeed.emit(time_total_time + "s", self.getRandomTime(tmp_speed)) time.sleep(0.5) now_time = int(time.time()) about_time, speed = self.getAboutTime(now_time - tmp_time + 0.1, readsize, totalFBytes) self.signFileSpeed.emit(about_time + "s", speed) tmp_time = now_time tmp_speed = speed time_total_time = about_time localfile.close() self.signFileBar.emit(fnum, fnum) now_time = int(time.time()) ab_time = self.getTimeFromat(now_time - start_time) + "s" self.signFileSpeed.emit(ab_time, "") self.signConfirm.emit(fname) def getRandomTime(self, speed): increment = random.randint(-2, 3) increment_dot = random.randint(-5, 8) speeds = "" if 'MB' in speed: speeds = str(float(speed[:-2]) + increment * 0.1) + "MB" elif 'KB' in speed: speeds = str( float(speed[:-2]) + increment * 2 + increment_dot * 0.05) + "KB" elif 'B' in speed: speeds = str(float(speed[:-1]) + increment) + "B" return speeds def getAboutTime(self, timespan, readsize, totalsize): speed = round(readsize / timespan, 2) if timespan == 0.1: speed /= 10 about_time = int(totalsize / speed) sp_unit = "B" if speed >= 1024: sp_unit = "KB" speed = round(speed / 1024, 2) if speed >= 1024: sp_unit = "MB" speed = round(speed / 1024, 2) ab_result = self.getTimeFromat(about_time) sp_result = str(speed) + sp_unit return ab_result, sp_result def getTimeFromat(self, about_time): ab_unit = [] if about_time >= 60: ab_unit.append(str(about_time % 60)) about_time = int(about_time / 60) if about_time >= 60: ab_unit.append(str(about_time % 60)) about_time = int(about_time / 60) ab_unit.append(str(about_time)) tmp_ab = ab_unit[::-1] ab_result = ':'.join(tmp_ab) return ab_result def sendConfirm(self): qheaer = self.confirmHeader() self.sendHeaderMsg(qheaer) def sendFileConfirm(self, fname): qheaer = self.confirmHeader(3, fname) self.sendHeaderMsg(qheaer) def readMessage(self): stream = QDataStream(self.tcpSocket) stream.setVersion(QDataStream.Qt_5_4) while self.tcpSocket.bytesAvailable() > SIZEOF_HEAD_INT: if self.headSize == 0: self.headSize = stream.readInt64() # fileBytes=stream.readInt64() # self.bytesReceive+=SIZEOF_HEAD_INT if self.tcpSocket.bytesAvailable() >= self.headSize: qheader = stream.readQString() # print("client recv head:",qheader) # self.bytesReceive += self.headSize self.handlerMessage(qheader) self.initRecv() else: break def handlerMessage(self, headers): if len(headers) < 1: return headStr = json.loads(headers) type = 0 if "type" in headStr: type = headStr["type"] if type == 3: if "status" in headStr and headStr["status"] == 0: self.flag = False # self.closeConnect()#断开连接 def sendFile(self, fname, fnum, filelen, filecont): self.sendInit() qheader = self.getHeader(fname, filelen, fnum, 2) self.sendmsg(qheader, filecont) # self.sendInit() def sendmsg(self, qheader, filecont): self.outBlock = QByteArray() sendout = QDataStream(self.outBlock, QIODevice.WriteOnly) sendout.setVersion(QDataStream.Qt_5_4) sendout.writeInt64(0) #占位 sendout.writeInt64(0) sendout.writeQString(qheader) headBytes = self.outBlock.size() sendout.writeRawData(filecont) fileBytes = self.outBlock.size() - headBytes sendout.device().seek(0) sendout.writeInt64(headBytes - SIZEOF_HEAD_INT) sendout.writeInt64(fileBytes) self.tcpSocket.write(self.outBlock) #head def sendHeaderMsg(self, qheader): self.outBlock = QByteArray() sendout = QDataStream(self.outBlock, QIODevice.WriteOnly) sendout.setVersion(QDataStream.Qt_5_4) sendout.writeInt64(0) #占位 sendout.writeInt64(0) sendout.writeQString(qheader) headBytes = self.outBlock.size() sendout.device().seek(0) sendout.writeInt64(headBytes - SIZEOF_HEAD_INT) self.tcpSocket.write(self.outBlock) #head def closeConnect(self): log_content = "client disconnect to %s" % (self.server_ip) self.signLog.emit(log_content) self.tcpSocket.disconnectFromHost() self.tcpSocket.close() # self.sign.emit(1) def initRecv(self): self.headSize = 0 def sendInit(self): # print("client sent init") self.fileBytes = 0 # self.flag=False def getHeader(self, fname, flen, fnum, type=0): data = {} data["type"] = type data["id"] = self.id data["filename"] = fname data["filelen"] = flen data["fnum"] = fnum strs = json.dumps(data) return _fromUtf8(strs) def confirmHeader(self, type=3, fname=""): data = {} data["type"] = type data["id"] = self.id data["confirm"] = "send" data["status"] = 0 if fname != "": data["filename"] = fname strs = json.dumps(data) return _fromUtf8(strs) def getHeaderMsg(self, contant): data = {} data["type"] = 1 data["msg"] = contant data["id"] = self.id strs = json.dumps(data) return _fromUtf8(strs)
class Dialog(QDialog): TotalBytes = 50 * 1024 * 1024 PayloadSize = 65536 def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.tcpServer = QTcpServer() self.tcpClient = QTcpSocket() self.bytesToWrite = 0 self.bytesWritten = 0 self.bytesReceived = 0 self.clientProgressBar = QProgressBar() self.clientStatusLabel = QLabel("Client ready") self.serverProgressBar = QProgressBar() self.serverStatusLabel = QLabel("Server ready") self.startButton = QPushButton("&Start") self.quitButton = QPushButton("&Quit") buttonBox = QDialogButtonBox() buttonBox.addButton(self.startButton, QDialogButtonBox.ActionRole) buttonBox.addButton(self.quitButton, QDialogButtonBox.RejectRole) self.startButton.clicked.connect(self.start) self.quitButton.clicked.connect(self.close) self.tcpServer.newConnection.connect(self.acceptConnection) self.tcpClient.connected.connect(self.startTransfer) self.tcpClient.bytesWritten.connect(self.updateClientProgress) self.tcpClient.error.connect(self.displayError) mainLayout = QVBoxLayout() mainLayout.addWidget(self.clientProgressBar) mainLayout.addWidget(self.clientStatusLabel) mainLayout.addWidget(self.serverProgressBar) mainLayout.addWidget(self.serverStatusLabel) mainLayout.addStretch(1) mainLayout.addSpacing(10) mainLayout.addWidget(buttonBox) self.setLayout(mainLayout) self.setWindowTitle("Loopback") def start(self): self.startButton.setEnabled(False) QApplication.setOverrideCursor(Qt.WaitCursor) self.bytesWritten = 0 self.bytesReceived = 0 while not self.tcpServer.isListening() and not self.tcpServer.listen(): ret = QMessageBox.critical( self, "Loopback", "Unable to start the test: %s." % self.tcpServer.errorString(), QMessageBox.Retry | QMessageBox.Cancel, ) if ret == QMessageBox.Cancel: return self.serverStatusLabel.setText("Listening") self.clientStatusLabel.setText("Connecting") self.tcpClient.connectToHost(QHostAddress(QHostAddress.LocalHost), self.tcpServer.serverPort()) def acceptConnection(self): self.tcpServerConnection = self.tcpServer.nextPendingConnection() self.tcpServerConnection.readyRead.connect(self.updateServerProgress) self.tcpServerConnection.error.connect(self.displayError) self.serverStatusLabel.setText("Accepted connection") self.tcpServer.close() def startTransfer(self): self.bytesToWrite = Dialog.TotalBytes - self.tcpClient.write( QByteArray(Dialog.PayloadSize, "@")) self.clientStatusLabel.setText("Connected") def updateServerProgress(self): self.bytesReceived += self.tcpServerConnection.bytesAvailable() self.tcpServerConnection.readAll() self.serverProgressBar.setMaximum(Dialog.TotalBytes) self.serverProgressBar.setValue(self.bytesReceived) self.serverStatusLabel.setText("Received %dMB" % (self.bytesReceived / (1024 * 1024))) if self.bytesReceived == Dialog.TotalBytes: self.tcpServerConnection.close() self.startButton.setEnabled(True) QApplication.restoreOverrideCursor() def updateClientProgress(self, numBytes): self.bytesWritten += numBytes if self.bytesToWrite > 0: self.bytesToWrite -= self.tcpClient.write( QByteArray(min(self.bytesToWrite, Dialog.PayloadSize), "@")) self.clientProgressBar.setMaximum(Dialog.TotalBytes) self.clientProgressBar.setValue(self.bytesWritten) self.clientStatusLabel.setText("Sent %dMB" % (self.bytesWritten / (1024 * 1024))) def displayError(self, socketError): if socketError == QTcpSocket.RemoteHostClosedError: return QMessageBox.information( self, "Network error", "The following error occured: %s." % self.tcpClient.errorString(), ) self.tcpClient.close() self.tcpServer.close() self.clientProgressBar.reset() self.serverProgressBar.reset() self.clientStatusLabel.setText("Client ready") self.serverStatusLabel.setText("Server ready") self.startButton.setEnabled(True) QApplication.restoreOverrideCursor()
class PulsedNMR(QMainWindow, Ui_PulsedNMR): rates = {0:25.0e3, 1:50.0e3, 2:250.0e3, 3:500.0e3, 4:2500.0e3} def __init__(self): super(PulsedNMR, self).__init__() self.setupUi(self) self.rateValue.addItems(['25', '50', '250', '500', '2500']) # IP address validator rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$') self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue)) # state variable self.idle = True # number of samples to show on the plot self.size = 50000 # buffer and offset for the incoming samples self.buffer = bytearray(8 * self.size) self.offset = 0 # create figure figure = Figure() figure.set_facecolor('none') self.axes = figure.add_subplot(111) self.canvas = FigureCanvas(figure) self.plotLayout.addWidget(self.canvas) # create navigation toolbar self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False) # remove subplots action actions = self.toolbar.actions() self.toolbar.removeAction(actions[7]) self.plotLayout.addWidget(self.toolbar) # create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # connect signals from buttons and boxes self.startButton.clicked.connect(self.start) self.freqValue.valueChanged.connect(self.set_freq) self.awidthValue.valueChanged.connect(self.set_awidth) self.deltaValue.valueChanged.connect(self.set_delta) self.rateValue.currentIndexChanged.connect(self.set_rate) # set rate self.rateValue.setCurrentIndex(2) # create timer for the repetitions self.timer = QTimer(self) self.timer.timeout.connect(self.fire) def start(self): if self.idle: self.startButton.setEnabled(False) self.socket.connectToHost(self.addrValue.text(), 1001) else: self.idle = True self.timer.stop() self.socket.close() self.offset = 0 self.startButton.setText('Start') self.startButton.setEnabled(True) def connected(self): self.idle = False self.set_freq(self.freqValue.value()) self.set_rate(self.rateValue.currentIndex()) self.set_awidth(self.awidthValue.value()) self.fire() self.timer.start(self.deltaValue.value()) self.startButton.setText('Stop') self.startButton.setEnabled(True) def read_data(self): size = self.socket.bytesAvailable() if self.offset + size < 8 * self.size: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: self.buffer[self.offset:8 * self.size] = self.socket.read(8 * self.size - self.offset) self.offset = 0 # plot the signal envelope data = np.frombuffer(self.buffer, np.complex64) self.curve.set_ydata(np.abs(data)) self.canvas.draw() def display_error(self, socketError): if socketError == QAbstractSocket.RemoteHostClosedError: pass else: QMessageBox.information(self, 'PulsedNMR', 'Error: %s.' % self.socket.errorString()) self.startButton.setText('Start') self.startButton.setEnabled(True) def set_freq(self, value): if self.idle: return self.socket.write(struct.pack('<I', 0<<28 | int(1.0e6 * value))) def set_rate(self, index): # time axis rate = float(PulsedNMR.rates[index]) time = np.linspace(0.0, (self.size - 1) * 1000.0 / rate, self.size) # reset toolbar self.toolbar.home() self.toolbar._views.clear() self.toolbar._positions.clear() # reset plot self.axes.clear() self.axes.grid() # plot zeros and get store the returned Line2D object self.curve, = self.axes.plot(time, np.zeros(self.size)) x1, x2, y1, y2 = self.axes.axis() # set y axis limits self.axes.axis((x1, x2, -0.1, 0.4)) self.axes.set_xlabel('time, ms') self.canvas.draw() # set repetition time minimum = self.size / rate * 2000.0 if minimum < 100.0: minimum = 100.0 self.deltaValue.setMinimum(minimum) self.deltaValue.setValue(minimum) if self.idle: return self.socket.write(struct.pack('<I', 1<<28 | index)) def set_awidth(self, value): if self.idle: return self.socket.write(struct.pack('<I', 2<<28 | int(1.0e1 * value))) def set_delta(self, value): if self.idle: return self.timer.stop() self.timer.start(value) def fire(self): if self.idle: return self.socket.write(struct.pack('<I', 3<<28))
class sendMessage(QObject): doSomeThing = pyqtSignal(str) # 收到一条命令去执行 def __init__(self, parent=None): # 初始化发送对象,首先要先建立连接 super(sendMessage, self).__init__(parent) self.socket = QTcpSocket() self.nextBlockSize = 0 self.socket.connectToHost(IP, PORT) self.deviceInfo = deviceInfo(DEVICE_FIX_ID, REGION_PROVINCE, REGION_CITY, REGION_AREA) # 保存盒子信息,可从某个文件读取 self.socket.connected.connect(self.initConnected) # 初始化连接,第一次连上就发送信息 self.socket.waitForConnected() # 等待设备连接完成 time.sleep(0.1) self.socket.readyRead.connect(self.readResponse) self.socket.disconnected.connect(self.serverHasStopped) self.socket.error.connect(self.serverHasError) self.doSomeThing.connect(self.doWhat) # 收到某条命令要执行的函数 def doWhat(self, order): # 收到dosome命令要执行的函数 if order: if ',' in order: order, model_type = order.split(",") else: model_type = None order_instance = generateOrder(order) t = Thread(target=order_instance.run, args=(self.deviceInfo, IP, 8870, model_type)) t.start() def fileToBytes(self, fileName): # 将文件转换成二进制 file = QFile(fileName) print(file.size()) count = 0 with open(fileName, 'rb') as f: while 1: filedata = f.read(1024) if not filedata: break count = count + filedata.__len__() print(count) @startSendMessage def initConnected( self, stream): # 每次连接上后 发送盒子的设备信息 fixID(固定id) region(所在地区) stream.writeQString('deviceInfo') # 设定信息类型 state deviceInfoToByte = pickle.dumps( deviceInfoJson ) # 将设备信息序列化成二进制发送 s = pickle.dumps(sendMessage1.deviceInfo) stream.writeBytes(deviceInfoToByte) ''' 接下来还有几点 1、盒子连接建立,发送设备信息。接收端接收一次。 2、规定好发送文件的格式 3、设计数据库 4、与网页交互 ''' @startSendMessage def sendFileBytes(self, stream, filePath, fileBytes): # stream 由装饰器传值 状态 文件名 文件字节 file = QFile(filePath) print(filePath) stream.writeQString('sendFile') # 发送文件 状态 stream.writeQString(file.fileName()) # 发送文件的名字 print(file.size()) stream.writeQString(str(file.size())) # 发送文件的大小 stream.writeBytes(fileBytes) def sendFile(self, filePath): with open(filePath, 'rb') as f: count = 0 while 1: # 循环传输 filedata = f.read(204800) print(filedata.__sizeof__()) if not filedata: break self.sendFileBytes(filePath, filedata) count = count + filedata.__sizeof__() print(count) @startSendMessage def sendImage(self, stream, imagePath, kind): # 传递图片,与图片类型 状态 图片类型 图片 stream.writeQString('sendImage') stream.writeQString(kind) stream.writeBytes(self.fileToBytes(imagePath)) @startSendMessage def sendResult( self, stream, kind, result, startTime, usedTime): # ,发送成功的状态,发送来 success 日期 信号类型 识别结果 识别开始时间 识别时间 stream.writeQString('successResult') # 发送成功状态 dateNow = time.strftime("%Y-%m-%d", time.localtime()) resultObject = resultInfo(dateNow, kind, result, startTime, usedTime) # 结果对象 (日期,类型,结果,开始时间,识别用时) resultBytes = pickle.dumps(resultObject) stream.writeBytes(resultBytes) def readResponse(self): # 收命令,要做的事情, stream = QDataStream(self.socket) print('--------------------') print('服务器响应') stream.setVersion(QDataStream.Qt_5_7) while True: self.nextBlockSize = 0 if self.nextBlockSize == 0: if self.socket.bytesAvailable() < SIZEOF_UINT16: print('没有内容了') break self.nextBlockSize = stream.readUInt16() else: print('错误') # 客户端主动断开时,去掉字典中的对应,在这里做一部分操作。 # 客户端主动断开的时候,要将其从self.myParent.sockeIdToSocketDict self.myParent.fixIdToSocketIdDict 中删掉 break if self.socket.bytesAvailable() < self.nextBlockSize: print("错误2") if (not self.socket.waitForReadyRead(60000) or self.socket.bytesAvailable() < self.nextBlockSize): break state = stream.readQString() # 读命令 sendModel print('state==' + state) if state == 'SENDFILE': filename = stream.readQString() # 读文件名 fileSize = stream.readInt() # 读文件大小 with open('../TEST/' + filename, 'ab') as f: while self.nextBlockSize > 0: fileBytes = stream.readBytes() # 读文件部分字节 f.write(fileBytes) print(fileBytes.__len__()) self.nextBlockSize = stream.readUInt64() print('self.nextBlockSize:' + str(self.nextBlockSize)) state = stream.readQString() filename = stream.readQString() # 读文件名 fileSize = stream.readInt() # 读文件大小 print('filename:' + filename) print('fileSize:' + str(fileSize)) elif state == 'test': print(stream.readQString()) elif state == 'ORDER': # 收到一条命令 要执行的命令 order = stream.readQString() # 读是什么命令 if order: # shou dao doThing self.doSomeThing.emit(order) def serverHasStopped(self): print('连接断开') self.socket.close() self.socket = QTcpSocket() print(self.socket.state()) # while self.socket.state() == 0: # print("重新连接") # time.sleep(5) # self.socket.connectToHost(IP, PORT) # self.socket.waitForConnected() # self.socket.close() def serverHasError(self, error): self.socket.close()
class TcpClient(QObject): ''' TCP/IP client class. Usage: import sys import tcp from PyQt4.QtCore import QCoreApplication from PyQt4.QtNetwork.QAbstractSocket import QAbstractSocket def main(): application = QCoreApplication(sys.argv) def onConnected(): print("Connected") def onDisconnected(): print("Disconnected") def onError(error): print("Error: ", error) if error[0] == QAbstractSocket.ConnectionRefusedError: # if connection refused sys.exit(1) # close the program def onRead(data): print("Read %s byte(s): %s" % (len(data), data)) tcpClient = tcp.TcpClient() tcpClient.onConnected = onConnected tcpClient.onDisconnected = onDisconnected tcpClient.onError = onError tcpClient.onRead = onRead tcpClient.connectToHost("localhost", 9000) tcpClient.write("Hello there") sys.exit(application.exec_()) if __name__ == "__main__": main() ''' def __init__(self, parent=None): QObject.__init__(self, parent) self.__socket = QTcpSocket(parent) # Callbacks self.__on_connected = None self.__on_disconnected = None self.__on_error = None self.__on_read = None # Signals and slots connections self.__socket.connected.connect(self.__onConnected) self.__socket.disconnected.connect(self.__onDisconnected) self.__socket.error.connect(self.__onError) self.__socket.readyRead.connect(self.__onReadyRead) # Slots @pyqtSlot() def __onConnected(self): ''' The slot is called when a connection to the specified host has been successfully established. Then, __on_connected callback is executed. :return: None ''' if self.__on_connected: self.__on_connected() @pyqtSlot() def __onDisconnected(self): ''' The slot is called when the connection to the host is closed. Then, __on_disconnected callback is executed. :return: None ''' if self.__on_disconnected: self.__on_disconnected() def __onError(self, socketError): ''' The slot is called when an error(PyQt4.QtNetwork.SocketError) <socketError> occurs. Then, error code(int) <errorCode> and error description(str) <errorDescription> are defined and passed to __on_error callback. :param error(PyQt4.QtNetwork.SocketError): error code; :return: None ''' errorCode = int(socketError) errorDescription = str(self.__socket.errorString()) error = (errorCode, errorDescription) if self.__on_error: self.__on_error(error) @pyqtSlot() def __onReadyRead(self): ''' The slot is called when new data is available for reading from the host. Then, all available data(str) is read and passed to __on_read callback. :return: None ''' if self.__on_read: self.__on_read(self.__socket.readAll().data()) # Setters def __connected(self, callback): self.__on_connected = callback def __disconnected(self, callback): self.__on_disconnected = callback def __error(self, callback): self.__on_error = callback def __read(self, callback): self.__on_read = callback # Properties onConnected = property(fset=__connected) onDisconnected = property(fset=__disconnected) onError = property(fset=__error) onRead = property(fset=__read) # Interface def connectToHost(self, host, port): ''' Attempt to make a connection to host(str) <host> on the given port(int) <port>. :param host(str), remote host; :param port(int), remote port; :return: None ''' self.__socket.connectToHost(host, port) def disconnectFromHost(self): ''' Attempt to close the connection. :return: None ''' self.__socket.disconnectFromHost() def close(self): ''' Close the connection with the host, and reset the name, address, port number and underlying socket descriptor. :return: None ''' self.__socket.close() def state(self): ''' Return the state of the connection. :return: QAbstractSocket.SocketState, socket state ''' return self.__socket.state() def write(self, data): ''' Write data(str) <data> to the host. :param data(str): outgoing data; :return: int, the number of bytes that were actually written, or -1 if an error occurred ''' return self.__socket.write(data)
class TcpSocketClient(QObject, ICommunicateTCPIP): readyReadClientID = pyqtSignal(int) disconnectedClientID = pyqtSignal(int) def __init__(self, parent=None): super(TcpSocketClient, self).__init__() self.tcpSocketClient = QTcpSocket(parent) self.setIsConnected(False) self.setTcpClientID(0) self.setPeerFullAddrStr(str()) self.tcpSocketClient.readyRead.connect(self.dataReceived) self.connectClientDisconnect(self.disConnected) def createConnection(self, ip, port): self.tcpSocketClient.connectToHost(ip, port) # 向目的ip服务器的端口进行连接 isOK = self.tcpSocketClient.waitForConnected( 2000) # 等2s, 若还无法连上服务器就算失败 self.setIsConnected(isOK) return isOK def send(self, data): """ 发送 :param data: str or bytearray :return: int """ if len(data) == 0 or data is None: return if isinstance(data, str): return self.tcpSocketClient.write(QByteArray(bytes(data, 'utf8'))) else: return self.tcpSocketClient.write(QByteArray(data)) def connectRec(self, slotRec): self.tcpSocketClient.readyRead.connect(slotRec) def connectClientDisconnect(self, slotRec): self.tcpSocketClient.disconnected.connect(slotRec) def read(self): """ 读取数据 :return: bytes """ datagram = self.tcpSocketClient.readAll() self.setRecSrcIp(self.tcpSocketClient.peerAddress()) self.setRecSrcPort(self.tcpSocketClient.peerPort()) return datagram.data() def close(self): self.tcpSocketClient.close() def connectRecWithClientID(self, slotRec): self.readyReadClientID.connect(slotRec) def connectDisconnectWithClientID(self, slotRec): self.disconnectedClientID.connect(slotRec) def setSocketDescriptor(self, socketDescriptor): return self.tcpSocketClient.setSocketDescriptor(socketDescriptor) @pyqtSlot() def dataReceived(self): self.readyReadClientID.emit(self.getTcpClientID()) @pyqtSlot() def disConnected(self): self.disconnectedClientID.emit(self.getTcpClientID()) def setIsConnected(self, isConnected): self.isConnected = isConnected def getIsConnected(self): return self.isConnected def setTcpClientID(self, tcpClientID): self.tcpClientID = tcpClientID def getTcpClientID(self): return self.tcpClientID def setPeerFullAddrStr(self, peerFullAddrStr): self.peerFullAddrStr = peerFullAddrStr def getPeerFullAddrStr(self): return self.peerFullAddrStr def getPeerIp(self): return self.tcpSocketClient.peerAddress().toString() def getPeerPort(self): return self.tcpSocketClient.peerPort()
class Averager(QMainWindow, Ui_Averager): def __init__(self): super(Averager, self).__init__() self.setupUi(self) # Set data acquisition variables self.idle = True # state variable self.size = 8193 # number of samples to show on the plot # max size self.buffer = bytearray( 4 * self.size) # buffer and offset for the incoming samples self.offset = 0 self.data = np.frombuffer(self.buffer, np.int32) self.isScaled = True self.isLogScale = False self.isFFT = False self.haveData = False self.showComp = 0 # Real, Imag, Abs, Phase from combo box # Create figure figure = Figure() figure.set_facecolor('none') self.axes = figure.add_subplot(111) self.canvas = FigureCanvas(figure) self.plotLayout.addWidget(self.canvas) # Create navigation toolbar self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False) # Remove subplots action actions = self.toolbar.actions() self.toolbar.removeAction(actions[7]) self.plotLayout.addWidget(self.toolbar) # Create TCP socket self.socket = QTcpSocket(self) self.socket.connected.connect(self.connected) self.socket.readyRead.connect(self.read_data) self.socket.error.connect(self.display_error) # Populate Combo boxes self.cbShowComp.clear() self.cbShowComp.addItems(["Real", "Imaginary", "Absolute", "Phase"]) self.cbShowComp.setCurrentIndex(0) self.cbNOS.clear() # Number of Samples for i in range(11): # maximal value set by the FPGA program self.cbNOS.addItems([str(1 << i)]) self.cbNOS.setCurrentIndex(10) self.cbNOA.clear() # Number of Averages for i in range(22): # maximal value could be larger self.cbNOA.addItems([str(1 << i)]) self.cbNOA.setCurrentIndex(0) self.cbTrigger.clear() # Trigger rate for i in range(26): # maximal value set by the FPGA program self.cbTrigger.addItems(["f0/" + str(int(1 << (26 + 1 - i)))]) self.cbTrigger.setCurrentIndex(16) # +1 comes from the fact that counter's lowest bit has f0/2 frequency # Connect UI elements and functions self.btnStart.clicked.connect(self.start) self.chkFFT.stateChanged.connect(self.update_values) self.chkScale.stateChanged.connect(self.update_values) self.chkLogScale.stateChanged.connect(self.update_values) self.cbShowComp.currentIndexChanged.connect(self.update_values) def update_values(self): self.isScaled = self.chkScale.isChecked() self.isLogScale = self.chkLogScale.isChecked() self.isFFT = self.chkFFT.isChecked() self.showComp = self.cbShowComp.currentIndex() self.plot() def start(self): if self.idle: print("connecting ...") self.btnStart.setEnabled(False) self.socket.connectToHost(self.txtIPA.text(), int(self.txtPort.text())) else: self.idle = True self.socket.close() self.offset = 0 self.btnStart.setText('Start') self.btnStart.setEnabled(True) print("Disconnected") def set_config(self): # Number of Samples self.size = int(1 << self.cbNOS.currentIndex()) self.naverages = (1 << int(self.cbNOA.currentIndex())) print("number of samples = " + str(self.size)) print("number of averages = " + str(self.naverages)) print("trigger = " + str(self.cbTrigger.currentIndex())) if self.idle: return self.socket.write( struct.pack('<I', 1 << 28 | self.cbTrigger.currentIndex())) self.socket.write( struct.pack('<I', 2 << 28 | self.cbNOS.currentIndex())) self.socket.write( struct.pack('<I', 3 << 28 | self.cbNOA.currentIndex())) #print( "Configuration sent") def connected(self): print("Connected") self.idle = False self.btnStart.setText('Stop') self.btnStart.setEnabled(True) self.set_config() self.start_measurement() def read_data(self): size = self.socket.bytesAvailable() print("got " + str(size)) if self.offset + size < 4 * self.size: self.buffer[self.offset:self.offset + size] = self.socket.read(size) self.offset += size else: #print( "have all the data") self.buffer[self.offset:4 * self.size] = self.socket.read(4 * self.size - self.offset) self.offset = 0 self.haveData = True self.plot() self.idle = True self.socket.close() self.offset = 0 self.btnStart.setText('Start') self.btnStart.setEnabled(True) print("Disconnected") def plot(self): if self.haveData == False: return # reset toolbar self.toolbar.home() ## PyQt4 implementation # self.toolbar._views.clear() # self.toolbar._positions.clear() ## PyQt5 implementation self.toolbar.update() # reset plot self.axes.clear() self.axes.grid() # set data self.time_step = 1. / 125 # us y_data = np.array(self.data[0:self.size], dtype=float) N = self.size # number of complex samples # scale y_data = y_data / self.naverages x_data = np.arange(1, N + 1) xlab = "Index" ylab = "14-bit ADC output" if self.isScaled == True: self.gnd = 0 * -146.6 self.vcc = 1133.7 y_data = 4.96 * (y_data - self.gnd) / (self.vcc - self.gnd) x_data = self.time_step * x_data xlab = 'Time (us)' ylab = 'Voltage' if self.isFFT == True: y_data[-1] = (y_data[0] + y_data[-2]) / 2 y_data = np.fft.fft(y_data) / N x_data = np.fft.fftfreq(y_data.size, self.time_step) x_data = np.fft.fftshift(x_data) y_data = np.fft.fftshift(y_data) xlab = 'Frequency (MHz)' ylab = 'Amplitude' if self.showComp == 0: y_data = y_data.real ylab = "Real " + ylab elif self.showComp == 1: y_data = y_data.imag ylab = "Imag " + ylab elif self.showComp == 2: y_data = np.abs(y_data) ylab = "Abs " + ylab else: y_data = np.angle(y_data) ylab = "Phase " + ylab if self.isLogScale == True: y_data = 20 * np.log10(y_data) ylab = ylab + ' (dBV)' else: ylab = ylab + ' (V)' #print( str(y_data[N/2-1]) + " " + str(y_data[N/2]) + " " + str(y_data[N/2+1])) self.curve = self.axes.plot(x_data, y_data) #x1, x2, y1, y2 = self.axes.axis() # set y axis limits #self.axes.axis((1, self.size, -1500,500)) self.axes.set_xlim([min(x_data), max(x_data)]) self.axes.set_xlabel(xlab) self.axes.set_ylabel(ylab) self.canvas.draw() def display_error(self, socketError): if socketError == QAbstractSocket.RemoteHostClosedError: pass else: QMessageBox.information(self, 'Averager', 'Error: %s.' % self.socket.errorString()) self.btnStart.setText('Start') self.btnStart.setEnabled(True) def start_measurement(self): if self.idle: return self.socket.write(struct.pack('<I', 0 << 28))
class JsonRpcTcpClient(QObject): def __init__(self, request_handler_instance): QObject.__init__(self) self.socket = QTcpSocket(self) self.connectionAttempts = 1 self.socket.readyRead.connect(self.onData) self.socket.error.connect(self.onSocketError) self.request_handler_instance = request_handler_instance self.nextid = 1 self.callbacks_result = {} self.callbacks_error = {} self.buffer = b'' def connect(self, host, port): self.host = host self.port = port self.socket.connectToHost(host, port) @QtCore.pyqtSlot(QAbstractSocket.SocketError) def onSocketError(self, error): if (error == QAbstractSocket.ConnectionRefusedError): self.socket.connectToHost(self.host, self.port) self.connectionAttempts += 1 #self._logger.info("reconnecting to JSONRPC server {}".format(self.connectionAttempts)) else: raise RuntimeError( "Connection error to JSON RPC server: {} ({})".format( self.socket.errorString(), error)) def close(self): self.socket.close() def parseRequest(self, request): try: m = getattr(self.request_handler_instance, request["method"]) if "params" in request and len(request["params"]) > 0: result = m(*request["params"]) else: result = m() # we do not only have a notification, but a request which awaits a response if "id" in request: responseObject = { "id": request["id"], "result": result, "jsonrpc": "2.0" } self.socket.write(json.dumps(responseObject)) except AttributeError: if "id" in request: responseObject = { "id": request["id"], "error": "no such method", "jsonrpc": "2.0" } self.socket.write(json.dumps(responseObject)) def parseResponse(self, response): if "error" in response: self._logger.error("response error {}".format(response)) if "id" in response: if response["id"] in self.callbacks_error: self.callbacks_error[response["id"]](response["error"]) elif "result" in response: if "id" in response: if response["id"] in self.callbacks_result: self.callbacks_result[response["id"]](response["result"]) if "id" in response: self.callbacks_error.pop(response["id"], None) self.callbacks_result.pop(response["id"], None) @QtCore.pyqtSlot() def onData(self): newData = b'' while self.socket.bytesAvailable(): newData += bytes(self.socket.readAll()) # this seems to be a new notification, which invalidates our buffer. This may happen on malformed JSON data if newData.startswith(b"{\"jsonrpc\":\"2.0\""): if len(self.buffer) > 0: self._logger.error( "parse error: discarding old possibly malformed buffer data {}" .format(self.buffer)) self.buffer = newData else: self.buffer += newData self.buffer = self.processBuffer(self.buffer.strip()) #from https://github.com/joncol/jcon-cpp/blob/master/src/jcon/json_rpc_endpoint.cpp#L107 def processBuffer(self, buf): if len(buf) == 0: return b'' if not buf.startswith(b'{'): self._logger.error( "parse error: buffer expected to start {{: {}".format(buf)) return b'' in_string = False brace_nesting_level = 0 for i, c in enumerate(buf): if c == ord('"'): in_string = not in_string if not in_string: if c == ord('{'): brace_nesting_level += 1 if c == ord('}'): brace_nesting_level -= 1 if brace_nesting_level < 0: self._logger.error( "parse error: brace_nesting_level < 0: {}".format( buf)) return b'' if brace_nesting_level == 0: complete_json_buf = buf[:i + 1] remaining_buf = buf[i + 1:] try: request = json.loads(complete_json_buf) except ValueError: self._logger.error( "json.loads failed for {}".format( complete_json_buf)) return b'' print("JsonRpcTcpClient received: {}".format(request)) # is this a request? if "method" in request: self.parseRequest(request) # this is only a response else: self.parseResponse(request) return self.processBuffer(remaining_buf.strip()) return buf def call(self, method, args=[], callback_result=None, callback_error=None): if self.socket.state() != QAbstractSocket.ConnectedState: raise RuntimeError("Not connected to the JSONRPC server.") rpcObject = {"method": method, "params": args, "jsonrpc": "2.0"} if callback_result: rpcObject["id"] = self.nextid self.callbacks_result[self.nextid] = callback_result if callback_error: self.callbacks_error[self.nextid] = callback_error self.nextid += 1 self._logger.debug("sending JSONRPC object {}".format(rpcObject)) self.socket.write(json.dumps(rpcObject).encode("utf-8") + b'\n')
class PulseGen(QtWidgets.QMainWindow, Ui_MainWindow): GENERATOR_PORT = 5000 def __init__(self, parent=None): super(PulseGen, self).__init__(parent) self.setupUi(self) self.pulse_gen_display = PulseGenDisplay() self.display_data = [0] * 500 self.pulse_height_max = self.pulse_height_dial.maximum() self.pulse_height_min = self.pulse_height_dial.minimum() self.pulse_gen_display.pulse_height = self.pulse_height_max # set pulse height self.pulse_gen_display.pulse_height = self.pulse_height_max self.pulse_height_dial.setValue(self.pulse_gen_display.pulse_height) self.pulse_height_dial.actionTriggered.connect(self.avoid_wrapping) self.pulse_height_dial.valueChanged.connect(self.pulse_height_changed) self.pulse_height_text.setText(str( self.pulse_gen_display.pulse_height)) # don't allow editing self.pulse_height_text.textChanged.connect(self.no_editing) # pulse shape for pulse_form in self.pulse_gen_display.pulse_shape.keys(): self.pulse_shape_combo.addItem(pulse_form) self.pulse_shape_combo.currentIndexChanged.connect( self.pulse_shape_changed) current_pulse_form = self.pulse_shape_combo.currentText() self.pulse_gen_display.pulse_form = self.pulse_gen_display.pulse_shape[ current_pulse_form] print("Current pulse form: " + current_pulse_form + " code: " + str(self.pulse_gen_display.pulse_form)) for pulse_freq in self.pulse_gen_display.frequencies.keys(): self.gen_freq_combo.addItem(pulse_freq) current_pulse_freq = self.gen_freq_combo.currentText() self.pulse_gen_display.pulse_T = self.pulse_gen_display.frequencies[ current_pulse_freq] print("Current pulse T: " + str(self.pulse_gen_display.pulse_T)) self.gen_freq_combo.currentIndexChanged.connect( self.pulse_freq_changed) for display_freq in self.pulse_gen_display.frequencies.keys(): self.display_freq_combo.addItem(display_freq) self.display_freq_combo.currentIndexChanged.connect( self.display_freq_changed) current_display_freq = self.display_freq_combo.currentText() self.pulse_gen_display.display_T = self.pulse_gen_display.frequencies[ current_display_freq] print("Current display T: " + str(self.pulse_gen_display.display_T)) self.start_stop_pb.clicked.connect(self.start_stop_meas) self.connect_pb.clicked.connect(self.connect) self.gen_chart = QChart() self.gen_chart.legend().hide() self.x_axis = QValueAxis() self.x_axis.setMax(500 * self.pulse_gen_display.display_T) self.x_axis.setMin(0) self.y_axis = QValueAxis() self.y_axis.setMax(3.3) self.y_axis.setMin(0) self.gen_chart.addAxis(self.x_axis, Qt.AlignBottom) self.gen_chart.addAxis(self.y_axis, Qt.AlignLeft) self.generator_screen.setChart(self.gen_chart) # display the initial pulse self.pulse_gen_display.calc_pulse() self.pulse_gen_display.get_display_data() self.series = QLineSeries() for i in range(500): self.series.append( i * self.pulse_gen_display.display_T, self.pulse_gen_display.display_data[i] * self.pulse_gen_display.calib) self.gen_chart.addSeries(self.series) self.series.attachAxis(self.x_axis) self.series.attachAxis(self.y_axis) self.display_pulse() self.pulse_height_timer = QTimer() self.pulse_height_timer.setSingleShot(True) self.pulse_height_timer.timeout.connect(self.pulse_height_ready) self.genRunning = False self.actionQuit.triggered.connect(self.quit) self.client_socket = QTcpSocket(self) self.connected = False self.show() def no_editing(self): self.pulse_height_text.setText(str( self.pulse_gen_display.pulse_height)) def avoid_wrapping(self, val): if val == QtWidgets.QAbstractSlider.SliderMove: minDistance = 1 if self.pulse_height_dial.value() == self.pulse_height_max \ and self.pulse_height_dial.sliderPosition()<self.pulse_height_max-minDistance: self.pulse_height_dial.setSliderPosition(self.pulse_height_max) elif self.pulse_height_dial.value() == self.pulse_height_min \ and self.pulse_height_dial.sliderPosition()>self.pulse_height_min+minDistance: self.pulse_height_dial.setSliderPosition(self.pulse_height_min) def pulse_shape_changed(self): ''' if self.genRunning: print("Current shape index: ",self.pulse_shape_combo.currentIndex()) print("current pulse form: ",self.pulse_gen_display.pulse_form) if self.pulse_shape_combo.currentIndex() == self.pulse_gen_display.pulse_form: return QMessageBox.warning(self, 'Pulse generation is active', 'Pulse generator is running\nPlease stop pulse generation before changing parameters') self.pulse_shape_combo.setCurrentIndex(self.pulse_gen_display.pulse_form) return ''' print("pulse shape changed") current_pulse_form = self.pulse_shape_combo.currentText() self.pulse_gen_display.pulse_form = self.pulse_gen_display.pulse_shape[ current_pulse_form] print("Current pulse form: " + current_pulse_form + " code: " + str(self.pulse_gen_display.pulse_form)) self.display_pulse() if not self.connected: return else: pulse_form_msg = "pulse_shape=" + str( self.pulse_gen_display.pulse_form) + "\n" print("Sending: " + pulse_form_msg) self.client_socket.write(bytes(pulse_form_msg, encoding="ascii")) self.client_socket.waitForReadyRead() responseMsg = self.client_socket.readAll() print("reponse msg: ", bytes(responseMsg).decode()) def pulse_freq_changed(self): new_freq = self.gen_freq_combo.currentText() self.pulse_gen_display.pulse_T = self.pulse_gen_display.frequencies[ new_freq] print("Pulse frequency changed to " + new_freq + "T: " + str(self.pulse_gen_display.pulse_T)) self.display_pulse() ''' if self.genRunning: if self.pulse_gen_display.frequencies[self.gen_freq_combo.currentText()] == self.pulse_gen_display.pulse_T: return QMessageBox.warning(self, 'Pulse generation is active', 'Pulse generator is running\nPlease stop pulse generation before changing parameters') index = 0 for freq in self.pulse_gen_display.frequencies.keys(): print("freq: ",freq) print("val: ",self.pulse_gen_display.frequencies[freq]) if self.pulse_gen_display.frequencies[freq] == self.pulse_gen_display.pulse_T: self.gen_freq_combo.setCurrentIndex(index) break index += 1 return ''' if not self.connected: return else: pulse_T_msg = "pulse_T=" + str( self.pulse_gen_display.pulse_T) + "\n" print("Sending: " + pulse_T_msg) self.client_socket.write(bytes(pulse_T_msg, encoding="ascii")) self.client_socket.waitForReadyRead() responseMsg = self.client_socket.readAll() print("reponse msg: ", bytes(responseMsg).decode()) def display_freq_changed(self): new_freq = self.display_freq_combo.currentText() self.pulse_gen_display.display_T = self.pulse_gen_display.frequencies[ new_freq] self.display_pulse() def pulse_height_changed(self): self.pulse_gen_display.pulse_height = self.pulse_height_dial.value() self.pulse_height_text.setText(str( self.pulse_gen_display.pulse_height)) self.display_pulse() self.pulse_height_timer.start(500) def pulse_height_ready(self): print("Timeout") if not self.connected: return else: pulse_height_msg = "pulse_height=" + str( self.pulse_gen_display.pulse_height) + "\n" print("Sending: " + pulse_height_msg) self.client_socket.write(bytes(pulse_height_msg, encoding="ascii")) self.client_socket.waitForReadyRead() responseMsg = self.client_socket.readAll() print("reponse msg: ", bytes(responseMsg).decode()) def connect(self): if self.connected: self.client_socket.close() self.connected = False self.connect_pb.setChecked(False) self.connect_pb.setText("Connect to Pulse Generator") return server_ip = str(self.server_ip_text.text()) port = self.GENERATOR_PORT print("Server IP: ", server_ip) if server_ip.find('xxx') != -1: print("bad IP") QMessageBox.about( self, 'Bad Server IP', 'Please give a correct Server IP\n' 'IP is ' + server_ip) self.connect_pb.setChecked(False) return else: print("Connecting to " + server_ip + ":", port) self.client_socket.connectToHost(server_ip, port) self.client_socket.waitForConnected(1000) if self.client_socket.state() != QTcpSocket.ConnectedState: QMessageBox.warning( self, 'Connection failed', 'Please check IP address and port number\nIs the server running?' ) self.connect_pb.setChecked(False) return print("Connection established") self.connect_pb.setText("Connected") self.client_socket.waitForReadyRead() connectMsg = self.client_socket.readAll() msgstring = bytes(connectMsg).decode() print("Connection message:" + msgstring) print("Send generator settings") pulse_form_msg = "pulse_shape=" + str( self.pulse_gen_display.pulse_form) + "\n" print("Sending: " + pulse_form_msg) self.client_socket.write(bytes(pulse_form_msg, encoding="ascii")) self.client_socket.waitForReadyRead() responseMsg = self.client_socket.readAll() print("reponse msg: ", bytes(responseMsg).decode()) pulse_T_msg = "pulse_T=" + str(self.pulse_gen_display.pulse_T) + "\n" print("Sending: " + pulse_T_msg) self.client_socket.write(bytes(pulse_T_msg, encoding="ascii")) self.client_socket.waitForReadyRead() responseMsg = self.client_socket.readAll() print("reponse msg: ", bytes(responseMsg).decode()) pulse_height_msg = "pulse_height=" + str( self.pulse_gen_display.pulse_height) + "\n" print("Sending: " + pulse_height_msg) self.client_socket.write(bytes(pulse_height_msg, encoding="ascii")) self.client_socket.waitForReadyRead() responseMsg = self.client_socket.readAll() print("reponse msg: ", bytes(responseMsg).decode()) running_msg = 'running?=\n' print("Sending: " + running_msg) self.client_socket.write(bytes(running_msg, encoding="ascii")) self.client_socket.waitForReadyRead() responseMsg = self.client_socket.readAll() response = bytes(responseMsg).decode() print("reponse msg: ", response) if response == 'yes\n': print("task is running") elif response == 'no\n': print("task is not running") else: print("Don't know if task is running") self.connected = True def start_stop_meas(self): if not self.connected: QMessageBox.about( self, 'You must be connected to the generator server\n' 'please connect and try again') return if self.start_stop_pb.isChecked(): print("Start generation") # send current generator settings self.start_stop_pb.setText("Stop Pulse Generation") msg = 'start=\n' print("Sending: " + msg) self.client_socket.write(msg.encode()) self.client_socket.waitForReadyRead() responseMsg = self.client_socket.readAll() print("reponse msg: ", bytes(responseMsg).decode()) self.genRunning = True else: print("Stop generation") self.start_stop_pb.setText("Start Pulse Generation") msg = 'stop=\n' self.client_socket.write(msg.encode()) self.client_socket.waitForReadyRead() responseMsg = self.client_socket.readAll() print("reponse msg: ", bytes(responseMsg).decode()) self.genRunning = False def readTrace(self): print("Message from the generator") data = self.server_socket.readAll() msgstring = bytes(data).decode() print(msgstring) print(data, type(data)) def display_pulse(self): self.pulse_gen_display.calc_pulse() self.pulse_gen_display.get_display_data() self.x_axis.setMax(500 * self.pulse_gen_display.display_T) data_points = self.series.pointsVector() for i in range(500): data_points[i].setX(i * self.pulse_gen_display.display_T) data_points[i].setY(self.pulse_gen_display.display_data[i] * self.pulse_gen_display.calib) self.series.replace(data_points) def quit(self): app.exit()