brain.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. # -*- coding: utf-8 -*-
  2. from __future__ import division
  3. from .__load__ import *
  4. # 大脑,技能,记忆
  5. class Brain(object):
  6. def init(self, robot):
  7. # vecan机器人
  8. self.robot = robot
  9. # 记忆
  10. self.memory = []
  11. # 询问模式
  12. self.hasPardon = False
  13. # 插件
  14. self.plugins = []
  15. #self.plugins = plugin_loader.get_plugins(self.robot)
  16. self.handling = False
  17. return self
  18. def isImmersive(self, plugin, text, parsed):
  19. return self.robot.getImmersiveMode() == plugin.SLUG and \
  20. plugin.isValidImmersive(text, parsed)
  21. def printPlugins(self):
  22. plugin_list = []
  23. for plugin in self.plugins:
  24. plugin_list.append(plugin.SLUG)
  25. self.robot.logger.info(self.log('已激活插件:{}'.format(plugin_list)))
  26. def query(self, text):
  27. """
  28. query 模块
  29. Arguments:
  30. text -- 用户输入
  31. """
  32. args = {
  33. "service_id": "S13442",
  34. "api_key": 'w5v7gUV3iPGsGntcM84PtOOM',
  35. "secret_key": 'KffXwW6E1alcGplcabcNs63Li6GvvnfL'
  36. }
  37. parsed = self.robot.doParse(text, **args)
  38. print parsed
  39. return parsed
  40. for plugin in self.plugins:
  41. if not plugin.isValid(text, parsed) and not self.isImmersive(plugin, text, parsed):
  42. continue
  43. self.robot.logger.info(self.log("'{}' 命中技能 {}".format(text, plugin.SLUG)))
  44. self.robot.matchPlugin = plugin.SLUG
  45. if plugin.IS_IMMERSIVE:
  46. self.robot.setImmersiveMode(plugin.SLUG)
  47. continueHandle = False
  48. try:
  49. self.handling = True
  50. continueHandle = plugin.handle(text, parsed)
  51. self.handling = False
  52. except Exception:
  53. self.robot.logger.critical('Failed to execute plugin',
  54. exc_info=True)
  55. reply = u"抱歉,插件{}出故障了,晚点再试试吧".format(plugin.SLUG)
  56. self.robot.say(reply, plugin=plugin.SLUG)
  57. else:
  58. self.robot.logger.debug(self.log("Handling of phrase '%s' by " +
  59. "plugin '%s' completed", text,
  60. plugin.SLUG))
  61. finally:
  62. if not continueHandle:
  63. return True
  64. self.robot.logger.debug(self.log("No plugin was able to handle phrase {} ".format(text)))
  65. return False
  66. def restore(self):
  67. """ 恢复某个技能的处理 """
  68. if not self.robot.immersiveMode:
  69. return
  70. for plugin in self.plugins:
  71. if plugin.SLUG == self.robot.immersiveMode and plugin.restore:
  72. plugin.restore()
  73. def pause(self):
  74. """ 暂停某个技能的处理 """
  75. if not self.robot.immersiveMode:
  76. return
  77. for plugin in self.plugins:
  78. if plugin.SLUG == self.robot.immersiveMode and plugin.pause:
  79. plugin.pause()
  80. def understand(self, fp):
  81. if self.robot and self.robot.tool['asr']:
  82. return self.robot.tool['asr'].asr(fp)
  83. return None
  84. def say(self, msg, cache=False):
  85. if self.robot and self.robot.tool['tts']:
  86. self.robot.tool['tts'].tts(msg)
  87. def think(self, query, uid='', onSay=None):
  88. # 统计
  89. #statistic.report(1)
  90. self.robot.stop()
  91. self.addMemory(0, query, uid)
  92. if onSay:
  93. self.onSay = onSay
  94. if query.strip() == '':
  95. self.pardon()
  96. return
  97. lastImmersiveMode = self.robot.immersiveMode
  98. if not self.query(query):
  99. # 没命中技能,使用机器人回复
  100. msg = self.robot.tool['ai'].ai(query)
  101. self.robot.say(msg, True, completed=self.robot.checkRestore)
  102. else:
  103. if lastImmersiveMode is not None and lastImmersiveMode != self.robot.matchPlugin:
  104. time.sleep(1)
  105. if self.checkSpeeker():
  106. self.robot.logger.debug(self.log('等说完再checkRestore'))
  107. self.speaker.appendOnCompleted(lambda: self.checkRestore())
  108. else:
  109. self.robot.logger.debug(self.log('checkRestore'))
  110. self.robot.checkRestore()
  111. def doubt(self, msg):
  112. if Demeter.config['snowboy']['active_mode'] and (msg.endswith('?') or msg.endswith(u'?') or u'告诉我' in msg or u'请回答' in msg):
  113. query = self.robot.ear.listen()
  114. self.think(query)
  115. def pardon(self):
  116. if not self.hasPardon:
  117. self.robot.say('抱歉,刚刚没听清,能再说一遍吗?', completed=lambda: self.response(self.robot.ear.listen()))
  118. self.hasPardon = True
  119. else:
  120. self.robot.say('没听清呢')
  121. self.hasPardon = False
  122. def getMemory(self):
  123. return self.memory
  124. def addMemory(self, t, text, uid=''):
  125. if t in (0, 1) and text != '':
  126. if text.endswith(',') or text.endswith(','):
  127. text = text[:-1]
  128. if uid == '' or uid == None or uid == 'null':
  129. uid = Demeter.uuid(__name__)
  130. # 将图片处理成HTML
  131. pattern = r'https?://.+\.(?:png|jpg|jpeg|bmp|gif|JPG|PNG|JPEG|BMP|GIF)'
  132. url_pattern = r'^https?://.+'
  133. imgs = re.findall(pattern, text)
  134. for img in imgs:
  135. text = text.replace(img, '<img src={} class="img"/>'.format(img))
  136. urls = re.findall(url_pattern, text)
  137. for url in urls:
  138. text = text.replace(url, '<a href={} target="_blank">{}</a>'.format(url, url))
  139. self.memory.append({'type': t, 'text': text, 'time': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), 'uid': uid})
  140. def log(self, text):
  141. return 'Brain:' + text