argenta 0.5.0b2__py3-none-any.whl → 1.0.0__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.
Files changed (36) hide show
  1. argenta/app/autocompleter/entity.py +57 -13
  2. argenta/app/defaults.py +7 -4
  3. argenta/app/dividing_line/models.py +55 -13
  4. argenta/app/models.py +376 -175
  5. argenta/app/registered_routers/entity.py +20 -7
  6. argenta/command/__init__.py +1 -1
  7. argenta/command/exceptions.py +22 -3
  8. argenta/command/flag/__init__.py +2 -2
  9. argenta/command/flag/defaults.py +21 -11
  10. argenta/command/flag/models.py +73 -92
  11. argenta/command/flags/__init__.py +16 -0
  12. argenta/command/flags/models.py +90 -0
  13. argenta/command/models.py +124 -39
  14. argenta/orchestrator/__init__.py +4 -0
  15. argenta/orchestrator/argparser/__init__.py +4 -0
  16. argenta/orchestrator/argparser/arguments/__init__.py +8 -0
  17. argenta/orchestrator/argparser/arguments/models.py +56 -0
  18. argenta/orchestrator/argparser/entity.py +59 -0
  19. argenta/orchestrator/entity.py +35 -0
  20. argenta/response/__init__.py +5 -0
  21. argenta/response/entity.py +29 -0
  22. argenta/response/status.py +8 -0
  23. argenta/router/__init__.py +1 -1
  24. argenta/router/command_handler/entity.py +57 -11
  25. argenta/router/defaults.py +1 -2
  26. argenta/router/entity.py +181 -92
  27. argenta/router/exceptions.py +17 -6
  28. argenta-1.0.0.dist-info/METADATA +70 -0
  29. argenta-1.0.0.dist-info/RECORD +37 -0
  30. {argenta-0.5.0b2.dist-info → argenta-1.0.0.dist-info}/WHEEL +1 -1
  31. argenta/app/exceptions.py +0 -10
  32. argenta/router/command_handlers/__init__.py +0 -0
  33. argenta/router/command_handlers/entity.py +0 -21
  34. argenta-0.5.0b2.dist-info/METADATA +0 -601
  35. argenta-0.5.0b2.dist-info/RECORD +0 -29
  36. {argenta-0.5.0b2.dist-info → argenta-1.0.0.dist-info/licenses}/LICENSE +0 -0
argenta/app/models.py CHANGED
@@ -11,33 +11,35 @@ 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 (UnprocessedInputFlagException,
15
- RepeatedInputFlagsException,
16
- EmptyInputCommandException,
17
- BaseInputCommandException)
18
- from argenta.app.exceptions import (NoRegisteredRoutersException,
19
- NoRegisteredHandlersException)
14
+ from argenta.command.exceptions import (
15
+ UnprocessedInputFlagException,
16
+ RepeatedInputFlagsException,
17
+ EmptyInputCommandException,
18
+ BaseInputCommandException,
19
+ )
20
20
  from argenta.app.registered_routers.entity import RegisteredRouters
21
-
22
-
23
-
24
- class AppInit:
25
- def __init__(self,
26
- prompt: str = '[italic dim bold]What do you want to do?\n',
27
- initial_message: str = '\nArgenta\n',
28
- farewell_message: str = '\nSee you\n',
29
- exit_command: Command = Command('Q', 'Exit command'),
30
- system_points_title: str | None = 'System points:',
31
- ignore_command_register: bool = True,
32
- dividing_line: StaticDividingLine | DynamicDividingLine = StaticDividingLine(),
33
- repeat_command_groups: bool = True,
34
- override_system_messages: bool = False,
35
- autocompleter: AutoCompleter = AutoCompleter(),
36
- print_func: Callable[[str], None] = Console().print) -> None:
21
+ from argenta.response import Response
22
+
23
+
24
+ class BaseApp:
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
40
- self._system_points_title = system_points_title
42
+ self._system_router_title = system_router_title
41
43
  self._dividing_line = dividing_line
42
44
  self._ignore_command_register = ignore_command_register
43
45
  self._repeat_command_groups_description = repeat_command_groups
@@ -47,167 +49,355 @@ class AppInit:
47
49
  self._farewell_message = farewell_message
48
50
  self._initial_message = initial_message
49
51
 
50
-
51
- 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)}'
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
- self._messages_on_startup = []
54
-
55
- self._invalid_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'[red bold]Incorrect flag syntax: {escape(raw_command)}')
56
- self._repeated_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'[red bold]Repeated input flags: {escape(raw_command)}')
57
- self._empty_input_command_handler: Callable[[], None] = lambda: print_func('[red bold]Empty input command')
58
- self._unknown_command_handler: Callable[[InputCommand], None] = lambda command: print_func(f"[red bold]Unknown command: {escape(command.get_trigger())}")
59
- self._exit_command_handler: Callable[[], None] = lambda: print_func(self._farewell_message)
60
-
61
-
62
- class AppSetters(AppInit):
63
- def set_description_message_pattern(self, pattern: Callable[[str, str], str]) -> None:
64
- self._description_message_gen: Callable[[str, str], str] = pattern
65
-
66
-
67
- def set_invalid_input_flags_handler(self, handler: Callable[[str], None]) -> None:
68
- self._invalid_input_flags_handler = handler
69
-
70
-
71
- def set_repeated_input_flags_handler(self, handler: Callable[[str], None]) -> None:
72
- self._repeated_input_flags_handler = handler
73
-
74
-
75
- def set_unknown_command_handler(self, handler: Callable[[str], None]) -> None:
76
- self._unknown_command_handler = handler
77
-
78
-
79
- def set_empty_command_handler(self, handler: Callable[[], None]) -> None:
80
- self._empty_input_command_handler = handler
81
-
82
-
83
- def set_exit_command_handler(self, handler: Callable[[], None]) -> None:
84
- self._exit_command_handler = handler
85
-
86
-
87
- class AppPrinters(AppInit):
88
- def _print_command_group_description(self):
56
+ self._messages_on_startup: list[str] = []
57
+
58
+ self._all_registered_triggers_in_lower: list[str] = []
59
+ self._all_registered_triggers_in_default_case: list[str] = []
60
+
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
+ )
76
+
77
+ def set_description_message_pattern(self, _: Callable[[str, str], str]) -> None:
78
+ """
79
+ Public. Sets the output pattern of the available commands
80
+ :param _: output pattern of the available commands
81
+ :return: None
82
+ """
83
+ self._description_message_gen: Callable[[str, str], str] = _
84
+
85
+ def set_incorrect_input_syntax_handler(self, _: Callable[[str], None]) -> None:
86
+ """
87
+ Public. Sets the handler for incorrect flags when entering a command
88
+ :param _: handler for incorrect flags when entering a command
89
+ :return: None
90
+ """
91
+ self._incorrect_input_syntax_handler = _
92
+
93
+ def set_repeated_input_flags_handler(self, _: Callable[[str], None]) -> None:
94
+ """
95
+ Public. Sets the handler for repeated flags when entering a command
96
+ :param _: handler for repeated flags when entering a command
97
+ :return: None
98
+ """
99
+ self._repeated_input_flags_handler = _
100
+
101
+ def set_unknown_command_handler(self, _: Callable[[str], None]) -> None:
102
+ """
103
+ Public. Sets the handler for unknown commands when entering a command
104
+ :param _: handler for unknown commands when entering a command
105
+ :return: None
106
+ """
107
+ self._unknown_command_handler = _
108
+
109
+ def set_empty_command_handler(self, _: Callable[[], None]) -> None:
110
+ """
111
+ Public. Sets the handler for empty commands when entering a command
112
+ :param _: handler for empty commands when entering a command
113
+ :return: None
114
+ """
115
+ self._empty_input_command_handler = _
116
+
117
+ def set_exit_command_handler(self, _: Callable[[], None]) -> None:
118
+ """
119
+ Public. Sets the handler for exit command when entering a command
120
+ :param _: handler for exit command when entering a command
121
+ :return: None
122
+ """
123
+ self._exit_command_handler = _
124
+
125
+ def _print_command_group_description(self) -> None:
126
+ """
127
+ Private. Prints the description of the available commands
128
+ :return: None
129
+ """
89
130
  for registered_router in self._registered_routers:
90
- if registered_router.get_title():
91
- self._print_func(registered_router.get_title())
131
+ if registered_router.title:
132
+ self._print_func(registered_router.title)
92
133
  for command_handler in registered_router.get_command_handlers():
93
- self._print_func(self._description_message_gen(
134
+ self._print_func(
135
+ self._description_message_gen(
94
136
  command_handler.get_handled_command().get_trigger(),
95
- command_handler.get_handled_command().get_description()))
96
- self._print_func('')
97
-
98
-
99
- def _print_framed_text_with_dynamic_line(self, text: str):
100
- clear_text = re.sub(r'\u001b\[[0-9;]*m', '', text)
101
- max_length_line = max([len(line) for line in clear_text.split('\n')])
102
- max_length_line = max_length_line if 10 <= max_length_line <= 80 else 80 if max_length_line > 80 else 10
103
- self._print_func(self._dividing_line.get_full_line(max_length_line))
104
- print(text.strip('\n'))
105
- self._print_func(self._dividing_line.get_full_line(max_length_line))
106
-
137
+ command_handler.get_handled_command().get_description(),
138
+ )
139
+ )
140
+ self._print_func("")
141
+
142
+ def _print_framed_text(self, text: str) -> None:
143
+ """
144
+ Private. Outputs text by framing it in a static or dynamic split strip
145
+ :param text: framed text
146
+ :return: None
147
+ """
148
+ if isinstance(self._dividing_line, StaticDividingLine):
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
+ )
107
156
 
108
- class AppNonStandardHandlers(AppPrinters):
109
- def _is_exit_command(self, command: InputCommand):
110
- if command.get_trigger().lower() == self._exit_command.get_trigger().lower():
111
- if self._ignore_command_register:
112
- system_router.input_command_handler(command)
157
+ elif isinstance(self._dividing_line, DynamicDividingLine):
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
+ )
179
+
180
+ def _is_exit_command(self, command: InputCommand) -> bool:
181
+ """
182
+ Private. Checks if the given command is an exit command
183
+ :param command: command to check
184
+ :return: is it an exit command or not as bool
185
+ """
186
+ if self._ignore_command_register:
187
+ if (
188
+ command.get_trigger().lower()
189
+ == self._exit_command.get_trigger().lower()
190
+ ):
191
+ return True
192
+ elif command.get_trigger().lower() in [
193
+ x.lower() for x in self._exit_command.get_aliases()
194
+ ]:
113
195
  return True
114
- elif command.get_trigger() == self._exit_command.get_trigger():
115
- system_router.input_command_handler(command)
196
+ else:
197
+ if command.get_trigger() == self._exit_command.get_trigger():
198
+ return True
199
+ elif command.get_trigger() in self._exit_command.get_aliases():
116
200
  return True
117
201
  return False
118
202
 
119
-
120
- def _is_unknown_command(self, command: InputCommand):
121
- for router_entity in self._registered_routers:
122
- for command_handler in router_entity.get_command_handlers():
123
- handled_command_trigger = command_handler.get_handled_command().get_trigger()
124
- handled_command_aliases = command_handler.get_handled_command().get_aliases()
125
- if handled_command_trigger.lower() == command.get_trigger().lower() and self._ignore_command_register:
126
- return False
127
- elif handled_command_trigger == command.get_trigger():
128
- return False
129
- elif handled_command_aliases:
130
- if (command.get_trigger().lower() in [x.lower() for x in handled_command_aliases]) and self._ignore_command_register:
131
- return False
132
- elif command.get_trigger() in handled_command_trigger:
133
- return False
134
- if isinstance(self._dividing_line, StaticDividingLine):
135
- self._print_func(self._dividing_line.get_full_line())
136
- self._unknown_command_handler(command)
137
- self._print_func(self._dividing_line.get_full_line())
138
- elif isinstance(self._dividing_line, DynamicDividingLine):
139
- with redirect_stdout(io.StringIO()) as f:
140
- self._unknown_command_handler(command)
141
- res: str = f.getvalue()
142
- self._print_framed_text_with_dynamic_line(res)
203
+ def _is_unknown_command(self, command: InputCommand) -> bool:
204
+ """
205
+ Private. Checks if the given command is an unknown command
206
+ :param command: command to check
207
+ :return: is it an unknown command or not as bool
208
+ """
209
+ input_command_trigger = command.get_trigger()
210
+ if self._ignore_command_register:
211
+ if input_command_trigger.lower() in self._all_registered_triggers_in_lower:
212
+ return False
213
+ else:
214
+ if input_command_trigger in self._all_registered_triggers_in_default_case:
215
+ return False
143
216
  return True
144
217
 
145
-
146
- def _error_handler(self, error: BaseInputCommandException, raw_command: str) -> None:
218
+ def _error_handler(
219
+ self, error: BaseInputCommandException, raw_command: str
220
+ ) -> None:
221
+ """
222
+ Private. Handles parsing errors of the entered command
223
+ :param error: error being handled
224
+ :param raw_command: the raw input command
225
+ :return: None
226
+ """
147
227
  match error:
148
228
  case UnprocessedInputFlagException():
149
- self._invalid_input_flags_handler(raw_command)
229
+ self._incorrect_input_syntax_handler(raw_command)
150
230
  case RepeatedInputFlagsException():
151
231
  self._repeated_input_flags_handler(raw_command)
152
232
  case EmptyInputCommandException():
153
233
  self._empty_input_command_handler()
154
234
 
155
-
156
- class AppValidators(AppInit):
157
- def _validate_number_of_routers(self) -> None:
158
- if not self._registered_routers:
159
- raise NoRegisteredRoutersException()
160
-
161
-
162
- def _validate_included_routers(self) -> None:
163
- for router in self._registered_routers:
164
- if not router.get_command_handlers():
165
- raise NoRegisteredHandlersException(router.get_name())
166
-
167
-
168
- class AppSetups(AppValidators, AppPrinters):
169
- def _setup_system_router(self):
170
- system_router.set_title(self._system_points_title)
235
+ def _setup_system_router(self) -> None:
236
+ """
237
+ Private. Sets up system router
238
+ :return: None
239
+ """
240
+ system_router.title = self._system_router_title
171
241
 
172
242
  @system_router.command(self._exit_command)
173
- def exit_command():
174
- self._exit_command_handler()
243
+ def exit_command(response: Response) -> None:
244
+ self._exit_command_handler(response)
175
245
 
176
246
  if system_router not in self._registered_routers.get_registered_routers():
177
- system_router.set_ignore_command_register(self._ignore_command_register)
247
+ system_router.set_command_register_ignore(self._ignore_command_register)
178
248
  self._registered_routers.add_registered_router(system_router)
179
249
 
180
- def _setup_default_view(self):
181
- if not self._override_system_messages:
182
- self._initial_message = f'\n[bold red]{text2art(self._initial_message, font='tarty1')}\n\n'
183
- self._farewell_message = (
184
- f'[bold red]\n{text2art(f'\n{self._farewell_message}\n', font='chanky')}[/bold red]\n'
185
- f'[red i]github.com/koloideal/Argenta[/red i] | [red bold i]made by kolo[/red bold i]\n')
186
-
187
- def _pre_cycle_setup(self):
188
- self._setup_default_view()
250
+ def _most_similar_command(self, unknown_command: str) -> str | None:
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
+ )
259
+ if not matches:
260
+ matches: list[str] | list = sorted(
261
+ cmd for cmd in all_commands if unknown_command.startswith(cmd)
262
+ )
263
+ if len(matches) == 1:
264
+ return matches[0]
265
+ elif len(matches) > 1:
266
+ return sorted(matches, key=lambda cmd: len(cmd))[0]
267
+ else:
268
+ return None
269
+
270
+ def _setup_default_view(self) -> None:
271
+ """
272
+ Private. Sets up default app view
273
+ :return: None
274
+ """
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
+ )
297
+
298
+ def unknown_command_handler(command: InputCommand) -> None:
299
+ cmd_trg: str = command.get_trigger()
300
+ mst_sim_cmd: str | None = self._most_similar_command(cmd_trg)
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
+ )
309
+ self._print_func(first_part_of_text + second_part_of_text)
310
+
311
+ self._unknown_command_handler = unknown_command_handler
312
+
313
+ def _pre_cycle_setup(self) -> None:
314
+ """
315
+ Private. Configures various aspects of the application before the start of the cycle
316
+ :return: None
317
+ """
189
318
  self._setup_system_router()
190
- self._validate_number_of_routers()
191
- self._validate_included_routers()
192
319
 
193
- all_triggers: list[str] = []
194
320
  for router_entity in self._registered_routers:
195
- all_triggers.extend(router_entity.get_triggers())
196
- all_triggers.extend(router_entity.get_aliases())
197
- self._autocompleter.initial_setup(all_triggers)
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
+ )
334
+
335
+ self._autocompleter.initial_setup(self._all_registered_triggers_in_lower)
336
+
337
+ if not self._override_system_messages:
338
+ self._setup_default_view()
198
339
 
199
340
  self._print_func(self._initial_message)
200
341
 
201
342
  for message in self._messages_on_startup:
202
343
  self._print_func(message)
203
- print('\n\n')
344
+ if self._messages_on_startup:
345
+ print("\n")
204
346
 
205
347
  if not self._repeat_command_groups_description:
206
348
  self._print_command_group_description()
207
349
 
208
350
 
209
- class App(AppSetters, AppNonStandardHandlers, AppSetups):
210
- def start_polling(self) -> None:
351
+ class App(BaseApp):
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:
366
+ """
367
+ Public. The essence of the application itself.
368
+ Configures and manages all aspects of the behavior and presentation of the user interacting with the user
369
+ :param prompt: displayed before entering the command
370
+ :param initial_message: displayed at the start of the app
371
+ :param farewell_message: displayed at the end of the app
372
+ :param exit_command: the entity of the command that will be terminated when entered
373
+ :param system_router_title: system router title
374
+ :param ignore_command_register: whether to ignore the case of the entered commands
375
+ :param dividing_line: the entity of the dividing line
376
+ :param repeat_command_groups: whether to repeat the available commands and their description
377
+ :param override_system_messages: whether to redefine the default formatting of system messages
378
+ :param autocompleter: the entity of the autocompleter
379
+ :param print_func: system messages text output function
380
+ :return: None
381
+ """
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
+ )
395
+
396
+ def run_polling(self) -> None:
397
+ """
398
+ Private. Starts the user input processing cycle
399
+ :return: None
400
+ """
211
401
  self._pre_cycle_setup()
212
402
  while True:
213
403
  if self._repeat_command_groups_description:
@@ -216,52 +406,63 @@ class App(AppSetters, AppNonStandardHandlers, AppSetups):
216
406
  raw_command: str = Console().input(self._prompt)
217
407
 
218
408
  try:
219
- input_command: InputCommand = InputCommand.parse(raw_command=raw_command)
409
+ input_command: InputCommand = InputCommand.parse(
410
+ raw_command=raw_command
411
+ )
220
412
  except BaseInputCommandException as error:
221
- if isinstance(self._dividing_line, StaticDividingLine):
222
- self._print_func(self._dividing_line.get_full_line())
413
+ with redirect_stdout(io.StringIO()) as f:
223
414
  self._error_handler(error, raw_command)
224
- self._print_func(self._dividing_line.get_full_line())
225
- elif isinstance(self._dividing_line, DynamicDividingLine):
226
- with redirect_stdout(io.StringIO()) as f:
227
- self._error_handler(error, raw_command)
228
- res: str = f.getvalue()
229
- self._print_framed_text_with_dynamic_line(res)
415
+ res: str = f.getvalue()
416
+ self._print_framed_text(res)
230
417
  continue
231
418
 
232
419
  if self._is_exit_command(input_command):
233
- self._autocompleter.exit_setup()
420
+ system_router.finds_appropriate_handler(input_command)
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
+ )
234
429
  return
235
430
 
236
431
  if self._is_unknown_command(input_command):
237
- continue
238
-
239
- if isinstance(self._dividing_line, StaticDividingLine):
240
- self._print_func(self._dividing_line.get_full_line())
241
- for registered_router in self._registered_routers:
242
- registered_router.input_command_handler(input_command)
243
- self._print_func(self._dividing_line.get_full_line())
244
- elif isinstance(self._dividing_line, DynamicDividingLine):
245
432
  with redirect_stdout(io.StringIO()) as f:
246
- for registered_router in self._registered_routers:
247
- registered_router.input_command_handler(input_command)
433
+ self._unknown_command_handler(input_command)
248
434
  res: str = f.getvalue()
249
- self._print_framed_text_with_dynamic_line(res)
250
-
251
- if not self._repeat_command_groups_description:
252
- self._print_func(self._prompt)
435
+ self._print_framed_text(res)
436
+ continue
253
437
 
438
+ with redirect_stdout(io.StringIO()) as f:
439
+ for registered_router in self._registered_routers:
440
+ registered_router.finds_appropriate_handler(input_command)
441
+ res: str = f.getvalue()
442
+ self._print_framed_text(res)
254
443
 
255
444
  def include_router(self, router: Router) -> None:
256
- router.set_ignore_command_register(self._ignore_command_register)
445
+ """
446
+ Public. Registers the router in the application
447
+ :param router: registered router
448
+ :return: None
449
+ """
450
+ router.set_command_register_ignore(self._ignore_command_register)
257
451
  self._registered_routers.add_registered_router(router)
258
452
 
259
-
260
453
  def include_routers(self, *routers: Router) -> None:
454
+ """
455
+ Public. Registers the routers in the application
456
+ :param routers: registered routers
457
+ :return: None
458
+ """
261
459
  for router in routers:
262
460
  self.include_router(router)
263
461
 
264
-
265
462
  def add_message_on_startup(self, message: str) -> None:
463
+ """
464
+ Public. Adds a message that will be displayed when the application is launched
465
+ :param message: the message being added
466
+ :return: None
467
+ """
266
468
  self._messages_on_startup.append(message)
267
-