argenta 0.2.2__tar.gz → 0.3.0a0__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.
Files changed (29) hide show
  1. {argenta-0.2.2 → argenta-0.3.0a0}/PKG-INFO +2 -2
  2. {argenta-0.2.2 → argenta-0.3.0a0}/argenta/app/entity.py +24 -11
  3. argenta-0.3.0a0/argenta/command/__init__.py +0 -0
  4. argenta-0.3.0a0/argenta/command/entity.py +60 -0
  5. argenta-0.3.0a0/argenta/command/exceptions.py +13 -0
  6. argenta-0.3.0a0/argenta/command/input_comand/__init__.py +0 -0
  7. argenta-0.3.0a0/argenta/command/input_comand/__pycache__/__init__.cpython-313.pyc +0 -0
  8. argenta-0.3.0a0/argenta/command/input_comand/__pycache__/entity.cpython-313.pyc +0 -0
  9. argenta-0.3.0a0/argenta/command/input_comand/__pycache__/exceptions.cpython-313.pyc +0 -0
  10. argenta-0.3.0a0/argenta/command/input_comand/entity.py +66 -0
  11. argenta-0.3.0a0/argenta/command/input_comand/exceptions.py +24 -0
  12. argenta-0.3.0a0/argenta/command/params/__init__.py +0 -0
  13. argenta-0.3.0a0/argenta/command/params/flag/__init__.py +0 -0
  14. argenta-0.3.0a0/argenta/command/params/flag/entity.py +45 -0
  15. argenta-0.3.0a0/argenta/command/params/flag/flags_group/__init__.py +0 -0
  16. argenta-0.3.0a0/argenta/command/params/flag/flags_group/entity.py +22 -0
  17. argenta-0.3.0a0/argenta/command/params/flag/input_flag/__init__.py +0 -0
  18. argenta-0.3.0a0/argenta/command/params/flag/input_flag/entity.py +11 -0
  19. argenta-0.3.0a0/argenta/router/__init__.py +3 -0
  20. argenta-0.3.0a0/argenta/router/entity.py +141 -0
  21. {argenta-0.2.2 → argenta-0.3.0a0}/argenta/router/exceptions.py +5 -5
  22. {argenta-0.2.2 → argenta-0.3.0a0}/pyproject.toml +14 -4
  23. argenta-0.2.2/argenta/router/__init__.py +0 -4
  24. argenta-0.2.2/argenta/router/entity.py +0 -123
  25. {argenta-0.2.2 → argenta-0.3.0a0}/LICENSE +0 -0
  26. {argenta-0.2.2 → argenta-0.3.0a0}/README.md +0 -0
  27. {argenta-0.2.2 → argenta-0.3.0a0}/argenta/__init__.py +0 -0
  28. {argenta-0.2.2 → argenta-0.3.0a0}/argenta/app/__init__.py +0 -0
  29. {argenta-0.2.2 → argenta-0.3.0a0}/argenta/app/exceptions.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: argenta
3
- Version: 0.2.2
4
- Summary: python library for creating cli apps
3
+ Version: 0.3.0a0
4
+ Summary: python library for creating custom shells
5
5
  License: MIT
6
6
  Author: kolo
7
7
  Author-email: kolo.is.main@gmail.com
@@ -1,4 +1,7 @@
1
1
  from typing import Callable
2
+ from ..command.entity import Command
3
+ from argenta.command.input_comand.entity import InputCommand
4
+ from argenta.command.input_comand.exceptions import InvalidInputFlagException
2
5
  from ..router.entity import Router
3
6
  from .exceptions import (InvalidRouterInstanceException,
4
7
  InvalidDescriptionMessagePatternException,
@@ -16,6 +19,7 @@ class App:
16
19
  prompt: str = 'Enter a command',
17
20
  initial_message: str = '\nHello, I am Argenta\n',
18
21
  farewell_message: str = '\nGoodBye\n',
22
+ invalid_input_flags_message: str = 'Invalid input flags',
19
23
  exit_command: str = 'Q',
20
24
  exit_command_description: str = 'Exit command',
21
25
  exit_command_title: str = 'System points:',
@@ -33,13 +37,14 @@ class App:
33
37
  self.ignore_exit_command_register = ignore_exit_command_register
34
38
  self.farewell_message = farewell_message
35
39
  self.initial_message = initial_message
40
+ self.invalid_input_flags_message = invalid_input_flags_message
36
41
  self.line_separate = line_separate
37
42
  self.command_group_description_separate = command_group_description_separate
38
43
  self.ignore_command_register = ignore_command_register
39
44
  self.repeat_command_groups = repeat_command_groups
40
45
 
41
46
  self._routers: list[Router] = []
42
- self._registered_router_entities: list[dict[str, str | list[dict[str, Callable[[], None] | str]] | Router]] = []
47
+ self._registered_router_entities: list[dict[str, str | list[dict[str, Callable[[], None] | Command]] | Router]] = []
43
48
  self._app_main_router: Router | None = None
44
49
  self._description_message_pattern: str = '[{command}] *=*=* {description}'
45
50
 
@@ -61,19 +66,27 @@ class App:
61
66
  self._print_command_group_description()
62
67
  self.print_func(self.prompt)
63
68
 
64
- command: str = input()
69
+ raw_command: str = input()
70
+ try:
71
+ input_command: InputCommand = InputCommand.parse(raw_command=raw_command)
72
+ except InvalidInputFlagException:
73
+ self.print_func(self.line_separate)
74
+ self.print_func(self.command_group_description_separate)
75
+ if not self.repeat_command_groups:
76
+ self.print_func(self.prompt)
77
+ continue
65
78
 
66
- self._checking_command_for_exit_command(command)
79
+ self._checking_command_for_exit_command(input_command.get_string_entity())
67
80
  self.print_func(self.line_separate)
68
81
 
69
- is_unknown_command: bool = self._check_is_command_unknown(command)
82
+ is_unknown_command: bool = self._check_is_command_unknown(input_command.get_string_entity())
70
83
  if is_unknown_command:
71
84
  if not self.repeat_command_groups:
72
85
  self.print_func(self.prompt)
73
86
  continue
74
87
 
75
88
  for router in self._routers:
76
- router.input_command_handler(command)
89
+ router.input_command_handler(input_command)
77
90
 
78
91
  self.print_func(self.line_separate)
79
92
  self.print_func(self.command_group_description_separate)
@@ -124,7 +137,7 @@ class App:
124
137
  router.set_ignore_command_register(self.ignore_command_register)
125
138
  self._routers.append(router)
126
139
 
127
- command_entities: list[dict[str, Callable[[], None] | str]] = router.get_command_entities()
140
+ command_entities: list[dict[str, Callable[[], None] | Command]] = router.get_command_entities()
128
141
  self._registered_router_entities.append({'name': router.get_name(),
129
142
  'title': router.get_title(),
130
143
  'entity': router,
@@ -187,14 +200,14 @@ class App:
187
200
 
188
201
 
189
202
  def _check_is_command_unknown(self, command: str):
190
- registered_router_entities: list[dict[str, str | list[dict[str, Callable[[], None] | str]] | Router]] = self._registered_router_entities
203
+ registered_router_entities: list[dict[str, str | list[dict[str, Callable[[], None] | Command]] | Router]] = self._registered_router_entities
191
204
  for router_entity in registered_router_entities:
192
205
  for command_entity in router_entity['commands']:
193
- if command_entity['command'].lower() == command.lower():
206
+ if command_entity['command'].get_string_entity().lower() == command.lower():
194
207
  if self.ignore_command_register:
195
208
  return False
196
209
  else:
197
- if command_entity['command'] == command:
210
+ if command_entity['command'].get_string_entity() == command:
198
211
  return False
199
212
  self._app_main_router.unknown_command_handler(command)
200
213
  self.print_func(self.line_separate)
@@ -207,8 +220,8 @@ class App:
207
220
  self.print_func(router_entity['title'])
208
221
  for command_entity in router_entity['commands']:
209
222
  self.print_func(self._description_message_pattern.format(
210
- command=command_entity['command'],
211
- description=command_entity['description']
223
+ command=command_entity['command'].get_string_entity(),
224
+ description=command_entity['command'].get_description()
212
225
  )
213
226
  )
214
227
  self.print_func(self.command_group_description_separate)
File without changes
@@ -0,0 +1,60 @@
1
+ from .params.flag.entity import Flag
2
+ from .params.flag.flags_group.entity import FlagsGroup
3
+ from .exceptions import (InvalidCommandInstanceException,
4
+ InvalidDescriptionInstanceException,
5
+ InvalidFlagsInstanceException)
6
+ from .params.flag.input_flag.entity import InputFlag
7
+
8
+
9
+ class Command:
10
+ def __init__(self, command: str,
11
+ description: str | None = None,
12
+ flags: Flag | FlagsGroup | None = None):
13
+ self._command = command
14
+ self._description = description
15
+ self._flags: FlagsGroup | None = flags if isinstance(flags, FlagsGroup) else FlagsGroup([flags]) if isinstance(flags, Flag) else flags
16
+
17
+ self._input_flags: InputFlag | FlagsGroup | None = None
18
+
19
+ def get_string_entity(self):
20
+ return self._command
21
+
22
+ def get_description(self):
23
+ if not self._description:
24
+ description = f'description for "{self._command}" command'
25
+ return description
26
+ else:
27
+ return self._description
28
+
29
+ def get_flags(self):
30
+ return self._flags
31
+
32
+ def set_command(self, command: str):
33
+ self._command = command
34
+
35
+ def validate_commands_params(self):
36
+ if not isinstance(self._command, str):
37
+ raise InvalidCommandInstanceException(self._command)
38
+ if not isinstance(self._description, str):
39
+ raise InvalidDescriptionInstanceException()
40
+ if not any([(isinstance(self._flags, Flag), isinstance(self._flags, FlagsGroup)), not self._flags]):
41
+ raise InvalidFlagsInstanceException
42
+
43
+ def validate_input_flag(self, flag: InputFlag):
44
+ registered_flags: FlagsGroup | Flag | None = self._flags
45
+ if registered_flags:
46
+ if isinstance(registered_flags, Flag):
47
+ if registered_flags.get_string_entity() == flag.get_string_entity():
48
+ is_valid = registered_flags.validate_input_flag_value(flag.get_value())
49
+ if is_valid:
50
+ return True
51
+ else:
52
+ for registered_flag in registered_flags:
53
+ if registered_flag.get_string_entity() == flag.get_string_entity():
54
+ is_valid = registered_flag.validate_input_flag_value(flag.get_value())
55
+ if is_valid:
56
+ return True
57
+ return False
58
+
59
+
60
+
@@ -0,0 +1,13 @@
1
+ class InvalidCommandInstanceException(Exception):
2
+ def __str__(self):
3
+ return "Invalid Command Instance"
4
+
5
+
6
+ class InvalidDescriptionInstanceException(Exception):
7
+ def __str__(self):
8
+ return "Invalid Description Instance"
9
+
10
+
11
+ class InvalidFlagsInstanceException(Exception):
12
+ def __str__(self):
13
+ return "Invalid Flags Instance"
@@ -0,0 +1,66 @@
1
+ from ..input_comand.exceptions import IncorrectInputFlagException, RepeatedInputFlagsException
2
+ from ..entity import Command
3
+ from ..params.flag.flags_group.entity import FlagsGroup
4
+ from ..params.flag.input_flag.entity import InputFlag
5
+
6
+ from typing import Generic, TypeVar
7
+
8
+
9
+ T = TypeVar('T')
10
+
11
+
12
+ class InputCommand(Command, Generic[T]):
13
+ def set_input_flags(self, input_flags: FlagsGroup):
14
+ self._input_flags = input_flags
15
+
16
+ def get_input_flags(self) -> FlagsGroup:
17
+ return self._input_flags
18
+
19
+ @staticmethod
20
+ def parse(raw_command: str) -> 'InputCommand[T]':
21
+ list_of_tokens = raw_command.split()
22
+ command = list_of_tokens[0]
23
+ list_of_tokens.pop(0)
24
+
25
+ flags: FlagsGroup = FlagsGroup()
26
+ current_flag_name = None
27
+ current_flag_value = None
28
+ for _ in list_of_tokens:
29
+ if _.startswith('-'):
30
+ flag_prefix_last_symbol_index = _.rfind('-')
31
+ if current_flag_name or len(_) < 2 or len(_[:flag_prefix_last_symbol_index]) > 3:
32
+ raise IncorrectInputFlagException()
33
+ else:
34
+ current_flag_name = _
35
+ else:
36
+ if not current_flag_name:
37
+ raise IncorrectInputFlagException()
38
+ else:
39
+ current_flag_value = _
40
+ if current_flag_name and current_flag_value:
41
+ flag_prefix_last_symbol_index = current_flag_name.rfind('-')
42
+ flag_prefix = current_flag_name[:flag_prefix_last_symbol_index]
43
+ flag_name = current_flag_name[flag_prefix_last_symbol_index:]
44
+
45
+ input_flag = InputFlag(flag_name=flag_name,
46
+ flag_prefix=flag_prefix)
47
+ input_flag.set_value(current_flag_value)
48
+
49
+ all_flags = [x.get_string_entity() for x in flags.get_flags()]
50
+ if input_flag.get_string_entity() not in all_flags:
51
+ flags.add_flag(input_flag)
52
+ else:
53
+ raise RepeatedInputFlagsException(input_flag)
54
+
55
+ current_flag_name = None
56
+ current_flag_value = None
57
+ if any([current_flag_name, current_flag_value]):
58
+ raise IncorrectInputFlagException()
59
+ if len(flags.get_flags()) == 0:
60
+ return InputCommand(command=command)
61
+ else:
62
+ input_command = InputCommand(command=command)
63
+ input_command.set_input_flags(flags)
64
+ return input_command
65
+
66
+
@@ -0,0 +1,24 @@
1
+ from ..params.flag.input_flag.entity import InputFlag
2
+
3
+
4
+ class InvalidInputFlagException(Exception):
5
+ def __init__(self, flag: InputFlag):
6
+ self.flag = flag
7
+ def __str__(self):
8
+ return ("Invalid Input Flags\n"
9
+ f"Unknown or invalid input flag: '{self.flag.get_string_entity()} {self.flag.get_value()}'")
10
+
11
+ class IncorrectInputFlagException(Exception):
12
+ def __str__(self):
13
+ return "Incorrect Input Flags"
14
+
15
+
16
+ class RepeatedInputFlagsException(Exception):
17
+ def __init__(self, flag: InputFlag):
18
+ self.flag = flag
19
+ def __str__(self):
20
+ return ("Repeated Input Flags\n"
21
+ f"Duplicate flag was detected in the input: '{self.flag.get_string_entity()}'")
22
+
23
+
24
+
File without changes
@@ -0,0 +1,45 @@
1
+ from typing import Literal
2
+
3
+
4
+ class Flag:
5
+ def __init__(self, flag_name: str,
6
+ flag_prefix: Literal['-', '--', '---'] = '-',
7
+ ignore_flag_value_register: bool = False,
8
+ possible_flag_values: list[str] = False):
9
+ self._flag_name = flag_name
10
+ self._flag_prefix = flag_prefix
11
+ self.possible_flag_values = possible_flag_values
12
+ self.ignore_flag_value_register = ignore_flag_value_register
13
+
14
+ self._value = None
15
+
16
+ def get_string_entity(self):
17
+ string_entity: str = self._flag_prefix + self._flag_name
18
+ return string_entity
19
+
20
+ def get_flag_name(self):
21
+ return self._flag_name
22
+
23
+ def get_flag_prefix(self):
24
+ return self._flag_prefix
25
+
26
+ def get_value(self):
27
+ return self._value
28
+
29
+ def set_value(self, value):
30
+ self._value = value
31
+
32
+ def validate_input_flag_value(self, input_flag_value: str):
33
+ if self.possible_flag_values:
34
+ if self.ignore_flag_value_register:
35
+ if input_flag_value.lower() in [x.lower() for x in self.possible_flag_values]:
36
+ return True
37
+ else:
38
+ return False
39
+ else:
40
+ if input_flag_value in self.possible_flag_values:
41
+ return True
42
+ else:
43
+ return False
44
+ else:
45
+ return True
@@ -0,0 +1,22 @@
1
+ from argenta.command.params.flag.entity import Flag
2
+ from argenta.command.params.flag.input_flag.entity import InputFlag
3
+
4
+
5
+ class FlagsGroup:
6
+ def __init__(self, flags: list[Flag | InputFlag] = None):
7
+ self._flags: list[Flag | InputFlag] = [] if not flags else flags
8
+
9
+ def get_flags(self):
10
+ return self._flags
11
+
12
+ def add_flag(self, flag: Flag | InputFlag):
13
+ self._flags.append(flag)
14
+
15
+ def add_flags(self, flags: list[Flag | InputFlag]):
16
+ self._flags.extend(flags)
17
+
18
+ def __iter__(self):
19
+ return iter(self._flags)
20
+
21
+ def __next__(self):
22
+ return next(iter(self))
@@ -0,0 +1,11 @@
1
+ from ...flag.entity import Flag
2
+
3
+
4
+ class InputFlag(Flag):
5
+ def set_value(self, value: str):
6
+ self._value = value
7
+
8
+ def get_value(self) -> str:
9
+ return self._value
10
+
11
+
@@ -0,0 +1,3 @@
1
+ from .entity import Router
2
+ from .exceptions import (UnknownCommandHandlerHasAlreadyBeenCreatedException,
3
+ InvalidDescriptionInstanceException)
@@ -0,0 +1,141 @@
1
+ from typing import Callable, Any
2
+ from ..command.entity import Command
3
+ from ..command.input_comand.entity import InputCommand
4
+ from ..command.input_comand.exceptions import InvalidInputFlagException
5
+ from ..command.params.flag.flags_group.entity import FlagsGroup
6
+ from ..router.exceptions import (UnknownCommandHandlerHasAlreadyBeenCreatedException,
7
+ RepeatedCommandException, RepeatedFlagNameException)
8
+
9
+
10
+ class Router:
11
+ def __init__(self,
12
+ title: str = 'Commands group title:',
13
+ name: str = 'subordinate'):
14
+
15
+ self.title = title
16
+ self.name = name
17
+
18
+ self._command_entities: list[dict[str, Callable[[], None] | Command]] = []
19
+ self.unknown_command_func: Callable[[str], None] | None = None
20
+ self._is_main_router: bool = False
21
+ self.ignore_command_register: bool = False
22
+
23
+
24
+ def command(self, command: Command) -> Callable[[Any], Any]:
25
+ command.validate_commands_params()
26
+ self._validate_command(command)
27
+
28
+ def command_decorator(func):
29
+ self._command_entities.append({'handler_func': func,
30
+ 'command': command})
31
+ def wrapper(*args, **kwargs):
32
+ return func(*args, **kwargs)
33
+ return wrapper
34
+
35
+ return command_decorator
36
+
37
+
38
+ def unknown_command(self, func):
39
+ if self.unknown_command_func is not None:
40
+ raise UnknownCommandHandlerHasAlreadyBeenCreatedException()
41
+
42
+ self.unknown_command_func: Callable = func
43
+
44
+ def wrapper(*args, **kwargs):
45
+ return func(*args, **kwargs)
46
+ return wrapper
47
+
48
+
49
+ def input_command_handler(self, input_command: InputCommand):
50
+ input_command_name: str = input_command.get_string_entity()
51
+ for command_entity in self._command_entities:
52
+ if input_command_name.lower() == command_entity['command'].get_string_entity().lower():
53
+ if self.ignore_command_register:
54
+ if input_command.get_input_flags():
55
+ for flag in input_command.get_input_flags():
56
+ is_valid = command_entity['command'].validate_input_flag(flag)
57
+ if not is_valid:
58
+ raise InvalidInputFlagException(flag)
59
+ return command_entity['handler_func'](input_command.get_input_flags())
60
+ else:
61
+ return command_entity['handler_func']()
62
+ else:
63
+ if input_command_name == command_entity['command'].get_string_entity():
64
+ if input_command.get_input_flags():
65
+ for flag in input_command.get_input_flags():
66
+ is_valid = command_entity['command'].validate_input_flag(flag)
67
+ if not is_valid:
68
+ raise InvalidInputFlagException(flag)
69
+ return command_entity['handler_func'](input_command.get_input_flags())
70
+ else:
71
+ return command_entity['handler_func']()
72
+
73
+
74
+ def unknown_command_handler(self, unknown_command):
75
+ self.unknown_command_func(unknown_command)
76
+
77
+
78
+ def _validate_command(self, command: Command):
79
+ command_name: str = command.get_string_entity()
80
+ if command in self.get_all_commands():
81
+ raise RepeatedCommandException()
82
+ if self.ignore_command_register:
83
+ if command_name.lower() in [x.lower() for x in self.get_all_commands()]:
84
+ raise RepeatedCommandException()
85
+
86
+ flags: FlagsGroup = command.get_flags()
87
+ if flags:
88
+ flags_name: list = [x.get_string_entity().lower() for x in flags]
89
+ if len(set(flags_name)) < len(flags_name):
90
+ raise RepeatedFlagNameException()
91
+
92
+
93
+ def set_router_as_main(self):
94
+ if self.name == 'subordinate':
95
+ self.name = 'main'
96
+ self._is_main_router = True
97
+
98
+
99
+ def set_ignore_command_register(self, ignore_command_register: bool):
100
+ self.ignore_command_register = ignore_command_register
101
+
102
+
103
+ def get_command_entities(self) -> list[dict[str, Callable[[], None] | Command]]:
104
+ return self._command_entities
105
+
106
+
107
+ def get_name(self) -> str:
108
+ return self.name
109
+
110
+
111
+ def get_title(self) -> str:
112
+ return self.title
113
+
114
+
115
+ def get_router_info(self) -> dict:
116
+ return {
117
+ 'title': self.title,
118
+ 'name': self.name,
119
+ 'ignore_command_register': self.ignore_command_register,
120
+ 'attributes': {
121
+ 'command_entities': self._command_entities,
122
+ 'unknown_command_func': self.unknown_command_func,
123
+ 'is_main_router': self._is_main_router
124
+ }
125
+
126
+ }
127
+
128
+
129
+ def get_all_commands(self) -> list[str]:
130
+ all_commands: list[str] = []
131
+ for command_entity in self._command_entities:
132
+ all_commands.append(command_entity['command'].get_string_entity())
133
+
134
+ return all_commands
135
+
136
+ def get_all_flags(self) -> list[FlagsGroup]:
137
+ all_flags: list[FlagsGroup] = []
138
+ for command_entity in self._command_entities:
139
+ all_flags.append(command_entity['command'].get_flags())
140
+
141
+ return all_flags
@@ -1,8 +1,3 @@
1
- class InvalidCommandInstanceException(Exception):
2
- def __str__(self):
3
- return "Invalid Command Instance"
4
-
5
-
6
1
  class InvalidDescriptionInstanceException(Exception):
7
2
  def __str__(self):
8
3
  return "Invalid Description Instance"
@@ -16,3 +11,8 @@ class UnknownCommandHandlerHasAlreadyBeenCreatedException(Exception):
16
11
  class RepeatedCommandException(Exception):
17
12
  def __str__(self):
18
13
  return "Commands in handler cannot be repeated"
14
+
15
+
16
+ class RepeatedFlagNameException(Exception):
17
+ def __str__(self):
18
+ return "Repeated flag name in register command"
@@ -1,15 +1,25 @@
1
1
  [project]
2
2
  name = "argenta"
3
- version = "0.2.2"
4
- description = "python library for creating cli apps"
3
+ version = "0.3.0-alpha"
4
+ description = "python library for creating custom shells"
5
5
  authors = [
6
6
  {name = "kolo",email = "kolo.is.main@gmail.com"}
7
7
  ]
8
8
  license = {text = "MIT"}
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
11
- dependencies = [
12
- ]
11
+ dependencies = [] # no dependencies
12
+
13
+
14
+ [tool.ruff]
15
+ exclude = [
16
+ ".idea",
17
+ "venv",
18
+ ".git",
19
+ "poetry.lock",
20
+ ".__pycache__",
21
+ "tests"
22
+ ]
13
23
 
14
24
 
15
25
  [build-system]
@@ -1,4 +0,0 @@
1
- from .entity import Router
2
- from .exceptions import (UnknownCommandHandlerHasAlreadyBeenCreatedException,
3
- InvalidDescriptionInstanceException,
4
- InvalidCommandInstanceException)
@@ -1,123 +0,0 @@
1
- from typing import Callable, Any
2
- from ..router.exceptions import (InvalidCommandInstanceException,
3
- UnknownCommandHandlerHasAlreadyBeenCreatedException,
4
- InvalidDescriptionInstanceException,
5
- RepeatedCommandException)
6
-
7
-
8
- class Router:
9
- def __init__(self,
10
- title: str = 'Commands group title:',
11
- name: str = 'subordinate'):
12
-
13
- self.title = title
14
- self.name = name
15
-
16
- self._command_entities: list[dict[str, Callable[[], None] | str]] = []
17
- self.unknown_command_func: Callable[[str], None] | None = None
18
- self._is_main_router: bool = False
19
- self.ignore_command_register: bool = False
20
-
21
-
22
- def command(self, command: str, description: str = None) -> Callable[[Any], Any]:
23
- processed_description = Router._validate_description(command, description)
24
- self._validate_command(command)
25
-
26
- def command_decorator(func):
27
- self._command_entities.append({'handler_func': func,
28
- 'command': command,
29
- 'description': processed_description})
30
- def wrapper(*args, **kwargs):
31
- return func(*args, **kwargs)
32
- return wrapper
33
-
34
- return command_decorator
35
-
36
-
37
- def unknown_command(self, func):
38
- if self.unknown_command_func is not None:
39
- raise UnknownCommandHandlerHasAlreadyBeenCreatedException()
40
-
41
- self.unknown_command_func: Callable = func
42
-
43
- def wrapper(*args, **kwargs):
44
- return func(*args, **kwargs)
45
- return wrapper
46
-
47
-
48
- def input_command_handler(self, input_command):
49
- for command_entity in self._command_entities:
50
- if input_command.lower() == command_entity['command'].lower():
51
- if self.ignore_command_register:
52
- return command_entity['handler_func']()
53
- else:
54
- if input_command == command_entity['command']:
55
- return command_entity['handler_func']()
56
-
57
-
58
- def unknown_command_handler(self, unknown_command):
59
- self.unknown_command_func(unknown_command)
60
-
61
-
62
- def _validate_command(self, command: str):
63
- if not isinstance(command, str):
64
- raise InvalidCommandInstanceException()
65
- if command in self.get_all_commands():
66
- raise RepeatedCommandException()
67
- if self.ignore_command_register:
68
- if command.lower() in [x.lower() for x in self.get_all_commands()]:
69
- raise RepeatedCommandException()
70
-
71
-
72
- @staticmethod
73
- def _validate_description(command: str, description: str):
74
- if not isinstance(description, str):
75
- if description is None:
76
- description = f'description for "{command}" command'
77
- else:
78
- raise InvalidDescriptionInstanceException()
79
- return description
80
-
81
-
82
- def set_router_as_main(self):
83
- if self.name == 'subordinate':
84
- self.name = 'main'
85
- self._is_main_router = True
86
-
87
-
88
- def set_ignore_command_register(self, ignore_command_register: bool):
89
- self.ignore_command_register = ignore_command_register
90
-
91
-
92
- def get_command_entities(self) -> list[dict[str, Callable[[], None] | str]]:
93
- return self._command_entities
94
-
95
-
96
- def get_name(self) -> str:
97
- return self.name
98
-
99
-
100
- def get_title(self) -> str:
101
- return self.title
102
-
103
-
104
- def get_router_info(self) -> dict:
105
- return {
106
- 'title': self.title,
107
- 'name': self.name,
108
- 'ignore_command_register': self.ignore_command_register,
109
- 'attributes': {
110
- 'command_entities': self._command_entities,
111
- 'unknown_command_func': self.unknown_command_func,
112
- 'is_main_router': self._is_main_router
113
- }
114
-
115
- }
116
-
117
-
118
- def get_all_commands(self) -> list[str]:
119
- all_commands: list[str] = []
120
- for command_entity in self._command_entities:
121
- all_commands.append(command_entity['command'])
122
-
123
- return all_commands
File without changes
File without changes
File without changes