diff --git a/Command/Callback.py b/Command/Callback.py new file mode 100644 index 0000000..c916afd --- /dev/null +++ b/Command/Callback.py @@ -0,0 +1,18 @@ +from .Command import Command +import re + +class Callback: + def __init__(this, patterns): + this.patterns = patterns + + def setStart(this, function): + this.start = function + + def start(this, params): + pass + + def answer(this, string): + for pattern in this.patterns: + if match := re.search(re.compile(Command.compilePattern(pattern)), string): + return this.start({**match.groupdict(), 'string':string}) + return None diff --git a/Command/Command.py b/Command/Command.py index 2fd65e0..471c594 100644 --- a/Command/Command.py +++ b/Command/Command.py @@ -227,9 +227,9 @@ class Command(ABC): for pattern in obj.getPatterns(): if match := re.search(re.compile(Command.compilePattern(pattern)), string): return { - 'cmd': obj, - 'params': {**match.groupdict(), 'string':string,}, - } + 'cmd': obj, + 'params': {**match.groupdict(), 'string':string,}, + } # return Question-Answer system if command not found return { 'cmd': Command.QA, diff --git a/Command/__init__.py b/Command/__init__.py index 1c973dd..4829b38 100644 --- a/Command/__init__.py +++ b/Command/__init__.py @@ -1 +1,2 @@ from .Command import * +from .Callback import * diff --git a/Media/__init__.py b/Media/__init__.py index d139dd2..fe6e04c 100644 --- a/Media/__init__.py +++ b/Media/__init__.py @@ -1,44 +1,63 @@ -from .film import * +from .Film import * import requests from bs4 import BeautifulSoup as BS import os +import Command ################################################################################ -def method(params): - def findFilm(name): - query = name + ' site:kinogo.by' - responce = requests.get(f'https://www.google.ru/search?&q={query}&lr=lang_ru&lang=ru') - page = BS(responce.content, 'html.parser') - link = page.select_one('.ZINbbc.xpd.O9g5cc.uUPGi>.kCrYT>a') - return link['href'][7:].split('&')[0] if link else None +def findFilm(name): + query = name + ' site:kinogo.by' + responce = requests.get(f'https://www.google.ru/search?&q={query}&lr=lang_ru&lang=ru') + page = BS(responce.content, 'html.parser') + link = page.select_one('.ZINbbc.xpd.O9g5cc.uUPGi>.kCrYT>a') + return link['href'][7:].split('&')[0] if link else None - def extractUrl(url): - responce = requests.get(url) - page = BS(responce.content, 'html.parser') - url = page.select_one('div[style="padding:22px; float:left; margin-left: 30px;"]>a[download]:last-child') - return url['href'] if url else None +def extractUrl(url): + responce = requests.get(url) + page = BS(responce.content, 'html.parser') + url = page.select_one('div[style="padding:22px; float:left; margin-left: 30px;"]>a[download]:last-child') + return url['href'] if url else None - def start(url): - os.system(f'lxterminal --command="vlc {url}"') +def startFilm(url): + os.system(f'lxterminal --command="vlc {url}"') +def main(params): name = params.get('text') - print(name) if name: if url:= extractUrl(findFilm(name)): - start(url) + startFilm(url) voice = text = 'Включаю' else: voice = text = 'Не могу найти фильм' + type = 'simple' else: voice = text = 'Какой фильм включить?' + type = 'question' + callback = kinogo_cb + return { + 'type': type, + 'text': text, + 'voice': voice, + 'callback': callback or None, + } + +def start(params): + name = params.get('text') + voice = text = 'Не могу найти фильм' + if name: + if url:= extractUrl(findFilm(name)): + startFilm(url) + voice = text = 'Включаю' return { 'type': 'simple', 'text': text, 'voice': voice, } +kinogo_cb = Command.Callback(['$text',]) +kinogo_cb.setStart(start) + patterns = ['* включ* фильм $text', '* включ* фильм*'] -subpatterns = ['$text',] -kinogo = film('KinogoPlayer', {}, patterns, subpatterns) -kinogo.setStart(method) +kinogo = Film('KinogoPlayer', {}, patterns) +kinogo.setStart(main) diff --git a/Media/film.py b/Media/film.py index e32b9a6..c400901 100644 --- a/Media/film.py +++ b/Media/film.py @@ -1,5 +1,5 @@ from Command import Command -class film(Command): +class Film(Command): def start(this, string): # main method pass diff --git a/telegram_bot.py b/telegram_bot.py index 90bcf28..bcb75b7 100644 --- a/telegram_bot.py +++ b/telegram_bot.py @@ -20,6 +20,9 @@ def reply(id, responce): bot.send_message(id, responce['text']) if responce['voice']: bot.send_voice(id, voice.generate(responce['voice']).getBytes() ) + if responce['type'] == 'background': # add background thread to list + responce['thread']['id'] = id + threads.append(responce['thread']) def check_threads(threads): for thread in threads: @@ -34,13 +37,24 @@ def main(id, text): if Command.isRepeat(text): reply(memory[0]['responce']); return - try: cmd, params = memory[0]['cmd'].checkContext(text).values(); params = {**memory[0]['params'], **params} - except: cmd, params = Command.reg_find(text).values() + if memory: + responce = memory[0]['responce'] + if responce['type'] == 'question': + if new_responce := responce['callback'].answer(text): + reply(id, new_responce) + memory.insert(0, { + 'cmd': responce['callback'], + 'params': None, + 'responce': new_responce, + }) + 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() responce = cmd.start(params) reply(id, responce) - if responce['type'] == 'background': # add background thread to list - responce['thread']['id'] = id - threads.append(responce['thread']) memory.insert(0, { 'cmd': cmd, 'params': params, diff --git a/voice_assistant.py b/voice_assistant.py index 5aff301..edef27e 100644 --- a/voice_assistant.py +++ b/voice_assistant.py @@ -33,30 +33,45 @@ def check_threads(): while True: # main loop check_threads() print('\nYou: ', end='') + # input speech = listener.listen() text = speech['text'] if speech['status'] == 'ok': print(text) voids = 0 + # set online add clean input if name in text if name := list(set(config.names) & set(text.split(' '))): online = True text = text.replace(name[0], '').strip() + # recognize and execute command if online: + # repeat last answer if Command.isRepeat(text): reply(memory[0]['responce']); continue + # recognize command with context try: cmd, params = memory[0]['cmd'].checkContext(text).values() - if memory[0].get('params'): - params = {**memory[0].get('params'), **params} + if memory[0].get('params'): params = {**memory[0].get('params'), **params} except: cmd, params = Command.reg_find(text).values() + # execute command responce = cmd.start(params) + # say answer reply(responce) + # waiting answer on question + if responce['type'] == 'question': + print('\nYou: ', end='') + speech = listener.listen() + if speech['status'] == 'ok': + text = speech['text'] + print(text) + if responce:= responce['callback'].answer(text): reply(responce) + # remember the command memory.insert(0, { 'text': text, 'cmd': cmd, - 'responce': responce + 'responce': responce, }) else: if speech['status'] == 'error': print('Отсутсвует подключение к интернету');