refactor app

This commit is contained in:
2025-04-08 10:33:45 +03:00
parent ca6634c6f0
commit 0dce4a0d9e
+94 -67
View File
@@ -21,7 +21,7 @@ from argenta.app.registered_routers.entity import RegisteredRouters
class BaseApp: class AppInit:
def __init__(self, def __init__(self,
prompt: str = '[italic dim bold]What do you want to do?\n', prompt: str = '[italic dim bold]What do you want to do?\n',
initial_message: str = '\nArgenta\n', initial_message: str = '\nArgenta\n',
@@ -44,40 +44,72 @@ class BaseApp:
self._repeat_command_groups_description = repeat_command_groups self._repeat_command_groups_description = repeat_command_groups
self._full_override_system_messages = full_override_system_messages self._full_override_system_messages = full_override_system_messages
self.farewell_message = farewell_message self._farewell_message = farewell_message
self.initial_message = initial_message self._initial_message = initial_message
self._description_message_pattern: str = '[bold red][{command}][/bold red] [blue dim]*=*=*[/blue dim] [bold yellow italic]{description}' self._description_message_pattern: str = '[bold red][{command}][/bold red] [blue dim]*=*=*[/blue dim] [bold yellow italic]{description}'
self._registered_routers: RegisteredRouters = RegisteredRouters() self._registered_routers: RegisteredRouters = RegisteredRouters()
self._messages_on_startup = [] self._messages_on_startup = []
self.invalid_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'[red bold]Incorrect flag syntax: {raw_command}') self._invalid_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'[red bold]Incorrect flag syntax: {raw_command}')
self.repeated_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'[red bold]Repeated input flags: {raw_command}') self._repeated_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'[red bold]Repeated input flags: {raw_command}')
self.empty_input_command_handler: Callable[[], None] = lambda: print_func('[red bold]Empty input command') self._empty_input_command_handler: Callable[[], None] = lambda: print_func('[red bold]Empty input command')
self.unknown_command_handler: Callable[[InputCommand], None] = lambda command: print_func(f"[red bold]Unknown command: {command.get_trigger()}") self._unknown_command_handler: Callable[[InputCommand], None] = lambda command: print_func(f"[red bold]Unknown command: {command.get_trigger()}")
self.exit_command_handler: Callable[[], None] = lambda: print_func(self.farewell_message) self._exit_command_handler: Callable[[], None] = lambda: print_func(self._farewell_message)
self._setup_default_view()
def _setup_default_view(self): class AppSetters(AppInit):
if not self._full_override_system_messages: def set_description_message_pattern(self, pattern: str) -> None:
self.initial_message = f'\n[bold red]{text2art(self.initial_message, font='tarty1')}\n\n' first_check = re.match(r'.*{command}.*', pattern)
self.farewell_message = (f'[bold red]\n{text2art(f'\n{self.farewell_message}\n', font='chanky')}[/bold red]\n' second_check = re.match(r'.*{description}.*', pattern)
f'[red i]github.com/koloideal/Argenta[/red i] | [red bold i]made by kolo[/red bold i]\n')
if bool(first_check) and bool(second_check):
self._description_message_pattern: str = pattern
else:
raise InvalidDescriptionMessagePatternException(pattern)
def _validate_number_of_routers(self) -> None: def set_invalid_input_flags_handler(self, handler: Callable[[str], None]) -> None:
if not self._registered_routers: self._invalid_input_flags_handler = handler
raise NoRegisteredRoutersException()
def _validate_included_routers(self) -> None: def set_repeated_input_flags_handler(self, handler: Callable[[str], None]) -> None:
for router in self._registered_routers: self._repeated_input_flags_handler = handler
if not router.get_command_handlers():
raise NoRegisteredHandlersException(router.get_name())
def set_unknown_command_handler(self, handler: Callable[[str], None]) -> None:
self._unknown_command_handler = handler
def set_empty_command_handler(self, handler: Callable[[], None]) -> None:
self._empty_input_command_handler = handler
def set_exit_command_handler(self, handler: Callable[[], None]) -> None:
self._exit_command_handler = handler
class AppPrinters(AppInit):
def _print_command_group_description(self):
for registered_router in self._registered_routers:
self._print_func(registered_router.get_title())
for command_handler in registered_router.get_command_handlers():
self._print_func(self._description_message_pattern.format(
command=command_handler.get_handled_command().get_trigger(),
description=command_handler.get_handled_command().get_description()))
self._print_func('')
def _print_framed_text_with_dynamic_line(self, text: str):
clear_text = re.sub(r'\u001b\[[0-9;]*m', '', text)
max_length_line = max([len(line) for line in clear_text.split('\n')])
max_length_line = max_length_line if 10 <= max_length_line <= 80 else 80 if max_length_line > 80 else 10
self._print_func(self._dividing_line.get_full_line(max_length_line))
print(text.strip('\n'))
self._print_func(self._dividing_line.get_full_line(max_length_line))
class AppNonStandardHandlers(AppInit, AppPrinters):
def _is_exit_command(self, command: InputCommand): def _is_exit_command(self, command: InputCommand):
if command.get_trigger().lower() == self._exit_command.lower(): if command.get_trigger().lower() == self._exit_command.lower():
if self._ignore_command_register: if self._ignore_command_register:
@@ -99,53 +131,69 @@ class BaseApp:
return False return False
if isinstance(self._dividing_line, StaticDividingLine): if isinstance(self._dividing_line, StaticDividingLine):
self._print_func(self._dividing_line.get_full_line()) self._print_func(self._dividing_line.get_full_line())
self.unknown_command_handler(command) self._unknown_command_handler(command)
self._print_func(self._dividing_line.get_full_line()) self._print_func(self._dividing_line.get_full_line())
elif isinstance(self._dividing_line, DynamicDividingLine): elif isinstance(self._dividing_line, DynamicDividingLine):
with redirect_stdout(io.StringIO()) as f: with redirect_stdout(io.StringIO()) as f:
self.unknown_command_handler(command) self._unknown_command_handler(command)
res: str = f.getvalue() res: str = f.getvalue()
self._print_framed_text_with_dynamic_line(res) self._print_framed_text_with_dynamic_line(res)
return True return True
def _print_command_group_description(self):
for registered_router in self._registered_routers:
self._print_func(registered_router.get_title())
for command_handler in registered_router.get_command_handlers():
self._print_func(self._description_message_pattern.format(
command=command_handler.get_handled_command().get_trigger(),
description=command_handler.get_handled_command().get_description()))
self._print_func('')
def _error_handler(self, error: BaseInputCommandException, raw_command: str) -> None: def _error_handler(self, error: BaseInputCommandException, raw_command: str) -> None:
match error: match error:
case UnprocessedInputFlagException(): case UnprocessedInputFlagException():
self.invalid_input_flags_handler(raw_command) self._invalid_input_flags_handler(raw_command)
case RepeatedInputFlagsException(): case RepeatedInputFlagsException():
self.repeated_input_flags_handler(raw_command) self._repeated_input_flags_handler(raw_command)
case EmptyInputCommandException(): case EmptyInputCommandException():
self.empty_input_command_handler() self._empty_input_command_handler()
def _print_framed_text_with_dynamic_line(self, text: str): class AppValidators(AppInit):
clear_text = re.sub(r'\u001b\[[0-9;]*m', '', text) def _validate_number_of_routers(self) -> None:
max_length_line = max([len(line) for line in clear_text.split('\n')]) if not self._registered_routers:
max_length_line = max_length_line if 10 <= max_length_line <= 80 else 80 if max_length_line > 80 else 10 raise NoRegisteredRoutersException()
self._print_func(self._dividing_line.get_full_line(max_length_line))
print(text.strip('\n'))
self._print_func(self._dividing_line.get_full_line(max_length_line)) def _validate_included_routers(self) -> None:
for router in self._registered_routers:
if not router.get_command_handlers():
raise NoRegisteredHandlersException(router.get_name())
class AppSetups(AppInit):
def _setup_system_router(self):
system_router.set_title(self._system_points_title)
@system_router.command(Command(self._exit_command, self._exit_command_description))
def exit_command():
self._exit_command_handler()
if system_router not in self._registered_routers.get_registered_routers():
system_router.set_ignore_command_register(self._ignore_command_register)
self._registered_routers.add_registered_router(system_router)
def _setup_default_view(self):
if not self._full_override_system_messages:
self._initial_message = f'\n[bold red]{text2art(self._initial_message, font='tarty1')}\n\n'
self._farewell_message = (
f'[bold red]\n{text2art(f'\n{self._farewell_message}\n', font='chanky')}[/bold red]\n'
f'[red i]github.com/koloideal/Argenta[/red i] | [red bold i]made by kolo[/red bold i]\n')
class App(BaseApp): class App(AppInit, AppSetters,
AppNonStandardHandlers,
AppValidators, AppSetups):
def start_polling(self) -> None: def start_polling(self) -> None:
self._setup_default_view()
self._setup_system_router() self._setup_system_router()
self._validate_number_of_routers() self._validate_number_of_routers()
self._validate_included_routers() self._validate_included_routers()
self._print_func(self.initial_message) self._print_func(self._initial_message)
for message in self._messages_on_startup: for message in self._messages_on_startup:
self._print_func(message) self._print_func(message)
@@ -211,24 +259,3 @@ class App(BaseApp):
def add_message_on_startup(self, message: str) -> None: def add_message_on_startup(self, message: str) -> None:
self._messages_on_startup.append(message) self._messages_on_startup.append(message)
def set_description_message_pattern(self, pattern: str) -> None:
first_check = re.match(r'.*{command}.*', pattern)
second_check = re.match(r'.*{description}.*', pattern)
if bool(first_check) and bool(second_check):
self._description_message_pattern: str = pattern
else:
raise InvalidDescriptionMessagePatternException(pattern)
def _setup_system_router(self):
system_router.set_title(self._system_points_title)
@system_router.command(Command(self._exit_command, self._exit_command_description))
def exit_command():
self.exit_command_handler()
if system_router not in self._registered_routers.get_registered_routers():
self.include_router(system_router)