diff --git a/mock/local_test.py b/mock/local_test.py index 729f39d..b643903 100644 --- a/mock/local_test.py +++ b/mock/local_test.py @@ -1,20 +1,80 @@ -import platform - -from argenta.response import Response, Status from argenta.app import App -from argenta.app.dividing_line import StaticDividingLine, DynamicDividingLine from argenta.app.autocompleter import AutoCompleter -from argenta.app.defaults import PredefinedMessages -from argenta.command import Command -from argenta.command.flags import Flags, InputFlags, InvalidValueInputFlags, UndefinedInputFlags, ValidInputFlags -from argenta.command.flag import Flag, InputFlag -from argenta.command.flag.defaults import PredefinedFlags from argenta.router import Router +from argenta.command import Command from argenta.orchestrator import Orchestrator +from argenta.app.dividing_line import DynamicDividingLine +from argenta.response import Response +import platform +import psutil +import os +import subprocess +import socket -from argenta.command.models import InputCommand -import inspect +# Маршрутизатор для работы с файлами +file_router = Router("Файловые операции") +@file_router.command(Command("list", "Список файлов")) +def list_files(response: Response): + files = os.listdir() + for file in files: + print(file) -print(platform.system()) +@file_router.command(Command("size", "Размер файла")) +def file_size(response: Response): + file_name = input("Введите имя файла: ") + if os.path.exists(file_name): + size = os.path.getsize(file_name) + print(f"Размер файла {file_name}: {size} байт") + else: + print(f"Файл {file_name} не найден") +# Маршрутизатор для системных операций +system_router = Router("Системные операции") + +@system_router.command(Command("info", "Информация о системе")) +def system_info(response: Response): + print(f"Система: {platform.system()}") + print(f"Версия: {platform.version()}") + print(f"Архитектура: {platform.architecture()}") + print(f"Процессор: {platform.processor()}") + +@system_router.command(Command("memory", "Информация о памяти")) +def memory_info(response: Response): + memory = psutil.virtual_memory() + print(f"Всего памяти: {memory.total / (1024**3):.2f} ГБ") + print(f"Доступно: {memory.available / (1024**3):.2f} ГБ") + print(f"Использовано: {memory.used / (1024**3):.2f} ГБ ({memory.percent}%)") + +# Маршрутизатор для сетевых операций +network_router = Router("Сетевые операции") + +@network_router.command(Command("ping", "Проверка доступности хоста")) +def ping_host(response: Response): + host = input("Введите имя хоста: ") + print(f"Пингую {host}...") + subprocess.run(["ping", "-c", "4", host]) + +@network_router.command(Command("ip", "Показать IP-адреса")) +def show_ip(response: Response): + hostname = socket.gethostname() + print(f"Имя хоста: {hostname}") + print(f"IP-адрес: {socket.gethostbyname(hostname)}") + +# Создание приложения и регистрация маршрутизаторов +app = App( + prompt="System> ", + initial_message="Системный монитор v1.0", + dividing_line=DynamicDividingLine("*"), + autocompleter=AutoCompleter('.hist') +) + +# Добавляем все маршрутизаторы +app.include_routers(file_router, system_router, network_router) + +# Добавляем сообщение при запуске +app.add_message_on_startup("Для просмотра доступных команд нажмите Enter") + +# Запускаем приложение +orchestrator = Orchestrator() +orchestrator.start_polling(app) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 4f74c4b..c611713 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ dependencies = [ [dependency-groups] dev = [ + "psutil>=7.0.0", "pydoc-markdown>=4.8.2,<5", ] diff --git a/src/argenta/app/models.py b/src/argenta/app/models.py index 1ceb947..9aa4983 100644 --- a/src/argenta/app/models.py +++ b/src/argenta/app/models.py @@ -21,8 +21,7 @@ from argenta.response import Response class BaseApp: - def __init__(self, - prompt: str, + def __init__(self, prompt: str, initial_message: str, farewell_message: str, exit_command: Command, @@ -55,7 +54,7 @@ class BaseApp: self._all_registered_triggers_in_lower: list[str] = [] self._all_registered_triggers_in_default_case: list[str] = [] - self._invalid_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'Incorrect flag syntax: {raw_command}') + self._incorrect_input_syntax_handler: Callable[[str], None] = lambda raw_command: print_func(f'Incorrect flag syntax: {raw_command}') self._repeated_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'Repeated input flags: {raw_command}') self._empty_input_command_handler: Callable[[], None] = lambda: print_func('Empty input command') self._unknown_command_handler: Callable[[InputCommand], None] = lambda command: print_func(f"Unknown command: {command.get_trigger()}") @@ -71,13 +70,13 @@ class BaseApp: self._description_message_gen: Callable[[str, str], str] = _ - def set_invalid_input_flags_handler(self, _: Callable[[str], None]) -> None: + def set_incorrect_input_syntax_handler(self, _: Callable[[str], None]) -> None: """ Public. Sets the handler for incorrect flags when entering a command :param _: handler for incorrect flags when entering a command :return: None """ - self._invalid_input_flags_handler = _ + self._incorrect_input_syntax_handler = _ def set_repeated_input_flags_handler(self, _: Callable[[str], None]) -> None: @@ -122,8 +121,8 @@ class BaseApp: :return: None """ for registered_router in self._registered_routers: - if registered_router.get_title(): - self._print_func(registered_router.get_title()) + if registered_router.title: + self._print_func(registered_router.title) for command_handler in registered_router.get_command_handlers(): self._print_func(self._description_message_gen( command_handler.get_handled_command().get_trigger(), @@ -196,7 +195,7 @@ class BaseApp: """ match error: case UnprocessedInputFlagException(): - self._invalid_input_flags_handler(raw_command) + self._incorrect_input_syntax_handler(raw_command) case RepeatedInputFlagsException(): self._repeated_input_flags_handler(raw_command) case EmptyInputCommandException(): @@ -208,7 +207,7 @@ class BaseApp: Private. Sets up system router :return: None """ - system_router.set_title(self._system_router_title) + system_router.title = self._system_router_title @system_router.command(self._exit_command) def exit_command(response: Response) -> None: @@ -244,7 +243,7 @@ class BaseApp: self._description_message_gen = lambda command, description: (f'[bold red]{escape("[" + command + "]")}[/bold red] ' f'[blue dim]*=*=*[/blue dim] ' f'[bold yellow italic]{escape(description)}') - self._invalid_input_flags_handler = lambda raw_command: self._print_func(f'[red bold]Incorrect flag syntax: {escape(raw_command)}') + self._incorrect_input_syntax_handler = lambda raw_command: self._print_func(f'[red bold]Incorrect flag syntax: {escape(raw_command)}') self._repeated_input_flags_handler = lambda raw_command: self._print_func(f'[red bold]Repeated input flags: {escape(raw_command)}') self._empty_input_command_handler = lambda: self._print_func('[red bold]Empty input command') diff --git a/src/argenta/router/entity.py b/src/argenta/router/entity.py index 00da35e..458e54f 100644 --- a/src/argenta/router/entity.py +++ b/src/argenta/router/entity.py @@ -23,7 +23,7 @@ class Router: :param title: the title of the router, displayed when displaying the available commands :return: None """ - self._title = title + self.title = title self._command_handlers: CommandHandlers = CommandHandlers() self._ignore_command_register: bool = False @@ -219,20 +219,3 @@ class Router: :return: registered command handlers as CommandHandlers """ return self._command_handlers - - - def get_title(self) -> str | None: - """ - Public. Gets title of the router - :return: the title of the router as str or None - """ - return self._title - - - def set_title(self, title: str) -> None: - """ - Public. Sets the title of the router - :param title: title that will be setted - :return: None - """ - self._title = title diff --git a/tests/system_tests/test_system_handling_non_standard_behavior.py b/tests/system_tests/test_system_handling_non_standard_behavior.py index ae7f32f..3314774 100644 --- a/tests/system_tests/test_system_handling_non_standard_behavior.py +++ b/tests/system_tests/test_system_handling_non_standard_behavior.py @@ -180,7 +180,7 @@ class TestSystemHandlerNormalWork(TestCase): app = App(override_system_messages=True, print_func=print) app.include_router(router) - app.set_invalid_input_flags_handler(lambda command: print(f'Incorrect flag syntax: "{command}"')) + app.set_incorrect_input_syntax_handler(lambda command: print(f'Incorrect flag syntax: "{command}"')) orchestrator.start_polling(app) output = mock_stdout.getvalue() diff --git a/tests/unit_tests/test_router.py b/tests/unit_tests/test_router.py index c6af57a..0284111 100644 --- a/tests/unit_tests/test_router.py +++ b/tests/unit_tests/test_router.py @@ -12,9 +12,6 @@ import re class TestRouter(unittest.TestCase): - def test_get_router_title(self): - self.assertEqual(Router(title='test title').get_title(), 'test title') - def test_register_command_with_spaces_in_trigger(self): router = Router() with self.assertRaises(TriggerContainSpacesException):