argenta 0.4.1__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.1 → argenta-0.4.6}/PKG-INFO +19 -15
- {argenta-0.4.1 → argenta-0.4.6}/README.md +16 -14
- argenta-0.4.6/argenta/app/__init__.py +3 -0
- argenta-0.4.6/argenta/app/defaults.py +8 -0
- {argenta-0.4.1 → argenta-0.4.6}/argenta/app/exceptions.py +0 -10
- argenta-0.4.6/argenta/app/models.py +214 -0
- argenta-0.4.6/argenta/app/registered_routers/__init__.py +0 -0
- argenta-0.4.6/argenta/app/registered_routers/entity.py +21 -0
- argenta-0.4.6/argenta/command/__init__.py +3 -0
- argenta-0.4.6/argenta/command/exceptions.py +23 -0
- argenta-0.4.6/argenta/command/flag/__init__.py +4 -0
- argenta-0.4.6/argenta/command/flag/defaults.py +21 -0
- argenta-0.4.6/argenta/command/flag/models.py +140 -0
- argenta-0.4.6/argenta/command/models.py +106 -0
- argenta-0.4.6/argenta/router/__init__.py +4 -0
- argenta-0.4.6/argenta/router/command_handler/__init__.py +0 -0
- argenta-0.4.6/argenta/router/command_handler/entity.py +21 -0
- argenta-0.4.6/argenta/router/command_handlers/__init__.py +0 -0
- argenta-0.4.6/argenta/router/command_handlers/entity.py +21 -0
- argenta-0.4.6/argenta/router/entity.py +126 -0
- {argenta-0.4.1 → argenta-0.4.6}/argenta/router/exceptions.py +1 -6
- {argenta-0.4.1 → argenta-0.4.6}/pyproject.toml +2 -8
- argenta-0.4.1/argenta/app/__init__.py +0 -1
- argenta-0.4.1/argenta/app/entity.py +0 -282
- argenta-0.4.1/argenta/command/__init__.py +0 -1
- argenta-0.4.1/argenta/command/entity.py +0 -110
- argenta-0.4.1/argenta/command/exceptions.py +0 -19
- argenta-0.4.1/argenta/command/flag/__init__.py +0 -2
- argenta-0.4.1/argenta/command/flag/defaults.py +0 -21
- argenta-0.4.1/argenta/command/flag/entity.py +0 -49
- argenta-0.4.1/argenta/command/flag/flags_group/__init__.py +0 -1
- argenta-0.4.1/argenta/command/flag/flags_group/entity.py +0 -35
- argenta-0.4.1/argenta/router/__init__.py +0 -1
- argenta-0.4.1/argenta/router/entity.py +0 -128
- {argenta-0.4.1 → argenta-0.4.6}/LICENSE +0 -0
- {argenta-0.4.1 → argenta-0.4.6}/argenta/__init__.py +0 -0
- {argenta-0.4.1 → argenta-0.4.6}/argenta/router/defaults.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
|
# Установка
|
@@ -71,14 +76,14 @@ if __name__ == '__main__':
|
|
71
76
|
import re
|
72
77
|
from argenta.router import Router
|
73
78
|
from argenta.command import Command
|
74
|
-
from argenta.command.flag import
|
79
|
+
from argenta.command.flag import Flags, Flag, InputFlags
|
75
80
|
|
76
81
|
router = Router()
|
77
82
|
|
78
|
-
registered_flags =
|
79
|
-
Flag(
|
80
|
-
|
81
|
-
|
83
|
+
registered_flags = Flags(
|
84
|
+
Flag(name='host',
|
85
|
+
prefix='--',
|
86
|
+
possible_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
|
82
87
|
Flag('port', '--', re.compile(r'^[0-9]{1,4}$')))
|
83
88
|
|
84
89
|
|
@@ -90,10 +95,10 @@ def handler():
|
|
90
95
|
@router.command(Command(trigger="ssh",
|
91
96
|
description='connect via ssh',
|
92
97
|
flags=registered_flags))
|
93
|
-
def handler_with_flags(flags:
|
98
|
+
def handler_with_flags(flags: InputFlags):
|
94
99
|
for flag in flags:
|
95
|
-
print(f'Flag name: {flag
|
96
|
-
f'Flag value: {flag
|
100
|
+
print(f'Flag name: {flag.get_name()}\n'
|
101
|
+
f'Flag value: {flag.get_value()}')
|
97
102
|
```
|
98
103
|
|
99
104
|
---
|
@@ -314,7 +319,6 @@ Router(title: str = 'Commands group title:',
|
|
314
319
|
---
|
315
320
|
|
316
321
|
### Исключения
|
317
|
-
- `RepeatedCommandException` - Одна и та же команда зарегистрирована в одном роутере
|
318
322
|
- `RepeatedFlagNameException` - Повторяющиеся зарегистрированные флаги в команде
|
319
323
|
- `TooManyTransferredArgsException` - Слишком много зарегистрированных аргументов у обработчика команды
|
320
324
|
- `RequiredArgumentNotPassedException` - Не зарегистрирован обязательный аргумент у обработчика команды(аргумент, через который будут переданы флаги введённой команды)
|
@@ -330,14 +334,14 @@ Router(title: str = 'Commands group title:',
|
|
330
334
|
```python
|
331
335
|
Command(trigger: str,
|
332
336
|
description: str = None,
|
333
|
-
flags: Flag |
|
337
|
+
flags: Flag | Flags = None)
|
334
338
|
```
|
335
339
|
|
336
340
|
**Аргументы:**
|
337
341
|
- **name : mean**
|
338
342
|
- `trigger` (`str`): Строковый триггер
|
339
343
|
- `description` (`str`): Описание команды, которое будет выведено в консоль при запуске оболочки
|
340
|
-
- `flags` (`Flag |
|
344
|
+
- `flags` (`Flag | Flags`): Флаги, которые будут обработаны при их наличии во вводе юзера
|
341
345
|
|
342
346
|
---
|
343
347
|
|
@@ -353,7 +357,7 @@ Command(trigger: str,
|
|
353
357
|
|
354
358
|
---
|
355
359
|
|
356
|
-
#### **.get_registered_flags() -> `
|
360
|
+
#### **.get_registered_flags() -> `Flags | None`**
|
357
361
|
|
358
362
|
*method mean* **::** возвращает зарегистрированные флаги экземпляра
|
359
363
|
|
@@ -417,14 +421,14 @@ Flag(flag_name: str,
|
|
417
421
|
|
418
422
|
---
|
419
423
|
|
420
|
-
## *class* :: `
|
424
|
+
## *class* :: `Flags`
|
421
425
|
Класс, объединяющий список флагов в один объект, используется в качестве
|
422
426
|
передаваемого аргумента `flags` экземпляру класса `Command`, при регистрации
|
423
427
|
хэндлера
|
424
428
|
|
425
429
|
### Конструктор
|
426
430
|
```python
|
427
|
-
|
431
|
+
Flags(*flagы: Flag)
|
428
432
|
```
|
429
433
|
|
430
434
|
---
|
@@ -5,6 +5,9 @@
|
|
5
5
|
## Описание
|
6
6
|
**Argenta** — Python library for creating custom shells
|
7
7
|
|
8
|
+

|
9
|
+
Пример внешнего вида TUI, написанного с помощью Argenta
|
10
|
+
|
8
11
|
---
|
9
12
|
|
10
13
|
# Установка
|
@@ -56,14 +59,14 @@ if __name__ == '__main__':
|
|
56
59
|
import re
|
57
60
|
from argenta.router import Router
|
58
61
|
from argenta.command import Command
|
59
|
-
from argenta.command.flag import
|
62
|
+
from argenta.command.flag import Flags, Flag, InputFlags
|
60
63
|
|
61
64
|
router = Router()
|
62
65
|
|
63
|
-
registered_flags =
|
64
|
-
Flag(
|
65
|
-
|
66
|
-
|
66
|
+
registered_flags = Flags(
|
67
|
+
Flag(name='host',
|
68
|
+
prefix='--',
|
69
|
+
possible_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
|
67
70
|
Flag('port', '--', re.compile(r'^[0-9]{1,4}$')))
|
68
71
|
|
69
72
|
|
@@ -75,10 +78,10 @@ def handler():
|
|
75
78
|
@router.command(Command(trigger="ssh",
|
76
79
|
description='connect via ssh',
|
77
80
|
flags=registered_flags))
|
78
|
-
def handler_with_flags(flags:
|
81
|
+
def handler_with_flags(flags: InputFlags):
|
79
82
|
for flag in flags:
|
80
|
-
print(f'Flag name: {flag
|
81
|
-
f'Flag value: {flag
|
83
|
+
print(f'Flag name: {flag.get_name()}\n'
|
84
|
+
f'Flag value: {flag.get_value()}')
|
82
85
|
```
|
83
86
|
|
84
87
|
---
|
@@ -299,7 +302,6 @@ Router(title: str = 'Commands group title:',
|
|
299
302
|
---
|
300
303
|
|
301
304
|
### Исключения
|
302
|
-
- `RepeatedCommandException` - Одна и та же команда зарегистрирована в одном роутере
|
303
305
|
- `RepeatedFlagNameException` - Повторяющиеся зарегистрированные флаги в команде
|
304
306
|
- `TooManyTransferredArgsException` - Слишком много зарегистрированных аргументов у обработчика команды
|
305
307
|
- `RequiredArgumentNotPassedException` - Не зарегистрирован обязательный аргумент у обработчика команды(аргумент, через который будут переданы флаги введённой команды)
|
@@ -315,14 +317,14 @@ Router(title: str = 'Commands group title:',
|
|
315
317
|
```python
|
316
318
|
Command(trigger: str,
|
317
319
|
description: str = None,
|
318
|
-
flags: Flag |
|
320
|
+
flags: Flag | Flags = None)
|
319
321
|
```
|
320
322
|
|
321
323
|
**Аргументы:**
|
322
324
|
- **name : mean**
|
323
325
|
- `trigger` (`str`): Строковый триггер
|
324
326
|
- `description` (`str`): Описание команды, которое будет выведено в консоль при запуске оболочки
|
325
|
-
- `flags` (`Flag |
|
327
|
+
- `flags` (`Flag | Flags`): Флаги, которые будут обработаны при их наличии во вводе юзера
|
326
328
|
|
327
329
|
---
|
328
330
|
|
@@ -338,7 +340,7 @@ Command(trigger: str,
|
|
338
340
|
|
339
341
|
---
|
340
342
|
|
341
|
-
#### **.get_registered_flags() -> `
|
343
|
+
#### **.get_registered_flags() -> `Flags | None`**
|
342
344
|
|
343
345
|
*method mean* **::** возвращает зарегистрированные флаги экземпляра
|
344
346
|
|
@@ -402,14 +404,14 @@ Flag(flag_name: str,
|
|
402
404
|
|
403
405
|
---
|
404
406
|
|
405
|
-
## *class* :: `
|
407
|
+
## *class* :: `Flags`
|
406
408
|
Класс, объединяющий список флагов в один объект, используется в качестве
|
407
409
|
передаваемого аргумента `flags` экземпляру класса `Command`, при регистрации
|
408
410
|
хэндлера
|
409
411
|
|
410
412
|
### Конструктор
|
411
413
|
```python
|
412
|
-
|
414
|
+
Flags(*flagы: Flag)
|
413
415
|
```
|
414
416
|
|
415
417
|
---
|
@@ -23,13 +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 RepeatedCommandInDifferentRoutersException(Exception):
|
29
|
-
def __str__(self):
|
30
|
-
return "Commands in different handlers cannot be repeated"
|
31
|
-
|
32
|
-
|
33
|
-
class IncorrectNumberOfHandlerArgsException(Exception):
|
34
|
-
def __str__(self):
|
35
|
-
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
|
+
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
from argenta.router import Router
|
2
|
+
|
3
|
+
|
4
|
+
class RegisteredRouters:
|
5
|
+
def __init__(self, registered_routers: list[Router] = None) -> None:
|
6
|
+
self._registered_routers = registered_routers if registered_routers else []
|
7
|
+
|
8
|
+
def get_registered_routers(self) -> list[Router]:
|
9
|
+
return self._registered_routers
|
10
|
+
|
11
|
+
def add_registered_router(self, router: Router):
|
12
|
+
self._registered_routers.append(router)
|
13
|
+
|
14
|
+
def add_registered_routers(self, *routers: Router):
|
15
|
+
self._registered_routers.extend(routers)
|
16
|
+
|
17
|
+
def __iter__(self):
|
18
|
+
return iter(self._registered_routers)
|
19
|
+
|
20
|
+
def __next__(self):
|
21
|
+
return next(iter(self._registered_routers))
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from argenta.command.flag.models import InputFlag, Flag
|
2
|
+
|
3
|
+
|
4
|
+
class BaseInputCommandException(Exception):
|
5
|
+
pass
|
6
|
+
|
7
|
+
|
8
|
+
class UnprocessedInputFlagException(BaseInputCommandException):
|
9
|
+
def __str__(self):
|
10
|
+
return "Unprocessed Input Flags"
|
11
|
+
|
12
|
+
|
13
|
+
class RepeatedInputFlagsException(BaseInputCommandException):
|
14
|
+
def __init__(self, flag: Flag | InputFlag):
|
15
|
+
self.flag = flag
|
16
|
+
def __str__(self):
|
17
|
+
return ("Repeated Input Flags\n"
|
18
|
+
f"Duplicate flag was detected in the input: '{self.flag.get_string_entity()}'")
|
19
|
+
|
20
|
+
|
21
|
+
class EmptyInputCommandException(BaseInputCommandException):
|
22
|
+
def __str__(self):
|
23
|
+
return "Input Command is empty"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from argenta.command.flag.models import Flag
|
3
|
+
import re
|
4
|
+
|
5
|
+
|
6
|
+
@dataclass
|
7
|
+
class PredeterminedFlags:
|
8
|
+
HELP = Flag(name='help', possible_values=False)
|
9
|
+
SHORT_HELP = Flag(name='h', prefix='-', possible_values=False)
|
10
|
+
|
11
|
+
INFO = Flag(name='info', possible_values=False)
|
12
|
+
SHORT_INFO = Flag(name='i', prefix='-', possible_values=False)
|
13
|
+
|
14
|
+
ALL = Flag(name='all', possible_values=False)
|
15
|
+
SHORT_ALL = Flag(name='a', prefix='-', possible_values=False)
|
16
|
+
|
17
|
+
HOST = Flag(name='host', possible_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
|
18
|
+
SHORT_HOST = Flag(name='h', prefix='-', possible_values=re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'))
|
19
|
+
|
20
|
+
PORT = Flag(name='port', possible_values=re.compile(r'^\d{1,5}$'))
|
21
|
+
SHORT_PORT = Flag(name='p', prefix='-', possible_values=re.compile(r'^\d{1,5}$'))
|
@@ -0,0 +1,140 @@
|
|
1
|
+
from typing import Literal, Pattern
|
2
|
+
from abc import ABC, abstractmethod
|
3
|
+
|
4
|
+
|
5
|
+
class BaseFlag:
|
6
|
+
def __init__(self, name: str,
|
7
|
+
prefix: Literal['-', '--', '---'] = '--'):
|
8
|
+
self._name = name
|
9
|
+
self._prefix = prefix
|
10
|
+
|
11
|
+
def get_string_entity(self):
|
12
|
+
string_entity: str = self._prefix + self._name
|
13
|
+
return string_entity
|
14
|
+
|
15
|
+
def get_name(self):
|
16
|
+
return self._name
|
17
|
+
|
18
|
+
def get_prefix(self):
|
19
|
+
return self._prefix
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
class InputFlag(BaseFlag):
|
24
|
+
def __init__(self, name: str,
|
25
|
+
prefix: Literal['-', '--', '---'] = '--',
|
26
|
+
value: str = None):
|
27
|
+
super().__init__(name, prefix)
|
28
|
+
self._flag_value = value
|
29
|
+
|
30
|
+
def get_value(self):
|
31
|
+
return self._flag_value
|
32
|
+
|
33
|
+
def set_value(self, value):
|
34
|
+
self._flag_value = value
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
class Flag(BaseFlag):
|
39
|
+
def __init__(self, name: str,
|
40
|
+
prefix: Literal['-', '--', '---'] = '--',
|
41
|
+
possible_values: list[str] | Pattern[str] | False = True):
|
42
|
+
super().__init__(name, prefix)
|
43
|
+
self.possible_values = possible_values
|
44
|
+
|
45
|
+
def validate_input_flag_value(self, input_flag_value: str | None):
|
46
|
+
if self.possible_values is False:
|
47
|
+
if input_flag_value is None:
|
48
|
+
return True
|
49
|
+
else:
|
50
|
+
return False
|
51
|
+
elif isinstance(self.possible_values, Pattern):
|
52
|
+
if isinstance(input_flag_value, str):
|
53
|
+
is_valid = bool(self.possible_values.match(input_flag_value))
|
54
|
+
if bool(is_valid):
|
55
|
+
return True
|
56
|
+
else:
|
57
|
+
return False
|
58
|
+
else:
|
59
|
+
return False
|
60
|
+
|
61
|
+
elif isinstance(self.possible_values, list):
|
62
|
+
if input_flag_value in self.possible_values:
|
63
|
+
return True
|
64
|
+
else:
|
65
|
+
return False
|
66
|
+
else:
|
67
|
+
return True
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
class BaseFlags(ABC):
|
72
|
+
__slots__ = ('_flags',)
|
73
|
+
|
74
|
+
@abstractmethod
|
75
|
+
def get_flags(self):
|
76
|
+
pass
|
77
|
+
|
78
|
+
@abstractmethod
|
79
|
+
def add_flag(self, flag: Flag | InputFlag):
|
80
|
+
pass
|
81
|
+
|
82
|
+
@abstractmethod
|
83
|
+
def add_flags(self, flags: list[Flag] | list[InputFlag]):
|
84
|
+
pass
|
85
|
+
|
86
|
+
@abstractmethod
|
87
|
+
def get_flag(self, name: str):
|
88
|
+
pass
|
89
|
+
|
90
|
+
def __iter__(self):
|
91
|
+
return iter(self._flags)
|
92
|
+
|
93
|
+
def __next__(self):
|
94
|
+
return next(iter(self))
|
95
|
+
|
96
|
+
def __getitem__(self, item):
|
97
|
+
return self._flags[item]
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
class Flags(BaseFlags, ABC):
|
102
|
+
def __init__(self, *flags: Flag):
|
103
|
+
self._flags = flags if flags else []
|
104
|
+
|
105
|
+
def get_flags(self) -> list[Flag]:
|
106
|
+
return self._flags
|
107
|
+
|
108
|
+
def add_flag(self, flag: Flag):
|
109
|
+
self._flags.append(flag)
|
110
|
+
|
111
|
+
def add_flags(self, flags: list[Flag]):
|
112
|
+
self._flags.extend(flags)
|
113
|
+
|
114
|
+
def get_flag(self, name: str) -> Flag | None:
|
115
|
+
if name in [flag.get_name() for flag in self._flags]:
|
116
|
+
return list(filter(lambda flag: flag.get_name() == name, self._flags))[0]
|
117
|
+
else:
|
118
|
+
return None
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
class InputFlags(BaseFlags, ABC):
|
123
|
+
def __init__(self, *flags: InputFlag):
|
124
|
+
self._flags = flags if flags else []
|
125
|
+
|
126
|
+
def get_flags(self) -> list[InputFlag]:
|
127
|
+
return self._flags
|
128
|
+
|
129
|
+
def add_flag(self, flag: InputFlag):
|
130
|
+
self._flags.append(flag)
|
131
|
+
|
132
|
+
def add_flags(self, flags: list[InputFlag]):
|
133
|
+
self._flags.extend(flags)
|
134
|
+
|
135
|
+
def get_flag(self, name: str) -> InputFlag | None:
|
136
|
+
if name in [flag.get_name() for flag in self._flags]:
|
137
|
+
return list(filter(lambda flag: flag.get_name() == name, self._flags))[0]
|
138
|
+
else:
|
139
|
+
return None
|
140
|
+
|