""" QEMU development and testing utilities This package provides a small handful of utilities for performing various tasks not directly related to the launching of a VM. """ # Copyright (C) 2021 Red Hat Inc. # # Authors: # John Snow # Cleber Rosa # # This work is licensed under the terms of the GNU GPL, version 2. See # the COPYING file in the top-level directory. # import os import re import shutil import textwrap from typing import Optional # pylint: disable=import-error from .accel import kvm_available, list_accel, tcg_available __all__ = ( 'add_visual_margin', 'get_info_usernet_hostfwd_port', 'kvm_available', 'list_accel', 'tcg_available', ) def get_info_usernet_hostfwd_port(info_usernet_output: str) -> Optional[int]: """ Returns the port given to the hostfwd parameter via info usernet :param info_usernet_output: output generated by hmp command "info usernet" :return: the port number allocated by the hostfwd option """ for line in info_usernet_output.split('\r\n'): regex = r'TCP.HOST_FORWARD.*127\.0\.0\.1\s+(\d+)\s+10\.' match = re.search(regex, line) if match is not None: return int(match[1]) return None # pylint: disable=too-many-arguments def add_visual_margin( content: str = '', width: Optional[int] = None, name: Optional[str] = None, padding: int = 1, upper_left: str = '┏', lower_left: str = '┗', horizontal: str = '━', vertical: str = '┃', ) -> str: """ Decorate and wrap some text with a visual decoration around it. This function assumes that the text decoration characters are single characters that display using a single monospace column. ┏━ Example ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┃ This is what this function looks like with text content that's ┃ wrapped to 66 characters. The right-hand margin is left open to ┃ accommodate the occasional unicode character that might make ┃ predicting the total "visual" width of a line difficult. This ┃ provides a visual distinction that's good-enough, though. ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ :param content: The text to wrap and decorate. :param width: The number of columns to use, including for the decoration itself. The default (None) uses the the available width of the current terminal, or a fallback of 72 lines. A negative number subtracts a fixed-width from the default size. The default obeys the COLUMNS environment variable, if set. :param name: A label to apply to the upper-left of the box. :param padding: How many columns of padding to apply inside. :param upper_left: Upper-left single-width text decoration character. :param lower_left: Lower-left single-width text decoration character. :param horizontal: Horizontal single-width text decoration character. :param vertical: Vertical single-width text decoration character. """ if width is None or width < 0: avail = shutil.get_terminal_size(fallback=(72, 24))[0] if width is None: _width = avail else: _width = avail + width else: _width = width prefix = vertical + (' ' * padding) def _bar(name: Optional[str], top: bool = True) -> str: ret = upper_left if top else lower_left if name is not None: ret += f"{horizontal} {name} " filler_len = _width - len(ret) ret += f"{horizontal * filler_len}" return ret def _wrap(line: str) -> str: return os.linesep.join( textwrap.wrap( line, width=_width - padding, initial_indent=prefix, subsequent_indent=prefix, replace_whitespace=False, drop_whitespace=True, break_on_hyphens=False) ) return os.linesep.join(( _bar(name, top=True), os.linesep.join(_wrap(line) for line in content.splitlines()), _bar(None, top=False), ))