mirror of
https://github.com/koloideal/Argenta.git
synced 2026-06-10 10:05:28 +03:00
work on docs, tests and some fix
This commit is contained in:
@@ -20,39 +20,18 @@ poetry add argenta
|
||||
|
||||
# Быстрый старт
|
||||
|
||||
Пример простейшей оболочки с командой без флагов
|
||||
```python
|
||||
# routers.py
|
||||
import re
|
||||
from argenta.router import Router
|
||||
from argenta.command import Command
|
||||
from argenta.command.params.flag import FlagsGroup, Flag
|
||||
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
list_of_flags = [
|
||||
Flag(flag_name='host',
|
||||
flag_prefix='--',
|
||||
possible_flag_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
|
||||
Flag(flag_name='port',
|
||||
flag_prefix='---',
|
||||
possible_flag_values=re.compile(r'^[0-9]{1,4}$'))
|
||||
]
|
||||
|
||||
|
||||
@router.command(Command("hello"))
|
||||
def handler():
|
||||
print("Hello, world!")
|
||||
|
||||
|
||||
@router.command(Command(command="ssh",
|
||||
description='connect via ssh',
|
||||
flags=FlagsGroup(list_of_flags)))
|
||||
def handler_with_flags(flags: dict):
|
||||
for flag in flags:
|
||||
print(f'Flag name: {flag['name']}\n
|
||||
f'Flag value: {flag['value']}')
|
||||
```
|
||||
|
||||
```python
|
||||
@@ -70,21 +49,51 @@ def main() -> None:
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
```
|
||||
Пример оболочки с командой, у которой зарегистрированы флаги
|
||||
|
||||
```python
|
||||
# routers.py
|
||||
import re
|
||||
from argenta.router import Router
|
||||
from argenta.command import Command
|
||||
from argenta.command.params.flag import FlagsGroup, Flag
|
||||
|
||||
router = Router()
|
||||
|
||||
list_of_flags = [
|
||||
Flag(flag_name='host',
|
||||
flag_prefix='--',
|
||||
possible_flag_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
|
||||
Flag(flag_name='port',
|
||||
flag_prefix='---',
|
||||
possible_flag_values=re.compile(r'^[0-9]{1,4}$'))
|
||||
]
|
||||
|
||||
|
||||
@router.command(Command("hello"))
|
||||
def handler():
|
||||
print("Hello, world!")
|
||||
|
||||
|
||||
@router.command(Command(trigger="ssh",
|
||||
description='connect via ssh',
|
||||
flags=FlagsGroup(list_of_flags)))
|
||||
def handler_with_flags(flags: dict):
|
||||
for flag in flags:
|
||||
print(f'Flag name: {flag['name']}\n
|
||||
f'Flag value: {flag['value']}')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Техническая документация
|
||||
# *classes* :
|
||||
|
||||
---
|
||||
|
||||
## declared *classes* :
|
||||
## *class* :: `App`
|
||||
Класс, определяющий поведение и состояние оболочки
|
||||
|
||||
---
|
||||
|
||||
### *class* :: `App`
|
||||
Класс, определяющий поведение и состояние приложения
|
||||
|
||||
#### Конструктор
|
||||
### Конструктор
|
||||
```python
|
||||
App(prompt: str = 'Enter a command',
|
||||
initial_greeting: str = '\nHello, I am Argenta\n',
|
||||
@@ -116,7 +125,7 @@ App(prompt: str = 'Enter a command',
|
||||
|
||||
---
|
||||
|
||||
#### **declared *methods***
|
||||
### ***methods***
|
||||
|
||||
---
|
||||
|
||||
@@ -206,7 +215,7 @@ App(prompt: str = 'Enter a command',
|
||||
|
||||
---
|
||||
|
||||
#### Примечания
|
||||
### Примечания
|
||||
|
||||
- В устанавливаемом паттерне сообщения описания команды необходимы быть два ключевых слова:
|
||||
`command` и `description`, каждое из которых должно быть заключено в фигурные скобки, после обработки
|
||||
@@ -222,7 +231,7 @@ App(prompt: str = 'Enter a command',
|
||||
|
||||
|
||||
|
||||
#### Исключения
|
||||
### Исключения
|
||||
|
||||
- `InvalidRouterInstanceException` — Переданный объект в метод `App().include_router()` не является экземпляром класса `Router`.
|
||||
- `InvalidDescriptionMessagePatternException` — Неправильный формат паттерна описания команд.
|
||||
@@ -233,23 +242,25 @@ App(prompt: str = 'Enter a command',
|
||||
|
||||
---
|
||||
|
||||
### *class* :: `Router`
|
||||
## *class* :: `Router`
|
||||
Класс, который определяет и конфигурирует обработчики команд
|
||||
|
||||
#### Конструктор
|
||||
### Конструктор
|
||||
```python
|
||||
Router(title: str = 'Commands group title:',
|
||||
name: str = 'subordinate')
|
||||
```
|
||||
|
||||
|
||||
|
||||
**Аргументы:**
|
||||
- **name : mean**
|
||||
- `title` (`str`): Заголовок группы команд.
|
||||
- `name` (`str`): Персональное название роутера
|
||||
|
||||
---
|
||||
|
||||
|
||||
#### **declared *methods***
|
||||
### ***methods***
|
||||
|
||||
---
|
||||
|
||||
@@ -281,10 +292,133 @@ Router(title: str = 'Commands group title:',
|
||||
|
||||
---
|
||||
|
||||
#### Исключения
|
||||
- `InvalidDescriptionInstanceException` - Переданный объект для регистрации описания команды не является строкой
|
||||
### Исключения
|
||||
- `RepeatedCommandException` - Одна и та же команда зарегистрирована в одном роутере
|
||||
- `RepeatedFlagNameException` - Повторяющиеся зарегистрированные флаги в команде
|
||||
- `TooManyTransferredArgsException` - Слишком много зарегистрированных аргументов у обработчика команды
|
||||
- `RequiredArgumentNotPassedException` - Не зарегистрирован обязательный аргумент у обработчика команды(аргумент, через который будут переданы флаги введённой команды)
|
||||
- `IncorrectNumberOfHandlerArgsException` - У обработчика нестандартного поведения зарегистрировано неверное количество аргументов(в большинстве случаев у него должен быть один аргумент)
|
||||
|
||||
---
|
||||
|
||||
## *class* :: `Command`
|
||||
Класс, экземпляр которого определяет строковый триггер хэндлера и конфигурирует его атрибуты
|
||||
|
||||
### Конструктор
|
||||
```python
|
||||
Command(trigger: str,
|
||||
description: str = None,
|
||||
flags: Flag | FlagsGroup = None)
|
||||
```
|
||||
|
||||
**Аргументы:**
|
||||
- **name : mean**
|
||||
- `trigger` (`str`): Строковый триггер
|
||||
- `description` (`str`): Описание команды, которое будет выведено в консоль при запуске оболочки
|
||||
- `flags` (`Flag | FlagsGroup`): Флаги, которые будут обработаны при их наличии во вводе юзера
|
||||
|
||||
---
|
||||
|
||||
**Command().**`get_trigger() -> str`
|
||||
|
||||
*method mean* **::** возвращает строковый триггер экземпляра
|
||||
|
||||
---
|
||||
|
||||
**Command().**`get_description() -> str`
|
||||
|
||||
*method mean* **::** возвращает описание команды
|
||||
|
||||
---
|
||||
|
||||
**Command().**`get_registered_flags() -> FlagsGroup | None`
|
||||
|
||||
*method mean* **::** возвращает зарегистрированные флаги экземпляра
|
||||
|
||||
---
|
||||
|
||||
### Исключения
|
||||
- `UnprocessedInputFlagException` - Некорректный синтаксис ввода команды
|
||||
- `RepeatedInputFlagsException` - Повторяющиеся флаги во введённой команде
|
||||
- `EmptyInputCommandException` - Введённая команда является пустой(не содержит символов)
|
||||
|
||||
**Примечание**
|
||||
Все вышеуказанные исключения класса `Command` вызываются в рантайме запущенным экземпляром класса
|
||||
`App`, а также по дефолту обрабатываются, при желании можно задать пользовательские
|
||||
обработчики для этих исключений ([подробнее см.](#methods-))
|
||||
|
||||
---
|
||||
|
||||
## *class* :: `Flag`
|
||||
Класс, экземпляры которого в большинстве случаев должны передаваться при создании
|
||||
экземпляра класса `Command` для регистрации допустимого флага при вводе юзером команды
|
||||
|
||||
### Конструктор
|
||||
```python
|
||||
Flag(flag_name: str,
|
||||
flag_prefix: Literal['-', '--', '---'] = '-',
|
||||
ignore_flag_value_register: bool = False,
|
||||
possible_flag_values: list[str] | Pattern[str] = False)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Аргументы:**
|
||||
- **name : mean**
|
||||
- `flag_name` (`str`): Имя флага
|
||||
- `flag_prefix` (`Literal['-', '--', '---']`): Префикс команды, допустимым значением является от одного до трёх минусов
|
||||
- `ignore_flag_value_register` (`bool`): Будет ли игнорироваться регистр значения введённого флага
|
||||
- `possible_flag_values` (`list[str] | Pattern[str]`): Множество допустимых значений флага, может быть задано
|
||||
списком с допустимыми значениями или регулярным выражением (рекомендуется `re.compile(r'example exspression')`)
|
||||
|
||||
---
|
||||
|
||||
### ***methods***
|
||||
|
||||
---
|
||||
|
||||
**Flag().**`get_sring_entity() -> str`
|
||||
|
||||
*method mean* **::** возвращает строковое представление флага(префикс + имя)
|
||||
|
||||
---
|
||||
|
||||
**Flag().**`get_flag_name() -> str`
|
||||
|
||||
*method mean* **::** возвращает имя флага
|
||||
|
||||
---
|
||||
|
||||
**Flag().**`get_flag_prefix() -> str`
|
||||
|
||||
*method mean* **::** возвращает префикс флага
|
||||
|
||||
---
|
||||
|
||||
## *class* :: `FlagsGroup`
|
||||
Класс, объединяющий список флагов в один объект, используется в качестве
|
||||
передаваемого аргумента `flags` экземпляру класса `Command`, при регистрации
|
||||
хэндлера
|
||||
|
||||
### Конструктор
|
||||
```python
|
||||
FlagsGroup(flags: list[Flag] = None)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Аргументы:**
|
||||
- **name : mean**
|
||||
- `flags` (`list[Flag]`): Список флагов, которые будут объединены в одну группу
|
||||
|
||||
---
|
||||
|
||||
### ***methods***
|
||||
|
||||
---
|
||||
|
||||
**FlagsGroup().**`get_flags() -> list[Flag]`
|
||||
|
||||
*method mean* **::** возвращает зарегистрированные флаги
|
||||
|
||||
---
|
||||
@@ -100,7 +100,7 @@ class App:
|
||||
self.print_func(self.prompt)
|
||||
continue
|
||||
|
||||
self._check_command_for_exit_command(input_command.get_string_entity())
|
||||
self._check_command_for_exit_command(input_command.get_trigger())
|
||||
|
||||
self.print_func(self.line_separate)
|
||||
is_unknown_command: bool = self._check_is_command_unknown(input_command)
|
||||
@@ -227,11 +227,11 @@ class App:
|
||||
registered_router_entities: list[dict[str, str | list[dict[str, Callable[[], None] | Command]] | Router]] = self._registered_router_entities
|
||||
for router_entity in registered_router_entities:
|
||||
for command_entity in router_entity['commands']:
|
||||
if command_entity['command'].get_string_entity().lower() == command.get_string_entity().lower():
|
||||
if command_entity['command'].get_trigger().lower() == command.get_trigger().lower():
|
||||
if self.ignore_command_register:
|
||||
return False
|
||||
else:
|
||||
if command_entity['command'].get_string_entity() == command.get_string_entity():
|
||||
if command_entity['command'].get_trigger() == command.get_trigger():
|
||||
return False
|
||||
self._unknown_command_handler(command)
|
||||
return True
|
||||
@@ -242,7 +242,7 @@ class App:
|
||||
self.print_func(router_entity['title'])
|
||||
for command_entity in router_entity['commands']:
|
||||
self.print_func(self._description_message_pattern.format(
|
||||
command=command_entity['command'].get_string_entity(),
|
||||
command=command_entity['command'].get_trigger(),
|
||||
description=command_entity['command'].get_description()
|
||||
)
|
||||
)
|
||||
|
||||
+13
-25
@@ -1,9 +1,6 @@
|
||||
from .params.flag.entity import Flag
|
||||
from .params.flag.flags_group.entity import FlagsGroup
|
||||
from .exceptions import (InvalidCommandInstanceException,
|
||||
InvalidDescriptionInstanceException,
|
||||
InvalidFlagsInstanceException,
|
||||
UnprocessedInputFlagException,
|
||||
from .exceptions import (UnprocessedInputFlagException,
|
||||
RepeatedInputFlagsException,
|
||||
EmptyInputCommandException)
|
||||
|
||||
@@ -14,37 +11,28 @@ T = TypeVar('T')
|
||||
|
||||
|
||||
class Command(Generic[T]):
|
||||
def __init__(self, command: str,
|
||||
def __init__(self, trigger: str,
|
||||
description: str = None,
|
||||
flags: Flag | FlagsGroup | None = None):
|
||||
self._command = command
|
||||
self._description = f'description for "{self._command}" command' if not description else description
|
||||
flags: Flag | FlagsGroup = None):
|
||||
self._trigger = trigger
|
||||
self._description = f'description for "{self._trigger}" command' if not description else description
|
||||
self._registered_flags: FlagsGroup | None = flags if isinstance(flags, FlagsGroup) else FlagsGroup([flags]) if isinstance(flags, Flag) else flags
|
||||
|
||||
self._input_flags: FlagsGroup | None = None
|
||||
|
||||
|
||||
def get_string_entity(self):
|
||||
return self._command
|
||||
def get_trigger(self) -> str:
|
||||
return self._trigger
|
||||
|
||||
|
||||
def get_description(self):
|
||||
def get_description(self) -> str:
|
||||
return self._description
|
||||
|
||||
|
||||
def get_registered_flags(self):
|
||||
def get_registered_flags(self) -> FlagsGroup | None:
|
||||
return self._registered_flags
|
||||
|
||||
|
||||
def validate_commands_params(self):
|
||||
if not isinstance(self._command, str):
|
||||
raise InvalidCommandInstanceException(self._command)
|
||||
if not isinstance(self._description, str):
|
||||
raise InvalidDescriptionInstanceException()
|
||||
if not any([(isinstance(self._registered_flags, FlagsGroup)), not self._registered_flags]):
|
||||
raise InvalidFlagsInstanceException
|
||||
|
||||
|
||||
def validate_input_flag(self, flag: Flag):
|
||||
registered_flags: FlagsGroup | None = self.get_registered_flags()
|
||||
if registered_flags:
|
||||
@@ -62,7 +50,7 @@ class Command(Generic[T]):
|
||||
return False
|
||||
|
||||
|
||||
def set_input_flags(self, input_flags: FlagsGroup):
|
||||
def _set_input_flags(self, input_flags: FlagsGroup):
|
||||
self._input_flags = input_flags
|
||||
|
||||
def get_input_flags(self) -> FlagsGroup:
|
||||
@@ -110,10 +98,10 @@ class Command(Generic[T]):
|
||||
if any([current_flag_name, current_flag_value]):
|
||||
raise UnprocessedInputFlagException()
|
||||
if len(flags.get_flags()) == 0:
|
||||
return Command(command=command)
|
||||
return Command(trigger=command)
|
||||
else:
|
||||
input_command = Command(command=command)
|
||||
input_command.set_input_flags(flags)
|
||||
input_command = Command(trigger=command)
|
||||
input_command._set_input_flags(flags)
|
||||
return input_command
|
||||
|
||||
|
||||
|
||||
@@ -1,21 +1,6 @@
|
||||
from .params.flag.entity import Flag
|
||||
|
||||
|
||||
class InvalidCommandInstanceException(Exception):
|
||||
def __str__(self):
|
||||
return "Invalid Command Instance"
|
||||
|
||||
|
||||
class InvalidDescriptionInstanceException(Exception):
|
||||
def __str__(self):
|
||||
return "Invalid Description Instance"
|
||||
|
||||
|
||||
class InvalidFlagsInstanceException(Exception):
|
||||
def __str__(self):
|
||||
return "Invalid Flags Instance"
|
||||
|
||||
|
||||
class UnprocessedInputFlagException(Exception):
|
||||
def __str__(self):
|
||||
return "Unprocessed Input Flags"
|
||||
|
||||
@@ -3,7 +3,7 @@ from typing import Literal, Pattern
|
||||
|
||||
class Flag:
|
||||
def __init__(self, flag_name: str,
|
||||
flag_prefix: Literal['-', '--', '---'] = '-',
|
||||
flag_prefix: Literal['-', '--', '---'] = '--',
|
||||
ignore_flag_value_register: bool = False,
|
||||
possible_flag_values: list[str] | Pattern[str] = False):
|
||||
self._flag_name = flag_name
|
||||
|
||||
@@ -5,7 +5,7 @@ class FlagsGroup:
|
||||
def __init__(self, flags: list[Flag] = None):
|
||||
self._flags: list[Flag] = [] if not flags else flags
|
||||
|
||||
def get_flags(self):
|
||||
def get_flags(self) -> list[Flag]:
|
||||
return self._flags
|
||||
|
||||
def add_flag(self, flag: Flag):
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
from .entity import Router
|
||||
from .exceptions import InvalidDescriptionInstanceException
|
||||
@@ -4,7 +4,8 @@ from inspect import getfullargspec
|
||||
from ..command.entity import Command
|
||||
from ..command.params.flag.entity import Flag
|
||||
from ..command.params.flag.flags_group.entity import FlagsGroup
|
||||
from ..router.exceptions import (RepeatedCommandException, RepeatedFlagNameException,
|
||||
from ..router.exceptions import (RepeatedCommandException,
|
||||
RepeatedFlagNameException,
|
||||
TooManyTransferredArgsException,
|
||||
RequiredArgumentNotPassedException,
|
||||
IncorrectNumberOfHandlerArgsException)
|
||||
@@ -25,7 +26,6 @@ class Router:
|
||||
|
||||
|
||||
def command(self, command: Command) -> Callable[[Any], Any]:
|
||||
command.validate_commands_params()
|
||||
self._validate_command(command)
|
||||
|
||||
def command_decorator(func):
|
||||
@@ -47,10 +47,10 @@ class Router:
|
||||
|
||||
|
||||
def input_command_handler(self, input_command: Command):
|
||||
input_command_name: str = input_command.get_string_entity()
|
||||
input_command_name: str = input_command.get_trigger()
|
||||
input_command_flags: FlagsGroup = input_command.get_input_flags()
|
||||
for command_entity in self._command_entities:
|
||||
if input_command_name.lower() == command_entity['command'].get_string_entity().lower():
|
||||
if input_command_name.lower() == command_entity['command'].get_trigger().lower():
|
||||
if command_entity['command'].get_registered_flags():
|
||||
if input_command_flags:
|
||||
for flag in input_command_flags:
|
||||
@@ -70,7 +70,7 @@ class Router:
|
||||
|
||||
|
||||
def _validate_command(self, command: Command):
|
||||
command_name: str = command.get_string_entity()
|
||||
command_name: str = command.get_trigger()
|
||||
if command_name in self.get_all_commands():
|
||||
raise RepeatedCommandException()
|
||||
if self._ignore_command_register:
|
||||
@@ -116,6 +116,6 @@ class Router:
|
||||
def get_all_commands(self) -> list[str]:
|
||||
all_commands: list[str] = []
|
||||
for command_entity in self._command_entities:
|
||||
all_commands.append(command_entity['command'].get_string_entity())
|
||||
all_commands.append(command_entity['command'].get_trigger())
|
||||
|
||||
return all_commands
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
class InvalidDescriptionInstanceException(Exception):
|
||||
def __str__(self):
|
||||
return "Invalid Description Instance"
|
||||
|
||||
|
||||
class RepeatedCommandException(Exception):
|
||||
def __str__(self):
|
||||
return "Commands in handler cannot be repeated"
|
||||
|
||||
@@ -4,6 +4,8 @@ import re
|
||||
def set_description_message_pattern(pattern: str) -> None:
|
||||
first_check = re.match(r'.*command.*', pattern)
|
||||
second_check = re.match(r'.*{description}.*', pattern)
|
||||
if bool(first_check) and bool(second_check):
|
||||
print('Success')
|
||||
|
||||
|
||||
set_description_message_pattern('Invalid des{ommand}cription pattern')
|
||||
@@ -1,75 +0,0 @@
|
||||
import os
|
||||
import shutil
|
||||
import time
|
||||
from zipfile import ZipFile
|
||||
import requests
|
||||
from ..local_data_func.get_script_release_tag import get_script_tag
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
class UpdateScript:
|
||||
|
||||
GITHUB_REPO = "https://api.github.com/repos/koloideal/WordMath"
|
||||
|
||||
@staticmethod
|
||||
def get_latest_release() -> dict:
|
||||
response = requests.get(f"{UpdateScript.GITHUB_REPO}/releases/latest")
|
||||
data = response.json()
|
||||
return {'tag': data['tag_name'],
|
||||
'url': data['zipball_url']}
|
||||
|
||||
|
||||
@staticmethod
|
||||
def download_new_release(zip_url):
|
||||
response = requests.get(zip_url, stream=True)
|
||||
response.raise_for_status()
|
||||
|
||||
total_size = int(response.headers.get("content-length", 0))
|
||||
block_size = 1024
|
||||
|
||||
with tqdm(total=total_size, unit="B", unit_scale=True) as progress_bar:
|
||||
with open('new_release.zip', "wb") as file:
|
||||
for data in response.iter_content(block_size):
|
||||
progress_bar.update(len(data))
|
||||
file.write(data)
|
||||
time.sleep(0.3)
|
||||
|
||||
with ZipFile('new_release.zip') as zip_file:
|
||||
zip_file.extractall("new_release")
|
||||
|
||||
|
||||
@staticmethod
|
||||
def upgrade_script():
|
||||
excluded_files = ['venv', '.venv', '.git', 'new_release']
|
||||
for obj in os.listdir():
|
||||
if obj not in excluded_files:
|
||||
if os.path.isfile(obj):
|
||||
os.remove(obj)
|
||||
elif os.path.isdir(obj):
|
||||
shutil.rmtree(obj)
|
||||
|
||||
new_release = os.listdir('new_release')
|
||||
new_release_name = new_release[0] if new_release[0].startswith('koloideal-WordMath') else None
|
||||
path = f'new_release/{new_release_name}'
|
||||
all_files = os.listdir(path)
|
||||
for file in all_files:
|
||||
shutil.move(path + '/' + file, './' + file)
|
||||
|
||||
shutil.rmtree('new_release')
|
||||
|
||||
|
||||
@staticmethod
|
||||
def start_update() -> bool:
|
||||
existing_release_tag: str = get_script_tag()
|
||||
latest_release: dict = UpdateScript.get_latest_release()
|
||||
latest_release_tag = latest_release['tag']
|
||||
latest_release_url = latest_release['url']
|
||||
|
||||
if latest_release_tag != existing_release_tag:
|
||||
#UpdateScript.download_new_release(latest_release_url)
|
||||
#UpdateScript.upgrade_script()
|
||||
return latest_release_tag
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
from numpy import ndarray
|
||||
from word2number import w2n
|
||||
from ..local_data_func.get_operator_synonyms import get_operator_synonyms
|
||||
import numexpr
|
||||
|
||||
|
||||
def word2num_math(string: str) -> ndarray | ZeroDivisionError | OverflowError:
|
||||
operator_synonyms: dict[str, list[str]] = get_operator_synonyms()
|
||||
|
||||
def variables_to_operator(synonym):
|
||||
for key in operator_synonyms.keys():
|
||||
if synonym in operator_synonyms[key]:
|
||||
return key
|
||||
|
||||
action = {
|
||||
"plus": '+',
|
||||
"minus": '-',
|
||||
"divide": '/',
|
||||
"multiply": '*',
|
||||
"degree": '**',
|
||||
}
|
||||
|
||||
result_string: str = ''
|
||||
all_variables_of_operators: list[str] = [x for l in operator_synonyms.values() for x in l]
|
||||
operators = {}
|
||||
|
||||
while True:
|
||||
is_clear = True
|
||||
number_of_operator = 1
|
||||
for word in string.split():
|
||||
try:
|
||||
if word in all_variables_of_operators:
|
||||
ope_index = string.index(word)
|
||||
if ope_index in operators.keys():
|
||||
is_clear = True
|
||||
break
|
||||
else:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
continue
|
||||
else:
|
||||
is_clear = False
|
||||
operators[number_of_operator] = variables_to_operator(word)
|
||||
number_of_operator += 1
|
||||
string = string.replace(word, "&&", 1)
|
||||
if is_clear:
|
||||
break
|
||||
|
||||
num_of_ope = 1
|
||||
for number in string.split("&&"):
|
||||
try:
|
||||
int_num = w2n.word_to_num(number.strip())
|
||||
except ValueError:
|
||||
return ValueError("Invalid input expression")
|
||||
if num_of_ope in operators.keys():
|
||||
result_string += f'{int_num} {action[operators[num_of_ope]]} '
|
||||
num_of_ope += 1
|
||||
else:
|
||||
result_string += f'{int_num}'
|
||||
|
||||
try:
|
||||
result = numexpr.evaluate(result_string)
|
||||
except ZeroDivisionError:
|
||||
return ZeroDivisionError('Except divide by zero')
|
||||
except OverflowError:
|
||||
return OverflowError('Too big result')
|
||||
else:
|
||||
return result
|
||||
@@ -1,20 +0,0 @@
|
||||
from rich.console import Console
|
||||
from ...business_logic.word2num_math import word2num_math
|
||||
|
||||
|
||||
console = Console()
|
||||
print_line_separator = lambda: console.print('\n[bold blue]--------------------------------------[/bold blue]\n')
|
||||
|
||||
|
||||
def start_solving_command():
|
||||
while True:
|
||||
console.print(
|
||||
"\n[italic]Enter a string expression or [bold italic green] Q [/bold italic green] for exit:[/italic]")
|
||||
string_expression = input()
|
||||
if string_expression.lower() == 'q':
|
||||
break
|
||||
else:
|
||||
print_line_separator()
|
||||
console.print(
|
||||
f'[bold green]Answer:[/bold green] [bold blue]{word2num_math(string_expression)}[/bold blue]')
|
||||
print_line_separator()
|
||||
@@ -1,26 +0,0 @@
|
||||
import requests
|
||||
from rich.console import Console
|
||||
from ...business_logic.script_updater import UpdateScript
|
||||
|
||||
|
||||
console = Console()
|
||||
print_line_separator = lambda: console.print('\n[bold green]--------------------------------------[/bold green]\n')
|
||||
|
||||
|
||||
def upgrade_command():
|
||||
try:
|
||||
requests.get('https://ya.ru')
|
||||
except requests.exceptions.ConnectionError:
|
||||
console.print('[bold red]No internet connection[/bold red]')
|
||||
else:
|
||||
latest_tag = UpdateScript.start_update()
|
||||
if latest_tag:
|
||||
print_line_separator()
|
||||
console.print(f"[bold yellow]The newest version ({latest_tag}) of the script has been successfully installed![/bold yellow]")
|
||||
print_line_separator()
|
||||
console.print("[bold yellow]Rerun the script for the changes to take effect[/bold yellow]")
|
||||
print_line_separator()
|
||||
exit(0)
|
||||
else:
|
||||
console.print('[bold red]You have the latest version installed[/bold red]')
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
import re
|
||||
from pprint import pprint
|
||||
|
||||
from rich.console import Console
|
||||
|
||||
from argenta.command.entity import Command
|
||||
from argenta.command.params.flag.entity import Flag
|
||||
from argenta.command.params.flag.flags_group.entity import FlagsGroup
|
||||
from argenta.router import Router
|
||||
from .handlers_implementation.help_command import help_command
|
||||
|
||||
|
||||
work_router: Router = Router(title='Work nts:')
|
||||
work_router.set_invalid_input_flag_handler(lambda flag: print(f'Invalid input flag: "{flag.get_string_entity()} {flag.get_value()}"'))
|
||||
|
||||
settings_router: Router = Router(title='Settings points:')
|
||||
|
||||
|
||||
console = Console()
|
||||
|
||||
flagi = FlagsGroup(flags=[
|
||||
|
||||
flags = FlagsGroup(flags=[
|
||||
Flag(flag_name='host',
|
||||
flag_prefix='--',
|
||||
possible_flag_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
|
||||
@@ -23,33 +27,21 @@ flagi = FlagsGroup(flags=[
|
||||
])
|
||||
|
||||
|
||||
@work_router.command(Command(command='0', description='Get Help'))
|
||||
@work_router.command(Command(trigger='0', description='Get Help'))
|
||||
def command_help():
|
||||
print('Help command')
|
||||
'''flags = args.get_flags()
|
||||
for flag in flags:
|
||||
print(f'name: "{flag.get_string_entity()}", value: "{flag.get_value()}"')'''
|
||||
#help_command()
|
||||
help_command()
|
||||
|
||||
|
||||
@work_router.command(Command(command='P', description='Start Solving', flags=flagi))
|
||||
def command_start_solving(argrrtrts: dict):
|
||||
@work_router.command(Command(trigger='P', description='Start Solving', flags=flags))
|
||||
def command_start_solving(args: dict):
|
||||
print('Solving...')
|
||||
pprint(argrrtrts)
|
||||
pprint(args)
|
||||
#start_solving_command()
|
||||
|
||||
|
||||
@settings_router.command(Command(command='G', description='Update WordMath'))
|
||||
@settings_router.command(Command(trigger='G', description='Update WordMath'))
|
||||
def command_update():
|
||||
print('uefi')
|
||||
# upgrade_command()
|
||||
|
||||
|
||||
def invalid_input_flag(flag: Flag):
|
||||
print(f'Invalid inpuuuuuuuuuuuuuuuuuuuuuuuut flag: "{flag.get_string_entity()} {flag.get_value()}"')
|
||||
|
||||
|
||||
work_router.set_invalid_input_flag_handler(invalid_input_flag)
|
||||
print('Command update')
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
{
|
||||
"minus": [
|
||||
"without",
|
||||
"lacking",
|
||||
"deprived_of",
|
||||
"bereft_of",
|
||||
"destitute_of",
|
||||
"minus"
|
||||
],
|
||||
"plus": [
|
||||
"added_to",
|
||||
"add",
|
||||
"coupled_with",
|
||||
"with_the_addition_of",
|
||||
"plus"
|
||||
],
|
||||
"divide": [
|
||||
"separate",
|
||||
"part",
|
||||
"split",
|
||||
"divide",
|
||||
"divide_by"
|
||||
],
|
||||
"multiply": [
|
||||
"extend",
|
||||
"expand",
|
||||
"spread",
|
||||
"build_up",
|
||||
"accumulate",
|
||||
"augment",
|
||||
"multiply",
|
||||
"times"
|
||||
],
|
||||
"degree": [
|
||||
"stage",
|
||||
"extent",
|
||||
"grade",
|
||||
"proportion",
|
||||
"gradation",
|
||||
"to_the_power_of",
|
||||
"degree",
|
||||
"to_the"
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"tag": "v4.1.1"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import json
|
||||
|
||||
|
||||
def get_operator_synonyms() -> dict[str, list[str]]:
|
||||
with open("tests/mock_app/local_data/operator_synonyms.json", "r", encoding="utf-8") as file:
|
||||
operator_synonyms: dict = json.load(file)
|
||||
|
||||
return operator_synonyms
|
||||
@@ -1,8 +0,0 @@
|
||||
import json
|
||||
|
||||
|
||||
def get_script_tag() -> str:
|
||||
with open("tests/mock_app/local_data/script_release_tag.json", "r", encoding="utf-8") as file:
|
||||
script_release_tag: str = json.load(file)['tag']
|
||||
|
||||
return script_release_tag
|
||||
@@ -1,5 +1,4 @@
|
||||
from argenta.command import Command
|
||||
from argenta.command.params.flag import Flag, FlagsGroup
|
||||
from argenta.command.exceptions import (UnprocessedInputFlagException,
|
||||
RepeatedInputFlagsException,
|
||||
EmptyInputCommandException)
|
||||
@@ -9,7 +8,7 @@ import unittest
|
||||
|
||||
class TestCommand(unittest.TestCase):
|
||||
def test_parse_correct_raw_command(self):
|
||||
self.assertEqual(Command.parse_input_command('ssh --host 192.168.0.3').get_string_entity(), 'ssh')
|
||||
self.assertEqual(Command.parse_input_command('ssh --host 192.168.0.3').get_trigger(), 'ssh')
|
||||
|
||||
def test_parse_raw_command_with_flag_name_without_value(self):
|
||||
with self.assertRaises(UnprocessedInputFlagException):
|
||||
@@ -28,5 +27,5 @@ class TestCommand(unittest.TestCase):
|
||||
Command.parse_input_command('')
|
||||
|
||||
def test_get_command_description(self):
|
||||
self.assertEqual(Command(command='test', description='test description').get_description(), 'test description')
|
||||
self.assertEqual(Command(trigger='test', description='test description').get_description(), 'test description')
|
||||
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ import re
|
||||
class TestFlag(unittest.TestCase):
|
||||
def test_get_string_entity(self):
|
||||
self.assertEqual(Flag(flag_name='test').get_string_entity(),
|
||||
'-test')
|
||||
'--test')
|
||||
|
||||
def test_get_string_entity2(self):
|
||||
self.assertEqual(Flag(flag_name='test',
|
||||
@@ -20,7 +20,7 @@ class TestFlag(unittest.TestCase):
|
||||
|
||||
def test_get_flag_prefix(self):
|
||||
self.assertEqual(Flag(flag_name='test').get_flag_prefix(),
|
||||
'-')
|
||||
'--')
|
||||
|
||||
def test_get_flag_prefix2(self):
|
||||
self.assertEqual(Flag(flag_name='test',
|
||||
|
||||
@@ -24,3 +24,26 @@ class TestFlagsGroup(unittest.TestCase):
|
||||
flags = FlagsGroup()
|
||||
flags.add_flags([Flag('test'), Flag('test2')])
|
||||
self.assertEqual(len(flags.get_flags()), 2)
|
||||
|
||||
def test_unparse_flags_to_dict(self):
|
||||
list_of_flags = [
|
||||
Flag('test1'),
|
||||
Flag('test2'),
|
||||
Flag('test3'),
|
||||
]
|
||||
flags = FlagsGroup(list_of_flags)
|
||||
serialized_flags = flags.unparse_to_dict()
|
||||
needed_result = {'test1': {'name': 'test1',
|
||||
'prefix': '--',
|
||||
'string_entity': '--test1',
|
||||
'value': None},
|
||||
'test2': {'name': 'test2',
|
||||
'prefix': '--',
|
||||
'string_entity': '--test2',
|
||||
'value': None},
|
||||
'test3': {'name': 'test3',
|
||||
'prefix': '--',
|
||||
'string_entity': '--test3',
|
||||
'value': None}}
|
||||
|
||||
self.assertDictEqual(serialized_flags, needed_result)
|
||||
|
||||
+19
-19
@@ -15,71 +15,71 @@ class TestRouter(unittest.TestCase):
|
||||
|
||||
def test_input_correct_command(self):
|
||||
router = Router()
|
||||
@router.command(Command(command='test'))
|
||||
@router.command(Command(trigger='test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
self.assertEqual(router.input_command_handler(Command(command='test')), 'correct result')
|
||||
self.assertEqual(router.input_command_handler(Command(trigger='test')), 'correct result')
|
||||
|
||||
def test_input_command_with_invalid_flag(self):
|
||||
router = Router()
|
||||
router.set_invalid_input_flag_handler(lambda x: x)
|
||||
|
||||
@router.command(Command(command='test'))
|
||||
@router.command(Command(trigger='test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
input_command = Command(command='test')
|
||||
input_command.set_input_flags(FlagsGroup([Flag('host')]))
|
||||
input_command = Command(trigger='test')
|
||||
input_command._set_input_flags(FlagsGroup([Flag('host')]))
|
||||
|
||||
self.assertEqual(router.input_command_handler(input_command), None)
|
||||
|
||||
def test_input_correct_command_with_one_register_and_ignore_command_register(self):
|
||||
router = Router()
|
||||
router.set_ignore_command_register(True)
|
||||
@router.command(Command(command='test'))
|
||||
@router.command(Command(trigger='test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
self.assertEqual(router.input_command_handler(Command(command='test')), 'correct result')
|
||||
self.assertEqual(router.input_command_handler(Command(trigger='test')), 'correct result')
|
||||
|
||||
def test_input_correct_command_with_different_register_and_ignore_command_register(self):
|
||||
router = Router()
|
||||
router.set_ignore_command_register(True)
|
||||
@router.command(Command(command='test'))
|
||||
@router.command(Command(trigger='test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
self.assertEqual(router.input_command_handler(Command(command='TeSt')), 'correct result')
|
||||
self.assertEqual(router.input_command_handler(Command(trigger='TeSt')), 'correct result')
|
||||
|
||||
def test_input_incorrect_command_with_ignore_command_register(self):
|
||||
router = Router()
|
||||
router.set_ignore_command_register(True)
|
||||
@router.command(Command(command='test'))
|
||||
@router.command(Command(trigger='test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
self.assertEqual(router.input_command_handler(Command(command='Test2')), None)
|
||||
self.assertEqual(router.input_command_handler(Command(trigger='Test2')), None)
|
||||
|
||||
def test_register_repeated_commands_with_one_register(self):
|
||||
router = Router()
|
||||
@router.command(Command(command='test'))
|
||||
@router.command(Command(trigger='test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
with self.assertRaises(RepeatedCommandException):
|
||||
@router.command(Command(command='test'))
|
||||
@router.command(Command(trigger='test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
def test_register_commands_with_different_register(self):
|
||||
router = Router()
|
||||
@router.command(Command(command='test'))
|
||||
@router.command(Command(trigger='test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
try:
|
||||
@router.command(Command(command='Test'))
|
||||
@router.command(Command(trigger='Test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
except RepeatedCommandException:
|
||||
@@ -88,24 +88,24 @@ class TestRouter(unittest.TestCase):
|
||||
def test_register_repeated_commands_with_one_register_and_set_ignore_command_register(self):
|
||||
router = Router()
|
||||
router.set_ignore_command_register(True)
|
||||
@router.command(Command(command='test'))
|
||||
@router.command(Command(trigger='test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
with self.assertRaises(RepeatedCommandException):
|
||||
@router.command(Command(command='test'))
|
||||
@router.command(Command(trigger='test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
def test_register_repeated_commands_with_different_register_and_set_ignore_command_register(self):
|
||||
router = Router()
|
||||
router.set_ignore_command_register(True)
|
||||
@router.command(Command(command='test'))
|
||||
@router.command(Command(trigger='test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
with self.assertRaises(RepeatedCommandException):
|
||||
@router.command(Command(command='Test'))
|
||||
@router.command(Command(trigger='Test'))
|
||||
def test():
|
||||
return 'correct result'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user