argenta 1.0.0b2__tar.gz → 1.0.2__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-1.0.0b2 → argenta-1.0.2}/.github/workflows/ruff.yml +1 -1
- {argenta-1.0.0b2 → argenta-1.0.2}/.gitignore +1 -1
- argenta-1.0.2/PKG-INFO +71 -0
- argenta-1.0.2/README.md +58 -0
- argenta-1.0.2/imgs/argenta_banner.png +0 -0
- argenta-1.0.2/imgs/argenta_logo.png +0 -0
- argenta-1.0.2/imgs/argenta_logo_strip.png +0 -0
- argenta-1.0.2/imgs/argenta_logo_strip.svg +46 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/mock/default_mock_app/main.py +3 -2
- argenta-1.0.2/mock/local_test.py +89 -0
- argenta-1.0.2/mock/mock_app/handlers/handlers_implementation/help_command.py +12 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/mock/mock_app/handlers/routers.py +10 -6
- {argenta-1.0.0b2 → argenta-1.0.2}/mock/mock_app/main.py +7 -4
- {argenta-1.0.0b2 → argenta-1.0.2}/pyproject.toml +2 -7
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/app/autocompleter/entity.py +30 -11
- argenta-1.0.2/src/argenta/app/defaults.py +12 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/app/dividing_line/models.py +8 -10
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/app/models.py +181 -114
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/app/registered_routers/entity.py +1 -1
- argenta-1.0.2/src/argenta/command/__init__.py +3 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/command/exceptions.py +9 -2
- argenta-1.0.2/src/argenta/command/flag/defaults.py +31 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/command/flag/models.py +14 -11
- argenta-1.0.2/src/argenta/command/flags/__init__.py +16 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/command/flags/models.py +11 -8
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/command/models.py +61 -36
- argenta-1.0.2/src/argenta/orchestrator/argparser/__init__.py +4 -0
- argenta-1.0.2/src/argenta/orchestrator/argparser/arguments/__init__.py +8 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/orchestrator/argparser/arguments/models.py +3 -2
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/orchestrator/argparser/entity.py +22 -12
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/orchestrator/entity.py +0 -1
- argenta-1.0.2/src/argenta/response/entity.py +29 -0
- argenta-1.0.2/src/argenta/response/status.py +8 -0
- argenta-1.0.2/src/argenta/router/__init__.py +4 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/router/command_handler/entity.py +1 -1
- argenta-1.0.2/src/argenta/router/defaults.py +4 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/router/entity.py +60 -60
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/router/exceptions.py +4 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/tests/system_tests/test_system_handling_non_standard_behavior.py +1 -1
- {argenta-1.0.0b2 → argenta-1.0.2}/tests/unit_tests/test_router.py +0 -4
- argenta-1.0.0b2/PKG-INFO +0 -1340
- argenta-1.0.0b2/README.md +0 -1327
- argenta-1.0.0b2/mock/local_test.py +0 -23
- argenta-1.0.0b2/mock/mock_app/handlers/handlers_implementation/help_command.py +0 -10
- argenta-1.0.0b2/src/argenta/app/defaults.py +0 -12
- argenta-1.0.0b2/src/argenta/command/__init__.py +0 -3
- argenta-1.0.0b2/src/argenta/command/flag/defaults.py +0 -24
- argenta-1.0.0b2/src/argenta/command/flags/__init__.py +0 -10
- argenta-1.0.0b2/src/argenta/orchestrator/argparser/__init__.py +0 -4
- argenta-1.0.0b2/src/argenta/orchestrator/argparser/arguments/__init__.py +0 -6
- argenta-1.0.0b2/src/argenta/response/entity.py +0 -27
- argenta-1.0.0b2/src/argenta/response/status.py +0 -9
- argenta-1.0.0b2/src/argenta/router/__init__.py +0 -4
- argenta-1.0.0b2/src/argenta/router/defaults.py +0 -4
- {argenta-1.0.0b2 → argenta-1.0.2}/.github/workflows/tests.yml +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/LICENSE +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/imgs/mock_app_preview1.png +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/imgs/mock_app_preview2.png +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/imgs/mock_app_preview3.png +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/imgs/mock_app_preview4.png +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/mock/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/mock/default_mock_app/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/mock/mock_app/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/mock/mock_app/handlers/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/mock/mock_app/handlers/handlers_implementation/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/app/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/app/autocompleter/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/app/dividing_line/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/app/registered_routers/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/command/flag/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/orchestrator/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/response/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/src/argenta/router/command_handler/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/tests/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/tests/system_tests/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/tests/system_tests/test_system_handling_normal_behavior.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/tests/unit_tests/__init__.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/tests/unit_tests/test_app.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/tests/unit_tests/test_command.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/tests/unit_tests/test_dividing_line.py +0 -0
- {argenta-1.0.0b2 → argenta-1.0.2}/tests/unit_tests/test_flag.py +0 -0
argenta-1.0.2/PKG-INFO
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: argenta
|
3
|
+
Version: 1.0.2
|
4
|
+
Summary: Python library for building modular CLI applications
|
5
|
+
Author-email: kolo <kolo.is.main@gmail.com>
|
6
|
+
License: MIT
|
7
|
+
License-File: LICENSE
|
8
|
+
Requires-Python: >=3.8
|
9
|
+
Requires-Dist: art<7.0,>=6.4
|
10
|
+
Requires-Dist: pyreadline3>=3.5.4
|
11
|
+
Requires-Dist: rich<15.0.0,>=14.0.0
|
12
|
+
Description-Content-Type: text/markdown
|
13
|
+
|
14
|
+
# Argenta
|
15
|
+
|
16
|
+
### Библиотека для создания модульных CLI приложeний
|
17
|
+
|
18
|
+

|
19
|
+
|
20
|
+
---
|
21
|
+
|
22
|
+
# Установка
|
23
|
+
```bash
|
24
|
+
pip install argenta
|
25
|
+
```
|
26
|
+
or
|
27
|
+
```bash
|
28
|
+
poetry add argenta
|
29
|
+
```
|
30
|
+
|
31
|
+
---
|
32
|
+
|
33
|
+
# Быстрый старт
|
34
|
+
|
35
|
+
Пример простейшего приложения
|
36
|
+
```python
|
37
|
+
# routers.py
|
38
|
+
from argenta.router import Router
|
39
|
+
from argenta.command import Command
|
40
|
+
from argenta.response import Response
|
41
|
+
|
42
|
+
|
43
|
+
router = Router()
|
44
|
+
|
45
|
+
@router.command(Command("hello"))
|
46
|
+
def handler(response: Response):
|
47
|
+
print("Hello, world!")
|
48
|
+
```
|
49
|
+
|
50
|
+
```python
|
51
|
+
# main.py
|
52
|
+
from argenta.app import App
|
53
|
+
from argenta.orchestrator import Orchestrator
|
54
|
+
from routers import router
|
55
|
+
|
56
|
+
app: App = App()
|
57
|
+
orchestrator: Orchestrator = Orchestrator()
|
58
|
+
|
59
|
+
|
60
|
+
def main() -> None:
|
61
|
+
app.include_router(router)
|
62
|
+
orchestrator.start_polling(app)
|
63
|
+
|
64
|
+
|
65
|
+
if __name__ == '__main__':
|
66
|
+
main()
|
67
|
+
```
|
68
|
+
## Полная [документация](https://argenta-docs.vercel.app) | MIT 2025 kolo | made by [kolo](https://t.me/kolo_id)
|
69
|
+
|
70
|
+
|
71
|
+
|
argenta-1.0.2/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# Argenta
|
2
|
+
|
3
|
+
### Библиотека для создания модульных CLI приложeний
|
4
|
+
|
5
|
+

|
6
|
+
|
7
|
+
---
|
8
|
+
|
9
|
+
# Установка
|
10
|
+
```bash
|
11
|
+
pip install argenta
|
12
|
+
```
|
13
|
+
or
|
14
|
+
```bash
|
15
|
+
poetry add argenta
|
16
|
+
```
|
17
|
+
|
18
|
+
---
|
19
|
+
|
20
|
+
# Быстрый старт
|
21
|
+
|
22
|
+
Пример простейшего приложения
|
23
|
+
```python
|
24
|
+
# routers.py
|
25
|
+
from argenta.router import Router
|
26
|
+
from argenta.command import Command
|
27
|
+
from argenta.response import Response
|
28
|
+
|
29
|
+
|
30
|
+
router = Router()
|
31
|
+
|
32
|
+
@router.command(Command("hello"))
|
33
|
+
def handler(response: Response):
|
34
|
+
print("Hello, world!")
|
35
|
+
```
|
36
|
+
|
37
|
+
```python
|
38
|
+
# main.py
|
39
|
+
from argenta.app import App
|
40
|
+
from argenta.orchestrator import Orchestrator
|
41
|
+
from routers import router
|
42
|
+
|
43
|
+
app: App = App()
|
44
|
+
orchestrator: Orchestrator = Orchestrator()
|
45
|
+
|
46
|
+
|
47
|
+
def main() -> None:
|
48
|
+
app.include_router(router)
|
49
|
+
orchestrator.start_polling(app)
|
50
|
+
|
51
|
+
|
52
|
+
if __name__ == '__main__':
|
53
|
+
main()
|
54
|
+
```
|
55
|
+
## Полная [документация](https://argenta-docs.vercel.app) | MIT 2025 kolo | made by [kolo](https://t.me/kolo_id)
|
56
|
+
|
57
|
+
|
58
|
+
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
3
|
+
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
4
|
+
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
5
|
+
width="809.000000pt" height="809.000000pt" viewBox="0 0 809.000000 809.000000"
|
6
|
+
preserveAspectRatio="xMidYMid meet">
|
7
|
+
|
8
|
+
<g transform="translate(0.000000,809.000000) scale(0.100000,-0.100000)"
|
9
|
+
fill="#000000" stroke="none">
|
10
|
+
<path d="M3845 7600 c-683 -38 -1333 -259 -1875 -639 -702 -492 -1223 -1251
|
11
|
+
-1434 -2089 -83 -330 -111 -602 -103 -980 6 -273 19 -393 67 -632 167 -829
|
12
|
+
642 -1593 1321 -2122 512 -399 1133 -656 1794 -745 165 -22 666 -25 825 -5
|
13
|
+
779 99 1451 397 2020 898 687 603 1095 1401 1201 2344 17 147 17 571 0 715
|
14
|
+
-59 518 -204 977 -442 1402 -180 322 -355 552 -629 823 -518 515 -1164 850
|
15
|
+
-1887 979 -254 45 -594 66 -858 51z m655 -234 c545 -76 1005 -248 1445 -541
|
16
|
+
195 -130 336 -245 506 -415 457 -456 758 -987 909 -1605 134 -547 132 -1119
|
17
|
+
-5 -1665 -149 -593 -445 -1112 -885 -1550 -624 -623 -1414 -966 -2315 -1006
|
18
|
+
-412 -18 -935 73 -1339 232 -656 259 -1228 720 -1610 1299 -298 450 -461 890
|
19
|
+
-538 1451 -28 210 -31 620 -4 819 103 786 437 1477 975 2016 149 149 266 249
|
20
|
+
417 357 315 225 692 405 1059 506 211 58 342 81 675 120 87 10 601 -3 710 -18z"/>
|
21
|
+
<path d="M3691 6759 c-231 -17 -522 -67 -660 -114 -227 -77 -354 -211 -381
|
22
|
+
-400 -14 -105 -13 -628 2 -643 9 -9 158 -12 611 -12 598 0 628 -2 649 -34 14
|
23
|
+
-21 8 -66 -12 -86 -20 -20 -33 -20 -908 -20 -857 0 -892 -1 -967 -20 -294 -75
|
24
|
+
-500 -321 -599 -715 -49 -195 -61 -309 -60 -585 0 -221 3 -272 23 -385 44
|
25
|
+
-251 116 -418 232 -540 78 -82 143 -123 254 -162 78 -27 85 -27 351 -31 l272
|
26
|
+
-4 16 23 c14 20 16 58 16 259 0 334 20 446 107 613 80 153 268 310 447 374
|
27
|
+
128 45 138 46 881 52 683 7 713 8 786 28 201 56 353 177 437 348 80 162 86
|
28
|
+
240 74 905 -11 608 -10 600 -84 743 -80 153 -240 271 -453 332 -252 73 -653
|
29
|
+
101 -1034 74z m-383 -466 c126 -78 147 -245 44 -355 -144 -154 -396 -54 -395
|
30
|
+
157 0 97 62 187 154 222 54 20 143 10 197 -24z"/>
|
31
|
+
<path d="M5451 5491 c-20 -20 -21 -30 -21 -283 0 -276 -7 -351 -42 -458 -81
|
32
|
+
-251 -281 -454 -523 -534 -149 -48 -151 -48 -890 -56 -678 -6 -703 -7 -780
|
33
|
+
-28 -139 -38 -219 -84 -315 -181 -61 -61 -95 -105 -117 -151 -65 -134 -64
|
34
|
+
-129 -75 -780 -12 -665 -10 -694 47 -817 122 -265 419 -429 895 -494 127 -18
|
35
|
+
592 -18 730 -1 377 48 646 169 785 355 57 75 67 94 96 182 20 64 23 94 27 325
|
36
|
+
4 238 3 257 -15 278 l-18 23 -551 -1 c-399 0 -559 3 -577 11 -51 23 -56 102
|
37
|
+
-8 126 9 4 439 10 956 13 1044 7 981 2 1125 75 178 89 305 255 386 502 84 257
|
38
|
+
111 618 73 973 -39 364 -167 655 -351 801 -63 50 -121 80 -213 110 -64 20 -93
|
39
|
+
23 -337 27 -260 4 -267 3 -287 -17z m-2104 -1698 c78 -52 531 -413 561 -447
|
40
|
+
17 -19 33 -48 37 -65 15 -71 3 -84 -323 -356 -275 -229 -310 -255 -342 -255
|
41
|
+
-78 1 -112 75 -61 134 9 10 86 75 171 144 247 201 355 294 358 311 1 9 -15 28
|
42
|
+
-38 44 -127 89 -503 393 -512 413 -23 50 20 103 82 104 15 0 45 -12 67 -27z
|
43
|
+
m1388 -1244 c59 -15 129 -77 151 -134 36 -96 0 -204 -88 -262 -36 -24 -51 -28
|
44
|
+
-118 -28 -67 0 -82 4 -118 28 -153 101 -124 338 48 392 57 17 71 18 125 4z"/>
|
45
|
+
</g>
|
46
|
+
</svg>
|
@@ -8,8 +8,8 @@ from argenta.orchestrator.argparser import ArgParser
|
|
8
8
|
from argenta.orchestrator.argparser.arguments import BooleanArgument
|
9
9
|
|
10
10
|
|
11
|
-
arg_parser = ArgParser(processed_args=[BooleanArgument(
|
12
|
-
app: App = App(autocompleter=AutoCompleter(
|
11
|
+
arg_parser = ArgParser(processed_args=[BooleanArgument("repeat")])
|
12
|
+
app: App = App(autocompleter=AutoCompleter(".hist"))
|
13
13
|
orchestrator: Orchestrator = Orchestrator()
|
14
14
|
|
15
15
|
|
@@ -22,5 +22,6 @@ def main():
|
|
22
22
|
|
23
23
|
orchestrator.start_polling(app)
|
24
24
|
|
25
|
+
|
25
26
|
if __name__ == "__main__":
|
26
27
|
main()
|
@@ -0,0 +1,89 @@
|
|
1
|
+
from argenta.app import App
|
2
|
+
from argenta.app.autocompleter import AutoCompleter
|
3
|
+
from argenta.router import Router
|
4
|
+
from argenta.command import Command
|
5
|
+
from argenta.orchestrator import Orchestrator
|
6
|
+
from argenta.app.dividing_line import DynamicDividingLine
|
7
|
+
from argenta.response import Response
|
8
|
+
import platform
|
9
|
+
import psutil
|
10
|
+
import os
|
11
|
+
import subprocess
|
12
|
+
import socket
|
13
|
+
|
14
|
+
# Маршрутизатор для работы с файлами
|
15
|
+
file_router = Router("Файловые операции")
|
16
|
+
|
17
|
+
|
18
|
+
@file_router.command(Command("list", "Список файлов"))
|
19
|
+
def list_files(response: Response):
|
20
|
+
files = os.listdir()
|
21
|
+
for file in files:
|
22
|
+
print(file)
|
23
|
+
|
24
|
+
|
25
|
+
@file_router.command(Command("size", "Размер файла"))
|
26
|
+
def file_size(response: Response):
|
27
|
+
file_name = input("Введите имя файла: ")
|
28
|
+
if os.path.exists(file_name):
|
29
|
+
size = os.path.getsize(file_name)
|
30
|
+
print(f"Размер файла {file_name}: {size} байт")
|
31
|
+
else:
|
32
|
+
print(f"Файл {file_name} не найден")
|
33
|
+
|
34
|
+
|
35
|
+
# Маршрутизатор для системных операций
|
36
|
+
system_router = Router("Системные операции")
|
37
|
+
|
38
|
+
|
39
|
+
@system_router.command(Command("info", "Информация о системе"))
|
40
|
+
def system_info(response: Response):
|
41
|
+
print(f"Система: {platform.system()}")
|
42
|
+
print(f"Версия: {platform.version()}")
|
43
|
+
print(f"Архитектура: {platform.architecture()}")
|
44
|
+
print(f"Процессор: {platform.processor()}")
|
45
|
+
|
46
|
+
|
47
|
+
@system_router.command(Command("memory", "Информация о памяти"))
|
48
|
+
def memory_info(response: Response):
|
49
|
+
memory = psutil.virtual_memory()
|
50
|
+
print(f"Всего памяти: {memory.total / (1024**3):.2f} ГБ")
|
51
|
+
print(f"Доступно: {memory.available / (1024**3):.2f} ГБ")
|
52
|
+
print(f"Использовано: {memory.used / (1024**3):.2f} ГБ ({memory.percent}%)")
|
53
|
+
|
54
|
+
|
55
|
+
# Маршрутизатор для сетевых операций
|
56
|
+
network_router = Router("Сетевые операции")
|
57
|
+
|
58
|
+
|
59
|
+
@network_router.command(Command("ping", "Проверка доступности хоста"))
|
60
|
+
def ping_host(response: Response):
|
61
|
+
host = input("Введите имя хоста: ")
|
62
|
+
print(f"Пингую {host}...")
|
63
|
+
subprocess.run(["ping", "-c", "4", host])
|
64
|
+
|
65
|
+
|
66
|
+
@network_router.command(Command("ip", "Показать IP-адреса"))
|
67
|
+
def show_ip(response: Response):
|
68
|
+
hostname = socket.gethostname()
|
69
|
+
print(f"Имя хоста: {hostname}")
|
70
|
+
print(f"IP-адрес: {socket.gethostbyname(hostname)}")
|
71
|
+
|
72
|
+
|
73
|
+
# Создание приложения и регистрация маршрутизаторов
|
74
|
+
app = App(
|
75
|
+
prompt="System> ",
|
76
|
+
initial_message="Pingator",
|
77
|
+
dividing_line=DynamicDividingLine("*"),
|
78
|
+
autocompleter=AutoCompleter(".hist", "e"),
|
79
|
+
)
|
80
|
+
|
81
|
+
# Добавляем все маршрутизаторы
|
82
|
+
app.include_routers(file_router, system_router, network_router)
|
83
|
+
|
84
|
+
# Добавляем сообщение при запуске
|
85
|
+
app.add_message_on_startup("Для просмотра доступных команд нажмите Enter")
|
86
|
+
|
87
|
+
# Запускаем приложение
|
88
|
+
orchestrator = Orchestrator()
|
89
|
+
orchestrator.start_polling(app)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from rich.console import Console
|
2
|
+
|
3
|
+
|
4
|
+
console = Console()
|
5
|
+
|
6
|
+
|
7
|
+
def help_command():
|
8
|
+
console.print(
|
9
|
+
"[italic bold]The main functionality of the script is to convert an expression from a string "
|
10
|
+
"to a mathematical one and then calculate this expression. "
|
11
|
+
"Project GitHub: https://github.com/koloideal/WordMath[/italic bold]"
|
12
|
+
)
|
@@ -7,12 +7,19 @@ from argenta.response import Response
|
|
7
7
|
from argenta.router import Router
|
8
8
|
|
9
9
|
|
10
|
-
work_router: Router = Router(title=
|
10
|
+
work_router: Router = Router(title="Work points:")
|
11
11
|
|
12
12
|
console = Console()
|
13
13
|
|
14
14
|
|
15
|
-
@work_router.command(
|
15
|
+
@work_router.command(
|
16
|
+
Command(
|
17
|
+
"get",
|
18
|
+
"Get Help",
|
19
|
+
aliases=["help", "Get_help"],
|
20
|
+
flags=Flags(PredefinedFlags.PORT, PredefinedFlags.HOST),
|
21
|
+
)
|
22
|
+
)
|
16
23
|
def command_help(response: Response):
|
17
24
|
print(response.status)
|
18
25
|
print(response.undefined_flags.get_flags())
|
@@ -20,12 +27,9 @@ def command_help(response: Response):
|
|
20
27
|
print(response.invalid_value_flags.get_flags())
|
21
28
|
|
22
29
|
|
23
|
-
@work_router.command(
|
30
|
+
@work_router.command("run")
|
24
31
|
def command_start_solving(response: Response):
|
25
32
|
print(response.status)
|
26
33
|
print(response.undefined_flags.get_flags())
|
27
34
|
print(response.valid_flags.get_flags())
|
28
35
|
print(response.invalid_value_flags.get_flags())
|
29
|
-
|
30
|
-
|
31
|
-
|
@@ -9,10 +9,12 @@ from argenta.orchestrator.argparser import ArgParser
|
|
9
9
|
from argenta.orchestrator.argparser.arguments import BooleanArgument
|
10
10
|
|
11
11
|
|
12
|
-
arg_parser = ArgParser(processed_args=[BooleanArgument(
|
13
|
-
app: App = App(
|
14
|
-
|
15
|
-
|
12
|
+
arg_parser = ArgParser(processed_args=[BooleanArgument("repeat")])
|
13
|
+
app: App = App(
|
14
|
+
dividing_line=DynamicDividingLine(),
|
15
|
+
autocompleter=AutoCompleter(),
|
16
|
+
repeat_command_groups=False,
|
17
|
+
)
|
16
18
|
orchestrator: Orchestrator = Orchestrator(arg_parser)
|
17
19
|
|
18
20
|
|
@@ -25,5 +27,6 @@ def main():
|
|
25
27
|
|
26
28
|
orchestrator.start_polling(app)
|
27
29
|
|
30
|
+
|
28
31
|
if __name__ == "__main__":
|
29
32
|
main()
|
@@ -1,9 +1,9 @@
|
|
1
1
|
[project]
|
2
2
|
name = "argenta"
|
3
|
-
version = "1.0.
|
3
|
+
version = "1.0.2"
|
4
4
|
description = "Python library for building modular CLI applications"
|
5
5
|
authors = [{ name = "kolo", email = "kolo.is.main@gmail.com" }]
|
6
|
-
requires-python = ">=3.
|
6
|
+
requires-python = ">=3.8"
|
7
7
|
readme = "README.md"
|
8
8
|
license = { text = "MIT" }
|
9
9
|
dependencies = [
|
@@ -12,11 +12,6 @@ dependencies = [
|
|
12
12
|
"pyreadline3>=3.5.4",
|
13
13
|
]
|
14
14
|
|
15
|
-
[dependency-groups]
|
16
|
-
dev = [
|
17
|
-
"pydoc-markdown>=4.8.2,<5",
|
18
|
-
]
|
19
|
-
|
20
15
|
[tool.ruff]
|
21
16
|
exclude = [
|
22
17
|
".idea",
|
@@ -1,9 +1,12 @@
|
|
1
1
|
import os
|
2
2
|
import readline
|
3
|
+
from typing import Never
|
3
4
|
|
4
5
|
|
5
6
|
class AutoCompleter:
|
6
|
-
def __init__(
|
7
|
+
def __init__(
|
8
|
+
self, history_filename: str = False, autocomplete_button: str = "tab"
|
9
|
+
) -> None:
|
7
10
|
"""
|
8
11
|
Public. Configures and implements auto-completion of input command
|
9
12
|
:param history_filename: the name of the file for saving the history of the autocompleter
|
@@ -12,7 +15,6 @@ class AutoCompleter:
|
|
12
15
|
"""
|
13
16
|
self.history_filename = history_filename
|
14
17
|
self.autocomplete_button = autocomplete_button
|
15
|
-
self.matches: list[str] = []
|
16
18
|
|
17
19
|
def _complete(self, text, state) -> str | None:
|
18
20
|
"""
|
@@ -21,16 +23,22 @@ class AutoCompleter:
|
|
21
23
|
:param state: the current cursor position is relative to the beginning of the line
|
22
24
|
:return: the desired candidate as str or None
|
23
25
|
"""
|
24
|
-
matches: list[str] = sorted(
|
26
|
+
matches: list[str] = sorted(
|
27
|
+
cmd for cmd in self.get_history_items() if cmd.startswith(text)
|
28
|
+
)
|
25
29
|
if len(matches) > 1:
|
26
30
|
common_prefix = matches[0]
|
27
31
|
for match in matches[1:]:
|
28
32
|
i = 0
|
29
|
-
while
|
33
|
+
while (
|
34
|
+
i < len(common_prefix)
|
35
|
+
and i < len(match)
|
36
|
+
and common_prefix[i] == match[i]
|
37
|
+
):
|
30
38
|
i += 1
|
31
39
|
common_prefix = common_prefix[:i]
|
32
40
|
if state == 0:
|
33
|
-
readline.insert_text(common_prefix[len(text):])
|
41
|
+
readline.insert_text(common_prefix[len(text) :])
|
34
42
|
readline.redisplay()
|
35
43
|
return None
|
36
44
|
elif len(matches) == 1:
|
@@ -52,21 +60,32 @@ class AutoCompleter:
|
|
52
60
|
readline.add_history(line)
|
53
61
|
|
54
62
|
readline.set_completer(self._complete)
|
55
|
-
readline.set_completer_delims(readline.get_completer_delims().replace(
|
56
|
-
readline.parse_and_bind(f
|
63
|
+
readline.set_completer_delims(readline.get_completer_delims().replace(" ", ""))
|
64
|
+
readline.parse_and_bind(f"{self.autocomplete_button}: complete")
|
57
65
|
|
58
|
-
def exit_setup(self) -> None:
|
66
|
+
def exit_setup(self, all_commands: list[str]) -> None:
|
59
67
|
"""
|
60
68
|
Private. Exit setup function
|
61
69
|
:return: None
|
62
70
|
"""
|
63
71
|
if self.history_filename:
|
64
72
|
readline.write_history_file(self.history_filename)
|
73
|
+
with open(self.history_filename, "r") as history_file:
|
74
|
+
raw_history = history_file.read()
|
75
|
+
pretty_history: list[str] = []
|
76
|
+
for line in set(raw_history.strip().split("\n")):
|
77
|
+
if line.split()[0] in all_commands:
|
78
|
+
pretty_history.append(line)
|
79
|
+
with open(self.history_filename, "w") as history_file:
|
80
|
+
history_file.write("\n".join(pretty_history))
|
65
81
|
|
66
82
|
@staticmethod
|
67
|
-
def get_history_items() -> list[str] | list:
|
83
|
+
def get_history_items() -> list[str] | list[Never]:
|
68
84
|
"""
|
69
85
|
Private. Returns a list of all commands entered by the user
|
70
|
-
:return: all commands entered by the user as list[str]
|
86
|
+
:return: all commands entered by the user as list[str] | list[Never]
|
71
87
|
"""
|
72
|
-
return [
|
88
|
+
return [
|
89
|
+
readline.get_history_item(i)
|
90
|
+
for i in range(1, readline.get_current_history_length() + 1)
|
91
|
+
]
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
|
3
|
+
|
4
|
+
@dataclass
|
5
|
+
class PredefinedMessages:
|
6
|
+
"""
|
7
|
+
Public. A dataclass with predetermined messages for quick use
|
8
|
+
"""
|
9
|
+
|
10
|
+
USAGE = "[b dim]Usage[/b dim]: [i]<command> <[green]flags[/green]>[/i]"
|
11
|
+
HELP = "[b dim]Help[/b dim]: [i]<command>[/i] [b red]--help[/b red]"
|
12
|
+
AUTOCOMPLETE = "[b dim]Autocomplete[/b dim]: [i]<part>[/i] [bold]<tab>"
|
@@ -2,7 +2,7 @@ from abc import ABC
|
|
2
2
|
|
3
3
|
|
4
4
|
class BaseDividingLine(ABC):
|
5
|
-
def __init__(self, unit_part: str =
|
5
|
+
def __init__(self, unit_part: str = "-") -> None:
|
6
6
|
"""
|
7
7
|
Private. The basic dividing line
|
8
8
|
:param unit_part: the single part of the dividing line
|
@@ -16,13 +16,13 @@ class BaseDividingLine(ABC):
|
|
16
16
|
:return: unit_part of dividing line as str
|
17
17
|
"""
|
18
18
|
if len(self._unit_part) == 0:
|
19
|
-
return
|
19
|
+
return " "
|
20
20
|
else:
|
21
21
|
return self._unit_part[0]
|
22
22
|
|
23
23
|
|
24
24
|
class StaticDividingLine(BaseDividingLine):
|
25
|
-
def __init__(self, unit_part: str =
|
25
|
+
def __init__(self, unit_part: str = "-", length: int = 25) -> None:
|
26
26
|
"""
|
27
27
|
Public. The static dividing line
|
28
28
|
:param unit_part: the single part of the dividing line
|
@@ -39,13 +39,13 @@ class StaticDividingLine(BaseDividingLine):
|
|
39
39
|
:return: full line of dividing line as str
|
40
40
|
"""
|
41
41
|
if is_override:
|
42
|
-
return f
|
42
|
+
return f"\n{self.length * self.get_unit_part()}\n"
|
43
43
|
else:
|
44
|
-
return f
|
44
|
+
return f"\n[dim]{self.length * self.get_unit_part()}[/dim]\n"
|
45
45
|
|
46
46
|
|
47
47
|
class DynamicDividingLine(BaseDividingLine):
|
48
|
-
def __init__(self, unit_part: str =
|
48
|
+
def __init__(self, unit_part: str = "-") -> None:
|
49
49
|
"""
|
50
50
|
Public. The dynamic dividing line
|
51
51
|
:param unit_part: the single part of the dividing line
|
@@ -61,8 +61,6 @@ class DynamicDividingLine(BaseDividingLine):
|
|
61
61
|
:return: full line of dividing line as str
|
62
62
|
"""
|
63
63
|
if is_override:
|
64
|
-
return f
|
64
|
+
return f"\n{length * self.get_unit_part()}\n"
|
65
65
|
else:
|
66
|
-
return f
|
67
|
-
|
68
|
-
|
66
|
+
return f"\n[dim]{self.get_unit_part() * length}[/dim]\n"
|