代码拉取完成,页面将自动刷新
同步操作将从 haok2/yiwa 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
# coding: utf8
"""yiwa后台-语音、浏览器、数据库等处理"""
import time
from importlib import import_module
from jieba import lcut, lcut_for_search
from asr.stt import listening, wakeup
from asr.awake import read_keywords
from nlp.comparison import match
from yiwa.browser import create as create_browser
from yiwa.db import DataConveyor
from yiwa.log import Log
from yiwa.settings import HOST, PORT, TIME
logger = Log().logger
ROOT = f"http://{HOST}:{PORT}"
if __name__ == "__main__":
WAKEUP = False
FAILURE = 0
data_conveyor = DataConveyor()
data_conveyor._init()
keywords = read_keywords()
browser = create_browser()
browser.get(ROOT)
def _todo(browser, action: str, param=""):
"""
做action对应的动作
:param browser: 浏览器对象
:param action: 动作路径, 例如: apps.self_discipline.action.encourage
:param param: 动作命令参数名, 例如: '放学写作业'
:return: 无
"""
# 解析action路径
mothed_path = action.split(".")
package_path = ".".join(mothed_path[:-1]) # 包
mothed_name = mothed_path[-1] # 方法
# 执行action
if package_path and mothed_name:
try:
package = import_module(package_path) # 动态导入包
todo = package.__getattribute__(mothed_name) # 获取包中的方法
if param:
todo(browser, param)
else:
todo(browser)
except Exception as e:
logger.error(f"动态执行页面动作失败:{e}")
def _command_filter(command):
"""过滤指令,缩小遍历范围"""
# 相同指令
same_commands = data_conveyor.filter_command(command)
if same_commands:
return same_commands
# 分词匹配指令,有限的硬件资源环境不允许本地NLP
all_commands = data_conveyor.all_command()
def __filter_by_words(_words):
actions = []
for commands, action in all_commands:
for _word in _words:
if _word in commands:
actions.append(action)
return data_conveyor.filter_command_by_actions(set(actions))
# 像似分词 https://cuiqingcai.com/5844.html
cut_words = lcut_for_search(command)
like_commands = __filter_by_words(cut_words)
if like_commands:
return like_commands
# 模糊分词
cut_all_words = lcut(command, cut_all=True)
vague_commands = __filter_by_words(cut_all_words)
if vague_commands:
return vague_commands
# 无匹配
return []
def _exec():
"""执行指令"""
access = False # 成功执行指令
voice2text = listening()
logger.info(f"发出指令>>> {voice2text}")
data_conveyor.stt(voice2text)
if voice2text is None:
return access
for commands, action, appid in _command_filter(voice2text):
found = False # 指令是否已找到
for command in commands.split(","):
if match(voice2text, command):
logger.info(f"指令命中: {command}")
data_conveyor.access(command)
if action.startswith("/"):
# 更新当前所在一级目录
data_conveyor.update_cur_appid(appid)
# 页面访问
browser.get(ROOT + action)
else:
# 页面动作,部分动作带有动态参数
if ":" in action:
# 带参数
_todo(browser, action.split(":")[0], command)
else:
# 不带参数
_todo(browser, action)
data_conveyor.hot(action) # +指令热度
found = True
break
if found:
access = True
break
else:
logger.info("~_~ 指令不匹配")
data_conveyor.info("~_~ 指令不匹配")
return access
while True:
try:
if WAKEUP:
FAILURE = 0 if _exec() else (FAILURE + 1)
else:
word, up = wakeup(keywords)
data_conveyor.stt(word)
if up:
WAKEUP = True
logger.info("^_^ 唤醒成功")
data_conveyor.wakeup()
FAILURE = 0 if _exec() else (FAILURE + 1)
else:
data_conveyor.stt("")
# 10次超时, 睡眠
if FAILURE >= 10:
logger.info("--! 睡眠待命")
data_conveyor.sleep()
WAKEUP = False
FAILURE = 0
except Exception as e:
logger.error(f"接收语音错误,{e}")
data_conveyor.error()
time.sleep(TIME)
browser.close()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。