mirror of
https://github.com/MarkParker5/STARK.git
synced 2024-11-24 08:12:13 +02:00
Add online/offline mode, change Command.find() and @Command.background() returns, fix bugs
This commit is contained in:
parent
5e94014dcd
commit
d75f1cb626
38
Command.py
38
Command.py
@ -39,10 +39,10 @@ class Command(ABC):
|
||||
}
|
||||
_regex = {
|
||||
# stars *
|
||||
f'([A-Za-zА-ЯЁа-яё0-9]+)\*([A-Za-zА-ЯЁа-яё0-9]+)': r'\\b\1.*\2\\b', # 'te*xt'
|
||||
f'\*([A-Za-zА-ЯЁа-яё0-9]+)': r'\\b.*\1', # '*text'
|
||||
f'([A-Za-zА-ЯЁа-яё0-9]+)\*': r'\1.*\\b', # 'text*'
|
||||
f'(^|\s)\*($|\s)': r'.*', # '*' ' * '
|
||||
'([A-Za-zА-ЯЁа-яё0-9\(\)\[\]\{\}]+)\*([A-Za-zА-ЯЁа-яё0-9\(\)\[\]\{\}]+)': r'\\b\1.*\2\\b', # 'te*xt'
|
||||
'\*([A-Za-zА-ЯЁа-яё0-9\(\)\[\]\{\}]+)': r'\\b.*\1', # '*text'
|
||||
'([A-Za-zА-ЯЁа-яё0-9\(\)\[\]\{\}]+)\*': r'\1.*\\b', # 'text*'
|
||||
'(^|\s)\*($|\s)': r'.*', # '*' ' * '
|
||||
# one of the list (a|b|c)
|
||||
'\(((?:.*\|)*.*)\)': r'(?:\1)',
|
||||
# 0 or 1 the of list [a|b|c]
|
||||
@ -131,19 +131,24 @@ class Command(ABC):
|
||||
list = Command.getList()
|
||||
for i, obj in enumerate( list ):
|
||||
chances[i] = 0
|
||||
x = 1 / ( sum([int(i) for i in obj.getKeywords().keys()]) or 1 )
|
||||
k = 1 / ( sum( [int(w)*len(kw) for w, kw in obj.getKeywords().items()] ) or 1 )
|
||||
for weight, kws in obj.getKeywords().items():
|
||||
k = x * weight / len(kws)
|
||||
for kw in kws:
|
||||
chances[i] += Command.ratio(string, kw) * k
|
||||
chances[i] += Command.ratio(string, kw) * weight * k
|
||||
if( sum( chances.values() ) ):
|
||||
top = max( chances.values() ) / sum( chances.values() ) * 100
|
||||
else:
|
||||
return list[0]
|
||||
return {
|
||||
'cmd': list[0],
|
||||
'params': None,
|
||||
}
|
||||
#if( max( chances.values() ) < 800 or top < 80): return list[0]
|
||||
for i, chance in chances.items():
|
||||
if chance == max( chances.values() ):
|
||||
return list[i]
|
||||
return {
|
||||
'cmd': list[i],
|
||||
'params': None,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def reg_find(string):
|
||||
@ -155,15 +160,21 @@ class Command(ABC):
|
||||
for ptrn, regex in Command._regex.items():
|
||||
pattern = re.sub(re.compile(ptrn), regex, pattern)
|
||||
# links $Pattern
|
||||
link = re.search(re.compile(f'\$[A-Za-zА-ЯЁа-яё0-9]+'), pattern)
|
||||
link = re.search(re.compile('\$[A-Za-zА-ЯЁа-яё0-9\(\)\[\]\{\}]+'), pattern)
|
||||
if link: pattern = re.sub('\\'+link[0], f'(?P<{link[0][1:]}>{Command._patterns[link[0][1:]]})', pattern)
|
||||
# find
|
||||
match = re.search(re.compile(pattern), string)
|
||||
if(match): return obj # match.groupdict()
|
||||
return None
|
||||
if(match): return {
|
||||
'cmd': obj,
|
||||
'params': match.groupdict(),
|
||||
}
|
||||
return {
|
||||
'cmd': list[0],
|
||||
'params': None,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def background(answer = ''):
|
||||
def background(answer = '', voice = ''):
|
||||
def decorator(cmd):
|
||||
def wrapper(text):
|
||||
finish_event = Event()
|
||||
@ -172,6 +183,7 @@ class Command(ABC):
|
||||
return {
|
||||
'type': 'background',
|
||||
'text': answer,
|
||||
'voice': voice,
|
||||
'thread': {
|
||||
'thread': thread,
|
||||
'finish_event': finish_event,
|
||||
|
@ -21,12 +21,12 @@ from .SmallTalk import *
|
||||
import datetime, time
|
||||
import math
|
||||
from Command import Command
|
||||
import time
|
||||
################################################################################
|
||||
def method(text):
|
||||
return {
|
||||
'type': 'simple',
|
||||
'text': 'Я не понимаю',
|
||||
'voice': 'Я не понимаю',
|
||||
}
|
||||
|
||||
keywords = {}
|
||||
@ -96,11 +96,16 @@ def method(text):
|
||||
str_num += 'десят'
|
||||
result.append(str_num)
|
||||
return ' '.join(result)
|
||||
answer = f'Сейчас {get_str_num(hours, 0)} {str_hour}'
|
||||
if(minutes): answer += f', {get_str_num(minutes, 1)} {str_minute}'
|
||||
|
||||
voice = f'Сейчас {get_str_num(hours, 0)} {str_hour}'
|
||||
if(minutes): voice += f', {get_str_num(minutes, 1)} {str_minute}'
|
||||
hours = now.hour if now.hour > 9 else '0'+str(now.hour)
|
||||
minutes = minutes if minutes > 9 else '0'+str(minutes) if minutes else '00'
|
||||
text = f'Текущее время: {hours}:{minutes}'
|
||||
return {
|
||||
'type': 'simple',
|
||||
'text': answer
|
||||
'text': text,
|
||||
'voice': voice,
|
||||
}
|
||||
|
||||
keywords = {
|
||||
@ -108,24 +113,25 @@ keywords = {
|
||||
5: ['текущее', 'сейчас', 'время'],
|
||||
1: ['сколько']
|
||||
}
|
||||
patterns = ['* который * час *', '* скольк* * врем* *', 'время']
|
||||
patterns = ['* который * час *', '* скольк* * (врем|час)* *', '* врем* *']
|
||||
ctime = SmallTalk('Current Time', keywords, patterns)
|
||||
ctime.setStart(method)
|
||||
################################################################################
|
||||
# Only for tests
|
||||
@Command.background('Запускаю фоновый процесс')
|
||||
@Command.background(answer = 'Запуск фонового процесса', voice = 'Запускаю фоновый процесс')
|
||||
def method(text, finish_event):
|
||||
time.sleep(10)
|
||||
finish_event.set()
|
||||
return {
|
||||
'text': 'Фоновый процесс завершен',
|
||||
'voice': 'Фоновый процесс завершен',
|
||||
}
|
||||
|
||||
|
||||
keywords = {
|
||||
10: ['тестирование', 'проверка', 'потоков', 'фоновых', 'процессов'],
|
||||
}
|
||||
patterns = ['* (тестир*|провер*) * [фоновых] * (процесс*|поток*) *']
|
||||
patterns = ['* [тест|провер]* * [фонов*] * (процесс|поток)* *']
|
||||
test = SmallTalk('Test threads', keywords, patterns)
|
||||
test.setStart(method)
|
||||
################################################################################
|
||||
|
@ -16,7 +16,6 @@ class Speech:
|
||||
|
||||
def speak(this):
|
||||
if( os.path.exists(this._path) ):
|
||||
print(f'Говорю: {this._text}')
|
||||
with open(this._path) as f:
|
||||
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as audio:
|
||||
mixer.init()
|
||||
|
@ -1,2 +1,3 @@
|
||||
goole_tts_json_key = "tts-gc-key.json"
|
||||
language_code = "ru-RU"
|
||||
names = ['арчи', 'archie']
|
||||
|
45
main.py
45
main.py
@ -2,11 +2,14 @@ import SpeechRecognition
|
||||
import Text2Speech
|
||||
import SmallTalk
|
||||
from Command import Command
|
||||
import config
|
||||
|
||||
listener = SpeechRecognition.SpeechToText()
|
||||
voice = Text2Speech.Engine()
|
||||
threads = []
|
||||
memory = []
|
||||
online = False
|
||||
voids = 0
|
||||
listener.listen_noise()
|
||||
|
||||
def check_threads():
|
||||
@ -14,27 +17,37 @@ def check_threads():
|
||||
if thread['finish_event'].is_set():
|
||||
responce = thread['thread'].join()
|
||||
if responce['text']:
|
||||
voice.generate(responce['text']).speak()
|
||||
print(' — '+responce['text'])
|
||||
if responce['voice']:
|
||||
voice.generate(responce['voice']).speak()
|
||||
thread['finish_event'].clear()
|
||||
del thread
|
||||
|
||||
while True: # main loop
|
||||
check_threads()
|
||||
print('Listening...')
|
||||
print('\nYou: ', end='')
|
||||
speech = listener.listen()
|
||||
text = speech['text']
|
||||
print('You: ')
|
||||
if text:
|
||||
cmd = Command.find(text)
|
||||
responce = cmd.start(text)
|
||||
memory.insert(0, {
|
||||
'text': text,
|
||||
'cmd': cmd,
|
||||
'responce': responce
|
||||
})
|
||||
if responce['type'] == 'background': # add background thread to list
|
||||
threads.append(responce['thread'])
|
||||
if responce['text']:
|
||||
voice.generate(responce['text']).speak()
|
||||
speech['status'] = 'ok' if text else 'void'
|
||||
if speech['status'] == 'ok':
|
||||
print(text)
|
||||
if set(config.names) & set(text.split(' ')): online = True
|
||||
if online:
|
||||
voids = 0
|
||||
cmd, params = Command.reg_find(text).values()
|
||||
responce = cmd.start(text)
|
||||
memory.insert(0, {
|
||||
'text': text,
|
||||
'cmd': cmd,
|
||||
'responce': responce
|
||||
})
|
||||
if responce['type'] == 'background': # add background thread to list
|
||||
threads.append(responce['thread'])
|
||||
if responce['text']:
|
||||
print('Archie: '+responce['text'])
|
||||
if responce['voice']:
|
||||
voice.generate(responce['voice']).speak()
|
||||
else:
|
||||
print(speech['status'])
|
||||
if speech['status'] == 'error': print('Отсутсвует подключение к интернету');
|
||||
elif speech['status'] == 'void': voids += 1
|
||||
if voids >= 3: online = False; voids = 0
|
||||
|
Loading…
Reference in New Issue
Block a user