from PySide2.QtCore import Qt, SIGNAL, QProcess, QByteArray from PySide2.QtWidgets import QDialog, QGridLayout, QTextEdit, QLineEdit, QCompleter from pygments import highlight from pygments.formatters.html import HtmlFormatter from pygments.lexers.data import JsonLexer from node_launcher.logging import log class ConsoleDialog(QDialog): def __init__(self, node): super().__init__() self.node = node self.show_help = True self.layout = QGridLayout() self.setLayout(self.layout) self.output_area = QTextEdit() self.output_area.setReadOnly(True) self.output_area.acceptRichText = True self.output_area.document().setMaximumBlockCount(5000) self.layout.addWidget(self.output_area) self.input_area = QLineEdit() self.completer = QCompleter() # noinspection PyUnresolvedReferences self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.input_area.setCompleter(self.completer) self.input_area.setFocus() self.layout.addWidget(self.input_area) self.connect(self.input_area, SIGNAL("returnPressed(void)"), self.execute_user_command) @property def cli(self): try: return self.node.software.cli except AttributeError: return None @property def cli_args(self): try: return self.node.configuration.cli_args except AttributeError: return None def showEvent(self, event): super().showEvent(event) if self.show_help: success = self.run_command('help') if success: self.show_help = False def execute_user_command(self): cmd = str(self.input_area.text()) self.input_area.clear() self.run_command(cmd) def run_command(self, command): try: if self.cli is None or self.cli_args is None: self.output_area.append('Node starting up, please try again later...') return False self.output_area.append(f'> {command}\n') process = QProcess() process.setProgram(self.cli) process.setCurrentReadChannel(0) # noinspection PyUnresolvedReferences process.readyReadStandardError.connect( lambda: self.handle_cli_error_output(process) ) # noinspection PyUnresolvedReferences process.readyReadStandardOutput.connect( lambda: self.handle_cli_output(process) ) args = command.split(' ') if args[0] == self.cli.split('/')[-1]: args.pop(0) process.setArguments(self.cli_args + args) process.start() log.info( 'run_command', program=self.cli, args=self.cli_args, cmd=command ) return True except Exception: self.output_area.append('Node starting up, please try again later...') return False def handle_cli_error_output(self, cli_process: QProcess): output: QByteArray = cli_process.readAllStandardError() message = output.data().decode('utf-8').strip() self.output_area.append(message) def handle_cli_output(self, cli_process: QProcess): output: QByteArray = cli_process.readAllStandardOutput() message = output.data().decode('utf-8').strip() if message.startswith('{') or message.startswith('['): formatter = HtmlFormatter() formatter.noclasses = True formatter.linenos = False formatter.nobackground = True message = highlight(message, JsonLexer(), formatter) self.output_area.insertHtml(message) else: self.output_area.append(message)