mirror of
https://github.com/koloideal/Argenta.git
synced 2026-06-10 10:05:28 +03:00
first beta - adding hints for similar commands, now - feature freezing
This commit is contained in:
+2
-8
@@ -11,13 +11,7 @@ from argenta.router import Router
|
||||
from argenta.orchestrator import Orchestrator
|
||||
|
||||
from argenta.command.models import InputCommand
|
||||
from argenta.app.utils import most_similar_command
|
||||
|
||||
|
||||
while True:
|
||||
cmd = input(">>> ")
|
||||
if cmd == "exit":
|
||||
break
|
||||
else:
|
||||
parse_cmd: InputCommand = InputCommand.parse(cmd)
|
||||
print(f'name: {parse_cmd.get_trigger()}\n'
|
||||
f'flags: {parse_cmd.get_input_flags().get_flags()}\n')
|
||||
print(most_similar_command('case', ['case', 'tester', 'poster', 'caser']))
|
||||
|
||||
@@ -2,8 +2,7 @@ from rich.console import Console
|
||||
|
||||
from argenta.command import Command
|
||||
from argenta.command.flag.defaults import PredefinedFlags
|
||||
from argenta.command.flag.models import Flag
|
||||
from argenta.command.flags.models import Flags
|
||||
from argenta.command.flags import Flags
|
||||
from argenta.response import Response
|
||||
from argenta.router import Router
|
||||
|
||||
@@ -13,8 +12,7 @@ work_router: Router = Router(title='Work points:')
|
||||
console = Console()
|
||||
|
||||
|
||||
@work_router.command(Command('get', 'Get Help', aliases=['help', 'Get_help'], flags=Flags(PredefinedFlags.PORT,
|
||||
PredefinedFlags.HOST)))
|
||||
@work_router.command(Command('get', 'Get Help', aliases=['help', 'Get_help'], flags=Flags(PredefinedFlags.PORT, PredefinedFlags.HOST)))
|
||||
def command_help(response: Response):
|
||||
print(response.status)
|
||||
print(response.undefined_flags.get_flags())
|
||||
|
||||
@@ -12,7 +12,7 @@ from argenta.orchestrator.argparser.arguments import BooleanArgument
|
||||
arg_parser = ArgParser(processed_args=[BooleanArgument('repeat')])
|
||||
app: App = App(dividing_line=DynamicDividingLine(),
|
||||
autocompleter=AutoCompleter('./mock/.hist'),
|
||||
repeat_command_groups=False)
|
||||
repeat_command_groups=False,)
|
||||
orchestrator: Orchestrator = Orchestrator(arg_parser)
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "argenta"
|
||||
version = "1.0.0-alpha5"
|
||||
version = "1.0.0-beta1"
|
||||
description = "Python library for creating TUI"
|
||||
authors = [{ name = "kolo", email = "kolo.is.main@gmail.com" }]
|
||||
requires-python = ">=3.11, <4.0"
|
||||
|
||||
+36
-13
@@ -219,22 +219,43 @@ class BaseApp:
|
||||
self._registered_routers.add_registered_router(system_router)
|
||||
|
||||
|
||||
def _most_similar_command(self, unknown_command: str) -> str | None:
|
||||
all_commands = self._all_registered_triggers_in_lower if self._ignore_command_register else self._all_registered_triggers_in_default_case
|
||||
matches: list[str] | list = sorted(cmd for cmd in all_commands if cmd.startswith(unknown_command))
|
||||
if not matches:
|
||||
matches: list[str] | list = sorted(cmd for cmd in all_commands if unknown_command.startswith(cmd))
|
||||
if len(matches) == 1:
|
||||
return matches[0]
|
||||
elif len(matches) > 1:
|
||||
return sorted(matches, key=lambda cmd: len(cmd))[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def _setup_default_view(self) -> None:
|
||||
"""
|
||||
Private. Sets up default app view
|
||||
:return: None
|
||||
"""
|
||||
if not self._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')
|
||||
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._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')
|
||||
self._unknown_command_handler = lambda command: self._print_func(f"[red bold]Unknown command: {escape(command.get_trigger())}")
|
||||
self._prompt = '[italic dim bold]What do you want to do?\n'
|
||||
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')
|
||||
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._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')
|
||||
|
||||
def unknown_command_handler(command: InputCommand) -> None:
|
||||
cmd_trg: str = command.get_trigger()
|
||||
mst_sim_cmd: str | None = self._most_similar_command(cmd_trg)
|
||||
first_part_of_text = f"[red]Unknown command:[/red] [blue]{escape(cmd_trg)}[/blue]"
|
||||
second_part_of_text = ('[red], most similar:[/red] ' + ('[blue]' + mst_sim_cmd + '[/blue]')) if mst_sim_cmd else ''
|
||||
self._print_func(first_part_of_text + second_part_of_text)
|
||||
|
||||
self._unknown_command_handler = unknown_command_handler
|
||||
|
||||
|
||||
def _pre_cycle_setup(self) -> None:
|
||||
@@ -242,7 +263,6 @@ class BaseApp:
|
||||
Private. Configures various aspects of the application before the start of the cycle
|
||||
:return: None
|
||||
"""
|
||||
self._setup_default_view()
|
||||
self._setup_system_router()
|
||||
|
||||
for router_entity in self._registered_routers:
|
||||
@@ -254,6 +274,9 @@ class BaseApp:
|
||||
|
||||
self._autocompleter.initial_setup(self._all_registered_triggers_in_lower)
|
||||
|
||||
if not self._override_system_messages:
|
||||
self._setup_default_view()
|
||||
|
||||
self._print_func(self._initial_message)
|
||||
|
||||
for message in self._messages_on_startup:
|
||||
@@ -268,7 +291,7 @@ class BaseApp:
|
||||
|
||||
class App(BaseApp):
|
||||
def __init__(self,
|
||||
prompt: str = '[italic dim bold]What do you want to do?\n',
|
||||
prompt: str = 'What do you want to do?\n',
|
||||
initial_message: str = '\nArgenta\n',
|
||||
farewell_message: str = '\nSee you\n',
|
||||
exit_command: Command = Command('Q', 'Exit command'),
|
||||
|
||||
@@ -139,11 +139,11 @@ class InputCommand(BaseCommand, Generic[InputCommandType]):
|
||||
|
||||
for k, _ in enumerate(list_of_tokens):
|
||||
if _.startswith('-'):
|
||||
if current_flag_name or len(_) < 2 or len(_[:_.rfind('-')]) > 3:
|
||||
if len(_) < 2 or len(_[:_.rfind('-')]) > 3:
|
||||
raise UnprocessedInputFlagException()
|
||||
current_flag_name = _
|
||||
else:
|
||||
if not current_flag_name:
|
||||
if not current_flag_name or current_flag_value:
|
||||
raise UnprocessedInputFlagException()
|
||||
current_flag_value = _
|
||||
|
||||
@@ -153,9 +153,9 @@ class InputCommand(BaseCommand, Generic[InputCommandType]):
|
||||
continue
|
||||
|
||||
input_flag = InputFlag(name=current_flag_name[current_flag_name.rfind('-') + 1:],
|
||||
prefix=cast(Literal['-', '--', '---'],
|
||||
current_flag_name[:current_flag_name.rfind('-')+1]),
|
||||
value=current_flag_value)
|
||||
prefix=cast(Literal['-', '--', '---'],
|
||||
current_flag_name[:current_flag_name.rfind('-')+1]),
|
||||
value=current_flag_value)
|
||||
|
||||
all_flags = [flag.get_string_entity() for flag in input_flags.get_flags()]
|
||||
if input_flag.get_string_entity() not in all_flags:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from typing import Callable, Literal
|
||||
from inspect import getfullargspec
|
||||
from typing import Callable, Literal, Type
|
||||
from inspect import getfullargspec, get_annotations
|
||||
from rich.console import Console
|
||||
|
||||
from argenta.command import Command
|
||||
from argenta.command.models import InputCommand
|
||||
from argenta.response import Response, Status
|
||||
@@ -12,8 +14,7 @@ from argenta.router.exceptions import (RepeatedFlagNameException,
|
||||
|
||||
|
||||
class Router:
|
||||
def __init__(self,
|
||||
title: str = None):
|
||||
def __init__(self, title: str = None):
|
||||
"""
|
||||
Public. Directly configures and manages handlers
|
||||
:param title: the title of the router, displayed when displaying the available commands
|
||||
@@ -157,6 +158,12 @@ class Router:
|
||||
elif len(transferred_args) == 0:
|
||||
raise RequiredArgumentNotPassedException()
|
||||
|
||||
arg_annotation: Type = get_annotations(func)[transferred_args[0]]
|
||||
if not arg_annotation is Response:
|
||||
Console().print(f'\n\n[b red]WARNING:[/b red] [i]The type of argument passed to the handler is [/i][blue]{Response}[/blue],'
|
||||
f' [i]but[/i] [bold blue]{arg_annotation}[/bold blue] [i]is specified[/i]', highlight=False)
|
||||
|
||||
|
||||
|
||||
def set_command_register_ignore(self, _: bool) -> None:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user