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