From d1d644d4220fc6c22d0e2d3ada062a10ef3b62a5 Mon Sep 17 00:00:00 2001 From: kolo Date: Thu, 10 Apr 2025 00:23:03 +0300 Subject: [PATCH] final adding --- argenta/app/autocompleter/entity.py | 9 ++++-- argenta/app/exceptions.py | 10 ------- argenta/app/models.py | 27 +++++++++--------- argenta/router/command_handler/entity.py | 12 ++++---- argenta/router/entity.py | 7 +++++ mock/.history | 11 -------- mock/local_test.py | 36 ++++-------------------- mock/mock_app/handlers/routers.py | 6 ++-- mock/mock_app/main.py | 2 +- tests/unit_tests/test_app.py | 15 ---------- 10 files changed, 42 insertions(+), 93 deletions(-) delete mode 100644 mock/.history delete mode 100644 tests/unit_tests/test_app.py diff --git a/argenta/app/autocompleter/entity.py b/argenta/app/autocompleter/entity.py index 9d726c5..4ed4641 100644 --- a/argenta/app/autocompleter/entity.py +++ b/argenta/app/autocompleter/entity.py @@ -1,6 +1,6 @@ -import readline import os +import readline class AutoCompleter: @@ -27,10 +27,14 @@ class AutoCompleter: else: return None - def initial_setup(self): + def initial_setup(self, all_commands: list[str]): if self.history_filename: if os.path.exists(self.history_filename): readline.read_history_file(self.history_filename) + else: + for line in all_commands: + readline.add_history(line) + readline.set_completer(self.complete) readline.set_completer_delims(readline.get_completer_delims().replace(' ', '')) readline.parse_and_bind(f'{self.autocomplete_button}: complete') @@ -42,4 +46,3 @@ class AutoCompleter: @staticmethod def get_history_items(): return [readline.get_history_item(i) for i in range(1, readline.get_current_history_length() + 1)] - diff --git a/argenta/app/exceptions.py b/argenta/app/exceptions.py index cca6373..28d047f 100644 --- a/argenta/app/exceptions.py +++ b/argenta/app/exceptions.py @@ -3,16 +3,6 @@ class InvalidRouterInstanceException(Exception): return "Invalid Router Instance" -class InvalidDescriptionMessagePatternException(Exception): - def __init__(self, pattern: str): - self.pattern = pattern - def __str__(self): - return ("Invalid Description Message Pattern\n" - "Correct pattern example: [{command}] *=*=* {description}\n" - "The pattern must contain two variables: `command` and `description` - description of the command\n" - f"Your pattern: {self.pattern}") - - class NoRegisteredRoutersException(Exception): def __str__(self): return "No Registered Router Found" diff --git a/argenta/app/models.py b/argenta/app/models.py index eac169c..5163037 100644 --- a/argenta/app/models.py +++ b/argenta/app/models.py @@ -1,5 +1,6 @@ from typing import Callable from rich.console import Console +from rich.markup import escape from art import text2art from contextlib import redirect_stdout import io @@ -15,7 +16,6 @@ from argenta.command.exceptions import (UnprocessedInputFlagException, EmptyInputCommandException, BaseInputCommandException) from argenta.app.exceptions import (InvalidRouterInstanceException, - InvalidDescriptionMessagePatternException, NoRegisteredRoutersException, NoRegisteredHandlersException) from argenta.app.registered_routers.entity import RegisteredRouters @@ -50,7 +50,8 @@ class AppInit: 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._description_message_gen: Callable[[str, str], str] = lambda command, description: f'[bold red]{escape('['+command+']')}[/bold red] [blue dim]*=*=*[/blue dim] [bold yellow italic]{escape(description)}' self._registered_routers: RegisteredRouters = RegisteredRouters() self._messages_on_startup = [] @@ -62,14 +63,8 @@ class AppInit: 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 set_description_message_pattern(self, pattern: Callable[[str, str], str]) -> None: + self._description_message_gen: Callable[[str, str], str] = pattern def set_invalid_input_flags_handler(self, handler: Callable[[str], None]) -> None: @@ -97,9 +92,9 @@ class AppPrinters(AppInit): 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(self._description_message_gen( + command_handler.get_handled_command().get_trigger(), + command_handler.get_handled_command().get_description())) self._print_func('') @@ -190,7 +185,11 @@ class AppSetups(AppValidators, AppPrinters): self._setup_system_router() self._validate_number_of_routers() self._validate_included_routers() - self._autocompleter.initial_setup() + + all_triggers: list[str] = [] + for router_entity in self._registered_routers: + all_triggers.extend(router_entity.get_triggers()) + self._autocompleter.initial_setup(all_triggers) self._print_func(self._initial_message) diff --git a/argenta/router/command_handler/entity.py b/argenta/router/command_handler/entity.py index 26f6a17..0ab2451 100644 --- a/argenta/router/command_handler/entity.py +++ b/argenta/router/command_handler/entity.py @@ -5,17 +5,17 @@ from argenta.command.flag.models import InputFlags class CommandHandler: def __init__(self, handler: Callable[[], None] | Callable[[InputFlags], None], handled_command: Command): - self.handler = handler - self.handled_command = handled_command + self._handler = handler + self._handled_command = handled_command def handling(self, input_flags: InputFlags = None): if input_flags is not None: - self.handler(input_flags) + self._handler(input_flags) else: - self.handler() + self._handler() def get_handler(self): - return self.handler + return self._handler def get_handled_command(self): - return self.handled_command \ No newline at end of file + return self._handled_command \ No newline at end of file diff --git a/argenta/router/entity.py b/argenta/router/entity.py index c2d32e2..d13bea0 100644 --- a/argenta/router/entity.py +++ b/argenta/router/entity.py @@ -110,6 +110,13 @@ class Router: self._ignore_command_register = ignore_command_register + def get_triggers(self): + all_triggers: list[str] = [] + for command_handler in self._command_handlers: + all_triggers.append(command_handler.get_handled_command().get_trigger()) + return all_triggers + + def get_command_handlers(self) -> CommandHandlers: return self._command_handlers diff --git a/mock/.history b/mock/.history deleted file mode 100644 index 61d7296..0000000 --- a/mock/.history +++ /dev/null @@ -1,11 +0,0 @@ -test -q -P -q -S -S --host 125 -q -S --host 125.0123 -0 -U -q diff --git a/mock/local_test.py b/mock/local_test.py index feb0874..89e6abd 100644 --- a/mock/local_test.py +++ b/mock/local_test.py @@ -1,32 +1,8 @@ -import readline +from rich.console import Console +from rich.markup import escape -def completer(text, state): - matches = sorted(cmd for cmd in get_history_items() if cmd.startswith(text)) - if len(matches) > 1: - common_prefix = matches[0] - for match in matches[1:]: - i = 0 - while i < len(common_prefix) and i < len(match) and common_prefix[i] == match[i]: - i += 1 - common_prefix = common_prefix[:i] - if state == 0: - readline.insert_text(common_prefix[len(text):]) - readline.redisplay() - return None - elif len(matches) == 1: - return matches[0] if state == 0 else None - else: - return None - -readline.set_completer(completer) -readline.parse_and_bind("tab: complete") - -def get_history_items(): - return [readline.get_history_item(i) for i in range(1, readline.get_current_history_length() + 1)] - -while True: - try: - line = input('> ') - except EOFError: - break \ No newline at end of file +console = Console() +text = lambda command, description: f'[bold red]{escape('['+command+']')}[/bold red] [blue dim]*=*=*[/blue dim] [bold yellow italic]{escape(description)}' +print(text('start', 'command start')) +console.print(text('start', 'command start')) diff --git a/mock/mock_app/handlers/routers.py b/mock/mock_app/handlers/routers.py index c2e9244..dc5c5c4 100644 --- a/mock/mock_app/handlers/routers.py +++ b/mock/mock_app/handlers/routers.py @@ -14,17 +14,17 @@ settings_router: Router = Router(title='Settings points:') console = Console() -@work_router.command(Command('0', 'Get Help')) +@work_router.command(Command('get', 'Get Help')) def command_help(): help_command() -@work_router.command(Command('S', 'Start Solving', Flags(PredeterminedFlags.HOST, PredeterminedFlags.PORT))) +@work_router.command(Command('start', 'Start Solving', Flags(PredeterminedFlags.HOST, PredeterminedFlags.PORT))) def command_start_solving(args: InputFlags): print(args.get_flag('test')) -@settings_router.command(Command('U', 'Update WordMath')) +@settings_router.command(Command('update', 'Update WordMath')) def command_update(): print('eeeeeee') diff --git a/mock/mock_app/main.py b/mock/mock_app/main.py index a33fd28..e9a0ed6 100644 --- a/mock/mock_app/main.py +++ b/mock/mock_app/main.py @@ -6,7 +6,7 @@ from argenta.app.dividing_line import DynamicDividingLine from argenta.app.autocompleter import AutoCompleter -autocompleter = AutoCompleter('./mock/.history') +autocompleter = AutoCompleter() app: App = App(dividing_line=DynamicDividingLine(), autocompleter=autocompleter) diff --git a/tests/unit_tests/test_app.py b/tests/unit_tests/test_app.py deleted file mode 100644 index 9236e33..0000000 --- a/tests/unit_tests/test_app.py +++ /dev/null @@ -1,15 +0,0 @@ -from argenta.app import App -from argenta.app.exceptions import InvalidDescriptionMessagePatternException - -import unittest - - -class TestApp(unittest.TestCase): - def test_set_invalid_description_message_pattern(self): - with self.assertRaises(InvalidDescriptionMessagePatternException): - App().set_description_message_pattern('Invalid description pattern') - - def test_set_invalid_description_message_pattern2(self): - with self.assertRaises(InvalidDescriptionMessagePatternException): - App().set_description_message_pattern('Invalid {desription} description {comand} pattern') -