def test_get_triggers(self): trigger1 = Trigger( name="snowboy", parameters={ 'pmdl_file': 'trigger/snowboy/resources/brain-FR-6samples.pmdl' }) sl = SettingLoader(file_path=self.settings_file_to_test) self.assertEqual([trigger1], sl._get_triggers(self.settings_dict))
def test_get_variables(self): expected_result = { "author": "Lamonf", "test_number": 60, "test": "brain" } sl = SettingLoader(file_path=self.settings_file_to_test) self.assertEqual(expected_result, sl._get_variables(self.settings_dict))
def test_get_resources(self): resources = Resources( neuron_folder="/tmp/brain/tests/brain_resources_dir/neurons", stt_folder="/tmp/brain/tests/brain_resources_dir/stt", tts_folder="/tmp/brain/tests/brain_resources_dir/tts", trigger_folder="/tmp/brain/tests/brain_resources_dir/trigger") expected_resource = resources sl = SettingLoader(file_path=self.settings_file_to_test) self.assertEqual(expected_resource, sl._get_resources(self.settings_dict))
def set_stts(new_stt): """ Add or update the speak to text list defined in the settings. :param new_stt: The new stt instance. """ settings = SettingLoader().settings list_no_duplicate_stt = [ stt for stt in settings.stts if stt.name != new_stt.name ] list_no_duplicate_stt.append(new_stt) settings.stts = list_no_duplicate_stt
def test_get_rest_api(self): expected_rest_api = RestAPI(password_protected=True, active=True, login="******", password="******", port=5000, allowed_cors_origin=False) sl = SettingLoader(file_path=self.settings_file_to_test) self.assertEqual(expected_rest_api, sl._get_rest_api(self.settings_dict))
def set_ttss(new_tts): """ Add a new TTS object in the list of tts in the settings. If TTS already exists in settings, it will be updated with the new tts provided values. :param new_tts: the new TTS object to add in the settings. """ settings = SettingLoader().settings list_no_duplicate_tts = [ tts for tts in settings.ttss if tts.name != new_tts.name ] list_no_duplicate_tts.append(new_tts) settings.ttss = list_no_duplicate_tts
def set_default_player(cls, default_player_name): """ Set dynamically a new default_player in the settings :param default_player_name: string value """ settings = SettingLoader().settings if cls._check_name_in_list_settings_entry(default_player_name, settings.players): settings.default_player_name = default_player_name else: logger.debug( "[Settings] default_player %s is not defined in settings file ", default_player_name)
def set_trigger(new_trigger): """ Update the list of triggers with a new trigger instance. If the trigger name already exists then it will be updated otherwise it will be added. :param new_trigger: the new trigger instance """ settings = SettingLoader().settings list_no_duplicate_triggers = [ trigger for trigger in settings.triggers if trigger.name != new_trigger.name ] list_no_duplicate_triggers.append(new_trigger) settings.triggers = list_no_duplicate_triggers
def set_players(new_player): """ Add a new Player object in the list of players in the settings. If PLayer already exists in settings, it will be updated with the new player provided values. :param new_player: the new PLayer object to add in the settings. """ settings = SettingLoader().settings list_no_duplicate_player = [ player for player in settings.players if player.name != new_player.name ] list_no_duplicate_player.append(new_player) settings.players = list_no_duplicate_player
def test_get_ttss(self): tts1 = Tts(name="pico2wave", parameters={ 'cache': True, 'language': 'fr-FR' }) tts2 = Tts(name="googletts", parameters={ 'language': 'fr', 'cache': True }) sl = SettingLoader(file_path=self.settings_file_to_test) self.assertEqual([tts1, tts2], sl._get_ttss(self.settings_dict))
def set_default_tts(cls, default_tts_name): """ Set dynamically a new default_tts_name in the settings :param default_tts_name: string value """ settings = SettingLoader().settings # Verify that the default name exists in the settings list if cls._check_name_in_list_settings_entry(default_tts_name, settings.ttss): settings.default_tts_name = default_tts_name else: logger.debug( "[SettingsEditor] default_tts %s is not defined in settings file ", default_tts_name)
def test_get_hooks(self): # test with only one hook set settings = dict() settings["hooks"] = {"on_start": "test_synapse"} expected_dict = { "on_start": "test_synapse", "on_waiting_for_trigger": None, "on_triggered": None, "on_start_listening": None, "on_stop_listening": None, "on_order_found": None, "on_order_not_found": None, "on_deaf": None, "on_undeaf": None, "on_mute": None, "on_unmute": None, "on_start_speaking": None, "on_stop_speaking": None } returned_dict = SettingLoader._get_hooks(settings) self.assertEqual(returned_dict, expected_dict) # test with no hook set settings = dict() expected_dict = { "on_start": None, "on_waiting_for_trigger": None, "on_triggered": None, "on_start_listening": None, "on_stop_listening": None, "on_order_found": None, "on_order_not_found": None, "on_deaf": None, "on_undeaf": None, "on_mute": None, "on_unmute": None, "on_start_speaking": None, "on_stop_speaking": None } returned_dict = SettingLoader._get_hooks(settings) self.assertEqual(returned_dict, expected_dict)
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 """ # get the child who called the class child_name = self.__class__.__name__ self.neuron_name = child_name sl = SettingLoader() self.settings = sl.settings brain_loader = BrainLoader() self.brain = brain_loader.brain self.tts = self._get_tts_object(settings=self.settings) # get templates if provided # Check if there is a template associate to the output message self.say_template = kwargs.get('say_template', None) # check if there is a template file associate to the output message self.file_template = kwargs.get('file_template', None) # keep the generated message self.tts_message = None # if the current call is api one self.is_api_call = kwargs.get('is_api_call', False) # boolean to know id the synapse is waiting for an answer self.is_waiting_for_answer = False # the synapse name to add the the buffer self.pending_synapse = None # a dict of parameters the user ask to save in short term memory self.brain_memory = kwargs.get('brain_memory', None) # parameters loaded from the order can be save now Cortex.save_parameter_from_order_in_memory(self.brain_memory)
def create_app(self): """ executed once at the beginning of the test """ # be sure that the singleton haven't been loaded before Singleton._instances = {} current_path = os.getcwd() if "/tests" in os.getcwd(): full_path_brain_to_test = current_path + os.sep + "synapses/brain_test_api.yml" self.audio_file = "files/bonjour.wav" else: full_path_brain_to_test = current_path + os.sep + "tests/synapses/brain_test_api.yml" self.audio_file = "tests/files/bonjour.wav" # rest api config sl = SettingLoader() sl.settings.rest_api.password_protected = False sl.settings.active = True sl.settings.port = 5000 sl.settings.allowed_cors_origin = "*" sl.settings.default_synapse = None sl.settings.hooks["on_order_not_found"] = "order-not-found-synapse" # prepare a test brain brain_to_test = full_path_brain_to_test brain_loader = BrainLoader(file_path=brain_to_test) brain = brain_loader.brain self.app = Flask(__name__) self.app.config['TESTING'] = True self.flask_api = FlaskAPI(self.app, port=5000, brain=brain) self.client = self.app.test_client() return self.flask_api.app
def check_auth(username, password): """This function is called to check if a username / password combination is valid. """ sl = SettingLoader() settings = sl.settings return username == settings.rest_api.login and password == settings.rest_api.password
def set_variables(variables): """ Update the settings variables dictionary. :param variables: The dict of variables with the new values. """ settings = SettingLoader().settings settings.variables.update(variables)
def set_hooks(hooks): """ Update the hooks dictionary defined in the settings with the new dictionary in param. :param hooks: the dictionary containing hooks to update. :type hooks : dict """ settings = SettingLoader().settings settings.hooks.update(hooks)
def decorated(*args, **kwargs): sl = SettingLoader() settings = sl.settings if settings.rest_api.password_protected: auth = request.authorization if not auth or not check_auth(auth.username, auth.password): return authenticate() return f(*args, **kwargs)
def set_energy_threshold(energy_threshold): """ Set the new value of the energy threshold to the settings. Must be an integer. :param energy_threshold: new value for the energy_threshold to push into the settings """ if isinstance(energy_threshold, int): settings = SettingLoader().settings settings.options.energy_threshold = energy_threshold
def set_adjust_for_ambient_noise_second(adjust_for_ambient_noise_second): """ Set a new value for the adjust_for_ambient_noise_second; Must be an integer. :param adjust_for_ambient_noise_second: new value to push to the adjust_for_ambient_noise_second in the Options settings """ if isinstance(adjust_for_ambient_noise_second, int): settings = SettingLoader().settings settings.options.adjust_for_ambient_noise_second = adjust_for_ambient_noise_second
def __init__(self, file_path=None): sl = SettingLoader() self.settings = sl.settings self.file_path = file_path if self.file_path is None: # we don't provide a file path, so search for the default one self.file_path = Utils.get_real_file_path(FILE_NAME) else: self.file_path = Utils.get_real_file_path(file_path) # if the returned file path is none, the file doesn't exist if self.file_path is None: raise BrainNotFound("brain file not found") self.yaml_config = self.get_yaml_config() self.brain = self.load_brain()
def setUp(self): # Init the folders, otherwise it raises an exceptions os.makedirs("/tmp/brain/tests/brain_resources_dir/neurons") os.makedirs("/tmp/brain/tests/brain_resources_dir/stt") os.makedirs("/tmp/brain/tests/brain_resources_dir/tts") os.makedirs("/tmp/brain/tests/brain_resources_dir/trigger") # get current script directory path. We are in /an/unknown/path/brain/core/tests cur_script_directory = os.path.dirname( os.path.abspath(inspect.getfile(inspect.currentframe()))) # get parent dir. Now we are in /an/unknown/path/brain root_dir = os.path.normpath(cur_script_directory + os.sep + os.pardir) self.settings_file_to_test = root_dir + os.sep + "tests/settings/settings_test.yml" self.settings = SettingLoader(file_path=self.settings_file_to_test)
def set_mute_status(mute=False): """ Define is the mute status :param mute: Boolean. If false, Brain.ai is voice is stopped """ logger.debug( "[SettingEditor] mute. Switch trigger process to mute : %s" % mute) settings = SettingLoader().settings if mute: Utils.print_info("Brain.ai now muted, voice has been stopped.") HookManager.on_mute() else: Utils.print_info("Brain.ai now speaking.") HookManager.on_unmute() settings.options.mute = mute
def test_launch_neuron(self): """ Test the Neuron Launcher trying to start a Neuron """ neuron = Neuron(name='neurone1', parameters={'var1': 'val1'}) sl = SettingLoader() resources = Resources(neuron_folder='/var/tmp/test/resources') sl.settings.resources = resources with mock.patch("brain.core.Utils.get_dynamic_class_instantiation" ) as mock_get_class_instantiation: NeuronLauncher.launch_neuron(neuron=neuron) mock_get_class_instantiation.assert_called_once_with( package_name="neurons", module_name=neuron.name, parameters=neuron.parameters, resources_dir=sl.settings.resources.neuron_folder) mock_get_class_instantiation.reset_mock()
def test_get_dynamic_class_instantiation(self): """ Test that an instance as been instantiate properly. """ sl = SettingLoader() sl.settings.resource_dir = '/var/tmp/test/resources' neuron = Neuron( name='Say', parameters={'message': 'test dynamic class instantiate'}) self.assertTrue( isinstance( Utils.get_dynamic_class_instantiation( package_name="neurons", module_name=neuron.name.capitalize(), parameters=neuron.parameters, resources_dir='/var/tmp/test/resources'), Say), "Fail instantiate a class")
def set_deaf_status(trigger_instance, deaf=False): """ Define is the trigger is listening or not. :param trigger_instance: the trigger instance coming from the order. It will be paused or unpaused. :param deaf: Boolean. If true, brain is trigger is paused """ logger.debug( "[MainController] deaf . Switch trigger process to deaf : %s" % deaf) settings = SettingLoader().settings if deaf: trigger_instance.pause() Utils.print_info("Brain.ai now deaf, trigger has been paused") HookManager.on_deaf() else: trigger_instance.unpause() Utils.print_info("Brain.ai now listening for trigger detection") HookManager.on_undeaf() settings.options.deaf = deaf
def __init__(self, **kwargs): """ This class is used to manage community resources. :param kwargs: git-url: the url of the module to clone and install """ super(ResourcesManager, self).__init__() # get settings sl = SettingLoader() self.settings = sl.settings # in case of update or install, url where self.git_url = kwargs.get('git_url', None) # temp path where we install the new module self.tmp_path = tempfile.gettempdir( ) + "/brain/resources/" + TMP_GIT_FOLDER self.dna_file_path = self.tmp_path + os.sep + DNA_FILE_NAME self.install_file_path = self.tmp_path + os.sep + INSTALL_FILE_NAME self.dna = None
def execute_synapses_in_hook_name(cls, hook_name): # need to import SynapseLauncher from here to avoid cross import from brain.core.SynapseLauncher import SynapseLauncher logger.debug("[HookManager] calling synapses in hook name: %s" % hook_name) settings = SettingLoader().settings # list of synapse to execute try: list_synapse = settings.hooks[hook_name] logger.debug("[HookManager] hook: %s , type: %s" % (hook_name, type(list_synapse))) except KeyError: # the hook haven't been set in setting. just skip the execution logger.debug("[HookManager] hook not set: %s" % hook_name) return None if isinstance(list_synapse, str): list_synapse = [list_synapse] return SynapseLauncher.start_synapse_by_list_name(list_synapse, new_lifo=True)
def __init__(self, callback=None, stt=None, audio_file_path=None): """ This class is called after we catch the hotword that has woken up Brain.ai. We now wait for an order spoken out loud by the user, translate the order into a text and run the action attached to this order from settings :param callback: callback function to call :type callback: Callback function :param stt: Speech to text plugin name to load. If not provided, :type stt: STT instance we will load the default one set in settings .. seealso:: STT """ # this is a trick to ignore ALSA output error # see http://stackoverflow.com/questions/7088672/pyaudio-working-but-spits-out-error-messages-each-time super(OrderListener, self).__init__() self.stt = stt self._ignore_stderr() self.stt_module_name = stt self.callback = callback sl = SettingLoader() self.settings = sl.settings self.stt_instance = None self.audio_file_path = audio_file_path
def test_replace_brackets_by_loaded_parameter(self): # ------------------- # test with string # ------------------- # the target value to replace is present in the loaded parameter dict neuron_parameters = {"param1": "this is a value {{ replaced }}"} loaded_parameters = {"replaced": "replaced successfully"} expected_result = {"param1": "this is a value replaced successfully"} self.assertEqual( expected_result, NeuronLauncher._replace_brackets_by_loaded_parameter( neuron_parameters, loaded_parameters)) # the target value with unicode to replace is present in the loaded parameter dict neuron_parameters = {"param1": "this is a value {{ replaced }}"} loaded_parameters = {"replaced": u"rêmpläcée successfülly"} expected_result = {"param1": "this is a value rêmpläcée successfülly"} self.assertEqual( expected_result, NeuronLauncher._replace_brackets_by_loaded_parameter( neuron_parameters, loaded_parameters)) # the target value to replace is NOT present in the loaded parameter dict neuron_parameters = {"param1": "this is a value {{ replaced }}"} loaded_parameters = {"not_exist": "replaced successfully"} with self.assertRaises(NeuronParameterNotAvailable): NeuronLauncher._replace_brackets_by_loaded_parameter( neuron_parameters, loaded_parameters) # one parameter doesn't contains bracket, the other one do neuron_parameters = { "param1": "this is a value {{ replaced }}", "param2": "value" } loaded_parameters = {"replaced": "replaced successfully"} expected_result = { "param1": "this is a value replaced successfully", "param2": "value" } self.assertEqual( expected_result, NeuronLauncher._replace_brackets_by_loaded_parameter( neuron_parameters, loaded_parameters)) # parameters are integer or boolean neuron_parameters = {"param1": 1, "param2": True} loaded_parameters = {"replaced": "replaced successfully"} expected_result = {"param1": 1, "param2": True} self.assertEqual( expected_result, NeuronLauncher._replace_brackets_by_loaded_parameter( neuron_parameters, loaded_parameters)) # parameters are say_template or file template. Should not be altered by the loader neuron_parameters = { "say_template": "{{output}}", "file_template": "here is a file" } loaded_parameters = {"output": "should not be used"} expected_result = { "say_template": "{{output}}", "file_template": "here is a file" } self.assertEqual( expected_result, NeuronLauncher._replace_brackets_by_loaded_parameter( neuron_parameters, loaded_parameters)) # replacing with variable sl = SettingLoader() sl.settings.variables = { "replaced": { "name": u'replaced successfully' } } neuron_parameters = { "param1": "this is a value {{ replaced['name'] }}" } loaded_parameters = {"name": "replaced successfully"} expected_result = {"param1": "this is a value replaced successfully"} self.assertEqual( expected_result, NeuronLauncher._replace_brackets_by_loaded_parameter( neuron_parameters, loaded_parameters)) # the parameter is a reserved key. for example from_answer_link from the neurotransmitter list_reserved_keys = [ "say_template", "file_template", "brain_memory", "from_answer_link" ] for reserved_key in list_reserved_keys: neuron_parameters = { reserved_key: "this is a value with {{ 'brackets '}}" } loaded_parameters = dict() expected_result = { reserved_key: "this is a value with {{ 'brackets '}}" } self.assertEqual( expected_result, NeuronLauncher._replace_brackets_by_loaded_parameter( neuron_parameters, loaded_parameters)) #### # tests with global variables #### # 1/ only one global variable sl = SettingLoader() sl.settings.variables = { "hello": "test", "hello2": "test2", } parameters = {'var1': '{{hello}}'} expected_parameters = {'var1': 'test'} self.assertEqual( expected_parameters, NeuronLauncher._replace_brackets_by_loaded_parameter( parameters, loaded_parameters)) # 2/ global variable with string after sl.settings.variables = { "hello": "test", "hello2": "test2", } parameters = {'var1': '{{hello}} Sispheor'} expected_parameters = {'var1': 'test Sispheor'} self.assertEqual( expected_parameters, NeuronLauncher._replace_brackets_by_loaded_parameter( parameters, loaded_parameters)) # 3/ global variable with int after parameters = {'var1': '{{hello}}0'} sl.settings.variables = { "hello": 60, "hello2": "test2", } expected_parameters = {'var1': '600'} self.assertEqual( expected_parameters, NeuronLauncher._replace_brackets_by_loaded_parameter( parameters, loaded_parameters)) # 4/ multiple global variables parameters = {'var1': '{{hello}} {{me}}'} sl.settings.variables = {"hello": "hello", "me": "LaMonf"} expected_parameters = {'var1': 'hello LaMonf'} self.assertEqual( expected_parameters, NeuronLauncher._replace_brackets_by_loaded_parameter( parameters, loaded_parameters)) # 5/ parameter value is a list parameters = {'var1': '[hello {{name}}, bonjour {{name}}]'} sl.settings.variables = { "name": "LaMonf", "hello2": "test2", } expected_parameters = {'var1': '[hello LaMonf, bonjour LaMonf]'} self.assertEqual( expected_parameters, NeuronLauncher._replace_brackets_by_loaded_parameter( parameters, loaded_parameters)) # 6/ parameter is a dict parameters = { 'random_dict': [{ 'synapse': 'synapse2', 'answers': ['absolument', '{{ name }}'] }, { 'synapse': 'synapse3', 'answers': ['{{ name }}'] }], 'default': 'synapse4' } sl.settings.variables = {"name": "nico"} expected_parameters = { 'random_dict': [{ 'synapse': 'synapse2', 'answers': ['absolument', 'nico'] }, { 'synapse': 'synapse3', 'answers': ['nico'] }], 'default': 'synapse4' } self.assertEqual( expected_parameters, NeuronLauncher._replace_brackets_by_loaded_parameter( parameters, loaded_parameters)) # 7/ parameter is a dict with a restricted word parameters = { 'from_answer_link': [{ 'synapse': 'synapse2', 'answers': ['absolument', '{{ name }}'] }, { 'synapse': 'synapse3', 'answers': ['{{ name }}'] }], 'default': 'synapse4' } sl.settings.variables = {"name": "nico"} expected_parameters = { 'from_answer_link': [{ 'synapse': 'synapse2', 'answers': ['absolument', '{{ name }}'] }, { 'synapse': 'synapse3', 'answers': ['{{ name }}'] }], 'default': 'synapse4' } self.assertEqual( expected_parameters, NeuronLauncher._replace_brackets_by_loaded_parameter( parameters, loaded_parameters))