argenta 0.4.5__tar.gz → 0.4.6__tar.gz
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-0.4.5 → argenta-0.4.6}/PKG-INFO +6 -1
- {argenta-0.4.5 → argenta-0.4.6}/README.md +3 -0
- argenta-0.4.6/argenta/app/__init__.py +3 -0
- argenta-0.4.6/argenta/app/defaults.py +8 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/app/exceptions.py +0 -5
- argenta-0.4.6/argenta/app/models.py +214 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/command/exceptions.py +8 -4
- {argenta-0.4.5 → argenta-0.4.6}/argenta/command/models.py +2 -1
- {argenta-0.4.5 → argenta-0.4.6}/argenta/router/command_handler/entity.py +2 -2
- {argenta-0.4.5 → argenta-0.4.6}/argenta/router/entity.py +17 -20
- {argenta-0.4.5 → argenta-0.4.6}/pyproject.toml +2 -8
- argenta-0.4.5/argenta/app/__init__.py +0 -3
- argenta-0.4.5/argenta/app/entity.py +0 -262
- {argenta-0.4.5 → argenta-0.4.6}/LICENSE +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/__init__.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/app/registered_routers/__init__.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/app/registered_routers/entity.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/command/__init__.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/command/flag/__init__.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/command/flag/defaults.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/command/flag/models.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/router/__init__.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/router/command_handler/__init__.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/router/command_handlers/__init__.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/router/command_handlers/entity.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/router/defaults.py +0 -0
- {argenta-0.4.5 → argenta-0.4.6}/argenta/router/exceptions.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: argenta
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.6
|
4
4
|
Summary: python library for creating custom shells
|
5
5
|
License: MIT
|
6
6
|
Author: kolo
|
@@ -11,6 +11,8 @@ Classifier: Programming Language :: Python :: 3
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
13
13
|
Classifier: Programming Language :: Python :: 3.13
|
14
|
+
Requires-Dist: art (>=6.4,<7.0)
|
15
|
+
Requires-Dist: rich (>=14.0.0,<15.0.0)
|
14
16
|
Description-Content-Type: text/markdown
|
15
17
|
|
16
18
|
# Argenta
|
@@ -20,6 +22,9 @@ Description-Content-Type: text/markdown
|
|
20
22
|
## Описание
|
21
23
|
**Argenta** — Python library for creating custom shells
|
22
24
|
|
25
|
+

|
26
|
+
Пример внешнего вида TUI, написанного с помощью Argenta
|
27
|
+
|
23
28
|
---
|
24
29
|
|
25
30
|
# Установка
|
@@ -23,8 +23,3 @@ class NoRegisteredHandlersException(Exception):
|
|
23
23
|
self.router_name = router_name
|
24
24
|
def __str__(self):
|
25
25
|
return f"No Registered Handlers Found For '{self.router_name}'"
|
26
|
-
|
27
|
-
|
28
|
-
class IncorrectNumberOfHandlerArgsException(Exception):
|
29
|
-
def __str__(self):
|
30
|
-
return "Incorrect Input Flags Handler has incorrect number of arguments"
|
@@ -0,0 +1,214 @@
|
|
1
|
+
from typing import Callable
|
2
|
+
from rich.console import Console
|
3
|
+
from art import text2art
|
4
|
+
import re
|
5
|
+
|
6
|
+
from argenta.command.models import Command, InputCommand
|
7
|
+
from argenta.router import Router
|
8
|
+
from argenta.router.defaults import system_router
|
9
|
+
from argenta.command.exceptions import (UnprocessedInputFlagException,
|
10
|
+
RepeatedInputFlagsException,
|
11
|
+
EmptyInputCommandException,
|
12
|
+
BaseInputCommandException)
|
13
|
+
from argenta.app.exceptions import (InvalidRouterInstanceException,
|
14
|
+
InvalidDescriptionMessagePatternException,
|
15
|
+
NoRegisteredRoutersException,
|
16
|
+
NoRegisteredHandlersException)
|
17
|
+
from argenta.app.registered_routers.entity import RegisteredRouters
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
class BaseApp:
|
22
|
+
def __init__(self,
|
23
|
+
prompt: str = '[italic dim bold]What do you want to do?\n',
|
24
|
+
initial_message: str = 'Argenta',
|
25
|
+
farewell_message: str = 'See you',
|
26
|
+
exit_command: str = 'Q',
|
27
|
+
exit_command_description: str = 'Exit command',
|
28
|
+
system_points_title: str = 'System points:',
|
29
|
+
ignore_command_register: bool = True,
|
30
|
+
line_separate: str = '-----',
|
31
|
+
repeat_command_groups: bool = True,
|
32
|
+
print_func: Callable[[str], None] = Console().print) -> None:
|
33
|
+
self._prompt = prompt
|
34
|
+
self._print_func = print_func
|
35
|
+
self._exit_command = exit_command
|
36
|
+
self._exit_command_description = exit_command_description
|
37
|
+
self._system_points_title = system_points_title
|
38
|
+
self._line_separate = line_separate
|
39
|
+
self._ignore_command_register = ignore_command_register
|
40
|
+
self._repeat_command_groups_description = repeat_command_groups
|
41
|
+
|
42
|
+
self.farewell_message = farewell_message
|
43
|
+
self.initial_message = initial_message
|
44
|
+
|
45
|
+
self._description_message_pattern: str = '[bold red][{command}][/bold red] [blue dim]*=*=*[/blue dim] [bold yellow italic]{description}'
|
46
|
+
self._registered_routers: RegisteredRouters = RegisteredRouters()
|
47
|
+
self._messages_on_startup = []
|
48
|
+
|
49
|
+
self.invalid_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'[red bold]Incorrect flag syntax: {raw_command}')
|
50
|
+
self.repeated_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'[red bold]Repeated input flags: {raw_command}')
|
51
|
+
self.empty_input_command_handler: Callable[[], None] = lambda: print_func('[red bold]Empty input command')
|
52
|
+
self.unknown_command_handler: Callable[[InputCommand], None] = lambda command: print_func(f"[red bold]Unknown command: {command.get_trigger()}")
|
53
|
+
self.exit_command_handler: Callable[[], None] = lambda: print_func(self.farewell_message)
|
54
|
+
|
55
|
+
self._setup_default_view(is_initial_message_default=initial_message == 'Argenta',
|
56
|
+
is_farewell_message_default=farewell_message == 'See you',
|
57
|
+
is_line_separate_default=line_separate == '-----')
|
58
|
+
|
59
|
+
|
60
|
+
def _setup_default_view(self, is_initial_message_default: bool,
|
61
|
+
is_farewell_message_default: bool,
|
62
|
+
is_line_separate_default: bool):
|
63
|
+
if is_initial_message_default:
|
64
|
+
self.initial_message = f'\n[bold red]{text2art('Argenta', font='tarty1')}\n\n'
|
65
|
+
if is_farewell_message_default:
|
66
|
+
self.farewell_message = (f'[bold red]\n{text2art('\nSee you\n', font='chanky')}[/bold red]\n'
|
67
|
+
f'[red i]github.com/koloideal/Argenta[/red i] | '
|
68
|
+
f'[red bold i]made by kolo[/red bold i]\n')
|
69
|
+
if is_line_separate_default:
|
70
|
+
self._line_separate = f'\n[dim]{"-" * 50}\n'
|
71
|
+
|
72
|
+
|
73
|
+
def _validate_number_of_routers(self) -> None:
|
74
|
+
if not self._registered_routers:
|
75
|
+
raise NoRegisteredRoutersException()
|
76
|
+
|
77
|
+
|
78
|
+
def _validate_included_routers(self) -> None:
|
79
|
+
for router in self._registered_routers:
|
80
|
+
if not router.get_command_handlers():
|
81
|
+
raise NoRegisteredHandlersException(router.get_name())
|
82
|
+
|
83
|
+
|
84
|
+
def _is_exit_command(self, command: InputCommand):
|
85
|
+
if command.get_trigger().lower() == self._exit_command.lower():
|
86
|
+
if self._ignore_command_register:
|
87
|
+
system_router.input_command_handler(command)
|
88
|
+
return True
|
89
|
+
elif command.get_trigger() == self._exit_command:
|
90
|
+
system_router.input_command_handler(command)
|
91
|
+
return True
|
92
|
+
return False
|
93
|
+
|
94
|
+
|
95
|
+
def _is_unknown_command(self, command: InputCommand):
|
96
|
+
for router_entity in self._registered_routers:
|
97
|
+
for command_handler in router_entity.get_command_handlers():
|
98
|
+
handled_command_trigger = command_handler.get_handled_command().get_trigger()
|
99
|
+
if handled_command_trigger.lower() == command.get_trigger().lower() and self._ignore_command_register:
|
100
|
+
return False
|
101
|
+
elif handled_command_trigger == command.get_trigger():
|
102
|
+
return False
|
103
|
+
self.unknown_command_handler(command)
|
104
|
+
return True
|
105
|
+
|
106
|
+
|
107
|
+
def _print_command_group_description(self):
|
108
|
+
for registered_router in self._registered_routers:
|
109
|
+
self._print_func(registered_router.get_title())
|
110
|
+
for command_handler in registered_router.get_command_handlers():
|
111
|
+
self._print_func(self._description_message_pattern.format(
|
112
|
+
command=command_handler.get_handled_command().get_trigger(),
|
113
|
+
description=command_handler.get_handled_command().get_description()))
|
114
|
+
self._print_func('')
|
115
|
+
|
116
|
+
|
117
|
+
def _error_handler(self, error: BaseInputCommandException, raw_command: str) -> None:
|
118
|
+
match error:
|
119
|
+
case UnprocessedInputFlagException():
|
120
|
+
self.invalid_input_flags_handler(raw_command)
|
121
|
+
case RepeatedInputFlagsException():
|
122
|
+
self.repeated_input_flags_handler(raw_command)
|
123
|
+
case EmptyInputCommandException():
|
124
|
+
self.empty_input_command_handler()
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
class App(BaseApp):
|
129
|
+
def start_polling(self) -> None:
|
130
|
+
self._setup_system_router()
|
131
|
+
self._validate_number_of_routers()
|
132
|
+
self._validate_included_routers()
|
133
|
+
|
134
|
+
self._print_func(self.initial_message)
|
135
|
+
|
136
|
+
for message in self._messages_on_startup:
|
137
|
+
self._print_func(message)
|
138
|
+
|
139
|
+
if not self._repeat_command_groups_description:
|
140
|
+
self._print_command_group_description()
|
141
|
+
|
142
|
+
while True:
|
143
|
+
if self._repeat_command_groups_description:
|
144
|
+
self._print_command_group_description()
|
145
|
+
|
146
|
+
raw_command: str = Console().input(self._prompt)
|
147
|
+
|
148
|
+
try:
|
149
|
+
input_command: InputCommand = InputCommand.parse(raw_command=raw_command)
|
150
|
+
except BaseInputCommandException as error:
|
151
|
+
self._print_func(self._line_separate)
|
152
|
+
self._error_handler(error, raw_command)
|
153
|
+
self._print_func(self._line_separate)
|
154
|
+
|
155
|
+
if not self._repeat_command_groups_description:
|
156
|
+
self._print_func(self._prompt)
|
157
|
+
continue
|
158
|
+
|
159
|
+
if self._is_exit_command(input_command):
|
160
|
+
return
|
161
|
+
|
162
|
+
self._print_func(self._line_separate)
|
163
|
+
|
164
|
+
if self._is_unknown_command(input_command):
|
165
|
+
self._print_func(self._line_separate)
|
166
|
+
if not self._repeat_command_groups_description:
|
167
|
+
self._print_func(self._prompt)
|
168
|
+
continue
|
169
|
+
|
170
|
+
for registered_router in self._registered_routers:
|
171
|
+
registered_router.input_command_handler(input_command)
|
172
|
+
|
173
|
+
self._print_func(self._line_separate)
|
174
|
+
if not self._repeat_command_groups_description:
|
175
|
+
self._print_func(self._prompt)
|
176
|
+
|
177
|
+
|
178
|
+
def include_router(self, router: Router) -> None:
|
179
|
+
if not isinstance(router, Router):
|
180
|
+
raise InvalidRouterInstanceException()
|
181
|
+
|
182
|
+
router.set_ignore_command_register(self._ignore_command_register)
|
183
|
+
self._registered_routers.add_registered_router(router)
|
184
|
+
|
185
|
+
|
186
|
+
def include_routers(self, *routers: Router) -> None:
|
187
|
+
for router in routers:
|
188
|
+
self.include_router(router)
|
189
|
+
|
190
|
+
|
191
|
+
def add_message_on_startup(self, message: str) -> None:
|
192
|
+
self._messages_on_startup.append(message)
|
193
|
+
|
194
|
+
|
195
|
+
def set_description_message_pattern(self, pattern: str) -> None:
|
196
|
+
first_check = re.match(r'.*{command}.*', pattern)
|
197
|
+
second_check = re.match(r'.*{description}.*', pattern)
|
198
|
+
|
199
|
+
if bool(first_check) and bool(second_check):
|
200
|
+
self._description_message_pattern: str = pattern
|
201
|
+
else:
|
202
|
+
raise InvalidDescriptionMessagePatternException(pattern)
|
203
|
+
|
204
|
+
|
205
|
+
def _setup_system_router(self):
|
206
|
+
system_router.set_title(self._system_points_title)
|
207
|
+
@system_router.command(Command(self._exit_command, self._exit_command_description))
|
208
|
+
def exit_command():
|
209
|
+
self.exit_command_handler()
|
210
|
+
|
211
|
+
if system_router not in self._registered_routers.get_registered_routers():
|
212
|
+
self.include_router(system_router)
|
213
|
+
|
214
|
+
|
@@ -1,12 +1,16 @@
|
|
1
1
|
from argenta.command.flag.models import InputFlag, Flag
|
2
2
|
|
3
3
|
|
4
|
-
class
|
4
|
+
class BaseInputCommandException(Exception):
|
5
|
+
pass
|
6
|
+
|
7
|
+
|
8
|
+
class UnprocessedInputFlagException(BaseInputCommandException):
|
5
9
|
def __str__(self):
|
6
10
|
return "Unprocessed Input Flags"
|
7
11
|
|
8
12
|
|
9
|
-
class RepeatedInputFlagsException(
|
13
|
+
class RepeatedInputFlagsException(BaseInputCommandException):
|
10
14
|
def __init__(self, flag: Flag | InputFlag):
|
11
15
|
self.flag = flag
|
12
16
|
def __str__(self):
|
@@ -14,6 +18,6 @@ class RepeatedInputFlagsException(Exception):
|
|
14
18
|
f"Duplicate flag was detected in the input: '{self.flag.get_string_entity()}'")
|
15
19
|
|
16
20
|
|
17
|
-
class EmptyInputCommandException(
|
21
|
+
class EmptyInputCommandException(BaseInputCommandException):
|
18
22
|
def __str__(self):
|
19
|
-
return "Input Command is empty"
|
23
|
+
return "Input Command is empty"
|
@@ -83,7 +83,8 @@ class InputCommand(BaseCommand, Generic[InputCommandType]):
|
|
83
83
|
|
84
84
|
if current_flag_name:
|
85
85
|
if not len(list_of_tokens) == k+1:
|
86
|
-
if not list_of_tokens[k+1].startswith('-'):
|
86
|
+
if not list_of_tokens[k+1].startswith('-'):
|
87
|
+
continue
|
87
88
|
|
88
89
|
input_flag = InputFlag(name=current_flag_name[current_flag_name.rfind('-')+1:],
|
89
90
|
prefix=cast(Literal['-', '--', '---'],
|
@@ -8,8 +8,8 @@ class CommandHandler:
|
|
8
8
|
self.handler = handler
|
9
9
|
self.handled_command = handled_command
|
10
10
|
|
11
|
-
def handling(self, input_flags: InputFlags):
|
12
|
-
if input_flags
|
11
|
+
def handling(self, input_flags: InputFlags = None):
|
12
|
+
if input_flags is not None:
|
13
13
|
self.handler(input_flags)
|
14
14
|
else:
|
15
15
|
self.handler()
|
@@ -22,7 +22,6 @@ class Router:
|
|
22
22
|
|
23
23
|
self._command_handlers: CommandHandlers = CommandHandlers()
|
24
24
|
self._ignore_command_register: bool = False
|
25
|
-
|
26
25
|
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 ''}")
|
27
26
|
|
28
27
|
|
@@ -51,23 +50,20 @@ class Router:
|
|
51
50
|
def input_command_handler(self, input_command: InputCommand):
|
52
51
|
input_command_name: str = input_command.get_trigger()
|
53
52
|
input_command_flags: InputFlags = input_command.get_input_flags()
|
53
|
+
|
54
54
|
for command_handler in self._command_handlers:
|
55
55
|
handle_command = command_handler.get_handled_command()
|
56
56
|
if input_command_name.lower() == handle_command.get_trigger().lower():
|
57
|
-
if handle_command.get_registered_flags():
|
58
|
-
if input_command_flags:
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
self._not_valid_flag_handler(flag)
|
63
|
-
return
|
64
|
-
command_handler.handling(input_command_flags)
|
65
|
-
return
|
57
|
+
if handle_command.get_registered_flags().get_flags():
|
58
|
+
if input_command_flags.get_flags():
|
59
|
+
if self._validate_input_flags(handle_command, input_command_flags):
|
60
|
+
command_handler.handling(input_command_flags)
|
61
|
+
return
|
66
62
|
else:
|
67
|
-
command_handler.handling(
|
63
|
+
command_handler.handling(input_command_flags)
|
68
64
|
return
|
69
65
|
else:
|
70
|
-
if input_command_flags:
|
66
|
+
if input_command_flags.get_flags():
|
71
67
|
self._not_valid_flag_handler(input_command_flags[0])
|
72
68
|
return
|
73
69
|
else:
|
@@ -75,6 +71,15 @@ class Router:
|
|
75
71
|
return
|
76
72
|
|
77
73
|
|
74
|
+
def _validate_input_flags(self, handle_command: Command, input_flags: InputFlags):
|
75
|
+
for flag in input_flags:
|
76
|
+
is_valid = handle_command.validate_input_flag(flag)
|
77
|
+
if not is_valid:
|
78
|
+
self._not_valid_flag_handler(flag)
|
79
|
+
return False
|
80
|
+
return True
|
81
|
+
|
82
|
+
|
78
83
|
@staticmethod
|
79
84
|
def _validate_command(command: Command):
|
80
85
|
command_name: str = command.get_trigger()
|
@@ -119,11 +124,3 @@ class Router:
|
|
119
124
|
|
120
125
|
def set_title(self, title: str):
|
121
126
|
self._title = title
|
122
|
-
|
123
|
-
|
124
|
-
def get_all_commands(self) -> list[str]:
|
125
|
-
all_commands: list[str] = []
|
126
|
-
for command_handler in self._command_handlers:
|
127
|
-
all_commands.append(command_handler.get_handled_command().get_trigger())
|
128
|
-
|
129
|
-
return all_commands
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "argenta"
|
3
|
-
version = "0.4.
|
3
|
+
version = "0.4.6"
|
4
4
|
description = "python library for creating custom shells"
|
5
5
|
authors = [
|
6
6
|
{name = "kolo", email = "kolo.is.main@gmail.com"}
|
@@ -8,7 +8,7 @@ authors = [
|
|
8
8
|
license = {text = "MIT"}
|
9
9
|
readme = "README.md"
|
10
10
|
requires-python = ">=3.11"
|
11
|
-
dependencies = [
|
11
|
+
dependencies = ["rich (>=14.0.0,<15.0.0)", "art (>=6.4,<7.0)"]
|
12
12
|
|
13
13
|
|
14
14
|
[tool.ruff]
|
@@ -27,11 +27,5 @@ requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
27
27
|
build-backend = "poetry.core.masonry.api"
|
28
28
|
|
29
29
|
[tool.poetry.group.dev.dependencies]
|
30
|
-
art = "^6.4"
|
31
|
-
rich = "^13.9.4"
|
32
|
-
numpy = "^2.2.2"
|
33
|
-
word2number = "^1.1"
|
34
|
-
numexpr = "^2.10.2"
|
35
|
-
requests = "^2.32.3"
|
36
30
|
pyreadline3 = "^3.5.4"
|
37
31
|
|
@@ -1,262 +0,0 @@
|
|
1
|
-
from typing import Callable
|
2
|
-
from inspect import getfullargspec
|
3
|
-
import re
|
4
|
-
|
5
|
-
from argenta.command.models import Command, InputCommand
|
6
|
-
from argenta.router import Router
|
7
|
-
from argenta.router.defaults import system_router
|
8
|
-
from argenta.command.exceptions import (UnprocessedInputFlagException,
|
9
|
-
RepeatedInputFlagsException,
|
10
|
-
EmptyInputCommandException)
|
11
|
-
from argenta.app.exceptions import (InvalidRouterInstanceException,
|
12
|
-
InvalidDescriptionMessagePatternException,
|
13
|
-
NoRegisteredRoutersException,
|
14
|
-
NoRegisteredHandlersException,
|
15
|
-
IncorrectNumberOfHandlerArgsException)
|
16
|
-
from argenta.app.registered_routers.entity import RegisteredRouters
|
17
|
-
|
18
|
-
|
19
|
-
class App:
|
20
|
-
def __init__(self,
|
21
|
-
prompt: str = 'Enter a command',
|
22
|
-
initial_message: str = '\nHello, I am Argenta\n',
|
23
|
-
farewell_message: str = '\nGoodBye\n',
|
24
|
-
invalid_input_flags_message: str = 'Invalid input flags',
|
25
|
-
exit_command: str = 'Q',
|
26
|
-
exit_command_description: str = 'Exit command',
|
27
|
-
system_points_title: str = 'System points:',
|
28
|
-
ignore_exit_command_register: bool = True,
|
29
|
-
ignore_command_register: bool = False,
|
30
|
-
line_separate: str = '',
|
31
|
-
command_group_description_separate: str = '',
|
32
|
-
repeat_command_groups: bool = True,
|
33
|
-
messages_on_startup: list[str] = None,
|
34
|
-
print_func: Callable[[str], None] = print) -> None:
|
35
|
-
self.prompt = prompt
|
36
|
-
self.print_func = print_func
|
37
|
-
self.exit_command = exit_command
|
38
|
-
self.exit_command_description = exit_command_description
|
39
|
-
self.system_points_title = system_points_title
|
40
|
-
self.ignore_exit_command_register = ignore_exit_command_register
|
41
|
-
self.farewell_message = farewell_message
|
42
|
-
self.initial_message = initial_message
|
43
|
-
self.invalid_input_flags_message = invalid_input_flags_message
|
44
|
-
self.line_separate = line_separate
|
45
|
-
self.command_group_description_separate = command_group_description_separate
|
46
|
-
self.ignore_command_register = ignore_command_register
|
47
|
-
self.repeat_command_groups = repeat_command_groups
|
48
|
-
self.messages_on_startup = messages_on_startup if messages_on_startup else []
|
49
|
-
|
50
|
-
self._description_message_pattern: str = '[{command}] *=*=* {description}'
|
51
|
-
self._registered_routers: RegisteredRouters = RegisteredRouters()
|
52
|
-
self._invalid_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'Incorrect flag syntax: "{raw_command}"')
|
53
|
-
self._repeated_input_flags_handler: Callable[[str], None] = lambda raw_command: print_func(f'Repeated input flags: "{raw_command}"')
|
54
|
-
self._empty_input_command_handler: Callable[[], None] = lambda: print_func('Empty input command')
|
55
|
-
self._unknown_command_handler: Callable[[InputCommand], None] = lambda command: print_func(f"Unknown command: {command.get_trigger()}")
|
56
|
-
self._exit_command_handler: Callable[[], None] = lambda: print_func(self.farewell_message)
|
57
|
-
|
58
|
-
|
59
|
-
def start_polling(self) -> None:
|
60
|
-
self._setup_system_router()
|
61
|
-
self._validate_number_of_routers()
|
62
|
-
self._validate_included_routers()
|
63
|
-
|
64
|
-
self.print_func(self.initial_message)
|
65
|
-
|
66
|
-
for message in self.messages_on_startup:
|
67
|
-
self.print_func(message)
|
68
|
-
|
69
|
-
if not self.repeat_command_groups:
|
70
|
-
self._print_command_group_description()
|
71
|
-
self.print_func(self.prompt)
|
72
|
-
|
73
|
-
while True:
|
74
|
-
if self.repeat_command_groups:
|
75
|
-
self._print_command_group_description()
|
76
|
-
self.print_func(self.prompt)
|
77
|
-
|
78
|
-
raw_command: str = input()
|
79
|
-
|
80
|
-
try:
|
81
|
-
input_command: InputCommand = InputCommand.parse(raw_command=raw_command)
|
82
|
-
except (UnprocessedInputFlagException,
|
83
|
-
RepeatedInputFlagsException,
|
84
|
-
EmptyInputCommandException) as error:
|
85
|
-
self.print_func(self.line_separate)
|
86
|
-
self._error_handler(error, raw_command)
|
87
|
-
self.print_func(self.line_separate)
|
88
|
-
|
89
|
-
if not self.repeat_command_groups:
|
90
|
-
self.print_func(self.prompt)
|
91
|
-
continue
|
92
|
-
|
93
|
-
is_exit = self._is_exit_command(input_command)
|
94
|
-
if is_exit:
|
95
|
-
return
|
96
|
-
|
97
|
-
self.print_func(self.line_separate)
|
98
|
-
is_unknown_command: bool = self._check_is_command_unknown(input_command)
|
99
|
-
|
100
|
-
if is_unknown_command:
|
101
|
-
self.print_func(self.line_separate)
|
102
|
-
self.print_func(self.command_group_description_separate)
|
103
|
-
if not self.repeat_command_groups:
|
104
|
-
self.print_func(self.prompt)
|
105
|
-
continue
|
106
|
-
|
107
|
-
for registered_router in self._registered_routers:
|
108
|
-
registered_router.input_command_handler(input_command)
|
109
|
-
|
110
|
-
self.print_func(self.line_separate)
|
111
|
-
self.print_func(self.command_group_description_separate)
|
112
|
-
if not self.repeat_command_groups:
|
113
|
-
self.print_func(self.prompt)
|
114
|
-
|
115
|
-
|
116
|
-
def set_initial_message(self, message: str) -> None:
|
117
|
-
self.initial_message: str = message
|
118
|
-
|
119
|
-
|
120
|
-
def set_farewell_message(self, message: str) -> None:
|
121
|
-
self.farewell_message: str = message
|
122
|
-
|
123
|
-
|
124
|
-
def set_description_message_pattern(self, pattern: str) -> None:
|
125
|
-
first_check = re.match(r'.*{command}.*', pattern)
|
126
|
-
second_check = re.match(r'.*{description}.*', pattern)
|
127
|
-
|
128
|
-
if bool(first_check) and bool(second_check):
|
129
|
-
self._description_message_pattern: str = pattern
|
130
|
-
else:
|
131
|
-
raise InvalidDescriptionMessagePatternException(pattern)
|
132
|
-
|
133
|
-
|
134
|
-
def set_invalid_input_flags_handler(self, handler: Callable[[str], None]) -> None:
|
135
|
-
args = getfullargspec(handler).args
|
136
|
-
if len(args) != 1:
|
137
|
-
raise IncorrectNumberOfHandlerArgsException()
|
138
|
-
else:
|
139
|
-
self._invalid_input_flags_handler = handler
|
140
|
-
|
141
|
-
|
142
|
-
def set_repeated_input_flags_handler(self, handler: Callable[[str], None]) -> None:
|
143
|
-
args = getfullargspec(handler).args
|
144
|
-
if len(args) != 1:
|
145
|
-
raise IncorrectNumberOfHandlerArgsException()
|
146
|
-
else:
|
147
|
-
self._repeated_input_flags_handler = handler
|
148
|
-
|
149
|
-
|
150
|
-
def set_unknown_command_handler(self, handler: Callable[[str], None]) -> None:
|
151
|
-
args = getfullargspec(handler).args
|
152
|
-
if len(args) != 1:
|
153
|
-
raise IncorrectNumberOfHandlerArgsException()
|
154
|
-
else:
|
155
|
-
self._unknown_command_handler = handler
|
156
|
-
|
157
|
-
|
158
|
-
def set_empty_command_handler(self, handler: Callable[[str], None]) -> None:
|
159
|
-
args = getfullargspec(handler).args
|
160
|
-
if len(args) != 1:
|
161
|
-
raise IncorrectNumberOfHandlerArgsException()
|
162
|
-
else:
|
163
|
-
self._empty_input_command_handler = handler
|
164
|
-
|
165
|
-
|
166
|
-
def set_exit_command_handler(self, handler: Callable[[], None]) -> None:
|
167
|
-
args = getfullargspec(handler).args
|
168
|
-
if len(args) != 0:
|
169
|
-
raise IncorrectNumberOfHandlerArgsException()
|
170
|
-
else:
|
171
|
-
self._exit_command_handler = handler
|
172
|
-
|
173
|
-
|
174
|
-
def add_message_on_startup(self, message: str) -> None:
|
175
|
-
self.messages_on_startup.append(message)
|
176
|
-
|
177
|
-
|
178
|
-
def include_router(self, router: Router) -> None:
|
179
|
-
if not isinstance(router, Router):
|
180
|
-
raise InvalidRouterInstanceException()
|
181
|
-
|
182
|
-
router.set_ignore_command_register(self.ignore_command_register)
|
183
|
-
self._registered_routers.add_registered_router(router)
|
184
|
-
|
185
|
-
|
186
|
-
def include_routers(self, *routers: Router) -> None:
|
187
|
-
for router in routers:
|
188
|
-
self.include_router(router)
|
189
|
-
|
190
|
-
|
191
|
-
def _validate_number_of_routers(self) -> None:
|
192
|
-
if not self._registered_routers:
|
193
|
-
raise NoRegisteredRoutersException()
|
194
|
-
|
195
|
-
|
196
|
-
def _validate_included_routers(self) -> None:
|
197
|
-
for router in self._registered_routers:
|
198
|
-
if not router.get_command_handlers():
|
199
|
-
raise NoRegisteredHandlersException(router.get_name())
|
200
|
-
|
201
|
-
|
202
|
-
def _setup_system_router(self):
|
203
|
-
system_router.set_title(self.system_points_title)
|
204
|
-
@system_router.command(Command(self.exit_command, self.exit_command_description))
|
205
|
-
def exit_command():
|
206
|
-
self._exit_command_handler()
|
207
|
-
if system_router not in self._registered_routers.get_registered_routers():
|
208
|
-
self.include_router(system_router)
|
209
|
-
|
210
|
-
|
211
|
-
def _is_exit_command(self, command: InputCommand):
|
212
|
-
if command.get_trigger().lower() == self.exit_command.lower():
|
213
|
-
if self.ignore_exit_command_register:
|
214
|
-
system_router.input_command_handler(command)
|
215
|
-
return True
|
216
|
-
else:
|
217
|
-
if command.get_trigger() == self.exit_command:
|
218
|
-
system_router.input_command_handler(command)
|
219
|
-
return True
|
220
|
-
return False
|
221
|
-
|
222
|
-
|
223
|
-
def _check_is_command_unknown(self, command: InputCommand):
|
224
|
-
for router_entity in self._registered_routers:
|
225
|
-
for command_handler in router_entity.get_command_handlers():
|
226
|
-
handled_command_trigger = command_handler.get_handled_command().get_trigger()
|
227
|
-
if handled_command_trigger.lower() == command.get_trigger().lower():
|
228
|
-
if self.ignore_command_register:
|
229
|
-
return False
|
230
|
-
else:
|
231
|
-
if handled_command_trigger == command.get_trigger():
|
232
|
-
return False
|
233
|
-
self._unknown_command_handler(command)
|
234
|
-
return True
|
235
|
-
|
236
|
-
|
237
|
-
def _print_command_group_description(self):
|
238
|
-
for registered_router in self._registered_routers:
|
239
|
-
self.print_func(registered_router.get_title())
|
240
|
-
for command_handler in registered_router.get_command_handlers():
|
241
|
-
self.print_func(self._description_message_pattern.format(
|
242
|
-
command=command_handler.get_handled_command().get_trigger(),
|
243
|
-
description=command_handler.get_handled_command().get_description()
|
244
|
-
)
|
245
|
-
)
|
246
|
-
self.print_func(self.command_group_description_separate)
|
247
|
-
|
248
|
-
|
249
|
-
def _error_handler(self,
|
250
|
-
error: UnprocessedInputFlagException |
|
251
|
-
RepeatedInputFlagsException |
|
252
|
-
EmptyInputCommandException,
|
253
|
-
raw_command: str) -> None:
|
254
|
-
match error:
|
255
|
-
case UnprocessedInputFlagException():
|
256
|
-
self._invalid_input_flags_handler(raw_command)
|
257
|
-
case RepeatedInputFlagsException():
|
258
|
-
self._repeated_input_flags_handler(raw_command)
|
259
|
-
case EmptyInputCommandException():
|
260
|
-
self._empty_input_command_handler()
|
261
|
-
|
262
|
-
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|