Beispiel #1
0
 def __init__(self):
     self.print_output: bool = True
     self._stdout: RichConsole = RichConsole(force_terminal=True,
                                             # color_system='256',
                                             width=160)
     self._stderr: RichConsole = RichConsole(file=sys.stderr,
                                             force_terminal=True,
                                             # color_system='256',
                                             width=160)
     self._stringio: RichConsole = RichConsole(file=StringIO(),
                                               width=160)
Beispiel #2
0
    def __init__(self, theme: dict = None):
        try:
            # pylint:disable=import-outside-toplevel
            from rich.console import Console as RichConsole
            from rich.theme import Theme
            if theme is None:
                if in_notebook():
                    theme = {
                        'repr.number': 'bold #87ff00',
                        'repr.attrib_name': 'bold #ff5fff',
                        'repr.str': 'italic #FFFF00',
                    }

            with_jupyter = in_notebook()
            console = RichConsole(record=False,
                                  log_path=False,
                                  force_jupyter=with_jupyter,
                                  force_terminal=(not with_jupyter),
                                  log_time_format='[%X] ',
                                  theme=Theme(theme))  #, width=width)

        except (ImportError, ModuleNotFoundError):
            console = Console()

        self.console = console
Beispiel #3
0
    def __init__(self):
        try:
            # pylint:disable=import-outside-toplevel
            from rich.console import Console as RichConsole
            console = RichConsole(log_path=False, width=TERM_WIDTH)
        except (ImportError, ModuleNotFoundError):
            console = Console()

        self.console = console
Beispiel #4
0
	def getResourceTreeText(self, maxLevel:int=0) -> str:
		"""	This function will generate a Text tree of a CSE's resource structure.
		"""
		from rich.console import Console as RichConsole

		console = RichConsole(color_system=None)
		console.begin_capture()
		console.print(self.getResourceTreeRich())
		return '\n'.join([item.rstrip() for item in console.end_capture().splitlines()])
Beispiel #5
0
    def __init__(
        self,
        level=logging.DEBUG,
        console=RichConsole(),
    ):

        super().__init__(level=level)

        self.console = console
        self._render = LogRender(show_level=True)
Beispiel #6
0
def test_prompt_disallows_empty_response(mocker):
    console = RichConsole(file=io.StringIO())
    Prompt.prompt_(
        "What is your name?",
        console=console,
        stream=io.StringIO("\nfoo"),
    )
    expected = ("What is your name?: Response required. Please try again.\n"
                "What is your name?: ")
    assert console.file.getvalue() == expected
Beispiel #7
0
def test_prompt_confirm(default, inner):
    console = RichConsole(file=io.StringIO())
    assert (Confirm.ask(
        "exit?",
        console=console,
        stream=io.StringIO("y\n"),
        default=default,
    ) is True)
    output = console.file.getvalue()
    assert output == f"exit? [{inner}]: "
Beispiel #8
0
def test_prompt_default(mocker):
    console = RichConsole(file=io.StringIO())
    mocked_validator = mocker.MagicMock(return_value="default")
    assert (Prompt.ask(
        "What is your name?",
        console=console,
        stream=io.StringIO(""),
        default="default",
        validator=mocked_validator,
    ) == "default")
    assert console.file.getvalue() == "What is your name? [default]: "
    mocked_validator.assert_has_calls([call("default")])
Beispiel #9
0
def table(state):
    table = RichTable(title="Results")

    data = state.get("output", [])
    if len(data) > 0:
        for column in data[0].keys():
            table.add_column(column)

    for item in data:
        table.add_row(*item.values())

    RichConsole().print(table)
Beispiel #10
0
def fake_shell(state):
    console = RichConsole()
    for result in state.get("output", []):
        server, host, command, output = (
            result["server"],
            result["host"],
            result["command"],
            result["output"],
        )
        console.print(f"ubuntu@{host}|{server} $ {command}")
        console.print(output)
        console.print()
Beispiel #11
0
def test_prompt_interrupt_message_not_interleaved(prompt_cls, side_effect,
                                                  mocker):
    """Test that the interrupt message is not interleaved with the prompt."""
    prompt = "should print exception in the next line"
    console = RichConsole(file=io.StringIO())

    with pytest.raises(side_effect):
        mocker.patch.object(console, "input", side_effect=side_effect)
        prompt_cls.ask(prompt=prompt, console=console)
    # as we are raising side_effect on the input, unfortunately we cannot
    # assert for the prompt string, only the newline.
    assert console.file.getvalue() == "\n"
Beispiel #12
0
def test_prompt_with_conditional_skip(mocker, default, brack):
    console = RichConsole(file=io.StringIO())
    mocked_validator = mocker.MagicMock(return_value="something")
    assert (Prompt.prompt_(
        "What is your name?",
        console=console,
        allow_omission=True,
        stream=io.StringIO("n\n"),
        default=default,
        validator=mocked_validator,
    ) is None)
    assert console.file.getvalue() == f"What is your name? {brack}: "
    mocked_validator.assert_not_called()
Beispiel #13
0
def test_prompt_shows_message_from_validator_response(mocker):
    console = RichConsole(file=io.StringIO())
    mocked_validator = mocker.MagicMock(
        return_value=("foo@email", "failed to send a verification email"))
    assert (Prompt.ask(
        "what is your email?",
        console=console,
        stream=io.StringIO("foo@email"),
        validator=mocked_validator,
    ) == "foo@email")
    mocked_validator.assert_has_calls([call("foo@email")])

    expected = "what is your email?: failed to send a verification email\n"
    assert console.file.getvalue() == expected
Beispiel #14
0
def test_prompt_retries_on_invalid_response_from_validator(mocker):
    console = RichConsole(file=io.StringIO())
    mocked_validator = mocker.MagicMock(
        side_effect=[InvalidResponse("it is a number"), "foo"])
    assert (Prompt.ask(
        "what is your name?",
        console=console,
        stream=io.StringIO("3\nfoo"),
        validator=mocked_validator,
    ) == "foo")
    mocked_validator.assert_has_calls([call("3"), call("foo")])

    expected = "what is your name?: it is a number\nwhat is your name?: "
    assert console.file.getvalue() == expected
Beispiel #15
0
def main(name, tag, region, sort, json):
    # Search
    search = {f'tag:{k}': v for k, v in dict(tag).items()}
    if name:
        search['tag:Name'] = name

    servers = find_instances(search, contains=True, region=region)

    # JSON mode
    if json:
        print(pyjson.dumps(servers, indent=2))
        sys.exit(0)

    # Table mode
    table = RichTable(title=f'Instances ({region})')
    fields = ['Name', 'PrivateIp', 'PublicIp', 'InstanceId']

    for header in fields:
        table.add_column(header)

    for server in sorted(servers, key=lambda k: k[sort]):
        table.add_row(*[server.get(f) for f in fields])

    RichConsole().print(table)
Beispiel #16
0
 def __init__(self, trees, raw_data_width=16):
     self.trees = trees
     self.raw_data_width = raw_data_width
     self.console = RichConsole(theme=default_theme)
Beispiel #17
0
 def __init__(self):
     self.rich = RichConsole()
     self.debug_enabled = False
Beispiel #18
0
def test_prompt_str():
    console = RichConsole(file=io.StringIO())
    assert (Prompt.ask("What is your name?",
                       console=console,
                       stream=io.StringIO("foo")) == "foo")
    assert console.file.getvalue() == "What is your name?: "
Beispiel #19
0
class Console(Table):

    _verbose = False
    console = RichConsole()
    logger = logger
    level = logging.DEBUG

    def __init__(self, name=None, log=False):

        super().__init__(
            box=None if name is None else box.SQUARE,
            show_header=name is not None,
            expand=True)

        if name is None:
            self.add_row(" ")
            self.thread = Operation(self)

    def debug(self, message, silent=False):
        self.logger.debug(message)
        if not silent:
            self._annotate(message, style="dim")

    def info(self, message):
        self.logger.info(message)
        if not self._verbose:
            self._annotate(message, "dim")

    def notice(self, message, silent=False):
        if self.logger.isEnabledFor(25):
            self.logger._log(25, message, args=None)

        if not silent:
            self._annotate(message, style="dim")

    def warn(self, message):
        self.logger.warn(message)
        if not self._verbose:
            self._annotate(message, "dark_red")

    def error(self, message):
        self.logger.error(message)
        if not self._verbose:
            self._annotate(message, "bold red")

    def critical(self, message):

        if isinstance(message, str):
            self.logger.critical(message)
            if not self._verbose:
                self._annotate(message, "bold red")
        else:
            self.stop()
            try:
                self.console.print_exception()
            except ValueError:
                self.console.print(message.__repr__())

        os._exit(1)

    def item(self, message):

        self.notice(message, silent=True)

        if self._verbose:
            return self

        service = self.__class__(name=message)
        service.add_column(message, justify="center")
        service.thread = self.thread.live

        self.add_row(service)
        self.spacer()

        return service

    def spacer(self):
        self.add_row()

    def task(self, message, function=None, args=[], done=None):

        self.notice(message, silent=True)

        (text, progress, busy) = self._add(message)

        results = function(*args)

        if done.__class__.__name__ == 'function':
            done = done(results)

        if done is not None:
            text._text = [done]
            self.notice(done, silent=True)

        busy._text = [""]
        progress.pulse = False
        progress.update(completed=progress.total)

        self._annotate()

        return results

    def tasklist(self, message, iterables=[], wait=None, done=None):

        if '__len__' in dir(iterables) and not len(iterables) > 0:
            return

        self.notice(message, silent=True)

        (text, progress, busy) = self._add(message, iterables=iterables)

        if wait is not None:
            self.debug(wait)
        else:
            self._annotate()

        for completed, iterable in enumerate(iterables, 1):

            if wait is not None:
                self._annotate()

            yield iterable

            if wait is not None:
                self.debug(wait)

            progress.update(completed=completed)

        if done is not None:
            self.notice(done, silent=True)
            text._text = [done]

        busy._text = [""]
        progress.pulse = False
        progress.update(completed=progress.total)

        self._annotate()

    def list(self, dictionaries=[]):

        if not isinstance(dictionaries, list):
            dictionaries = [dictionaries]

        if not len(dictionaries) > 0:
            return

        t = Table.grid(expand=True)

        for k in dictionaries[0].keys():
            t.add_column(str(k))

        for d in dictionaries:
            t.add_row(*d.values())

        if self._verbose:
            self.console.print(t)
        else:
            self.add_row(t)

    def input(self, message):

        def readchar():

            fd = sys.stdin.fileno()
            settings = termios.tcgetattr(fd)

            try:
                tty.setraw(sys.stdin.fileno())
                char = sys.stdin.read(1)
            finally:
                termios.tcsetattr(fd, termios.TCSADRAIN, settings)

            if char == '\x03':
                raise KeyboardInterrupt

            elif char == '\x04':
                raise EOFError

            return char

        def read(main, message, value):

            (text, value, _) = self._add(message, override=value)
            text.style = "b"
            value.style = "i"

            try:
                self.refresh()
                char = None

                while True:

                    with console.thread.live._lock:
                        char = readchar()
                        # Enter
                        if ord(char) == 13:
                            break
                        # Delete
                        elif ord(char) in [27]:
                            continue
                        # Backspace
                        elif ord(char) == 127:
                            value._text = [''.join(value._text)[:-1]]

                        else:
                            value._text = [''.join([*value._text, char])]

                        self.refresh()

            except (KeyboardInterrupt, EOFError):
                value.style = None
                self.stop()
                os._exit(0)

        if not self._verbose:
            value = Text("")

            input_thread = threading.Thread(target=read,
                                            args=(self, message, value))
            input_thread.start()
            input_thread.join()

            return ''.join(value._text)
        else:
            sys.stdout.write(message)
            sys.stdout.flush()
            return input()

    def verbose(self):

        if self._verbose:
            return

        log = Log(console=self.console, level=self.level)

        self.stop()
        self.logger.addHandler(log)
        self._verbose = True

    def _add(self, message, iterables=[], override=None):

        key = Text(message, overflow='ellipsis', no_wrap=True)
        busy = Text()

        if override is None:

            total = 1.0
            pulse = True

            try:
                total = len(iterables) if iterables != [] else 1
                pulse = iterables == []

            # Not all iterables have a length
            except TypeError:
                pass

            busy._text = ["→"]
            color = Style(color="rgb(161, 209, 255)", dim=True)
            value = ProgressBar(total=total, pulse=pulse,
                                complete_style=color,
                                finished_style=color,
                                pulse_style=color)
        else:
            value = override

        operation = Table(box=None, show_header=False,
                          show_footer=False, show_edge=True,
                          padding=(0, 0 if self.show_header else 1))

        operation.add_column(width=3 if self.show_header else 2,
                             justify="center")
        operation.add_column(width=62 if self.show_header else 60)
        operation.add_column()
        operation.add_row(busy, key, value)

        self.add_row(operation)
        return (key, value, busy)

    def _annotate(self, message="", style=None):

        if self._verbose:
            return

        self.caption = message
        self.caption_style = style
        self.refresh()

    def start(self):
        if not console.thread.live._started:
            self.thread.start()

    def refresh(self):
        if self.thread is not None:
            self.thread.refresh()

    def stop(self):
        if console.thread.live._started:
            self.thread.stop()
            self.console.print()
Beispiel #20
0
"""
Import the necessary ``Rich`` objects, and then
import this module as needed elsewhere.
"""
from rich.style import Style as RichStyle
from rich.console import Console as RichConsole
from rich.progress import Progress as RichProgress
from rich.syntax import Syntax as RichSyntax

_console = RichConsole()