From 0dce4a0d9e120b85b5bfe1cc35935bc1ef2bbc4c Mon Sep 17 00:00:00 2001 From: kolo Date: Tue, 8 Apr 2025 10:33:45 +0300 Subject: [PATCH] refactor app --- argenta/app/models.py | 161 ++++++++++++++++++++++++------------------ 1 file changed, 94 insertions(+), 67 deletions(-) diff --git a/argenta/app/models.py b/argenta/app/models.py index 04ca32c..3357a94 100644 --- a/argenta/app/models.py +++ b/argenta/app/models.py @@ -21,7 +21,7 @@ from argenta.app.registered_routers.entity import RegisteredRouters -class BaseApp: +class AppInit: def __init__(self, prompt: str = '[italic dim bold]What do you want to do?\n', initial_message: str = '\nArgenta\n', @@ -44,40 +44,72 @@ class BaseApp: self._repeat_command_groups_description = repeat_command_groups self._full_override_system_messages = full_override_system_messages - self.farewell_message = farewell_message - self.initial_message = initial_message + self._farewell_message = farewell_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._registered_routers: RegisteredRouters = RegisteredRouters() 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.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.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._setup_default_view() + 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._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._exit_command_handler: Callable[[], None] = lambda: print_func(self._farewell_message) - 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 AppSetters(AppInit): + 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 _validate_number_of_routers(self) -> None: - if not self._registered_routers: - raise NoRegisteredRoutersException() + def set_invalid_input_flags_handler(self, handler: Callable[[str], None]) -> None: + self._invalid_input_flags_handler = handler - def _validate_included_routers(self) -> None: - for router in self._registered_routers: - if not router.get_command_handlers(): - raise NoRegisteredHandlersException(router.get_name()) + def set_repeated_input_flags_handler(self, handler: Callable[[str], None]) -> None: + self._repeated_input_flags_handler = handler + 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): if command.get_trigger().lower() == self._exit_command.lower(): if self._ignore_command_register: @@ -99,53 +131,69 @@ class BaseApp: return False if isinstance(self._dividing_line, StaticDividingLine): 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()) elif isinstance(self._dividing_line, DynamicDividingLine): with redirect_stdout(io.StringIO()) as f: - self.unknown_command_handler(command) + self._unknown_command_handler(command) res: str = f.getvalue() self._print_framed_text_with_dynamic_line(res) 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: match error: case UnprocessedInputFlagException(): - self.invalid_input_flags_handler(raw_command) + self._invalid_input_flags_handler(raw_command) case RepeatedInputFlagsException(): - self.repeated_input_flags_handler(raw_command) + self._repeated_input_flags_handler(raw_command) case EmptyInputCommandException(): - self.empty_input_command_handler() + self._empty_input_command_handler() - 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 AppValidators(AppInit): + def _validate_number_of_routers(self) -> None: + if not self._registered_routers: + raise NoRegisteredRoutersException() + + + 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: + self._setup_default_view() self._setup_system_router() self._validate_number_of_routers() self._validate_included_routers() - self._print_func(self.initial_message) + self._print_func(self._initial_message) for message in self._messages_on_startup: self._print_func(message) @@ -211,24 +259,3 @@ class App(BaseApp): def add_message_on_startup(self, message: str) -> None: 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) - -