mirror of
https://github.com/koloideal/Argenta.git
synced 2026-06-10 10:05:28 +03:00
viewr
This commit is contained in:
@@ -1,14 +1,43 @@
|
||||
from typing import Iterable
|
||||
__all__ = ["Viewer"]
|
||||
|
||||
import re
|
||||
from contextlib import redirect_stdout
|
||||
from io import StringIO
|
||||
from typing import Iterable, Callable, TypeAlias
|
||||
|
||||
from rich.text import Text
|
||||
|
||||
from argenta.app import StaticDividingLine, DynamicDividingLine
|
||||
from argenta.app.presentation.renderers import Renderer
|
||||
from argenta.app.protocols import Printer, DescriptionMessageGenerator
|
||||
from argenta.app.registered_routers.entity import RegisteredRouters
|
||||
|
||||
|
||||
AVAILABLE_DIVIDING_LINES: TypeAlias = StaticDividingLine | DynamicDividingLine | None
|
||||
|
||||
|
||||
class Viewer:
|
||||
def __init__(self, printer: Printer, renderer: Renderer):
|
||||
ANSI_ESCAPE_RE: re.Pattern[str] = re.compile(r"\u001b\[[0-9;]*m")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
printer: Printer,
|
||||
renderer: Renderer,
|
||||
dividing_line: AVAILABLE_DIVIDING_LINES,
|
||||
override_system_messages: bool
|
||||
):
|
||||
self._printer = printer
|
||||
self._renderer = renderer
|
||||
self._dividing_line = dividing_line
|
||||
self._override_system_messages = override_system_messages
|
||||
self._stdout_buffer: StringIO = StringIO()
|
||||
|
||||
def _capture_stdout(self, func: Callable[[], None]) -> str:
|
||||
self._stdout_buffer.seek(0)
|
||||
self._stdout_buffer.truncate(0)
|
||||
with redirect_stdout(self._stdout_buffer):
|
||||
func()
|
||||
return self._stdout_buffer.getvalue()
|
||||
|
||||
def view_messages_on_startup(self, messages: Iterable[str]) -> None:
|
||||
self._printer(self._renderer.render_messages_on_startup(messages))
|
||||
@@ -25,3 +54,43 @@ class Viewer:
|
||||
)
|
||||
)
|
||||
|
||||
def view_initial_message(self, initial_message: str) -> None:
|
||||
self._printer(initial_message)
|
||||
|
||||
def view_framed_text_from_generator(
|
||||
self,
|
||||
output_text_generator: Callable[[], None],
|
||||
is_stdout_redirected_by_router: bool = False,
|
||||
) -> None:
|
||||
match (self._dividing_line, is_stdout_redirected_by_router):
|
||||
case (None, bool()):
|
||||
output_text_generator()
|
||||
case (DynamicDividingLine(), False):
|
||||
stdout_result = self._capture_stdout(
|
||||
lambda: output_text_generator()
|
||||
)
|
||||
clear_text = self.ANSI_ESCAPE_RE.sub("", stdout_result)
|
||||
max_length_line = max([len(line) for line in clear_text.split("\n")])
|
||||
max_length_line = (
|
||||
max_length_line
|
||||
if 10 <= max_length_line <= 100
|
||||
else 100
|
||||
if max_length_line > 100
|
||||
else 10
|
||||
)
|
||||
dividing_line_as_str: str = self._dividing_line.get_full_dynamic_line(
|
||||
length=max_length_line, is_override=self._override_system_messages
|
||||
)
|
||||
self._printer(dividing_line_as_str + "\n")
|
||||
self._printer(Text.from_ansi(stdout_result.strip("\n")).markup)
|
||||
self._printer('\n' + dividing_line_as_str)
|
||||
|
||||
case (StaticDividingLine() as dividing_line, bool()) | (DynamicDividingLine() as dividing_line, True):
|
||||
dividing_line_as_str: str = StaticDividingLine(dividing_line.get_unit_part()).get_full_static_line(
|
||||
is_override=self._override_system_messages
|
||||
)
|
||||
self._printer(dividing_line_as_str + '\n')
|
||||
output_text_generator()
|
||||
self._printer('\n' + dividing_line_as_str)
|
||||
case _:
|
||||
raise NotImplementedError(f"Dividing line with type {self._dividing_line} is not implemented")
|
||||
|
||||
Reference in New Issue
Block a user