1
0
mirror of https://github.com/MarkParker5/STARK.git synced 2024-11-24 08:12:13 +02:00

Fully new layout (in progress)

This commit is contained in:
MarkParker5 2021-08-21 02:09:37 +03:00
parent 9f147ada14
commit 9a08765f70
63 changed files with 268 additions and 304 deletions

8
Controls/Control.py Normal file
View File

@ -0,0 +1,8 @@
from abc import ABC, abstractmethod
class Control(ABC):
@abstractmethod
def start(self):
# entry point of the control
pass

View File

@ -0,0 +1,4 @@
class DJango(Control):
def start(self):
# run manage.py
pass

View File

@ -0,0 +1,97 @@
#!/usr/local/bin/python3.8
from Command import Command
import Text2Speech
import telebot
import config
import modules
import time
import os
class TelegramBot(Control):
threads = []
online = True
voids = 0
memory = []
voice = Text2Speech.Engine()
bot = telebot.TeleBot(config.telebot)
# Singleton
def __new__(self, cls):
if not hasattr(cls, 'instance'):
cls.instance = super(VoiceAssistant, cls).__new__(cls)
return cls.instance
def reply(self, id, response):
if response.text:
bot.send_message(id, response.text)
if response.voice:
bot.send_voice(id, voice.generate(response.voice).getBytes() )
if response.thread: # add background thread to list
response.thread['id'] = id
threads.append(response.thread)
def check_threads(self, threads):
for thread in threads:
if thread['finish_event'].is_set():
response = thread['thread'].join()
reply(thread['id'], response)
thread['finish_event'].clear()
del thread
def main(self, id, text):
text = text.lower()
if Command.isRepeat(text):
reply(id, memory[0]['response']);
return
if memory:
response = memory[0]['response']
if response.callback:
if new_response := response.callback.answer(text):
reply(id, new_response)
memory.insert(0, {
'cmd': response.callback,
'params': None,
'response': new_response,
})
return
try:
cmd, params = memory[0]['cmd'].checkContext(text).values()
if memory[0].get('params'): params = {**memory[0].get('params'), **params}
except:
cmd, params = Command.reg_find(text).values()
response = cmd.start(params)
reply(id, response)
memory.insert(0, {
'cmd': cmd,
'params': params,
'response': response,
})
@bot.message_handler(commands=['vlc', 'queue', 'cmd'])
def simple_commands(msg):
command = msg.text.replace('/cmd', '').replace('/vlc', 'vlc')
if '/queue' in msg.text: command = command.replace('/queue', '') + '--playlist-enqueue'
os.system(f'lxterminal --command="{command}"')
@bot.message_handler(commands=['terminal'])
def terminal(msg):
command = msg.text.replace('/terminal', '')
output = os.popen(command).read()
bot.send_message(msg.chat.id, output)
@bot.message_handler(content_types = ['text'])
def execute(msg):
main(msg.chat.id, msg.text)
def start(self):
while True:
try:
print("Start polling...")
bot.polling(callback = check_threads, args = (threads,) )
except:
time.sleep(10)
print("Polling failed")
if __name__ == '__main__':
TelegramBot().start()

View File

@ -0,0 +1,150 @@
#!/usr/local/bin/python3.8
import SpeechRecognition
import Text2Speech
from Command import Command
import config
import modules
import os
if config.double_clap_activation:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(12, GPIO.IN)
GPIO.add_event_detect(12, GPIO.RISING, callback = checkClap)
class VoiceAssistant(Control):
listener = SpeechRecognition.SpeechToText()
voice = Text2Speech.Engine()
threads = []
reports = []
memory = []
voids = 0
lastClapTime = 0
doubleClap = False
# Singleton
def __new__(cls):
if not hasattr(cls, 'instance'):
cls.instance = super(VoiceAssistant, cls).__new__(cls)
return cls.instance
def start(self):
listener.listen_noise()
os.system('clear')
while True:
if voids >= 3:
voids = 0
if config.double_clap_activation:
print('\nSleep (-_-)zzZZ\n')
sleep()
print('\nYou: ', end='')
speech = listener.listen()
print(speech.get('text') or '', end='')
while True:
if speech['status'] == 'error':
break
if speech['status'] == 'void':
voids += 1
break
text = speech['text']
cmd, params = Command.reg_find(text).values()
try: response = cmd.start(params)
except: break
reply(response)
check_threads()
report()
if response.callback:
speech = recognize(response.callback, {})
else:
break
def recognize(self, callback, params):
print('\nYou: ', end='')
speech = listener.listen()
if speech['status'] in ['error', 'void']:
return speech
text = speech['text']
print(text, end='')
while True:
check_threads()
if not callback: break
try:
if response := callback.answer(text):
reply(response)
except:
break
memory.insert(0, {
'text': text,
'cmd': cmd,
'response': response,
})
speech = recognize(response.callback, params)
if callback.once: break
return speech
def report(self):
global reports
for response in reports:
if response.voice:
voice.generate(response.voice).speak()
time.sleep(2)
reports = []
def reply(self, response):
if response.text: # print answer
print('\nArchie: '+response.text)
if response.voice: # say answer
voice.generate(response.voice).speak()
if response.thread: # add background thread to stack
threads.append(response.thread)
def check_threads(self):
for thread in threads:
if not thread['finish_event'].is_set(): continue
response = thread['thread'].join()
reply(response)
if response.callback:
if response.callback.quiet:
response.callback.start()
else:
for _ in range(3):
print('\nYou: ', end='')
speech = listener.listen()
if speech['status'] == 'ok':
print(speech['text'], '\n')
new_response = response.callback.answer(speech['text'])
reply(new_response)
break
else:
reports.append(response)
thread['finish_event'].clear()
del thread
# check double clap from arduino microphone module
def checkClap(self, channel):
global lastClapTime
global doubleClap
now = time.time()
delta = now - lastClapTime
if 0.1 < delta < 0.6:
doubleClap = True
else:
lastClapTime = now
# waiting for double clap
def sleep(self):
global lastClapTime
lastClapTime = 0
global doubleClap
while not doubleClap:
check_threads()
time.sleep(1)
else:
doubleClap = False
if __name__ == '__main__':
VoiceAssistant().start()

View File

@ -26,7 +26,7 @@
from abc import ABC, abstractmethod # for abstract class and methods
from abc import ABC, abstractmethod
# from fuzzywuzzy import fuzz
from threading import Thread, Event
import re

View File

@ -1,72 +0,0 @@
from bs4 import BeautifulSoup as BS
from Command import Command, Response
import wikipedia as wiki
import requests
import random
import json
import re
class QA(Command):
def googleDictionary(this, word):
response = requests.get(f'https://api.dictionaryapi.dev/api/v2/entries/ru/{word}')
if response.status_code == 200:
response = json.loads(response.content)
text = ''
r = response[0]
definition = r['meanings'][0]['definitions'][0]
short = r['word'].lower().capitalize() + ' (' + ( r['meanings'][0]['partOfSpeech'].capitalize() if r['meanings'][0]['partOfSpeech'] != 'undefined' else 'Разговорный' ) + ') — ' + definition['definition'].lower().capitalize() + ( '. Синонимы: ' + ', '.join(definition['synonyms']) if definition['synonyms'] else '')
short = short.replace(word[0].lower()+'.', word.lower())
short = short.replace(word[0].upper()+'.', word.capitalize())
short = short.replace('-н.', '-нибудь')
short = short.replace('потр.', 'потребляется')
short = short.replace('знач.', 'значении')
for r in response:
text += '\n' + r['word'].lower().capitalize() + ' (' + (r['meanings'][0]['partOfSpeech'].capitalize() if r['meanings'][0]['partOfSpeech'] != 'undefined' else 'Разговорный') + ')\n'
for definition in r['meanings'][0]['definitions']:
text += '\t' + definition['definition'].lower().capitalize()
if example := definition.get('example'):
text += '\n\tНапример: ' + example
if synonyms := definition['synonyms']:
text += '\n\tСинонимы: ' + ', '.join(synonyms) + '.'
if antonyms := definition['antonyms']:
text += '\n\tАнтонимы: ' + ', '.join(antonyms) + '.'
text += '\n\n'
return {
'text': text,
'short': short,
}
return {}
def wikipedia(this, word):
wiki.set_lang("ru")
article = wiki.summary(word, sentences=5)
try: return article[:article.find('\n\n')][:600]
except: return ''
def googleSearch(this, word):
response = requests.get(f'https://www.google.ru/search?&q={word}&lr=lang_ru&lang=ru')
page = BS(response.content, 'html.parser')
info = page.select('div.BNeawe>div>div.BNeawe')
return info[0].get_text() if info else ''
def start(this, params):
query = params['string']
if 'вики' in query:
query = query.replace('википедия', '').replace('вики', '').strip()
try: search = this.googleSearch(query)
except: search = ''
try: wiki = this.wikipedia(query) if not 'Википедия' in search else ''
except: wiki = ''
try: gdict = this.googleDictionary(query)
except: gdict = []
voice = search or (gdict['short'] if gdict else '') or wiki
text = (f'Google Search:\n\t{search}' if search else '') + (f'\n\nWikipedia:\n\t{wiki}' if wiki else '') + ('\n\nDictionary:'+gdict['text'] if gdict else '')
else:
try: search = this.googleSearch(query)
except: search = ''
voice = text = search or random.choice(['Не совсем понимаю, о чём вы.', 'Вот эта последняя фраза мне не ясна.', 'А вот это не совсем понятно.', 'Можете сказать то же самое другими словами?', 'Вот сейчас я совсем вас не понимаю.', 'Попробуйте выразить свою мысль по-другому',])
return Response(text = text, voice = voice)
Command.QA = QA('QA', {}, [])

View File

@ -1 +0,0 @@
from .QA import *

View File

Before

Width:  |  Height:  |  Size: 337 KiB

After

Width:  |  Height:  |  Size: 337 KiB

View File

View File

View File

@ -1,6 +0,0 @@
import QA
import SmallTalk
import Media
import SmartHome
import Raspi
import Zieit

7
start.py Normal file
View File

@ -0,0 +1,7 @@
#!/usr/local/bin/python3.8
# entry point
# TODO:
# import subprocess
# start oll controls in own thread or subprocess:
# voice assistant, telegram bot, django(api and ui)

View File

@ -17,5 +17,5 @@ for name, module in modules.items():
print(f'[error]\t{name} launch failed')
print('Running server...')
os.system(f'lxterminal --command="python3.8 {config.path}/manage.py runserver 192.168.0.129:8000 & read"')
os.system(f'lxterminal --command="python3.8 {config.path}/Controls/Django/manage.py runserver 192.168.0.129:8000 & read"')
os.system(f'lxterminal --command="vlc"')

View File

@ -1,86 +0,0 @@
#!/usr/local/bin/python3.8
from Command import Command
import Text2Speech
import telebot
import config
import modules
import time
import os
threads = []
online = True
voids = 0
memory = []
voice = Text2Speech.Engine()
bot = telebot.TeleBot(config.telebot)
def reply(id, response):
if response.text:
bot.send_message(id, response.text)
if response.voice:
bot.send_voice(id, voice.generate(response.voice).getBytes() )
if response.thread: # add background thread to list
response.thread['id'] = id
threads.append(response.thread)
def check_threads(threads):
for thread in threads:
if thread['finish_event'].is_set():
response = thread['thread'].join()
reply(thread['id'], response)
thread['finish_event'].clear()
del thread
def main(id, text):
text = text.lower()
if Command.isRepeat(text):
reply(id, memory[0]['response']);
return
if memory:
response = memory[0]['response']
if response.callback:
if new_response := response.callback.answer(text):
reply(id, new_response)
memory.insert(0, {
'cmd': response.callback,
'params': None,
'response': new_response,
})
return
try:
cmd, params = memory[0]['cmd'].checkContext(text).values()
if memory[0].get('params'): params = {**memory[0].get('params'), **params}
except:
cmd, params = Command.reg_find(text).values()
response = cmd.start(params)
reply(id, response)
memory.insert(0, {
'cmd': cmd,
'params': params,
'response': response,
})
@bot.message_handler(commands=['vlc', 'queue', 'cmd'])
def simple_commands(msg):
command = msg.text.replace('/cmd', '').replace('/vlc', 'vlc')
if '/queue' in msg.text: command = command.replace('/queue', '') + '--playlist-enqueue'
os.system(f'lxterminal --command="{command}"')
@bot.message_handler(commands=['terminal'])
def terminal(msg):
command = msg.text.replace('/terminal', '')
output = os.popen(command).read()
bot.send_message(msg.chat.id, output)
@bot.message_handler(content_types = ['text'])
def execute(msg):
main(msg.chat.id, msg.text)
while True:
try:
print("Start polling...")
bot.polling(callback = check_threads, args = (threads,) )
except:
time.sleep(10)
print("Polling failed")

View File

@ -1,137 +0,0 @@
#!/usr/local/bin/python3.8
import SpeechRecognition
import Text2Speech
from Command import Command
import config
import modules
import os
listener = SpeechRecognition.SpeechToText()
voice = Text2Speech.Engine()
threads = []
reports = []
memory = []
voids = 0
if config.double_clap_activation:
# check double clap from arduino microphone module
def checkClap(channel):
global lastClapTime
global doubleClap
now = time.time()
delta = now - lastClapTime
if 0.1 < delta < 0.6:
doubleClap = True
else:
lastClapTime = now
# waiting for double clap
def sleep():
global lastClapTime
lastClapTime = 0
global doubleClap
while not doubleClap:
check_threads()
time.sleep(1)
else:
doubleClap = False
import RPi.GPIO as GPIO
import time
lastClapTime = 0
doubleClap = False
GPIO.setmode(GPIO.BCM)
GPIO.setup(12, GPIO.IN)
GPIO.add_event_detect(12, GPIO.RISING, callback=checkClap)
def check_threads():
for thread in threads:
if not thread['finish_event'].is_set(): continue
response = thread['thread'].join()
reply(response)
if response.callback:
if response.callback.quiet:
response.callback.start()
else:
for _ in range(3):
print('\nYou: ', end='')
speech = listener.listen()
if speech['status'] == 'ok':
print(speech['text'], '\n')
new_response = response.callback.answer(speech['text'])
reply(new_response)
break
else:
reports.append(response)
thread['finish_event'].clear()
del thread
def report():
global reports
for response in reports:
if response.voice:
voice.generate(response.voice).speak()
time.sleep(2)
reports = []
def reply(response):
if response.text: # print answer
print('\nArchie: '+response.text)
if response.voice: # say answer
voice.generate(response.voice).speak()
if response.thread: # add background thread to stack
threads.append(response.thread)
def recognize(callback, params):
print('\nYou: ', end='')
speech = listener.listen()
if speech['status'] in ['error', 'void']:
return speech
text = speech['text']
print(text, end='')
while True:
check_threads()
if not callback: break
try:
if response := callback.answer(text):
reply(response)
except:
break
memory.insert(0, {
'text': text,
'cmd': cmd,
'response': response,
})
speech = recognize(response.callback, params)
if callback.once: break
return speech
listener.listen_noise()
os.system('clear')
while True:
if voids >= 3:
voids = 0
if config.double_clap_activation:
print('\nSleep (-_-)zzZZ\n')
sleep()
print('\nYou: ', end='')
speech = listener.listen()
print(speech.get('text') or '', end='')
while True:
if speech['status'] == 'error':
break
if speech['status'] == 'void':
voids += 1
break
text = speech['text']
cmd, params = Command.reg_find(text).values()
try: response = cmd.start(params)
except: break
reply(response)
check_threads()
report()
if response.callback:
speech = recognize(response.callback, {})
else:
break