argenta 1.0.0b2__py3-none-any.whl → 1.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- argenta/app/autocompleter/entity.py +30 -11
- argenta/app/defaults.py +3 -3
- argenta/app/dividing_line/models.py +8 -10
- argenta/app/models.py +181 -114
- argenta/app/registered_routers/entity.py +1 -1
- argenta/command/__init__.py +1 -1
- argenta/command/exceptions.py +9 -2
- argenta/command/flag/defaults.py +17 -10
- argenta/command/flag/models.py +14 -11
- argenta/command/flags/__init__.py +14 -8
- argenta/command/flags/models.py +11 -8
- argenta/command/models.py +61 -36
- argenta/orchestrator/argparser/__init__.py +1 -1
- argenta/orchestrator/argparser/arguments/__init__.py +5 -3
- argenta/orchestrator/argparser/arguments/models.py +3 -2
- argenta/orchestrator/argparser/entity.py +22 -12
- argenta/orchestrator/entity.py +0 -1
- argenta/response/entity.py +13 -11
- argenta/response/status.py +4 -5
- argenta/router/__init__.py +1 -1
- argenta/router/command_handler/entity.py +1 -1
- argenta/router/defaults.py +1 -1
- argenta/router/entity.py +60 -60
- argenta/router/exceptions.py +4 -0
- argenta-1.0.2.dist-info/METADATA +71 -0
- argenta-1.0.2.dist-info/RECORD +37 -0
- argenta-1.0.0b2.dist-info/METADATA +0 -1340
- argenta-1.0.0b2.dist-info/RECORD +0 -37
- {argenta-1.0.0b2.dist-info → argenta-1.0.2.dist-info}/WHEEL +0 -0
- {argenta-1.0.0b2.dist-info → argenta-1.0.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,9 +1,12 @@
|
|
1
1
|
import os
|
2
2
|
import readline
|
3
|
+
from typing import Never
|
3
4
|
|
4
5
|
|
5
6
|
class AutoCompleter:
|
6
|
-
def __init__(
|
7
|
+
def __init__(
|
8
|
+
self, history_filename: str = False, autocomplete_button: str = "tab"
|
9
|
+
) -> None:
|
7
10
|
"""
|
8
11
|
Public. Configures and implements auto-completion of input command
|
9
12
|
:param history_filename: the name of the file for saving the history of the autocompleter
|
@@ -12,7 +15,6 @@ class AutoCompleter:
|
|
12
15
|
"""
|
13
16
|
self.history_filename = history_filename
|
14
17
|
self.autocomplete_button = autocomplete_button
|
15
|
-
self.matches: list[str] = []
|
16
18
|
|
17
19
|
def _complete(self, text, state) -> str | None:
|
18
20
|
"""
|
@@ -21,16 +23,22 @@ class AutoCompleter:
|
|
21
23
|
:param state: the current cursor position is relative to the beginning of the line
|
22
24
|
:return: the desired candidate as str or None
|
23
25
|
"""
|
24
|
-
matches: list[str] = sorted(
|
26
|
+
matches: list[str] = sorted(
|
27
|
+
cmd for cmd in self.get_history_items() if cmd.startswith(text)
|
28
|
+
)
|
25
29
|
if len(matches) > 1:
|
26
30
|
common_prefix = matches[0]
|
27
31
|
for match in matches[1:]:
|
28
32
|
i = 0
|
29
|
-
while
|
33
|
+
while (
|
34
|
+
i < len(common_prefix)
|
35
|
+
and i < len(match)
|
36
|
+
and common_prefix[i] == match[i]
|
37
|
+
):
|
30
38
|
i += 1
|
31
39
|
common_prefix = common_prefix[:i]
|
32
40
|
if state == 0:
|
33
|
-
readline.insert_text(common_prefix[len(text):])
|
41
|
+
readline.insert_text(common_prefix[len(text) :])
|
34
42
|
readline.redisplay()
|
35
43
|
return None
|
36
44
|
elif len(matches) == 1:
|
@@ -52,21 +60,32 @@ class AutoCompleter:
|
|
52
60
|
readline.add_history(line)
|
53
61
|
|
54
62
|
readline.set_completer(self._complete)
|
55
|
-
readline.set_completer_delims(readline.get_completer_delims().replace(
|
56
|
-
readline.parse_and_bind(f
|
63
|
+
readline.set_completer_delims(readline.get_completer_delims().replace(" ", ""))
|
64
|
+
readline.parse_and_bind(f"{self.autocomplete_button}: complete")
|
57
65
|
|
58
|
-
def exit_setup(self) -> None:
|
66
|
+
def exit_setup(self, all_commands: list[str]) -> None:
|
59
67
|
"""
|
60
68
|
Private. Exit setup function
|
61
69
|
:return: None
|
62
70
|
"""
|
63
71
|
if self.history_filename:
|
64
72
|
readline.write_history_file(self.history_filename)
|
73
|
+
with open(self.history_filename, "r") as history_file:
|
74
|
+
raw_history = history_file.read()
|
75
|
+
pretty_history: list[str] = []
|
76
|
+
for line in set(raw_history.strip().split("\n")):
|
77
|
+
if line.split()[0] in all_commands:
|
78
|
+
pretty_history.append(line)
|
79
|
+
with open(self.history_filename, "w") as history_file:
|
80
|
+
history_file.write("\n".join(pretty_history))
|
65
81
|
|
66
82
|
@staticmethod
|
67
|
-
def get_history_items() -> list[str] | list:
|
83
|
+
def get_history_items() -> list[str] | list[Never]:
|
68
84
|
"""
|
69
85
|
Private. Returns a list of all commands entered by the user
|
70
|
-
:return: all commands entered by the user as list[str]
|
86
|
+
:return: all commands entered by the user as list[str] | list[Never]
|
71
87
|
"""
|
72
|
-
return [
|
88
|
+
return [
|
89
|
+
readline.get_history_item(i)
|
90
|
+
for i in range(1, readline.get_current_history_length() + 1)
|
91
|
+
]
|
argenta/app/defaults.py
CHANGED
@@ -6,7 +6,7 @@ class PredefinedMessages:
|
|
6
6
|
"""
|
7
7
|
Public. A dataclass with predetermined messages for quick use
|
8
8
|
"""
|
9
|
-
USAGE = '[b dim]Usage[/b dim]: [i]<command> <[green]flags[/green]>[/i]'
|
10
|
-
HELP = '[b dim]Help[/b dim]: [i]<command>[/i] [b red]--help[/b red]'
|
11
|
-
AUTOCOMPLETE = '[b dim]Autocomplete[/b dim]: [i]<part>[/i] [bold]<tab>'
|
12
9
|
|
10
|
+
USAGE = "[b dim]Usage[/b dim]: [i]<command> <[green]flags[/green]>[/i]"
|
11
|
+
HELP = "[b dim]Help[/b dim]: [i]<command>[/i] [b red]--help[/b red]"
|
12
|
+
AUTOCOMPLETE = "[b dim]Autocomplete[/b dim]: [i]<part>[/i] [bold]<tab>"
|
@@ -2,7 +2,7 @@ from abc import ABC
|
|
2
2
|
|
3
3
|
|
4
4
|
class BaseDividingLine(ABC):
|
5
|
-
def __init__(self, unit_part: str =
|
5
|
+
def __init__(self, unit_part: str = "-") -> None:
|
6
6
|
"""
|
7
7
|
Private. The basic dividing line
|
8
8
|
:param unit_part: the single part of the dividing line
|
@@ -16,13 +16,13 @@ class BaseDividingLine(ABC):
|
|
16
16
|
:return: unit_part of dividing line as str
|
17
17
|
"""
|
18
18
|
if len(self._unit_part) == 0:
|
19
|
-
return
|
19
|
+
return " "
|
20
20
|
else:
|
21
21
|
return self._unit_part[0]
|
22
22
|
|
23
23
|
|
24
24
|
class StaticDividingLine(BaseDividingLine):
|
25
|
-
def __init__(self, unit_part: str =
|
25
|
+
def __init__(self, unit_part: str = "-", length: int = 25) -> None:
|
26
26
|
"""
|
27
27
|
Public. The static dividing line
|
28
28
|
:param unit_part: the single part of the dividing line
|
@@ -39,13 +39,13 @@ class StaticDividingLine(BaseDividingLine):
|
|
39
39
|
:return: full line of dividing line as str
|
40
40
|
"""
|
41
41
|
if is_override:
|
42
|
-
return f
|
42
|
+
return f"\n{self.length * self.get_unit_part()}\n"
|
43
43
|
else:
|
44
|
-
return f
|
44
|
+
return f"\n[dim]{self.length * self.get_unit_part()}[/dim]\n"
|
45
45
|
|
46
46
|
|
47
47
|
class DynamicDividingLine(BaseDividingLine):
|
48
|
-
def __init__(self, unit_part: str =
|
48
|
+
def __init__(self, unit_part: str = "-") -> None:
|
49
49
|
"""
|
50
50
|
Public. The dynamic dividing line
|
51
51
|
:param unit_part: the single part of the dividing line
|
@@ -61,8 +61,6 @@ class DynamicDividingLine(BaseDividingLine):
|
|
61
61
|
:return: full line of dividing line as str
|
62
62
|
"""
|
63
63
|
if is_override:
|
64
|
-
return f
|
64
|
+
return f"\n{length * self.get_unit_part()}\n"
|
65
65
|
else:
|
66
|
-
return f
|
67
|
-
|
68
|
-
|
66
|
+
return f"\n[dim]{self.get_unit_part() * length}[/dim]\n"
|
argenta/app/models.py
CHANGED
@@ -11,29 +11,31 @@ from argenta.router import Router
|
|
11
11
|
from argenta.router.defaults import system_router
|
12
12
|
from argenta.app.autocompleter import AutoCompleter
|
13
13
|
from argenta.app.dividing_line.models import StaticDividingLine, DynamicDividingLine
|
14
|
-
from argenta.command.exceptions import (
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
from argenta.command.exceptions import (
|
15
|
+
UnprocessedInputFlagException,
|
16
|
+
RepeatedInputFlagsException,
|
17
|
+
EmptyInputCommandException,
|
18
|
+
BaseInputCommandException,
|
19
|
+
)
|
18
20
|
from argenta.app.registered_routers.entity import RegisteredRouters
|
19
21
|
from argenta.response import Response
|
20
22
|
|
21
23
|
|
22
|
-
|
23
24
|
class BaseApp:
|
24
|
-
def __init__(
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
25
|
+
def __init__(
|
26
|
+
self,
|
27
|
+
prompt: str,
|
28
|
+
initial_message: str,
|
29
|
+
farewell_message: str,
|
30
|
+
exit_command: Command,
|
31
|
+
system_router_title: str | None,
|
32
|
+
ignore_command_register: bool,
|
33
|
+
dividing_line: StaticDividingLine | DynamicDividingLine,
|
34
|
+
repeat_command_groups: bool,
|
35
|
+
override_system_messages: bool,
|
36
|
+
autocompleter: AutoCompleter,
|
37
|
+
print_func: Callable[[str], None],
|
38
|
+
) -> None:
|
37
39
|
self._prompt = prompt
|
38
40
|
self._print_func = print_func
|
39
41
|
self._exit_command = exit_command
|
@@ -47,20 +49,30 @@ class BaseApp:
|
|
47
49
|
self._farewell_message = farewell_message
|
48
50
|
self._initial_message = initial_message
|
49
51
|
|
50
|
-
|
51
|
-
|
52
|
+
self._description_message_gen: Callable[[str, str], str] = (
|
53
|
+
lambda command, description: f"[{command}] *=*=* {description}"
|
54
|
+
)
|
52
55
|
self._registered_routers: RegisteredRouters = RegisteredRouters()
|
53
56
|
self._messages_on_startup: list[str] = []
|
54
57
|
|
55
58
|
self._all_registered_triggers_in_lower: list[str] = []
|
56
59
|
self._all_registered_triggers_in_default_case: list[str] = []
|
57
60
|
|
58
|
-
self.
|
59
|
-
|
60
|
-
|
61
|
-
self.
|
62
|
-
|
63
|
-
|
61
|
+
self._incorrect_input_syntax_handler: Callable[[str], None] = (
|
62
|
+
lambda raw_command: print_func(f"Incorrect flag syntax: {raw_command}")
|
63
|
+
)
|
64
|
+
self._repeated_input_flags_handler: Callable[[str], None] = (
|
65
|
+
lambda raw_command: print_func(f"Repeated input flags: {raw_command}")
|
66
|
+
)
|
67
|
+
self._empty_input_command_handler: Callable[[], None] = lambda: print_func(
|
68
|
+
"Empty input command"
|
69
|
+
)
|
70
|
+
self._unknown_command_handler: Callable[[InputCommand], None] = (
|
71
|
+
lambda command: print_func(f"Unknown command: {command.get_trigger()}")
|
72
|
+
)
|
73
|
+
self._exit_command_handler: Callable[[Response], None] = (
|
74
|
+
lambda response: print_func(self._farewell_message)
|
75
|
+
)
|
64
76
|
|
65
77
|
def set_description_message_pattern(self, _: Callable[[str, str], str]) -> None:
|
66
78
|
"""
|
@@ -70,15 +82,13 @@ class BaseApp:
|
|
70
82
|
"""
|
71
83
|
self._description_message_gen: Callable[[str, str], str] = _
|
72
84
|
|
73
|
-
|
74
|
-
def set_invalid_input_flags_handler(self, _: Callable[[str], None]) -> None:
|
85
|
+
def set_incorrect_input_syntax_handler(self, _: Callable[[str], None]) -> None:
|
75
86
|
"""
|
76
87
|
Public. Sets the handler for incorrect flags when entering a command
|
77
88
|
:param _: handler for incorrect flags when entering a command
|
78
89
|
:return: None
|
79
90
|
"""
|
80
|
-
self.
|
81
|
-
|
91
|
+
self._incorrect_input_syntax_handler = _
|
82
92
|
|
83
93
|
def set_repeated_input_flags_handler(self, _: Callable[[str], None]) -> None:
|
84
94
|
"""
|
@@ -88,7 +98,6 @@ class BaseApp:
|
|
88
98
|
"""
|
89
99
|
self._repeated_input_flags_handler = _
|
90
100
|
|
91
|
-
|
92
101
|
def set_unknown_command_handler(self, _: Callable[[str], None]) -> None:
|
93
102
|
"""
|
94
103
|
Public. Sets the handler for unknown commands when entering a command
|
@@ -97,7 +106,6 @@ class BaseApp:
|
|
97
106
|
"""
|
98
107
|
self._unknown_command_handler = _
|
99
108
|
|
100
|
-
|
101
109
|
def set_empty_command_handler(self, _: Callable[[], None]) -> None:
|
102
110
|
"""
|
103
111
|
Public. Sets the handler for empty commands when entering a command
|
@@ -106,7 +114,6 @@ class BaseApp:
|
|
106
114
|
"""
|
107
115
|
self._empty_input_command_handler = _
|
108
116
|
|
109
|
-
|
110
117
|
def set_exit_command_handler(self, _: Callable[[], None]) -> None:
|
111
118
|
"""
|
112
119
|
Public. Sets the handler for exit command when entering a command
|
@@ -115,21 +122,22 @@ class BaseApp:
|
|
115
122
|
"""
|
116
123
|
self._exit_command_handler = _
|
117
124
|
|
118
|
-
|
119
125
|
def _print_command_group_description(self) -> None:
|
120
126
|
"""
|
121
127
|
Private. Prints the description of the available commands
|
122
128
|
:return: None
|
123
129
|
"""
|
124
130
|
for registered_router in self._registered_routers:
|
125
|
-
if registered_router.
|
126
|
-
self._print_func(registered_router.
|
131
|
+
if registered_router.title:
|
132
|
+
self._print_func(registered_router.title)
|
127
133
|
for command_handler in registered_router.get_command_handlers():
|
128
|
-
self._print_func(
|
134
|
+
self._print_func(
|
135
|
+
self._description_message_gen(
|
129
136
|
command_handler.get_handled_command().get_trigger(),
|
130
|
-
command_handler.get_handled_command().get_description()
|
131
|
-
|
132
|
-
|
137
|
+
command_handler.get_handled_command().get_description(),
|
138
|
+
)
|
139
|
+
)
|
140
|
+
self._print_func("")
|
133
141
|
|
134
142
|
def _print_framed_text(self, text: str) -> None:
|
135
143
|
"""
|
@@ -138,19 +146,36 @@ class BaseApp:
|
|
138
146
|
:return: None
|
139
147
|
"""
|
140
148
|
if isinstance(self._dividing_line, StaticDividingLine):
|
141
|
-
self._print_func(
|
142
|
-
|
143
|
-
|
149
|
+
self._print_func(
|
150
|
+
self._dividing_line.get_full_static_line(self._override_system_messages)
|
151
|
+
)
|
152
|
+
print(text.strip("\n"))
|
153
|
+
self._print_func(
|
154
|
+
self._dividing_line.get_full_static_line(self._override_system_messages)
|
155
|
+
)
|
144
156
|
|
145
157
|
elif isinstance(self._dividing_line, DynamicDividingLine):
|
146
|
-
clear_text = re.sub(r
|
147
|
-
max_length_line = max([len(line) for line in clear_text.split(
|
148
|
-
max_length_line =
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
158
|
+
clear_text = re.sub(r"\u001b\[[0-9;]*m", "", text)
|
159
|
+
max_length_line = max([len(line) for line in clear_text.split("\n")])
|
160
|
+
max_length_line = (
|
161
|
+
max_length_line
|
162
|
+
if 10 <= max_length_line <= 80
|
163
|
+
else 80
|
164
|
+
if max_length_line > 80
|
165
|
+
else 10
|
166
|
+
)
|
167
|
+
|
168
|
+
self._print_func(
|
169
|
+
self._dividing_line.get_full_dynamic_line(
|
170
|
+
max_length_line, self._override_system_messages
|
171
|
+
)
|
172
|
+
)
|
173
|
+
print(text.strip("\n"))
|
174
|
+
self._print_func(
|
175
|
+
self._dividing_line.get_full_dynamic_line(
|
176
|
+
max_length_line, self._override_system_messages
|
177
|
+
)
|
178
|
+
)
|
154
179
|
|
155
180
|
def _is_exit_command(self, command: InputCommand) -> bool:
|
156
181
|
"""
|
@@ -159,9 +184,14 @@ class BaseApp:
|
|
159
184
|
:return: is it an exit command or not as bool
|
160
185
|
"""
|
161
186
|
if self._ignore_command_register:
|
162
|
-
if
|
187
|
+
if (
|
188
|
+
command.get_trigger().lower()
|
189
|
+
== self._exit_command.get_trigger().lower()
|
190
|
+
):
|
163
191
|
return True
|
164
|
-
elif command.get_trigger().lower() in [
|
192
|
+
elif command.get_trigger().lower() in [
|
193
|
+
x.lower() for x in self._exit_command.get_aliases()
|
194
|
+
]:
|
165
195
|
return True
|
166
196
|
else:
|
167
197
|
if command.get_trigger() == self._exit_command.get_trigger():
|
@@ -170,7 +200,6 @@ class BaseApp:
|
|
170
200
|
return True
|
171
201
|
return False
|
172
202
|
|
173
|
-
|
174
203
|
def _is_unknown_command(self, command: InputCommand) -> bool:
|
175
204
|
"""
|
176
205
|
Private. Checks if the given command is an unknown command
|
@@ -186,8 +215,9 @@ class BaseApp:
|
|
186
215
|
return False
|
187
216
|
return True
|
188
217
|
|
189
|
-
|
190
|
-
|
218
|
+
def _error_handler(
|
219
|
+
self, error: BaseInputCommandException, raw_command: str
|
220
|
+
) -> None:
|
191
221
|
"""
|
192
222
|
Private. Handles parsing errors of the entered command
|
193
223
|
:param error: error being handled
|
@@ -196,19 +226,18 @@ class BaseApp:
|
|
196
226
|
"""
|
197
227
|
match error:
|
198
228
|
case UnprocessedInputFlagException():
|
199
|
-
self.
|
229
|
+
self._incorrect_input_syntax_handler(raw_command)
|
200
230
|
case RepeatedInputFlagsException():
|
201
231
|
self._repeated_input_flags_handler(raw_command)
|
202
232
|
case EmptyInputCommandException():
|
203
233
|
self._empty_input_command_handler()
|
204
234
|
|
205
|
-
|
206
235
|
def _setup_system_router(self) -> None:
|
207
236
|
"""
|
208
237
|
Private. Sets up system router
|
209
238
|
:return: None
|
210
239
|
"""
|
211
|
-
system_router.
|
240
|
+
system_router.title = self._system_router_title
|
212
241
|
|
213
242
|
@system_router.command(self._exit_command)
|
214
243
|
def exit_command(response: Response) -> None:
|
@@ -218,12 +247,19 @@ class BaseApp:
|
|
218
247
|
system_router.set_command_register_ignore(self._ignore_command_register)
|
219
248
|
self._registered_routers.add_registered_router(system_router)
|
220
249
|
|
221
|
-
|
222
250
|
def _most_similar_command(self, unknown_command: str) -> str | None:
|
223
|
-
all_commands =
|
224
|
-
|
251
|
+
all_commands = (
|
252
|
+
self._all_registered_triggers_in_lower
|
253
|
+
if self._ignore_command_register
|
254
|
+
else self._all_registered_triggers_in_default_case
|
255
|
+
)
|
256
|
+
matches: list[str] | list = sorted(
|
257
|
+
cmd for cmd in all_commands if cmd.startswith(unknown_command)
|
258
|
+
)
|
225
259
|
if not matches:
|
226
|
-
matches: list[str] | list = sorted(
|
260
|
+
matches: list[str] | list = sorted(
|
261
|
+
cmd for cmd in all_commands if unknown_command.startswith(cmd)
|
262
|
+
)
|
227
263
|
if len(matches) == 1:
|
228
264
|
return matches[0]
|
229
265
|
elif len(matches) > 1:
|
@@ -231,33 +267,49 @@ class BaseApp:
|
|
231
267
|
else:
|
232
268
|
return None
|
233
269
|
|
234
|
-
|
235
270
|
def _setup_default_view(self) -> None:
|
236
271
|
"""
|
237
272
|
Private. Sets up default app view
|
238
273
|
:return: None
|
239
274
|
"""
|
240
|
-
self._prompt =
|
241
|
-
self._initial_message =
|
242
|
-
|
243
|
-
|
244
|
-
self.
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
self.
|
249
|
-
|
275
|
+
self._prompt = "[italic dim bold]What do you want to do?\n"
|
276
|
+
self._initial_message = (
|
277
|
+
f"\n[bold red]{text2art(self._initial_message, font='tarty1')}\n"
|
278
|
+
)
|
279
|
+
self._farewell_message = (
|
280
|
+
f"[bold red]\n{text2art(f'\n{self._farewell_message}\n', font='chanky')}[/bold red]\n"
|
281
|
+
f"[red i]github.com/koloideal/Argenta[/red i] | [red bold i]made by kolo[/red bold i]\n"
|
282
|
+
)
|
283
|
+
self._description_message_gen = lambda command, description: (
|
284
|
+
f"[bold red]{escape('[' + command + ']')}[/bold red] "
|
285
|
+
f"[blue dim]*=*=*[/blue dim] "
|
286
|
+
f"[bold yellow italic]{escape(description)}"
|
287
|
+
)
|
288
|
+
self._incorrect_input_syntax_handler = lambda raw_command: self._print_func(
|
289
|
+
f"[red bold]Incorrect flag syntax: {escape(raw_command)}"
|
290
|
+
)
|
291
|
+
self._repeated_input_flags_handler = lambda raw_command: self._print_func(
|
292
|
+
f"[red bold]Repeated input flags: {escape(raw_command)}"
|
293
|
+
)
|
294
|
+
self._empty_input_command_handler = lambda: self._print_func(
|
295
|
+
"[red bold]Empty input command"
|
296
|
+
)
|
250
297
|
|
251
298
|
def unknown_command_handler(command: InputCommand) -> None:
|
252
299
|
cmd_trg: str = command.get_trigger()
|
253
300
|
mst_sim_cmd: str | None = self._most_similar_command(cmd_trg)
|
254
|
-
first_part_of_text =
|
255
|
-
|
301
|
+
first_part_of_text = (
|
302
|
+
f"[red]Unknown command:[/red] [blue]{escape(cmd_trg)}[/blue]"
|
303
|
+
)
|
304
|
+
second_part_of_text = (
|
305
|
+
("[red], most similar:[/red] " + ("[blue]" + mst_sim_cmd + "[/blue]"))
|
306
|
+
if mst_sim_cmd
|
307
|
+
else ""
|
308
|
+
)
|
256
309
|
self._print_func(first_part_of_text + second_part_of_text)
|
257
310
|
|
258
311
|
self._unknown_command_handler = unknown_command_handler
|
259
312
|
|
260
|
-
|
261
313
|
def _pre_cycle_setup(self) -> None:
|
262
314
|
"""
|
263
315
|
Private. Configures various aspects of the application before the start of the cycle
|
@@ -266,11 +318,19 @@ class BaseApp:
|
|
266
318
|
self._setup_system_router()
|
267
319
|
|
268
320
|
for router_entity in self._registered_routers:
|
269
|
-
self._all_registered_triggers_in_default_case.extend(
|
270
|
-
|
271
|
-
|
272
|
-
self.
|
273
|
-
|
321
|
+
self._all_registered_triggers_in_default_case.extend(
|
322
|
+
router_entity.get_triggers()
|
323
|
+
)
|
324
|
+
self._all_registered_triggers_in_default_case.extend(
|
325
|
+
router_entity.get_aliases()
|
326
|
+
)
|
327
|
+
|
328
|
+
self._all_registered_triggers_in_lower.extend(
|
329
|
+
[x.lower() for x in router_entity.get_triggers()]
|
330
|
+
)
|
331
|
+
self._all_registered_triggers_in_lower.extend(
|
332
|
+
[x.lower() for x in router_entity.get_aliases()]
|
333
|
+
)
|
274
334
|
|
275
335
|
self._autocompleter.initial_setup(self._all_registered_triggers_in_lower)
|
276
336
|
|
@@ -282,26 +342,27 @@ class BaseApp:
|
|
282
342
|
for message in self._messages_on_startup:
|
283
343
|
self._print_func(message)
|
284
344
|
if self._messages_on_startup:
|
285
|
-
print(
|
345
|
+
print("\n")
|
286
346
|
|
287
347
|
if not self._repeat_command_groups_description:
|
288
348
|
self._print_command_group_description()
|
289
349
|
|
290
350
|
|
291
|
-
|
292
351
|
class App(BaseApp):
|
293
|
-
def __init__(
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
352
|
+
def __init__(
|
353
|
+
self,
|
354
|
+
prompt: str = "What do you want to do?\n",
|
355
|
+
initial_message: str = "\nArgenta\n",
|
356
|
+
farewell_message: str = "\nSee you\n",
|
357
|
+
exit_command: Command = Command("Q", "Exit command"),
|
358
|
+
system_router_title: str | None = "System points:",
|
359
|
+
ignore_command_register: bool = True,
|
360
|
+
dividing_line: StaticDividingLine | DynamicDividingLine = StaticDividingLine(),
|
361
|
+
repeat_command_groups: bool = True,
|
362
|
+
override_system_messages: bool = False,
|
363
|
+
autocompleter: AutoCompleter = AutoCompleter(),
|
364
|
+
print_func: Callable[[str], None] = Console().print,
|
365
|
+
) -> None:
|
305
366
|
"""
|
306
367
|
Public. The essence of the application itself.
|
307
368
|
Configures and manages all aspects of the behavior and presentation of the user interacting with the user
|
@@ -318,18 +379,19 @@ class App(BaseApp):
|
|
318
379
|
:param print_func: system messages text output function
|
319
380
|
:return: None
|
320
381
|
"""
|
321
|
-
super().__init__(
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
382
|
+
super().__init__(
|
383
|
+
prompt=prompt,
|
384
|
+
initial_message=initial_message,
|
385
|
+
farewell_message=farewell_message,
|
386
|
+
exit_command=exit_command,
|
387
|
+
system_router_title=system_router_title,
|
388
|
+
ignore_command_register=ignore_command_register,
|
389
|
+
dividing_line=dividing_line,
|
390
|
+
repeat_command_groups=repeat_command_groups,
|
391
|
+
override_system_messages=override_system_messages,
|
392
|
+
autocompleter=autocompleter,
|
393
|
+
print_func=print_func,
|
394
|
+
)
|
333
395
|
|
334
396
|
def run_polling(self) -> None:
|
335
397
|
"""
|
@@ -344,7 +406,9 @@ class App(BaseApp):
|
|
344
406
|
raw_command: str = Console().input(self._prompt)
|
345
407
|
|
346
408
|
try:
|
347
|
-
input_command: InputCommand = InputCommand.parse(
|
409
|
+
input_command: InputCommand = InputCommand.parse(
|
410
|
+
raw_command=raw_command
|
411
|
+
)
|
348
412
|
except BaseInputCommandException as error:
|
349
413
|
with redirect_stdout(io.StringIO()) as f:
|
350
414
|
self._error_handler(error, raw_command)
|
@@ -354,7 +418,14 @@ class App(BaseApp):
|
|
354
418
|
|
355
419
|
if self._is_exit_command(input_command):
|
356
420
|
system_router.finds_appropriate_handler(input_command)
|
357
|
-
self.
|
421
|
+
if self._ignore_command_register:
|
422
|
+
self._autocompleter.exit_setup(
|
423
|
+
self._all_registered_triggers_in_lower
|
424
|
+
)
|
425
|
+
else:
|
426
|
+
self._autocompleter.exit_setup(
|
427
|
+
self._all_registered_triggers_in_default_case
|
428
|
+
)
|
358
429
|
return
|
359
430
|
|
360
431
|
if self._is_unknown_command(input_command):
|
@@ -370,7 +441,6 @@ class App(BaseApp):
|
|
370
441
|
res: str = f.getvalue()
|
371
442
|
self._print_framed_text(res)
|
372
443
|
|
373
|
-
|
374
444
|
def include_router(self, router: Router) -> None:
|
375
445
|
"""
|
376
446
|
Public. Registers the router in the application
|
@@ -380,7 +450,6 @@ class App(BaseApp):
|
|
380
450
|
router.set_command_register_ignore(self._ignore_command_register)
|
381
451
|
self._registered_routers.add_registered_router(router)
|
382
452
|
|
383
|
-
|
384
453
|
def include_routers(self, *routers: Router) -> None:
|
385
454
|
"""
|
386
455
|
Public. Registers the routers in the application
|
@@ -390,7 +459,6 @@ class App(BaseApp):
|
|
390
459
|
for router in routers:
|
391
460
|
self.include_router(router)
|
392
461
|
|
393
|
-
|
394
462
|
def add_message_on_startup(self, message: str) -> None:
|
395
463
|
"""
|
396
464
|
Public. Adds a message that will be displayed when the application is launched
|
@@ -398,4 +466,3 @@ class App(BaseApp):
|
|
398
466
|
:return: None
|
399
467
|
"""
|
400
468
|
self._messages_on_startup.append(message)
|
401
|
-
|