|
@@ -0,0 +1,159 @@
|
|
|
+import logging
|
|
|
+import os
|
|
|
+import random
|
|
|
+
|
|
|
+from jinja2 import Template
|
|
|
+
|
|
|
+from core.ConfigurationManager import SettingLoader
|
|
|
+
|
|
|
+
|
|
|
+class NoTemplateException(Exception):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+class MultipleTemplateException(Exception):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+class TemplateFileNotFoundException(Exception):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+class TTSModuleNotFound(Exception):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+class TTSNotInstantiable(Exception):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+class NeuronModule(object):
|
|
|
+ def __init__(self, **kwargs):
|
|
|
+ """
|
|
|
+ Class used by neuron for talking
|
|
|
+ :param kwargs: Same parameter as the Child. Can contain info about the tts to use instead of the
|
|
|
+ default one
|
|
|
+ """
|
|
|
+
|
|
|
+ child_name = self.__class__.__name__
|
|
|
+ logging.debug("NeuronModule called from class %s with parameters: %s" % (child_name, kwargs))
|
|
|
+
|
|
|
+
|
|
|
+ tts = kwargs.get('tts', None)
|
|
|
+ if tts is None:
|
|
|
+
|
|
|
+ self.tts = SettingLoader().get_default_text_to_speech()
|
|
|
+ else:
|
|
|
+ self.tts = tts
|
|
|
+
|
|
|
+
|
|
|
+ self.override_cache = kwargs.get('cache', None)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ self.say_template = kwargs.get('say_template', None)
|
|
|
+
|
|
|
+ self.file_template = kwargs.get('file_template', None)
|
|
|
+
|
|
|
+ def say(self, message):
|
|
|
+ """
|
|
|
+ USe TTS to speak out loud the Message.
|
|
|
+ A message can be a string, a list or a dict
|
|
|
+ If it's a string, simply use the TTS with the message
|
|
|
+ If it's a list, we select randomly a string in the list and give it to the TTS
|
|
|
+ If it's a dict, we use the template given in parameter to create a string that we give to the TTS
|
|
|
+ :param message: Can be a String or a dict
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ logging.debug("NeuronModule Say() called with message: %s" % message)
|
|
|
+
|
|
|
+ tts_message = None
|
|
|
+
|
|
|
+ if isinstance(message, str):
|
|
|
+ print "message is string"
|
|
|
+ tts_message = message
|
|
|
+
|
|
|
+ if isinstance(message, list):
|
|
|
+ print "message is list"
|
|
|
+ tts_message = self._get_message_from_list(message)
|
|
|
+
|
|
|
+ if isinstance(message, dict):
|
|
|
+ print "message is dict"
|
|
|
+ tts_message = self._get_message_from_dict(message)
|
|
|
+
|
|
|
+ if message is not None:
|
|
|
+
|
|
|
+ tts_instance = self._get_tts_instance(self.tts)
|
|
|
+ tts_args = SettingLoader().get_tts_args(self.tts)
|
|
|
+
|
|
|
+ if self.override_cache:
|
|
|
+ tts_args = self._update_cache_var(self.override_cache, tts_args)
|
|
|
+ tts_instance.say(words=tts_message, **(tts_args if tts_args is not None else {}))
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def _get_message_from_list(message_list):
|
|
|
+ """
|
|
|
+ Return an element from the list randomly
|
|
|
+ :param message_list:
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ return random.choice(message_list)
|
|
|
+
|
|
|
+ def _get_message_from_dict(self, message_dict):
|
|
|
+ returned_message = None
|
|
|
+
|
|
|
+ if (self.say_template is not None and self.file_template is None) or \
|
|
|
+ (self.say_template is None and self.file_template is not None):
|
|
|
+
|
|
|
+
|
|
|
+ if self.say_template is not None:
|
|
|
+ if isinstance(self.say_template, list):
|
|
|
+
|
|
|
+ self.say_template = random.choice(self.say_template)
|
|
|
+ t = Template(self.say_template)
|
|
|
+ returned_message = t.render(**message_dict)
|
|
|
+
|
|
|
+
|
|
|
+ if self.file_template is not None:
|
|
|
+ real_file_template_path = "templates/%s" % self.file_template
|
|
|
+ if os.path.isfile(real_file_template_path):
|
|
|
+
|
|
|
+ t = Template(self._get_content_of_file(real_file_template_path))
|
|
|
+ returned_message = t.render(**message_dict)
|
|
|
+ else:
|
|
|
+ raise TemplateFileNotFoundException("Template file %s not found in templates folder"
|
|
|
+ % real_file_template_path)
|
|
|
+ return returned_message
|
|
|
+
|
|
|
+ else:
|
|
|
+ raise NoTemplateException("You must specify a say_template or a file_template")
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def _get_content_of_file(real_file_template_path):
|
|
|
+ with open(real_file_template_path, 'r') as content_file:
|
|
|
+ return content_file.read()
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def _get_tts_instance(tts_name):
|
|
|
+
|
|
|
+ tts = tts_name.capitalize()
|
|
|
+ logging.info("Import TTS module named %s " % tts)
|
|
|
+ mod = __import__('tts', fromlist=[str(tts)])
|
|
|
+ try:
|
|
|
+ klass = getattr(mod, tts)
|
|
|
+ except ImportError, e:
|
|
|
+ raise TTSModuleNotFound("The TTS not found: %s" % e)
|
|
|
+
|
|
|
+ if klass is not None:
|
|
|
+
|
|
|
+ return klass()
|
|
|
+ else:
|
|
|
+ raise TTSNotInstantiable("TTS module %s not instantiable" % tts)
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def _update_cache_var(new_override_cache, args_list):
|
|
|
+ print "args for TTS plugin before update: %s" % str(args_list)
|
|
|
+ args_list["cache"] = new_override_cache
|
|
|
+
|
|
|
+ print "args for TTS plugin after update: %s" % str(args_list)
|
|
|
+ return args_list
|