# -*- coding: utf-8 -*- from __future__ import division from .__load__ import * # 大脑,技能,记忆 class Brain(object): def init(self, robot): # vecan机器人 self.robot = robot # 记忆 self.memory = [] # 询问模式 self.hasPardon = False self.handling = False return self def isImmersive(self, skill, text, parsed): return self.robot.getImmersiveMode() == skill.__name__ and \ skill.matchImmersive(text, parsed) 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__) self.robot.logger.info(self.log('载入技能:{}'.format(loadSkill))) def wakeup(self): self.loadSkill() def query(self, text): args = { "service_id": "S13442", } parsed = self.robot.doParse(text, **args) return parsed for skill in self.skills: if not skill.match(text, parsed) and not self.isImmersive(skill, text, parsed): continue skill.init(self.robot) self.robot.logger.info(self.log("'{}' 命中技能 {}".format(text, skill.__name__))) self.robot.matchskill = skill.__name__ if skill.IS_IMMERSIVE: self.robot.setImmersiveMode(skill.__name__) continueHandle = False try: self.handling = True continueHandle = skill.handle(text, parsed) self.handling = False except Exception: self.robot.logger.critical('Failed to execute skill', exc_info=True) reply = u"抱歉,插件{}出故障了,晚点再试试吧".format(skill.__name__) self.robot.say(reply, skill=skill.__name__) else: self.robot.logger.debug(self.log("Handling of phrase '%s' by " + "skill '%s' completed", text, skill.__name__)) finally: if not continueHandle: return True 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 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 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']: return self.robot.tool['asr'].asr(fp) return None def say(self, msg, cache=False): if self.robot and self.robot.tool['tts']: self.robot.tool['tts'].tts(msg) def think(self, query, uid='', onSay=None): # 统计 #statistic.report(1) self.robot.stop() self.addMemory(0, query, uid) if onSay: self.onSay = onSay if query.strip() == '': self.pardon() return lastImmersiveMode = self.robot.immersiveMode if not self.query(query): # 没命中技能,使用机器人回复 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.matchskill: time.sleep(1) if self.checkSpeeker(): self.robot.logger.debug(self.log('等说完再checkRestore')) self.speaker.appendOnCompleted(lambda: self.checkRestore()) else: 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.think(self.robot.ear.listen())) self.hasPardon = True else: self.robot.say('没听清呢') self.hasPardon = False def getMemory(self): return self.memory def addMemory(self, t, text, uid=''): if t in (0, 1) and text != '': if text.endswith(',') or text.endswith(','): text = text[:-1] if uid == '' or uid == None or uid == 'null': uid = Demeter.uuid(__name__) # 将图片处理成HTML pattern = r'https?://.+\.(?:png|jpg|jpeg|bmp|gif|JPG|PNG|JPEG|BMP|GIF)' url_pattern = r'^https?://.+' imgs = re.findall(pattern, text) for img in imgs: text = text.replace(img, ''.format(img)) urls = re.findall(url_pattern, text) for url in urls: text = text.replace(url, '{}'.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): return 'Brain:' + text