class TCPServer(QObject): def __init__(self, port): QObject.__init__(self) # logging instance self.log = logging.getLogger('SMIGOL.TCPServer.{0}'.format(port)) # TCP server to listen for control commands self.tcp_server = QTcpServer() # TCP server listenning port self.tcp_port = port # TCP socket connection self.tcp_connection = None def start(self): self.log.info("Starting TCP server...") if self.tcp_server.listen(port=self.tcp_port): txt = "Listening at http://localhost:{0} for a connection" self.log.info(txt.format(self.tcp_server.serverPort())) self.tcp_server.newConnection.connect(self._accept_connection) else: self.log.critical("Unable to start: {0}".format( self.tcp_server.errorString())) def disconnect(self): if self.tcp_connection and self.tcp_connection.state( ) == QTcpSocket.ConnectedState: loop = QEventLoop() self.tcp_connection.disconnected.connect(loop.quit) self.tcp_connection.disconnectFromHost() self.log.debug("Entering disconnect state...") if self.tcp_connection.state() == QTcpSocket.ConnectedState: loop.exec_() self.log.debug("Done waiting, closing server...") if self.tcp_server.isListening(): self.tcp_server.close() self.log.info("Server closed") def _accept_connection(self): if not self.tcp_connection: self.tcp_connection = self.tcp_server.nextPendingConnection() self.tcp_connection.error.connect(self._error_occurred) txt = "Accepted connection" self.log.debug(txt.format(self.tcp_server.serverPort())) else: self.log.warning("Received a second connection, ignoring it...") self.tcp_server.nextPendingConnection() def _error_occurred(self, socket_error): if socket_error == QTcpSocket.RemoteHostClosedError: self.log.info(self.tcp_connection.errorString()) else: self.log.error(self.tcp_connection.errorString())
class Dialog(QDialog): TotalBytes = 50 * 1024 * 1024 PayloadSize = 65536 def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.settings = QSettings('settings.ini', QSettings.IniFormat) self.tcpServer = QTcpServer() self.chBox = QCheckBox("Print log to window") self.text = QPlainTextEdit() self.serverStatusLabel = QLabel("Server ready") self.lblFileName = QLabel("Choose file before start!") self.saveButton = QPushButton("&Choose file...") self.startButton = QPushButton("&Start") self.stopButton = QPushButton("S&top") self.quitButton = QPushButton("&Quit") self.file = None self.tcpServerConnection = None self._lineCounter = 0 self._lineBuf = '' buttonBox = QDialogButtonBox() buttonBox.addButton(self.startButton, QDialogButtonBox.ActionRole) buttonBox.addButton(self.stopButton, QDialogButtonBox.RejectRole) buttonBox.addButton(self.quitButton, QDialogButtonBox.RejectRole) clearButon = QPushButton('&Clear') self.saveButton.clicked.connect(self.savedlg) self.startButton.clicked.connect(self.start) self.stopButton.clicked.connect(self.stopClicked) self.quitButton.clicked.connect(self.close) clearButon.clicked.connect(self.text.clear) self.tcpServer.newConnection.connect(self.acceptConnection) saveLayout = QHBoxLayout() saveLayout.addWidget(self.lblFileName) saveLayout.addStretch(1) saveLayout.addWidget(self.saveButton) topTextLayout = QHBoxLayout() topTextLayout.addWidget(self.chBox) topTextLayout.addStretch(1) topTextLayout.addWidget(clearButon) mainLayout = QVBoxLayout() mainLayout.addLayout(saveLayout) mainLayout.addLayout(topTextLayout) mainLayout.addWidget(self.text) mainLayout.addWidget(self.serverStatusLabel) # mainLayout.addStretch(1) mainLayout.addSpacing(10) mainLayout.addWidget(buttonBox) self.setLayout(mainLayout) self.title = "Simple Logger" self.ver = '1.0' self.setWindowIcon(QIcon('./icon.png')) self.setWindowTitle("{} {}".format(self.title, self.ver)) def start(self): if self.file is None: QMessageBox.critical(self, self.title, "Unable open log file.\nPlease, select another file.") return self.startButton.setEnabled(False) while not self.tcpServer.isListening() and not self.tcpServer.listen(port=9112): ret = QMessageBox.critical(self, self.title, "Unable to start the test: %s." % self.tcpServer.errorString(), QMessageBox.Retry | QMessageBox.Cancel) if ret == QMessageBox.Cancel: return self.serverStatusLabel.setText("Waiting connection ...") def acceptConnection(self): self.tcpServerConnection = self.tcpServer.nextPendingConnection() self.tcpServerConnection.readyRead.connect(self.updateLog) self.tcpServerConnection.error.connect(self.displayError) self.file = QFile(self.filename) if not self.file.open(QFile.Append): QMessageBox.warning(self, self.title, "Unable to write file {}:\n{}.".format(self.filename, self.file.errorString())) self.file = None return self.textStream = QTextStream(self.file) self.textStream.setCodec('UTF-8') self.serverStatusLabel.setText("Logging ...") self.tcpServer.close() def savedlg(self): self.filename = QFileDialog.getSaveFileName(self, "Log Filename", self.settings.value('directories/dir_save', QDir.currentPath()), "Text (*.log *.txt);;All (*)") if not self.filename: return self.file = QFile(self.filename) self.lblFileName.setText(self.filename) if not self.file.open(QFile.WriteOnly): QMessageBox.warning(self, self.title, "Unable to write file {}:\n{}.".format(self.filename, self.file.errorString())) self.file = None return self.textStream = QTextStream(self.file) self.textStream.setCodec('UTF-8') self.settings.setValue('directories/dir_save', QFileInfo(self.file).path()) self.file.close() def updateLog(self): if self.tcpServerConnection.bytesAvailable(): data = self.tcpServerConnection.readAll() line = "{}".format(str(data.data().decode())) if self.chBox.isChecked(): self._lineCounter += 1 self._lineBuf += line if self._lineCounter > 10: self.text.appendPlainText(self._lineBuf) self._lineCounter = 0 self._lineBuf = '' self.textStream << line self.file.flush() # self.serverStatusLabel.setText(line) def closeEvent(self, event): if self.file is not None: self.file.flush() self.file.close() def stopClicked(self): if self.tcpServerConnection is not None: self.tcpServerConnection.close() self.file.close() self.startButton.setEnabled(True) self.serverStatusLabel.setText("Logger ready") def displayError(self, socketError): if socketError == QTcpSocket.RemoteHostClosedError: return QMessageBox.information(self, "Network error", "The following error occured: %s." % self.tcpServer.errorString()) self.tcpServer.close() self.file.close() self.serverStatusLabel.setText("Logger ready") self.startButton.setEnabled(True)
class ControlServer(QObject): # Signal to inform that the set logging level command has been received logging_command_received = pyqtSignal(int) # Signal to inform that the quit command has been received and the system should exit quit_command_received = pyqtSignal() def __init__(self): QObject.__init__(self) # logging instance self.log = logging.getLogger('GDAIS.ControlServer') # TCP server to listen for control commands self.tcp_server = QTcpServer() # regexp to check if command is 'set_log_level' self.valid_loglevel = re.compile(r"^set_log_level (\d?0)$") def start(self): self.log.info("Starting TCP server...") if self.tcp_server.listen(port=12345): txt = "Listening at http://localhost:{0} for commands" self.log.info(txt.format(self.tcp_server.serverPort())) self.tcp_server.newConnection.connect(self._accept_connection) else: self.log.warn("Unable to start: {0}".format( self.tcp_server.errorString())) # define a timer to auto-quit the app after 10 sec timeout = 10 # seconds self.log.warn( "GDAIS will run for {0} seconds and then die".format(timeout)) self.timer = QTimer() self.timer.timeout.connect(self.quit) self.timer.start(timeout * 1000) # msec def quit(self): if self.tcp_connection and self.tcp_connection.state( ) == QTcpSocket.ConnectedState: loop = QEventLoop() self.tcp_connection.disconnected.connect(loop.quit) self.tcp_connection.disconnectFromHost() self.log.debug("Entering disconnect state...") if self.tcp_connection.state() == QTcpSocket.ConnectedState: loop.exec_() self.log.debug("Done waiting, closing server...") if self.tcp_server.isListening(): self.tcp_server.close() self.quit_command_received.emit() def _accept_connection(self): self.tcp_connection = self.tcp_server.nextPendingConnection() self.tcp_connection.readyRead.connect(self._read_data) self.tcp_connection.error.connect(self._error_ocurred) self.log.debug("Accepted connection") def _read_data(self): tcp_data = self.tcp_connection.readAll() if tcp_data == 'quit': self.log.info("Received 'quit' command") self.quit() elif self.valid_loglevel.match(tcp_data): self.log.info("Received 'set_log_level' command") try: new_level = int(self.valid_loglevel.match(tcp_data).group(1)) except ValueError: self.log.exception("Level has to be an integer value") else: self.logging_command_received.emit(new_level) else: self.log.error("Received unknown command: {0}".format(tcp_data)) def _error_ocurred(self, socket_error): if socket_error == QTcpSocket.RemoteHostClosedError: self.log.info(self.tcp_connection.errorString()) else: self.log.error(self.tcp_connection.errorString())
class Dialog(QDialog): TotalBytes = 50 * 1024 * 1024 PayloadSize = 65536 def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.settings = QSettings('settings.ini', QSettings.IniFormat) self.tcpServer = QTcpServer() self.chBox = QCheckBox("Print log to window") self.text = QPlainTextEdit() self.serverStatusLabel = QLabel("Server ready") self.lblFileName = QLabel("Choose file before start!") self.saveButton = QPushButton("&Choose file...") self.startButton = QPushButton("&Start") self.stopButton = QPushButton("S&top") self.quitButton = QPushButton("&Quit") self.file = None self.tcpServerConnection = None self._lineCounter = 0 self._lineBuf = '' buttonBox = QDialogButtonBox() buttonBox.addButton(self.startButton, QDialogButtonBox.ActionRole) buttonBox.addButton(self.stopButton, QDialogButtonBox.RejectRole) buttonBox.addButton(self.quitButton, QDialogButtonBox.RejectRole) clearButon = QPushButton('&Clear') self.saveButton.clicked.connect(self.savedlg) self.startButton.clicked.connect(self.start) self.stopButton.clicked.connect(self.stopClicked) self.quitButton.clicked.connect(self.close) clearButon.clicked.connect(self.text.clear) self.tcpServer.newConnection.connect(self.acceptConnection) saveLayout = QHBoxLayout() saveLayout.addWidget(self.lblFileName) saveLayout.addStretch(1) saveLayout.addWidget(self.saveButton) topTextLayout = QHBoxLayout() topTextLayout.addWidget(self.chBox) topTextLayout.addStretch(1) topTextLayout.addWidget(clearButon) mainLayout = QVBoxLayout() mainLayout.addLayout(saveLayout) mainLayout.addLayout(topTextLayout) mainLayout.addWidget(self.text) mainLayout.addWidget(self.serverStatusLabel) # mainLayout.addStretch(1) mainLayout.addSpacing(10) mainLayout.addWidget(buttonBox) self.setLayout(mainLayout) self.title = "Simple Logger" self.ver = '1.0' self.setWindowIcon(QIcon('./icon.png')) self.setWindowTitle("{} {}".format(self.title, self.ver)) def start(self): if self.file is None: QMessageBox.critical( self, self.title, "Unable open log file.\nPlease, select another file.") return self.startButton.setEnabled(False) while not self.tcpServer.isListening() and not self.tcpServer.listen( port=9112): ret = QMessageBox.critical( self, self.title, "Unable to start the test: %s." % self.tcpServer.errorString(), QMessageBox.Retry | QMessageBox.Cancel) if ret == QMessageBox.Cancel: return self.serverStatusLabel.setText("Waiting connection ...") def acceptConnection(self): self.tcpServerConnection = self.tcpServer.nextPendingConnection() self.tcpServerConnection.readyRead.connect(self.updateLog) self.tcpServerConnection.error.connect(self.displayError) self.file = QFile(self.filename) if not self.file.open(QFile.Append): QMessageBox.warning( self, self.title, "Unable to write file {}:\n{}.".format( self.filename, self.file.errorString())) self.file = None return self.textStream = QTextStream(self.file) self.textStream.setCodec('UTF-8') self.serverStatusLabel.setText("Logging ...") self.tcpServer.close() def savedlg(self): self.filename = QFileDialog.getSaveFileName( self, "Log Filename", self.settings.value('directories/dir_save', QDir.currentPath()), "Text (*.log *.txt);;All (*)") if not self.filename: return self.file = QFile(self.filename) self.lblFileName.setText(self.filename) if not self.file.open(QFile.WriteOnly): QMessageBox.warning( self, self.title, "Unable to write file {}:\n{}.".format( self.filename, self.file.errorString())) self.file = None return self.textStream = QTextStream(self.file) self.textStream.setCodec('UTF-8') self.settings.setValue('directories/dir_save', QFileInfo(self.file).path()) self.file.close() def updateLog(self): if self.tcpServerConnection.bytesAvailable(): data = self.tcpServerConnection.readAll() line = "{}".format(str(data.data().decode())) if self.chBox.isChecked(): self._lineCounter += 1 self._lineBuf += line if self._lineCounter > 10: self.text.appendPlainText(self._lineBuf) self._lineCounter = 0 self._lineBuf = '' self.textStream << line self.file.flush() # self.serverStatusLabel.setText(line) def closeEvent(self, event): if self.file is not None: self.file.flush() self.file.close() def stopClicked(self): if self.tcpServerConnection is not None: self.tcpServerConnection.close() self.file.close() self.startButton.setEnabled(True) self.serverStatusLabel.setText("Logger ready") def displayError(self, socketError): if socketError == QTcpSocket.RemoteHostClosedError: return QMessageBox.information( self, "Network error", "The following error occured: %s." % self.tcpServer.errorString()) self.tcpServer.close() self.file.close() self.serverStatusLabel.setText("Logger ready") self.startButton.setEnabled(True)