mirror of
https://github.com/koloideal/Argenta.git
synced 2026-06-10 10:05:28 +03:00
new models, logic refactor, renaminf constants and other
This commit is contained in:
+23
-43
@@ -8,12 +8,12 @@ from argenta.router.defaults import system_router
|
|||||||
from argenta.command.exceptions import (UnprocessedInputFlagException,
|
from argenta.command.exceptions import (UnprocessedInputFlagException,
|
||||||
RepeatedInputFlagsException,
|
RepeatedInputFlagsException,
|
||||||
EmptyInputCommandException)
|
EmptyInputCommandException)
|
||||||
from .exceptions import (InvalidRouterInstanceException,
|
from argenta.app.exceptions import (InvalidRouterInstanceException,
|
||||||
InvalidDescriptionMessagePatternException,
|
InvalidDescriptionMessagePatternException,
|
||||||
NoRegisteredRoutersException,
|
NoRegisteredRoutersException,
|
||||||
NoRegisteredHandlersException,
|
NoRegisteredHandlersException,
|
||||||
RepeatedCommandInDifferentRoutersException,
|
|
||||||
IncorrectNumberOfHandlerArgsException)
|
IncorrectNumberOfHandlerArgsException)
|
||||||
|
from argenta.app.models import RegisteredRouters
|
||||||
|
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
@@ -47,9 +47,8 @@ class App:
|
|||||||
self.repeat_command_groups = repeat_command_groups
|
self.repeat_command_groups = repeat_command_groups
|
||||||
self.messages_on_startup = messages_on_startup if messages_on_startup else []
|
self.messages_on_startup = messages_on_startup if messages_on_startup else []
|
||||||
|
|
||||||
self._routers: list[Router] = []
|
|
||||||
self._description_message_pattern: str = '[{command}] *=*=* {description}'
|
self._description_message_pattern: str = '[{command}] *=*=* {description}'
|
||||||
self._registered_router_entities: list[dict[str, str | list[dict[str, Callable[[], None] | Command]] | Router]] = []
|
self._registered_routers: RegisteredRouters = RegisteredRouters()
|
||||||
self._invalid_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'Incorrect flag syntax: "{raw_command}"')
|
self._invalid_input_flags_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._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(f'Empty input command')
|
self._empty_input_command_handler: Callable[[], None] = lambda: print_func(f'Empty input command')
|
||||||
@@ -61,7 +60,6 @@ class App:
|
|||||||
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._validate_all_router_commands()
|
|
||||||
|
|
||||||
self.print_func(self.initial_message)
|
self.print_func(self.initial_message)
|
||||||
|
|
||||||
@@ -122,8 +120,8 @@ class App:
|
|||||||
self.print_func(self.prompt)
|
self.print_func(self.prompt)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for router in self._routers:
|
for registered_router in self._registered_routers:
|
||||||
router.input_command_handler(input_command)
|
registered_router.input_command_handler(input_command)
|
||||||
|
|
||||||
self.print_func(self.line_separate)
|
self.print_func(self.line_separate)
|
||||||
self.print_func(self.command_group_description_separate)
|
self.print_func(self.command_group_description_separate)
|
||||||
@@ -198,49 +196,31 @@ class App:
|
|||||||
raise InvalidRouterInstanceException()
|
raise InvalidRouterInstanceException()
|
||||||
|
|
||||||
router.set_ignore_command_register(self.ignore_command_register)
|
router.set_ignore_command_register(self.ignore_command_register)
|
||||||
self._routers.append(router)
|
self._registered_routers.add_registered_router(router)
|
||||||
|
|
||||||
command_entities: list[dict[str, Callable[[], None] | Command]] = router.get_command_entities()
|
|
||||||
self._registered_router_entities.append({'name': router.get_name(),
|
|
||||||
'title': router.get_title(),
|
|
||||||
'entity': router,
|
|
||||||
'commands': command_entities})
|
|
||||||
|
|
||||||
|
def include_routers(self, *routers: Router) -> None:
|
||||||
|
for router in routers:
|
||||||
|
self.include_router(router)
|
||||||
|
|
||||||
def _validate_number_of_routers(self) -> None:
|
def _validate_number_of_routers(self) -> None:
|
||||||
if not self._routers:
|
if not self._registered_routers:
|
||||||
raise NoRegisteredRoutersException()
|
raise NoRegisteredRoutersException()
|
||||||
|
|
||||||
|
|
||||||
def _validate_included_routers(self) -> None:
|
def _validate_included_routers(self) -> None:
|
||||||
for router in self._routers:
|
for router in self._registered_routers:
|
||||||
if not router.get_command_entities():
|
if not router.get_command_handlers():
|
||||||
raise NoRegisteredHandlersException(router.get_name())
|
raise NoRegisteredHandlersException(router.get_name())
|
||||||
|
|
||||||
|
|
||||||
def _validate_all_router_commands(self) -> None:
|
|
||||||
for idx in range(len(self._registered_router_entities)):
|
|
||||||
current_router: Router = self._registered_router_entities[idx]['entity']
|
|
||||||
routers_without_current_router = self._registered_router_entities.copy()
|
|
||||||
routers_without_current_router.pop(idx)
|
|
||||||
|
|
||||||
current_router_all_commands: list[str] = current_router.get_all_commands()
|
|
||||||
|
|
||||||
for router_entity in routers_without_current_router:
|
|
||||||
if len(set(current_router_all_commands).intersection(set(router_entity['entity'].get_all_commands()))) > 0:
|
|
||||||
raise RepeatedCommandInDifferentRoutersException()
|
|
||||||
if self.ignore_command_register:
|
|
||||||
if len(set([x.lower() for x in current_router_all_commands]).intersection(set([x.lower() for x in router_entity['entity'].get_all_commands()]))) > 0:
|
|
||||||
raise RepeatedCommandInDifferentRoutersException()
|
|
||||||
|
|
||||||
|
|
||||||
def _setup_system_router(self):
|
def _setup_system_router(self):
|
||||||
system_router.set_title(self.system_points_title)
|
system_router.set_title(self.system_points_title)
|
||||||
@system_router.command(Command(self.exit_command, self.exit_command_description))
|
@system_router.command(Command(self.exit_command, self.exit_command_description))
|
||||||
def exit_command():
|
def exit_command():
|
||||||
self._exit_command_handler()
|
self._exit_command_handler()
|
||||||
|
|
||||||
if system_router not in [router['entity'] for router in self._registered_router_entities]:
|
if system_router not in self._registered_routers.get_registered_routers():
|
||||||
self.include_router(system_router)
|
self.include_router(system_router)
|
||||||
|
|
||||||
|
|
||||||
@@ -257,26 +237,26 @@ class App:
|
|||||||
|
|
||||||
|
|
||||||
def _check_is_command_unknown(self, command: Command):
|
def _check_is_command_unknown(self, command: Command):
|
||||||
registered_router_entities: list[dict[str, str | list[dict[str, Callable[[], None] | Command]] | Router]] = self._registered_router_entities
|
for router_entity in self._registered_routers:
|
||||||
for router_entity in registered_router_entities:
|
for command_handler in router_entity.get_command_handlers():
|
||||||
for command_entity in router_entity['commands']:
|
handled_command_trigger = command_handler.get_handled_command().get_trigger()
|
||||||
if command_entity['command'].get_trigger().lower() == command.get_trigger().lower():
|
if handled_command_trigger.lower() == command.get_trigger().lower():
|
||||||
if self.ignore_command_register:
|
if self.ignore_command_register:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
if command_entity['command'].get_trigger() == command.get_trigger():
|
if handled_command_trigger == command.get_trigger():
|
||||||
return False
|
return False
|
||||||
self._unknown_command_handler(command)
|
self._unknown_command_handler(command)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _print_command_group_description(self):
|
def _print_command_group_description(self):
|
||||||
for router_entity in self._registered_router_entities:
|
for registered_router in self._registered_routers:
|
||||||
self.print_func(router_entity['title'])
|
self.print_func(registered_router.get_title())
|
||||||
for command_entity in router_entity['commands']:
|
for command_handler in registered_router.get_command_handlers():
|
||||||
self.print_func(self._description_message_pattern.format(
|
self.print_func(self._description_message_pattern.format(
|
||||||
command=command_entity['command'].get_trigger(),
|
command=command_handler.get_handled_command().get_trigger(),
|
||||||
description=command_entity['command'].get_description()
|
description=command_handler.get_handled_command().get_description()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.print_func(self.command_group_description_separate)
|
self.print_func(self.command_group_description_separate)
|
||||||
|
|||||||
@@ -25,11 +25,6 @@ class NoRegisteredHandlersException(Exception):
|
|||||||
return f"No Registered Handlers Found For '{self.router_name}'"
|
return f"No Registered Handlers Found For '{self.router_name}'"
|
||||||
|
|
||||||
|
|
||||||
class RepeatedCommandInDifferentRoutersException(Exception):
|
|
||||||
def __str__(self):
|
|
||||||
return "Commands in different handlers cannot be repeated"
|
|
||||||
|
|
||||||
|
|
||||||
class IncorrectNumberOfHandlerArgsException(Exception):
|
class IncorrectNumberOfHandlerArgsException(Exception):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Incorrect Input Flags Handler has incorrect number of arguments"
|
return "Incorrect Input Flags Handler has incorrect number of arguments"
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
from argenta.router import Router
|
||||||
|
|
||||||
|
|
||||||
|
class RegisteredRouters:
|
||||||
|
def __init__(self, registered_routers: list[Router] = None) -> None:
|
||||||
|
self._registered_routers = registered_routers if registered_routers else []
|
||||||
|
|
||||||
|
def get_registered_routers(self) -> list[Router]:
|
||||||
|
return self._registered_routers
|
||||||
|
|
||||||
|
def add_registered_router(self, router: Router):
|
||||||
|
self._registered_routers.append(router)
|
||||||
|
|
||||||
|
def add_registered_routers(self, *routers: Router):
|
||||||
|
self._registered_routers.extend(routers)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self._registered_routers)
|
||||||
|
|
||||||
|
def __next__(self):
|
||||||
|
return next(iter(self._registered_routers))
|
||||||
@@ -5,17 +5,17 @@ import re
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class DefaultFlags:
|
class DefaultFlags:
|
||||||
help_flag = Flag(flag_name='help', possible_flag_values=False)
|
HELP = Flag(flag_name='help', possible_flag_values=False)
|
||||||
short_help_flag = Flag(flag_name='h', flag_prefix='-', possible_flag_values=False)
|
SHORT_HELP = Flag(flag_name='h', flag_prefix='-', possible_flag_values=False)
|
||||||
|
|
||||||
info_flag = Flag(flag_name='info', possible_flag_values=False)
|
INFO = Flag(flag_name='info', possible_flag_values=False)
|
||||||
short_info_flag = Flag(flag_name='i', flag_prefix='-', possible_flag_values=False)
|
SHORT_INFO = Flag(flag_name='i', flag_prefix='-', possible_flag_values=False)
|
||||||
|
|
||||||
all_flag = Flag(flag_name='all', possible_flag_values=False)
|
ALL = Flag(flag_name='all', possible_flag_values=False)
|
||||||
short_all_flag = Flag(flag_name='a', flag_prefix='-', possible_flag_values=False)
|
SHORT_ALL = Flag(flag_name='a', flag_prefix='-', possible_flag_values=False)
|
||||||
|
|
||||||
host_flag = Flag(flag_name='host', possible_flag_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
|
HOST = Flag(flag_name='host', possible_flag_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
|
||||||
short_host_flag = Flag(flag_name='h', flag_prefix='-', possible_flag_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
|
SHORT_HOST = Flag(flag_name='h', flag_prefix='-', possible_flag_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
|
||||||
|
|
||||||
port_flag = Flag(flag_name='port', possible_flag_values=re.compile(r'^\d{1,5}$'))
|
PORT = Flag(flag_name='port', possible_flag_values=re.compile(r'^\d{1,5}$'))
|
||||||
short_port_flag = Flag(flag_name='p', flag_prefix='-', possible_flag_values=re.compile(r'^\d{1,5}$'))
|
SHORT_PORT = Flag(flag_name='p', flag_prefix='-', possible_flag_values=re.compile(r'^\d{1,5}$'))
|
||||||
|
|||||||
+20
-18
@@ -1,10 +1,10 @@
|
|||||||
from typing import Callable, Any
|
from typing import Callable, Any
|
||||||
from inspect import getfullargspec
|
from inspect import getfullargspec
|
||||||
|
|
||||||
from ..command.entity import Command
|
from argenta.command import Command
|
||||||
from argenta.command.flag.entity import Flag
|
from argenta.router.models import CommandHandler, CommandHandlers
|
||||||
from argenta.command.flag.flags_group import FlagsGroup
|
from argenta.command.flag import Flag, FlagsGroup
|
||||||
from ..router.exceptions import (RepeatedCommandException,
|
from argenta.router.exceptions import (RepeatedCommandException,
|
||||||
RepeatedFlagNameException,
|
RepeatedFlagNameException,
|
||||||
TooManyTransferredArgsException,
|
TooManyTransferredArgsException,
|
||||||
RequiredArgumentNotPassedException,
|
RequiredArgumentNotPassedException,
|
||||||
@@ -20,7 +20,7 @@ class Router:
|
|||||||
self._title = title
|
self._title = title
|
||||||
self._name = name
|
self._name = name
|
||||||
|
|
||||||
self._command_entities: list[dict[str, Callable[[], None] | Command]] = []
|
self._command_handlers: CommandHandlers = CommandHandlers()
|
||||||
self._ignore_command_register: bool = False
|
self._ignore_command_register: bool = False
|
||||||
|
|
||||||
self._not_valid_flag_handler: Callable[[Flag], None] = lambda flag: print(f"Undefined or incorrect input flag: {flag.get_string_entity()}{(' '+flag.get_value()) if flag.get_value() else ''}")
|
self._not_valid_flag_handler: Callable[[Flag], None] = lambda flag: print(f"Undefined or incorrect input flag: {flag.get_string_entity()}{(' '+flag.get_value()) if flag.get_value() else ''}")
|
||||||
@@ -31,14 +31,15 @@ class Router:
|
|||||||
|
|
||||||
def command_decorator(func):
|
def command_decorator(func):
|
||||||
Router._validate_func_args(command, func)
|
Router._validate_func_args(command, func)
|
||||||
self._command_entities.append({'handler_func': func,
|
self._command_handlers.add_command_handler(CommandHandler(func, command))
|
||||||
'command': command})
|
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
return command_decorator
|
return command_decorator
|
||||||
|
|
||||||
|
|
||||||
def set_invalid_input_flag_handler(self, func):
|
def set_invalid_input_flag_handler(self, func):
|
||||||
processed_args = getfullargspec(func).args
|
processed_args = getfullargspec(func).args
|
||||||
if len(processed_args) != 1:
|
if len(processed_args) != 1:
|
||||||
@@ -50,24 +51,25 @@ class Router:
|
|||||||
def input_command_handler(self, input_command: Command):
|
def input_command_handler(self, input_command: Command):
|
||||||
input_command_name: str = input_command.get_trigger()
|
input_command_name: str = input_command.get_trigger()
|
||||||
input_command_flags: FlagsGroup = input_command.get_input_flags()
|
input_command_flags: FlagsGroup = input_command.get_input_flags()
|
||||||
for command_entity in self._command_entities:
|
for command_handler in self._command_handlers:
|
||||||
if input_command_name.lower() == command_entity['command'].get_trigger().lower():
|
handle_command = command_handler.get_handled_command()
|
||||||
if command_entity['command'].get_registered_flags():
|
if input_command_name.lower() == handle_command.get_trigger().lower():
|
||||||
|
if handle_command.get_registered_flags():
|
||||||
if input_command_flags:
|
if input_command_flags:
|
||||||
for flag in input_command_flags:
|
for flag in input_command_flags:
|
||||||
is_valid = command_entity['command'].validate_input_flag(flag)
|
is_valid = handle_command.validate_input_flag(flag)
|
||||||
if not is_valid:
|
if not is_valid:
|
||||||
self._not_valid_flag_handler(flag)
|
self._not_valid_flag_handler(flag)
|
||||||
return
|
return
|
||||||
return command_entity['handler_func'](input_command_flags.unparse_to_dict())
|
return command_handler.handling(input_command_flags.unparse_to_dict())
|
||||||
else:
|
else:
|
||||||
return command_entity['handler_func']({})
|
return command_handler.handling({})
|
||||||
else:
|
else:
|
||||||
if input_command_flags:
|
if input_command_flags:
|
||||||
self._not_valid_flag_handler(input_command_flags[0])
|
self._not_valid_flag_handler(input_command_flags[0])
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
return command_entity['handler_func']()
|
return command_handler.handling()
|
||||||
|
|
||||||
|
|
||||||
def _validate_command(self, command: Command):
|
def _validate_command(self, command: Command):
|
||||||
@@ -104,8 +106,8 @@ class Router:
|
|||||||
self._ignore_command_register = ignore_command_register
|
self._ignore_command_register = ignore_command_register
|
||||||
|
|
||||||
|
|
||||||
def get_command_entities(self) -> list[dict[str, Callable[[], None] | Command]]:
|
def get_command_handlers(self) -> CommandHandlers:
|
||||||
return self._command_entities
|
return self._command_handlers
|
||||||
|
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_name(self) -> str:
|
||||||
@@ -122,7 +124,7 @@ class Router:
|
|||||||
|
|
||||||
def get_all_commands(self) -> list[str]:
|
def get_all_commands(self) -> list[str]:
|
||||||
all_commands: list[str] = []
|
all_commands: list[str] = []
|
||||||
for command_entity in self._command_entities:
|
for command_handler in self._command_handlers:
|
||||||
all_commands.append(command_entity['command'].get_trigger())
|
all_commands.append(command_handler.get_handled_command().get_trigger())
|
||||||
|
|
||||||
return all_commands
|
return all_commands
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
from typing import Callable
|
||||||
|
from argenta.command import Command
|
||||||
|
|
||||||
|
|
||||||
|
class CommandHandler:
|
||||||
|
def __init__(self, handler: Callable[[], None] | Callable[[dict], None], handled_command: Command):
|
||||||
|
self.handler = handler
|
||||||
|
self.handled_command = handled_command
|
||||||
|
|
||||||
|
def handling(self, input_flags: dict = None):
|
||||||
|
if input_flags is not None:
|
||||||
|
self.handler(input_flags)
|
||||||
|
else:
|
||||||
|
self.handler()
|
||||||
|
|
||||||
|
def get_handler(self):
|
||||||
|
return self.handler
|
||||||
|
|
||||||
|
def get_handled_command(self):
|
||||||
|
return self.handled_command
|
||||||
|
|
||||||
|
|
||||||
|
class CommandHandlers:
|
||||||
|
def __init__(self, command_handlers: list[CommandHandler] = None):
|
||||||
|
self.command_handlers = command_handlers if command_handlers else []
|
||||||
|
|
||||||
|
def get_command_handlers(self) -> list[CommandHandler]:
|
||||||
|
return self.command_handlers
|
||||||
|
|
||||||
|
def add_command_handler(self, command_handler: CommandHandler):
|
||||||
|
self.command_handlers.append(command_handler)
|
||||||
|
|
||||||
|
def add_command_handlers(self, *command_handlers: CommandHandler):
|
||||||
|
self.command_handlers.extend(command_handlers)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self.command_handlers)
|
||||||
|
|
||||||
|
def __next__(self):
|
||||||
|
return next(iter(self.command_handlers))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ def command_help():
|
|||||||
help_command()
|
help_command()
|
||||||
|
|
||||||
|
|
||||||
@work_router.command(Command(trigger='P', description='Start Solving', flags=FlagsGroup(DefaultFlags.host_flag, DefaultFlags.port_flag)))
|
@work_router.command(Command(trigger='P', description='Start Solving', flags=FlagsGroup(DefaultFlags.HOST, DefaultFlags.PORT)))
|
||||||
def command_start_solving(args: dict):
|
def command_start_solving(args: dict):
|
||||||
print('Solving...')
|
print('Solving...')
|
||||||
pprint(args)
|
pprint(args)
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ app: App = App(prompt='[italic white bold]What do you want to do(enter number of
|
|||||||
line_separate=f'\n{"[bold green]-[/bold green][bold red]-[/bold red]"*25}\n',
|
line_separate=f'\n{"[bold green]-[/bold green][bold red]-[/bold red]"*25}\n',
|
||||||
print_func=Console().print,
|
print_func=Console().print,
|
||||||
command_group_description_separate='',
|
command_group_description_separate='',
|
||||||
repeat_command_groups=True,
|
repeat_command_groups=True)
|
||||||
ignore_exit_command_register=False)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@@ -20,8 +19,7 @@ def main():
|
|||||||
ascii_goodbye_message: str = text2art('GoodBye', font='small')
|
ascii_goodbye_message: str = text2art('GoodBye', font='small')
|
||||||
goodbye_message: str = f'[bold red]\n{ascii_goodbye_message}{' '*12}made by kolo\n'
|
goodbye_message: str = f'[bold red]\n{ascii_goodbye_message}{' '*12}made by kolo\n'
|
||||||
|
|
||||||
app.include_router(work_router)
|
app.include_routers(work_router, settings_router)
|
||||||
app.include_router(settings_router)
|
|
||||||
|
|
||||||
app.set_initial_message(initial_greeting)
|
app.set_initial_message(initial_greeting)
|
||||||
app.set_farewell_message(goodbye_message)
|
app.set_farewell_message(goodbye_message)
|
||||||
|
|||||||
Reference in New Issue
Block a user