from jinja2 import Template import random import os.path import logging from core.ConfigurationManager.SettingLoader import SettingLoader class NoTemplateException(Exception): pass class MultipleTemplateException(Exception): pass class TemplateFileNotFoundException(Exception): pass class TTSModuleNotFound(Exception): pass class TTSNotInstantiable(Exception): pass class Neurone(object): def __init__(self, name=None, parameters=None): # get the name of the plugin who load Neurone mother class # print self.__class__.__name__ self.name = name self.parameters = parameters # print "Neurone class called with name %s and parameters: %s" % (name, parameters) # get the tts if is specified otherwise use default tts = self.parameters.get('tts', None) if tts is not None: self.tts = tts else: self.tts = SettingLoader().get_default_text_to_speech() # get tts args self.tts_args = SettingLoader().get_tts_args(self.tts) # capitalise for loading module name self.tts = self.tts.capitalize() # load the module self.tts_instance = self._get_tts_instance() def say(self, message, kwargs): # get the tts if is specified otherwise use default tts = kwargs.get('tts', None) if tts is not None: self.tts = tts self.tts_args = SettingLoader().get_tts_args(self.tts) # get if the cache settings is present override_cache = kwargs.get('cache', None) if override_cache is not None: # the user set the "cache var" self.tts_args = self._update_cache_var(override_cache) # check if it's a single message or multiple one if isinstance(message, list): # then we pick randomly one message message = random.choice(message) # Check if there is a template associate to the output message say_template = kwargs.get('say_template', None) # check if there is a template file associate to the output message file_template = kwargs.get('file_template', None) # we check if the user provide a say_template or a file_template, Not both if say_template is not None and file_template is not None: raise MultipleTemplateException("You must provide a say_template or a file_template, not both") # check on of the two option is set if isinstance(message, dict): if (say_template is not None and file_template is None) or \ (say_template is None and file_template is not None): if say_template is not None: # the user choose a say_template option if isinstance(say_template, list): # then we pick randomly one template say_template = random.choice(say_template) t = Template(say_template) message = t.render(**message) if file_template is not None: # the user choose a file_template option real_file_template_path = "templates/%s" % file_template if os.path.isfile(real_file_template_path): # load the content of the file as template t = Template(self._get_content_of_file(real_file_template_path)) message = t.render(**message) else: raise TemplateFileNotFoundException("Template file %s not found in templates folder" % real_file_template_path) else: raise NoTemplateException("You must specify a say_template or a file_template", message.keys()) # here we use the tts to make jarvis talk # the module is imported on fly, depending on the selected tts from settings self.tts_instance.say(words=message, **(self.tts_args if self.tts_args is not None else {})) def _get_tts_instance(self): logging.info("Import TTS module named %s " % self.tts) mod = __import__('tts', fromlist=[str(self.tts)]) try: klass = getattr(mod, self.tts) except ImportError, e: raise TTSModuleNotFound("The TTS not found: %s" % e) if klass is not None: # run the plugin return klass() else: raise TTSNotInstantiable("TTS module %s not instantiable" % self.tts) @staticmethod def _check_file_exist(real_file_template): return os.path.isfile(real_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() def _update_cache_var(self, override_cache): print "args for TTS plugin before update: %s" % str(self.tts_args) self.tts_args["cache"] = override_cache print "args for TTS plugin after update: %s" % str(self.tts_args) return self.tts_args