def includedFiles(self): ''' Returns all included files in the document. ''' result = [] b = self.document().begin() while b != self.document().end(): text = b.text() index = self.index(text) if index > -1: startIndex = text.find('"', index) if startIndex > -1: endIndex = text.find('"', startIndex + 1) fileName = text[startIndex + 1:endIndex] if len(fileName) > 0: try: path = interpret_path(fileName) f = QFile(path) ext = os.path.splitext(path) if f.exists() and ext[1] in nm.settings().SEARCH_IN_EXT: result.append(path) except: import traceback print traceback.format_exc(1) b = b.next() return result
def includedFiles(self): ''' Returns all included files in the document. ''' result = [] b = self.document().begin() while b != self.document().end(): text = b.text() index = self.index(text) if index > -1: startIndex = text.find('"', index) if startIndex > -1: endIndex = text.find('"', startIndex + 1) fileName = text[startIndex + 1:endIndex] if len(fileName) > 0: try: path = interpret_path(fileName) f = QFile(path) ext = os.path.splitext(path) if f.exists() and ext[1] in nm.settings( ).SEARCH_IN_EXT: result.append(path) except: import traceback print traceback.format_exc(1) b = b.next() return result
def focusInEvent(self, event): # check for file changes try: if self.filename and self.file_info: if self.file_info.lastModified() != QFileInfo( self.filename).lastModified(): self.file_info = QFileInfo(self.filename) result = MessageBox.question(self, "File changed", "File was changed, reload?", buttons=MessageBox.Yes | MessageBox.No) if result == MessageBox.Yes: f = QFile(self.filename) if f.open(QIODevice.ReadOnly | QIODevice.Text): self.setText(unicode(f.readAll(), "utf-8")) self.document().setModified(False) self.textChanged.emit() else: MessageBox.critical( self, "Error", "Cannot open launch file%s" % self.filename) except: pass QTextEdit.focusInEvent(self, event)
def _connect(self, masteruri, screen_name, nodename, user=None): self._masteruri = masteruri if self.qfile is not None and self.qfile.isOpen(): self.qfile.close() self.clear_signal.emit() host = get_hostname(masteruri) if nm.is_local(host): self._nodename = nodename if screen_name: screen_log = screen.get_logfile(node=nodename) else: screen_log = screen.get_ros_logfile(node=nodename) self.qfile = QFile(screen_log) self.setWindowTitle(nodename) if self.qfile.open(QIODevice.ReadOnly): self._first_fill = True self.qfile.seek(self.qfile.size() - 1) # self.lread() self._info = "END" self.thread = threading.Thread(target=self._read_log, kwargs={"filename": screen_log}) self.thread.setDaemon(True) self.thread.start() else: self._valid = False else: self._connect_ssh(host, nodename, user) self.logger_handler = LoggerHandler( nodename, masteruri=masteruri, layout=self.scrollAreaWidgetContents.layout()) self.logger_handler.update() return False
def _included_files(self, path): ''' Returns all included files in the given file. ''' result = [] with open(path, 'r') as f: data = f.read() reg = QRegExp("=[\s\t]*\".*\"") reg.setMinimal(True) pos = reg.indexIn(data) while pos != -1 and self._isrunning: try: pp = interpret_path(reg.cap(0).strip('"')) f = QFile(pp) ext = os.path.splitext(pp) if f.exists() and ext[1] in nm.settings().SEARCH_IN_EXT: result.append(pp) except Exception as exp: parsed_text = pp try: parsed_text = reg.cap(0).strip('"') except: pass self.warning_signal.emit("Error while parse '%s': %s" % (parsed_text, exp)) pos += reg.matchedLength() pos = reg.indexIn(data, pos) return result
def included_files(cls, text_or_path, regexp_retruns=[], regexp_filelist=[QRegExp("\\btextfile\\b"), QRegExp("\\bfile\\b"), QRegExp("\\bdefault\\b"), QRegExp("\\bvalue=.*pkg:\/\/\\b"), QRegExp("\\bvalue=.*package:\/\/\\b"), QRegExp("\\bvalue=.*\$\(find\\b"), QRegExp("\\bargs=.*\$\(find\\b")], recursive=True, unique=True): ''' :param regexp_retruns: the list with patterns which are returned as result. If empy it's the same as 'regexp_filelist' :param regexp_filelist: the list with all patterns to find include files ''' result = [] lines = [] pwd = '.' f = QFile(text_or_path) if f.exists(): pwd = os.path.dirname(text_or_path) with open(text_or_path, 'r') as f: content = f.read() # remove the comments comment_pattern = QRegExp("<!--.*?-->") pos = comment_pattern.indexIn(content) while pos != -1: content = content[:pos] + content[pos + comment_pattern.matchedLength():] pos = comment_pattern.indexIn(content) lines = content.splitlines() else: lines = [text_or_path] line_index = 0 for line in lines: index = cls._index(line, regexp_filelist) if index > -1: startIndex = line.find('"', index) if startIndex > -1: endIndex = line.find('"', startIndex + 1) fileName = line[startIndex + 1:endIndex] if len(fileName) > 0: try: path = cls.interpretPath(fileName, pwd) if os.path.isfile(path): if not regexp_retruns or cls._index(line, regexp_retruns) > -1: if not unique: result.append((line_index, path)) else: result.append(path) ext = os.path.splitext(path) if recursive and ext[1] in nm.settings().SEARCH_IN_EXT: result += cls.included_files(path, regexp_retruns, regexp_filelist) except Exception: import traceback print traceback.format_exc() line_index += 1 if unique: return list(set(result)) return result
def included_files(cls, text_or_path, regexp_list=[QRegExp("\\btextfile\\b"), QRegExp("\\bfile\\b"), QRegExp("\\bdefault\\b"), QRegExp("\\bvalue=.*pkg:\/\/\\b"), QRegExp("\\bvalue=.*package:\/\/\\b"), QRegExp("\\bvalue=.*\$\(find\\b"), QRegExp("\\bargs=.*\$\(find\\b")], recursive=True, unique=True): result = [] lines = [] pwd = '.' f = QFile(text_or_path) if f.exists(): pwd = os.path.dirname(text_or_path) with open(text_or_path, 'r') as f: content = f.read() # remove the comments comment_pattern = QRegExp("<!--.*?-->") pos = comment_pattern.indexIn(content) while pos != -1: content = content[:pos] + content[pos + comment_pattern.matchedLength():] pos = comment_pattern.indexIn(content) lines = content.splitlines() else: lines = [text_or_path] line_index = 0 for line in lines: index = cls._index(line, regexp_list) if index > -1: startIndex = line.find('"', index) if startIndex > -1: endIndex = line.find('"', startIndex + 1) fileName = line[startIndex + 1:endIndex] if len(fileName) > 0: try: path = cls.interpretPath(fileName, pwd) if os.path.isfile(path): if not unique: result.append((line_index, path)) else: result.append(path) ext = os.path.splitext(path) if recursive and ext[1] in nm.settings().SEARCH_IN_EXT: result += cls.included_files(path, regexp_list) except Exception: import traceback print traceback.format_exc() line_index += 1 if unique: return list(set(result)) return result
def __init__(self, filename, parent=None): self.parent = parent QTextEdit.__init__(self, parent) self.setObjectName(' - '.join(['Editor', filename])) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_custom_context_menu) # self.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.setAcceptRichText(False) font = QFont() font.setFamily("Fixed".decode("utf-8")) font.setPointSize(12) self.setFont(font) self.setLineWrapMode(QTextEdit.NoWrap) self.setTabStopWidth(25) self.setAcceptRichText(False) self.setCursorWidth(2) self.setFontFamily("courier new") self.setProperty("backgroundVisible", True) self.regexp_list = [ QRegExp("\\binclude\\b"), QRegExp("\\btextfile\\b"), QRegExp("\\bfile\\b"), QRegExp("\\bvalue=.*pkg:\/\/\\b"), QRegExp("\\bvalue=.*package:\/\/\\b"), QRegExp("\\bvalue=.*\$\(find\\b"), QRegExp("\\bargs=.*\$\(find\\b"), QRegExp("\\bdefault=.*\$\(find\\b") ] self.filename = filename self.file_info = None if self.filename: f = QFile(filename) if f.open(QIODevice.ReadOnly | QIODevice.Text): self.file_info = QFileInfo(filename) self.setText(unicode(f.readAll(), "utf-8")) self.path = '.' # enables drop events self.setAcceptDrops(True) if filename.endswith('.launch'): self.hl = XmlHighlighter(self.document()) self.cursorPositionChanged.connect(self._document_position_changed) else: self.hl = YamlHighlighter(self.document()) # variables for threaded search self._search_thread = None self._stop = False
def mouseReleaseEvent(self, event): ''' Opens the new editor, if the user clicked on the included file and sets the default cursor. ''' if event.modifiers() == Qt.ControlModifier or event.modifiers() == Qt.ShiftModifier: cursor = self.cursorForPosition(event.pos()) index = self.index(cursor.block().text()) if index > -1: startIndex = cursor.block().text().find('"', index) if startIndex > -1: endIndex = cursor.block().text().find('"', startIndex + 1) fileName = cursor.block().text()[startIndex + 1:endIndex] if len(fileName) > 0: try: qf = QFile(interpret_path(fileName)) if not qf.exists(): # create a new file, if it does not exists result = QMessageBox.question(self, "File not found", '\n\n'.join(["Create a new file?", qf.fileName()]), QMessageBox.Yes | QMessageBox.No) if result == QMessageBox.Yes: d = os.path.dirname(qf.fileName()) if not os.path.exists(d): os.makedirs(d) with open(qf.fileName(), 'w') as f: if qf.fileName().endswith('.launch'): f.write('<launch>\n\n</launch>') event.setAccepted(True) self.load_request_signal.emit(qf.fileName()) else: event.setAccepted(True) self.load_request_signal.emit(qf.fileName()) except Exception, e: WarningMessageBox(QMessageBox.Warning, "File not found %s" % fileName, str(e)).exec_()
def mouseReleaseEvent(self, event): ''' Opens the new editor, if the user clicked on the included file and sets the default cursor. ''' if event.modifiers() == Qt.ControlModifier or event.modifiers() == Qt.ShiftModifier: cursor = self.cursorForPosition(event.pos()) inc_files = LaunchConfig.included_files(cursor.block().text(), recursive=False) if inc_files: try: qf = QFile(inc_files[0]) if not qf.exists(): # create a new file, if it does not exists result = MessageBox.question(self, "File not found", '\n\n'.join(["Create a new file?", qf.fileName()]), buttons=MessageBox.Yes | MessageBox.No) if result == MessageBox.Yes: d = os.path.dirname(qf.fileName()) if not os.path.exists(d): os.makedirs(d) with open(qf.fileName(), 'w') as f: if qf.fileName().endswith('.launch'): f.write('<launch>\n\n</launch>') event.setAccepted(True) self.load_request_signal.emit(qf.fileName()) else: event.setAccepted(True) self.load_request_signal.emit(qf.fileName()) except Exception, e: MessageBox.critical(self, "Error", "File not found %s" % inc_files[0], detailed_text=utf8(e))
def focusInEvent(self, event): # check for file changes try: if self.filename and self.file_info: if self.file_info.lastModified() != QFileInfo(self.filename).lastModified(): self.file_info = QFileInfo(self.filename) result = MessageBox.question(self, "File changed", "File was changed, reload?", buttons=MessageBox.Yes | MessageBox.No) if result == MessageBox.Yes: f = QFile(self.filename) if f.open(QIODevice.ReadOnly | QIODevice.Text): self.setText(unicode(f.readAll(), "utf-8")) self.document().setModified(False) self.textChanged.emit() else: MessageBox.critical(self, "Error", "Cannot open launch file%s" % self.filename) except: pass QTextEdit.focusInEvent(self, event)
def __init__(self, filename, parent=None): self.parent = parent QTextEdit.__init__(self, parent) self.setObjectName(' - '.join(['Editor', filename])) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_custom_context_menu) # self.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.setAcceptRichText(False) font = QFont() font.setFamily("Fixed".decode("utf-8")) font.setPointSize(12) self.setFont(font) self.setLineWrapMode(QTextEdit.NoWrap) self.setTabStopWidth(25) self.setAcceptRichText(False) self.setCursorWidth(2) self.setFontFamily("courier new") self.setProperty("backgroundVisible", True) self.regexp_list = [QRegExp("\\binclude\\b"), QRegExp("\\btextfile\\b"), QRegExp("\\bfile\\b"), QRegExp("\\bvalue=.*pkg:\/\/\\b"), QRegExp("\\bvalue=.*package:\/\/\\b"), QRegExp("\\bvalue=.*\$\(find\\b"), QRegExp("\\bargs=.*\$\(find\\b"), QRegExp("\\bdefault=.*\$\(find\\b")] self.filename = filename self.file_info = None if self.filename: f = QFile(filename) if f.open(QIODevice.ReadOnly | QIODevice.Text): self.file_info = QFileInfo(filename) self.setText(unicode(f.readAll(), "utf-8")) self.path = '.' # enables drop events self.setAcceptDrops(True) if filename.endswith('.launch'): self.hl = XmlHighlighter(self.document()) self.cursorPositionChanged.connect(self._document_position_changed) else: self.hl = YamlHighlighter(self.document()) # variables for threaded search self._search_thread = None self._stop = False
def _save_dot(self): file_name, _ = QFileDialog.getSaveFileName(self._widget, self.tr('Save as DOT'), 'rosgraph.dot', self.tr('DOT graph (*.dot)')) if file_name is None or file_name == '': return handle = QFile(file_name) if not handle.open(QIODevice.WriteOnly | QIODevice.Text): return handle.write(self._current_dotcode) handle.close()
def save(self, force=False): ''' Saves changes to the file. :return: saved, errors, msg :rtype: bool, bool, str ''' if force or self.document().isModified() or not QFileInfo( self.filename).exists(): f = QFile(self.filename) if f.open(QIODevice.WriteOnly | QIODevice.Text): f.write(self.toPlainText().encode('utf-8')) self.document().setModified(False) self.file_info = QFileInfo(self.filename) ext = os.path.splitext(self.filename) # validate the xml structure of the launch files if ext[1] in self.CONTEXT_FILE_EXT: imported = False try: from lxml import etree imported = True parser = etree.XMLParser() etree.fromstring(self.toPlainText().encode('utf-8'), parser) except Exception as e: if imported: self.markLine(e.position[0]) return True, True, "%s" % e # validate the yaml structure of yaml files elif ext[1] in self.YAML_VALIDATION_FILES: try: import yaml yaml.load(self.toPlainText().encode('utf-8')) except yaml.MarkedYAMLError as e: return True, True, "%s" % e return True, False, '' else: return False, True, "Cannot write XML file" return False, False, ''
def save(self, force=False): ''' Saves changes to the file. :return: saved, errors, msg :rtype: bool, bool, str ''' if force or self.document().isModified() or not QFileInfo(self.filename).exists(): f = QFile(self.filename) if f.open(QIODevice.WriteOnly | QIODevice.Text): f.write(self.toPlainText().encode('utf-8')) self.document().setModified(False) self.file_info = QFileInfo(self.filename) ext = os.path.splitext(self.filename) # validate the xml structure of the launch files if ext[1] in self.CONTEXT_FILE_EXT: imported = False try: from lxml import etree imported = True parser = etree.XMLParser() etree.fromstring(self.toPlainText().encode('utf-8'), parser) except Exception as e: if imported: self.markLine(e.position[0]) return True, True, "%s" % e # validate the yaml structure of yaml files elif ext[1] in self.YAML_VALIDATION_FILES: try: import yaml yaml.load(self.toPlainText().encode('utf-8')) except yaml.MarkedYAMLError as e: return True, True, "%s" % e return True, False, '' else: return False, True, "Cannot write XML file" return False, False, ''
def mouseReleaseEvent(self, event): ''' Opens the new editor, if the user clicked on the included file and sets the default cursor. ''' if event.modifiers() == Qt.ControlModifier or event.modifiers( ) == Qt.ShiftModifier: cursor = self.cursorForPosition(event.pos()) index = self.index(cursor.block().text()) if index > -1: startIndex = cursor.block().text().find('"', index) if startIndex > -1: endIndex = cursor.block().text().find('"', startIndex + 1) fileName = cursor.block().text()[startIndex + 1:endIndex] if len(fileName) > 0: try: qf = QFile(interpret_path(fileName)) if not qf.exists(): # create a new file, if it does not exists result = QMessageBox.question( self, "File not found", '\n\n'.join( ["Create a new file?", qf.fileName()]), QMessageBox.Yes | QMessageBox.No) if result == QMessageBox.Yes: d = os.path.dirname(qf.fileName()) if not os.path.exists(d): os.makedirs(d) with open(qf.fileName(), 'w') as f: if qf.fileName().endswith('.launch'): f.write('<launch>\n\n</launch>') event.setAccepted(True) self.load_request_signal.emit( qf.fileName()) else: event.setAccepted(True) self.load_request_signal.emit(qf.fileName()) except Exception, e: WarningMessageBox(QMessageBox.Warning, "File not found %s" % fileName, str(e)).exec_()
def _save_dot(self): file_name, _ = QFileDialog.getSaveFileName(self._widget, self.tr('Save as DOT'), 'rospackgraph.dot', self.tr('DOT graph (*.dot)')) if file_name is None or file_name == '': return handle = QFile(file_name) if not handle.open(QIODevice.WriteOnly | QIODevice.Text): return handle.write(self._current_dotcode) handle.close()
def mouseReleaseEvent(self, event): ''' Opens the new editor, if the user clicked on the included file and sets the default cursor. ''' if event.modifiers() == Qt.ControlModifier or event.modifiers( ) == Qt.ShiftModifier: cursor = self.cursorForPosition(event.pos()) inc_files = LaunchConfig.included_files(cursor.block().text(), recursive=False) if inc_files: try: qf = QFile(inc_files[0]) if not qf.exists(): # create a new file, if it does not exists result = MessageBox.question( self, "File not found", '\n\n'.join(["Create a new file?", qf.fileName()]), buttons=MessageBox.Yes | MessageBox.No) if result == MessageBox.Yes: d = os.path.dirname(qf.fileName()) if not os.path.exists(d): os.makedirs(d) with open(qf.fileName(), 'w') as f: if qf.fileName().endswith('.launch'): f.write('<launch>\n\n</launch>') event.setAccepted(True) self.load_request_signal.emit(qf.fileName()) else: event.setAccepted(True) self.load_request_signal.emit(qf.fileName()) except Exception, e: MessageBox.critical(self, "Error", "File not found %s" % inc_files[0], detailed_text=utf8(e))
class ScreenWidget(QWidget): ''' Shows the output of a screen. ''' clear_signal = Signal() cleared_signal = Signal() output = Signal(str) output_prefix = Signal(str) error_signal = Signal(str) auth_signal = Signal(str, str, str) # host, nodename, user def __init__(self, masteruri, screen_name, nodename, user=None, parent=None): ''' Creates the window, connects the signals and init the class. ''' QWidget.__init__(self, parent) # load the UI file screen_dock_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'ui', 'logscreen', 'ScreenWidget.ui') loadUi(screen_dock_file, self) self.setObjectName("ScreenWidget") self.setWindowIcon(nm.settings().icon('crystal_clear_show_io.png')) # self.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetClosable) self.pauseButton.setIcon(nm.settings().icon('sekkyumu_pause.png')) self._valid = True self._lock = threading.RLock() self.finished = False self.qfile = None self.thread = None self._info = '' self._masteruri = '' self._nodename = '' self._first_fill = True self._seek_start = -1 self._seek_end = -1 self._pause_read_end = False self._ssh_output_file = None self._ssh_error_file = None self._ssh_input_file = None self._on_pause = False self._char_format_end = None self.loggers.setVisible(False) self.loglevelButton.toggled.connect(self.on_toggle_loggers) self.logger_handler = None # connect to the button signals self.output.connect(self._on_output) self.output_prefix.connect(self._on_output_prefix) self.error_signal.connect(self._on_error) self.auth_signal.connect(self.on_request_pw) self.clearCloseButton.clicked.connect(self.clear) # self.pauseButton.clicked.connect(self.stop) self.pauseButton.toggled.connect(self.pause) self.clear_signal.connect(self.clear) self.textBrowser.verticalScrollBar().valueChanged.connect( self.on_scrollbar_position_changed) self.textBrowser.verticalScrollBar().rangeChanged.connect( self.on_scrollbar_range_changed) self.textBrowser.set_reader(self) self.tf = TerminalFormats() self.hl = ScreenHighlighter(self.textBrowser.document()) self.searchFrame.setVisible(False) self.grepFrame.setVisible(False) self.grepLineEdit.textChanged.connect(self.on_grep_changed) self._shortcut_search = QShortcut( QKeySequence(self.tr("Ctrl+F", "Activate search")), self) self._shortcut_search.activated.connect(self.on_search) self._shortcut_grep = QShortcut( QKeySequence(self.tr("Ctrl+G", "Activate grep")), self) self._shortcut_grep.activated.connect(self.on_grep) self.searchLineEdit.editingFinished.connect(self.on_search_prev) self.searchNextButton.clicked.connect(self.on_search_next) self.searchPrevButton.clicked.connect(self.on_search_prev) # self.visibilityChanged.connect(self.stop) self._connect(masteruri, screen_name, nodename, user) def masteruri(self): return self._masteruri def name(self): return self._nodename def clear(self): ''' Removes all messages and emit the `cleared_signal`. ''' self.textBrowser.clear() self.infoLabel.setText('') self.cleared_signal.emit() def finish(self): self.finished = True self.output.disconnect() self.output_prefix.disconnect() self.close() def closeEvent(self, event): self.stop() QWidget.closeEvent(self, event) def hide(self): self.stop() QWidget.hide(self) def close(self): self.stop() QWidget.close(self) def on_search(self): self.searchFrame.setVisible(not self.searchFrame.isVisible()) if self.searchFrame.isVisible(): self.searchLineEdit.setFocus() self.searchLineEdit.selectAll() else: cursor = self.textBrowser.textCursor() cursor.clearSelection() self.textBrowser.setTextCursor(cursor) self.textBrowser.setFocus() def on_search_next(self): self._perform_search(forward=True) def on_search_prev(self): self._perform_search(forward=False) def _perform_search(self, forward=False): search_str = self.searchLineEdit.text() if search_str: cursor = self.textBrowser.textCursor() if forward: search_result = self.textBrowser.document().find( search_str, cursor) else: search_result = self.textBrowser.document().find( search_str, cursor, QTextDocument.FindBackward) if search_result.position() > -1: self.textBrowser.setTextCursor(search_result) self.searchLabel.setText('') # self.searchLabel.setText('%d' % search_result.position()) else: self.searchLabel.setText('no results') else: self.searchLabel.setText('') def on_grep(self): self.grepFrame.setVisible(not self.grepFrame.isVisible()) if self.grepFrame.isVisible(): self.grepLineEdit.setFocus() self.on_grep_changed(self.grepLineEdit.text()) self.hl.set_grep_text('') self.grepLineEdit.selectAll() else: self.on_grep_changed('') self.textBrowser.setFocus() def on_grep_changed(self, text): self.hl.set_grep_text(text) def stop(self): ''' ''' if self.qfile is not None and self.qfile.isOpen(): self.qfile.close() self.qfile = None self._seek_start = -1 self._seek_end = -1 self._pause_read_end = False # self.clear() try: self._ssh_output_file.close() self._ssh_error_file.close() # send Ctrl+C to remote process self._ssh_input_file.write('%s\n' % chr(3)) self._ssh_input_file.close() except Exception: pass def pause(self, state): self._on_pause = state def valid(self): return self._valid def _connect(self, masteruri, screen_name, nodename, user=None): self._masteruri = masteruri if self.qfile is not None and self.qfile.isOpen(): self.qfile.close() self.clear_signal.emit() host = get_hostname(masteruri) if nm.is_local(host): self._nodename = nodename if screen_name: screen_log = screen.get_logfile(node=nodename) else: screen_log = screen.get_ros_logfile(node=nodename) self.qfile = QFile(screen_log) self.setWindowTitle(nodename) if self.qfile.open(QIODevice.ReadOnly): self._first_fill = True self.qfile.seek(self.qfile.size() - 1) # self.lread() self._info = "END" self.thread = threading.Thread(target=self._read_log, kwargs={"filename": screen_log}) self.thread.setDaemon(True) self.thread.start() else: self._valid = False else: self._connect_ssh(host, nodename, user) self.logger_handler = LoggerHandler( nodename, masteruri=masteruri, layout=self.scrollAreaWidgetContents.layout()) self.logger_handler.update() return False def _read_log(self, filename, lines=80): while self.qfile is not None and self.qfile.isOpen(): with self._lock: if self._first_fill: chars_count = self._seek_count_lines(lines) self._seek_start = self.qfile.pos() data = self.qfile.read(chars_count) if sys.version_info > (3, 0): data = data.decode('utf-8') self.output.emit(data) self._seek_end = self.qfile.pos() self._first_fill = False else: if self._seek_end != -1: self.qfile.seek(self._seek_end) if (not self._pause_read_end and self.qfile.bytesAvailable()): start = self.qfile.pos() data = self.qfile.readAll().data() if sys.version_info > (3, 0): data = data.decode('utf-8') self.output.emit(data) self._seek_end = self.qfile.pos() self._info = "NEW: %d" % (self._seek_end - start) time.sleep(0.25) def reverse_read(self, lines=20): with self._lock: if self.qfile is not None and self.qfile.isOpen(): if lines == -1: self.qfile.seek(0) chars_count = self._seek_start else: self.qfile.seek(self._seek_start) chars_count = self._seek_count_lines(lines) self._seek_start = self.qfile.pos() data = self.qfile.read(chars_count) if sys.version_info > (3, 0): data = data.decode('utf-8') self.output_prefix.emit(data) def _seek_count_lines(self, lines=20): if self.qfile.pos() < 2: self.qfile.seek(0) return self.qfile.pos() count = 0 chars_count = 2 line_size = 0 count_reached = False self.qfile.seek(self.qfile.pos() - 2) while (not count_reached) and (self.qfile.pos() > 0): ch = self.qfile.read(1) self.qfile.seek(self.qfile.pos() - 2) chars_count += 1 line_size += 1 if line_size > 120: count += 1 line_size = 0 if ch == '\n': count += 1 line_size = 0 if count >= lines: count_reached = True return chars_count + 1 def _on_output_prefix(self, msg): ''' This text will be prepended ''' if self.finished or self._on_pause: return if msg: cursor = QTextCursor(self.textBrowser.document()) self.tf.insert_formated(cursor, msg.rstrip()) self.textBrowser.setTextCursor(cursor) self.textBrowser.moveCursor(QTextCursor.Start) self._update_info_label() def _on_output(self, msg): ''' This text will be appended. ''' if self.finished or self._on_pause: return if msg: at_end = self.textBrowser.verticalScrollBar().value( ) > self.textBrowser.verticalScrollBar().maximum() - 20 cursor_select = self.textBrowser.textCursor() # store selection and do not scroll to the appended text if not cursor_select.hasSelection(): cursor_select = None cursor = self.textBrowser.textCursor() cursor.movePosition(QTextCursor.End) if self.hl.has_grep_text(): # grep new text lines = msg.splitlines(True) for line in lines: if self.hl.contains_grep_text(line): self._char_format_end = self.tf.insert_formated( cursor, line, char_format=None) else: self._char_format_end = self.tf.insert_formated( cursor, msg, char_format=self._char_format_end) if cursor_select is not None: # restore selection self.textBrowser.setTextCursor(cursor_select) elif at_end: self.textBrowser.moveCursor(QTextCursor.End) self._update_info_label() if not self.finished: self.show() def on_scrollbar_position_changed(self, value): self._update_info_label() def on_scrollbar_range_changed(self, min, max): self._update_info_label() def _on_error(self, msg): self.textBrowser.append(msg) self._update_info_label('SSH ERROR') def _update_info_label(self, info=''): info_text = info vbar_value = self.textBrowser.verticalScrollBar().value() if not info_text: if vbar_value == 0: if self._seek_start == 0: info_text = 'START' else: info_text += "%d %%" % (self._seek_start * 100 / self._seek_end) elif vbar_value == self.textBrowser.verticalScrollBar().maximum(): info_text = 'END' else: info_text = "%d / %d" % ( vbar_value / 20, self.textBrowser.verticalScrollBar().maximum() / 20) self.infoLabel.setText(info_text + '\t%s / %s' % (sizeof_fmt(self._seek_end - self._seek_start), sizeof_fmt(self._seek_end))) def _connect_ssh(self, host, nodename, user=None, pw=None): try: if user is not None: self.infoLabel.setText('connecting to %s@%s' % (user, host)) else: self.infoLabel.setText('connecting to %s' % host) ok = False self.ssh_input_file, self.ssh_output_file, self.ssh_error_file, ok = nm.ssh( ).ssh_exec(host, [ nm.settings().start_remote_script, '--tail_screen_log', nodename ], user, pw, auto_pw_request=False, get_pty=True) if ok: thread = threading.Thread(target=self._read_ssh_output, args=((self.ssh_output_file, ))) thread.setDaemon(True) thread.start() thread = threading.Thread(target=self._read_ssh_error, args=((self.ssh_error_file, ))) thread.setDaemon(True) thread.start() elif self.ssh_output_file: self.ssh_output_file.close() self.ssh_error_file.close() except nm.AuthenticationRequest as e: self.auth_signal.emit(host, nodename, user) except Exception as e: self.error_signal.emit('%s\n' % e) def on_request_pw(self, host, nodename, user): res, user, pw = nm.ssh()._requestPW(user, host) if res: self._connect_ssh(host, nodename, user, pw) def _read_ssh_output(self, output_file): while not output_file.closed: text = output_file.readline() if text: self.output.emit(text) def _read_ssh_error(self, error_file): try: while not error_file.closed: text = error_file.readline() if text: self.error_signal.emit(text) except Exception: pass def on_toggle_loggers(self, state): self.loggers.setVisible(state) if state: self.logger_handler.update()
def _save_dataset(self): formats = ['CSV', 'PKL', 'H5', 'DLS', 'FANN'] supported_formats = '' for f in formats: supported_formats += f + ';;' self._data_filename, self._data_format = QFileDialog.getSaveFileName( self._widget, self.tr('Save dataset'), 'dataset_name', self.tr(supported_formats[:-2])) if self._data_filename is None or self._data_filename == '': return self._data_filename += '.' + self._data_format.lower() if self._data_format == 'CSV': # fill up the list of selected data leaves self._fill_selected_leaves_list() # create new stream file data_file = QFile(self._data_filename) if not data_file.open(QIODevice.WriteOnly | QIODevice.Text): return self._file_stream = QTextStream(data_file) # fill up single line record dictionary with topic keys self._line_record['timestamp'] = 0 for leaf in self._selected_leaves: #self._get_selected_items_list(): self._line_record[leaf] = 0 # write out header for key in self._line_record: self._file_stream << key << ',' self._file_stream << '\n' # open bag file bag = rosbag.Bag(self._bag_filename) # cycle through selected base topics for topic, message, time in bag.read_messages( self._get_selected_topics()): # traverse down the message slots # print('Traversing: ' + topic) self._line_record['timestamp'] = str(time) self._export_leaf_instance(message, '', '', topic, []) data_file.close() print('File saved: ' + self._data_filename) elif self._data_format == 'PKL': df = rosbag_pandas.bag_to_dataframe(self._bag_filename, self._get_selected_topics()) df.to_pickle(self._data_filename) print('File saved: ' + self._data_filename) elif self._data_format == 'H5': df = rosbag_pandas.bag_to_dataframe(self._bag_filename, self._get_selected_topics()) hdf_store = HDFStore(self._data_filename) hdf_store['df'] = df hdf_store.close() print('File saved: ' + self._data_filename) elif self._data_format == 'DLS': self._no_support_warning() elif self._data_format == 'FANN': self._no_support_warning() else: self._no_support_warning()
import sys from python_qt_binding.QtWidgets import QApplication, QWidget, QVBoxLayout from python_qt_binding.QtCore import QFile, QIODevice, QObject from rqt_graph.ros_graph import RosGraph class FakePluginContext(QObject): def __init__(self): super(FakePluginContext, self).__init__() self.setObjectName('FakePluginContext') def serial_number(self): return 0 def add_widget(self, widget): pass if __name__ == "__main__": app = QApplication(sys.argv) fpc = FakePluginContext() r = RosGraph(fpc) handle = QFile(sys.argv[1]) if not handle.open(QIODevice.WriteOnly | QIODevice.Text): exit(1) handle.write(r._generate_dotcode()) handle.close()