feat: refine assistant logic and update docs
This commit is contained in:
@@ -11,20 +11,57 @@ import re
|
||||
import platform
|
||||
from ..core.roman import replace_roman_numerals
|
||||
|
||||
try:
|
||||
import pymorphy3
|
||||
|
||||
_MORPH = pymorphy3.MorphAnalyzer()
|
||||
except Exception:
|
||||
_MORPH = None
|
||||
|
||||
# Карта для перевода слов в цифры ("пять" -> 5)
|
||||
NUMBER_MAP = {
|
||||
"ноль": 0,
|
||||
"один": 1,
|
||||
"одна": 1,
|
||||
"раз": 1,
|
||||
"единица": 1,
|
||||
"единичка": 1,
|
||||
"два": 2,
|
||||
"две": 2,
|
||||
"двойка": 2,
|
||||
"двоечка": 2,
|
||||
"три": 3,
|
||||
"тройка": 3,
|
||||
"троечка": 3,
|
||||
"четыре": 4,
|
||||
"четверка": 4,
|
||||
"четверочка": 4,
|
||||
"пять": 5,
|
||||
"пятерка": 5,
|
||||
"пятерочка": 5,
|
||||
"шесть": 6,
|
||||
"шестерка": 6,
|
||||
"шестерочка": 6,
|
||||
"семь": 7,
|
||||
"семерка": 7,
|
||||
"семерочка": 7,
|
||||
"восемь": 8,
|
||||
"восьмерка": 8,
|
||||
"восьмерочка": 8,
|
||||
"девять": 9,
|
||||
"девятка": 9,
|
||||
"девяточка": 9,
|
||||
"десять": 10,
|
||||
"десятка": 10,
|
||||
"десяточка": 10,
|
||||
}
|
||||
_VOLUME_COMMAND_RE = re.compile(r"\b(громкост\w*|звук\w*|volume)\b")
|
||||
|
||||
|
||||
def _lemmatize(token: str) -> str:
|
||||
if _MORPH is None:
|
||||
return token
|
||||
return _MORPH.parse(token)[0].normal_form.replace("ё", "е")
|
||||
|
||||
|
||||
def _get_volume_command(level: int):
|
||||
@@ -149,16 +186,25 @@ def parse_volume_text(text: str) -> int | None:
|
||||
Пытается найти число громкости в тексте.
|
||||
Понимает и цифры ("5"), и слова ("пять").
|
||||
"""
|
||||
text = replace_roman_numerals(text.lower())
|
||||
text = replace_roman_numerals(text.lower().replace("ё", "е"))
|
||||
|
||||
# 1. Ищем цифры (1-10)
|
||||
num_match = re.search(r"\b(10|[1-9])\b", text)
|
||||
if num_match:
|
||||
return int(num_match.group())
|
||||
# 1. Ищем цифры в любом месте фразы.
|
||||
for match in re.finditer(r"\d+", text):
|
||||
value = int(match.group())
|
||||
if 1 <= value <= 10:
|
||||
return value
|
||||
|
||||
# 2. Ищем слова из словаря
|
||||
for word, value in NUMBER_MAP.items():
|
||||
if word in text:
|
||||
# 2. Ищем числительные и разговорные формы по леммам:
|
||||
# "семерку", "десяточку", "на двух" -> 7, 10, 2.
|
||||
for token in re.findall(r"[a-zA-Zа-яА-ЯёЁ]+", text):
|
||||
value = NUMBER_MAP.get(_lemmatize(token))
|
||||
if value is not None and 1 <= value <= 10:
|
||||
return value
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def is_volume_command(text: str) -> bool:
|
||||
if not text:
|
||||
return False
|
||||
return bool(_VOLUME_COMMAND_RE.search(text.lower().replace("ё", "е")))
|
||||
|
||||
Reference in New Issue
Block a user