|
@@ -11,84 +11,84 @@ class Brain(object):
|
|
|
self.memory = []
|
|
|
# 询问模式
|
|
|
self.hasPardon = False
|
|
|
- # 插件
|
|
|
- self.plugins = []
|
|
|
- #self.plugins = plugin_loader.get_plugins(self.robot)
|
|
|
self.handling = False
|
|
|
return self
|
|
|
|
|
|
- def isImmersive(self, plugin, text, parsed):
|
|
|
- return self.robot.getImmersiveMode() == plugin.SLUG and \
|
|
|
- plugin.isValidImmersive(text, parsed)
|
|
|
+ def isImmersive(self, skill, text, parsed):
|
|
|
+ return self.robot.getImmersiveMode() == skill.__name__ and \
|
|
|
+ skill.matchImmersive(text, parsed)
|
|
|
|
|
|
- def wakeup(self):
|
|
|
- plugin_list = []
|
|
|
- for plugin in self.plugins:
|
|
|
- plugin_list.append(plugin.SLUG)
|
|
|
- self.robot.logger.info(self.log('已激活插件:{}'.format(plugin_list)))
|
|
|
+ def loadSkill(self):
|
|
|
+ self.skills = []
|
|
|
+ loadSkill = []
|
|
|
+ locations = [
|
|
|
+ File.path() + 'service/skill',
|
|
|
+ '~/.vecan/skill',
|
|
|
+ ]
|
|
|
+ for skill in Demeter.getPath(locations):
|
|
|
+ skill = getattr(skill, skill.__name__.capitalize())
|
|
|
+ self.skills.append(skill)
|
|
|
+ loadSkill.append(skill.__name__)
|
|
|
|
|
|
- def query(self, text):
|
|
|
- """
|
|
|
- query 模块
|
|
|
+ self.robot.logger.info(self.log('载入技能:{}'.format(loadSkill)))
|
|
|
|
|
|
- Arguments:
|
|
|
- text -- 用户输入
|
|
|
- """
|
|
|
+ def wakeup(self):
|
|
|
+ self.loadSkill()
|
|
|
|
|
|
+ def query(self, text):
|
|
|
args = {
|
|
|
"service_id": "S13442",
|
|
|
- "api_key": 'w5v7gUV3iPGsGntcM84PtOOM',
|
|
|
- "secret_key": 'KffXwW6E1alcGplcabcNs63Li6GvvnfL'
|
|
|
}
|
|
|
parsed = self.robot.doParse(text, **args)
|
|
|
return parsed
|
|
|
|
|
|
- for plugin in self.plugins:
|
|
|
- if not plugin.isValid(text, parsed) and not self.isImmersive(plugin, text, parsed):
|
|
|
+ for skill in self.skills:
|
|
|
+ if not skill.match(text, parsed) and not self.isImmersive(skill, text, parsed):
|
|
|
continue
|
|
|
|
|
|
- self.robot.logger.info(self.log("'{}' 命中技能 {}".format(text, plugin.SLUG)))
|
|
|
- self.robot.matchPlugin = plugin.SLUG
|
|
|
+ skill.init(self.robot)
|
|
|
+ self.robot.logger.info(self.log("'{}' 命中技能 {}".format(text, skill.__name__)))
|
|
|
+ self.robot.matchskill = skill.__name__
|
|
|
|
|
|
- if plugin.IS_IMMERSIVE:
|
|
|
- self.robot.setImmersiveMode(plugin.SLUG)
|
|
|
+ if skill.IS_IMMERSIVE:
|
|
|
+ self.robot.setImmersiveMode(skill.__name__)
|
|
|
|
|
|
continueHandle = False
|
|
|
try:
|
|
|
self.handling = True
|
|
|
- continueHandle = plugin.handle(text, parsed)
|
|
|
+ continueHandle = skill.handle(text, parsed)
|
|
|
self.handling = False
|
|
|
except Exception:
|
|
|
- self.robot.logger.critical('Failed to execute plugin',
|
|
|
+ self.robot.logger.critical('Failed to execute skill',
|
|
|
exc_info=True)
|
|
|
- reply = u"抱歉,插件{}出故障了,晚点再试试吧".format(plugin.SLUG)
|
|
|
- self.robot.say(reply, plugin=plugin.SLUG)
|
|
|
+ reply = u"抱歉,插件{}出故障了,晚点再试试吧".format(skill.__name__)
|
|
|
+ self.robot.say(reply, skill=skill.__name__)
|
|
|
else:
|
|
|
self.robot.logger.debug(self.log("Handling of phrase '%s' by " +
|
|
|
- "plugin '%s' completed", text,
|
|
|
- plugin.SLUG))
|
|
|
+ "skill '%s' completed", text,
|
|
|
+ skill.__name__))
|
|
|
finally:
|
|
|
if not continueHandle:
|
|
|
return True
|
|
|
|
|
|
- self.robot.logger.debug(self.log("No plugin was able to handle phrase {} ".format(text)))
|
|
|
+ self.robot.logger.debug(self.log("No skill was able to handle phrase {} ".format(text)))
|
|
|
return False
|
|
|
|
|
|
+ """ 恢复某个技能的处理 """
|
|
|
def restore(self):
|
|
|
- """ 恢复某个技能的处理 """
|
|
|
if not self.robot.immersiveMode:
|
|
|
return
|
|
|
- for plugin in self.plugins:
|
|
|
- if plugin.SLUG == self.robot.immersiveMode and plugin.restore:
|
|
|
- plugin.restore()
|
|
|
+ for skill in self.skills:
|
|
|
+ if skill.__name__ == self.robot.immersiveMode and skill.restore:
|
|
|
+ skill.restore()
|
|
|
|
|
|
+ """ 暂停某个技能的处理 """
|
|
|
def pause(self):
|
|
|
- """ 暂停某个技能的处理 """
|
|
|
if not self.robot.immersiveMode:
|
|
|
return
|
|
|
- for plugin in self.plugins:
|
|
|
- if plugin.SLUG == self.robot.immersiveMode and plugin.pause:
|
|
|
- plugin.pause()
|
|
|
+ for skill in self.skills:
|
|
|
+ if skill.__name__ == self.robot.immersiveMode and skill.pause:
|
|
|
+ skill.pause()
|
|
|
|
|
|
def understand(self, fp):
|
|
|
if self.robot and self.robot.tool['asr']:
|
|
@@ -119,7 +119,7 @@ class Brain(object):
|
|
|
msg = self.robot.tool['ai'].ai(query)
|
|
|
self.robot.say(msg, True, completed=self.robot.checkRestore)
|
|
|
else:
|
|
|
- if lastImmersiveMode is not None and lastImmersiveMode != self.robot.matchPlugin:
|
|
|
+ if lastImmersiveMode is not None and lastImmersiveMode != self.robot.matchskill:
|
|
|
time.sleep(1)
|
|
|
if self.checkSpeeker():
|
|
|
self.robot.logger.debug(self.log('等说完再checkRestore'))
|
|
@@ -128,11 +128,13 @@ class Brain(object):
|
|
|
self.robot.logger.debug(self.log('checkRestore'))
|
|
|
self.robot.checkRestore()
|
|
|
|
|
|
+ # 询问
|
|
|
def doubt(self, msg):
|
|
|
if Demeter.config['snowboy']['active_mode'] and (msg.endswith('?') or msg.endswith(u'?') or u'告诉我' in msg or u'请回答' in msg):
|
|
|
query = self.robot.ear.listen()
|
|
|
self.think(query)
|
|
|
|
|
|
+ # 没听清
|
|
|
def pardon(self):
|
|
|
if not self.hasPardon:
|
|
|
self.robot.say('抱歉,刚刚没听清,能再说一遍吗?', completed=lambda: self.response(self.robot.ear.listen()))
|
|
@@ -159,6 +161,7 @@ class Brain(object):
|
|
|
urls = re.findall(url_pattern, text)
|
|
|
for url in urls:
|
|
|
text = text.replace(url, '<a href={} target="_blank">{}</a>'.format(url, url))
|
|
|
+ # 后续存入数据库,分为永久记忆、临时记忆、碎片记忆
|
|
|
self.memory.append({'type': t, 'text': text, 'time': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), 'uid': uid})
|
|
|
|
|
|
def log(self, text):
|