Exemple #1
0
    def _generate_audio_file(self):
        """
        Generic method used as a Callback in TTSModule
        """

        # Prepare payload
        payload = self.get_payload()

        headers = {"Content-Type": "application/json", "Accept": "audio/wav"}

        url = "%s/synthesize?voice=%s" % (TTS_URL, self.voice)

        response = requests.post(url,
                                 auth=HTTPBasicAuth(self.username,
                                                    self.password),
                                 headers=headers,
                                 json=payload)

        logger.debug("[Watson TTS] status code: %s" % response.status_code)

        if response.status_code == 200:
            # OK we get the audio we can write the sound file
            FileManager.write_in_file(self.file_path, response.content)
            Utils.print_info(
                "Text to Speech Engine: audio file generated by Watson")
        else:
            logger.debug("[Watson TTS] Fail to get audio. Header: %s" %
                         response.headers)
    def test_create_directory(self):
        """
        Test to create a new directory.
        """
        # set up
        cache_path = "/tmp/brain/tests/testDirectory"
        if os.path.exists(cache_path):
            os.removedirs(cache_path)

        # Test FileManager.create_directory
        FileManager.create_directory(cache_path)
        self.assertTrue(os.path.exists(cache_path),
                        "Fail creating a directory to the path ")

        # Remove the directory
        os.removedirs(cache_path)
Exemple #3
0
    def _get_cache_path(settings):
        """
        Return the path where to store the cache

        :param settings: The YAML settings file
        :type settings: dict
        :return: the path to store the cache
        :rtype: String

        :Example:

            cache_path = cls._get_cache_path(settings)

        .. seealso::
        .. raises:: SettingNotFound, NullSettingException, SettingInvalidException
        .. warnings:: Class Method and Private
        """

        try:
            cache_path = settings["cache_path"]
        except KeyError as e:
            raise SettingNotFound("%s setting not found" % e)

        if cache_path is None:
            raise NullSettingException("cache_path setting cannot be null")

        # test if that path is usable
        if FileManager.is_path_exists_or_creatable(cache_path):
            return cache_path
        else:
            raise SettingInvalidException(
                "The cache_path seems to be invalid: %s" % cache_path)
Exemple #4
0
 def convert_mp3_to_wav(file_path_mp3):
     """ 
     PyAudio, AlsaPlayer, sounddevices  do not support mp3 files 
     MP3 files must be converted to a wave in order to be played
     This function assumes ffmpeg is available on the system
     :param file_path_mp3: the file path to convert from mp3 to wav
     """
     logger.debug("[PlayerModule] Converting mp3 file to wav file: %s" % file_path_mp3)
     fnull = open(os.devnull, 'w')
     # temp file
     tmp_file_wav = file_path_mp3 + ".wav"
     # Convert mp3 to wave
     subprocess.call(['avconv', '-y', '-i', file_path_mp3, tmp_file_wav],
                     stdout=fnull, stderr=fnull)
     # remove the original file
     FileManager.remove_file(file_path_mp3)
     # rename the temp file with the same name as the original file
     os.rename(tmp_file_wav, file_path_mp3)
    def test_write_in_file(self):
        """
        Test to write in file.
        """

        # set up the context
        dir_path = "/tmp/brain/tests/"
        file_name = "test_FileManager_writeInFile"
        file_path = os.path.join(dir_path, file_name)
        in_file_text = "[Brain.ai] Testing the write_in_file method from Utils.FileManager"
        if os.path.exists(file_path):
            os.remove(file_path)
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

        # Test FileManager.write_in_file
        FileManager.write_in_file(file_path=file_path, content=in_file_text)
        with open(file_path, 'r') as content_file:
            content = content_file.read()
            self.assertEqual(content, in_file_text,
                             "Fail writing in the file ")

        if sys.version_info[0] > 2:
            # Test writing of bytes object for python3
            FileManager.write_in_file(file_path=file_path,
                                      content=bytes(in_file_text, 'utf-8'))
            with open(file_path, 'r') as content_file:
                content = content_file.read()
                self.assertEqual(content, in_file_text,
                                 "Fail writing in the file ")

        # Clean up
        if os.path.exists(file_path):
            os.remove(file_path)

        # run into IOError by trying to write something in root
        dir_path = "/root/"
        file_name = "test_FileManager_writeInFile"
        file_path = os.path.join(dir_path, file_name)
        self.assertFalse(
            FileManager.write_in_file(file_path=file_path,
                                      content=in_file_text))
    def test_is_path_exists_or_creatable(self):
        """
        Test the _is_path_exists_or_creatable
        4 scenarii :
            - the file exists and is creatable : return True
            - the file does not exist but is creatable : return True
            - the file exists but is not allowed : return True --> need a review !
            - the file does not exist and is not allowed : return False
        """

        # set up the context
        dir_path = "/tmp/brain/tests/"
        file_name = "test_FileManager_fileIsPathExistsOrCreatable"
        file_path = os.path.join(dir_path, file_name)
        if os.path.exists(file_path):
            os.remove(file_path)
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

        # Test the file exist and creatable : return True
        with open(file_path, "wb") as file_open:
            file_open.write(
                b"[Brain.ai] Test Running the test_is_path_exists_or_creatable method"
            )
            file_open.close()
        self.assertTrue(FileManager.is_path_exists_or_creatable(file_path),
                        "Fail to assert the file exist ")

        # test the file not exist but creatable : return True
        os.remove(file_path)
        self.assertTrue(FileManager.is_path_exists_or_creatable(file_path),
                        "Fail asserting the file does not exist ")

        # test the file exist but not creatable : return True
        # file_exist_not_allowed = "/root/.ssh/known_hosts"
        # self.assertTrue(FileManager.is_path_creatable(file_exist_not_allowed))

        # test the file not exist and not allowed : return False
        not_allowed_root_path = "/root/"
        not_allowed_path = os.path.join(not_allowed_root_path, file_name)
        self.assertFalse(FileManager.is_path_creatable(not_allowed_path),
                         "Fail to assert not accessing this path ")
    def test_remove_file(self):
        """
        Test to remove a file
        """

        # set up the context
        dir_path = "/tmp/brain/tests/"
        file_name = "test_FileManager_fileRemove"
        file_path = os.path.join(dir_path, file_name)
        if os.path.exists(file_path):
            os.remove(file_path)
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

        # Test to remove the file
        # FileManager.remove_file
        with open(file_path, "wb") as file_open:
            file_open.write(b"")
            file_open.close()
        FileManager.remove_file(file_path=file_path)
        self.assertFalse(os.path.exists(file_path), "Fail removing the file")
Exemple #8
0
    def test_is_file_already_in_cache(self):
        """
        Test if file is already stored in cache
        """

        base_cache_path = "/tmp/brain/tests/TTSModule/tests/default/"
        md5_word = "5c186d1e123be2667fb5fd54640e4fd0"
        file_path = os.path.join(base_cache_path,
                                 "5c186d1e123be2667fb5fd54640e4fd0.tts")

        if os.path.isfile(file_path):
            # Remove the file
            FileManager.remove_file(file_path)
        # Create a tmp file
        if not os.path.exists(base_cache_path):
            os.makedirs(base_cache_path)
        tmp_path = os.path.join(base_cache_path, md5_word + ".tts")
        FileManager.write_in_file(
            tmp_path, "[brain-test] test_is_file_already_in_cache")

        # Test true
        self.assertTrue(
            TTSModule._is_file_already_in_cache(
                base_cache_path=base_cache_path, file_path=file_path),
            "Fail retrieving the cached file. The file does not exist but it should !"
        )

        # Remove the tmp file
        FileManager.remove_file(tmp_path)

        # Test False
        self.assertFalse(
            TTSModule._is_file_already_in_cache(
                base_cache_path=base_cache_path, file_path=file_path),
            "Fail asserting that the file does not exist.")
    def test_is_path_creatable(self):
        """
        Test if the path is creatable for the user
        Does the user has the permission to use this path ?
        """

        # set up the context
        dir_path = "/tmp/brain/tests/"
        file_name = "test_FileManager_filePathCreatable"
        file_path = os.path.join(dir_path, file_name)
        if os.path.exists(file_path):
            os.remove(file_path)
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

        # test not allowed : return False
        not_allowed_root_path = "/root/"
        not_allowed_path = os.path.join(not_allowed_root_path, file_name)
        self.assertFalse(FileManager.is_path_creatable(not_allowed_path),
                         "Fail to assert not accessing this path ")
        # test allowed : return True
        self.assertTrue(FileManager.is_path_creatable(file_path))
Exemple #10
0
    def test_generate_and_play(self):
        """
        Test to generate and play sound
        """
        def new_play_audio(TTSModule):
            pass

        words = "brain"

        with mock.patch.object(TTSModule, 'play_audio', new=new_play_audio):
            settings = Settings(cache_path="/tmp/brain/tests")
            self.TTSMod.settings = settings

            # test missing callback
            with self.assertRaises(TtsGenerateAudioFunctionNotFound):
                self.TTSMod.generate_and_play(words=words)

            # Assert Callback is called
            # no Cache
            self.TTSMod.cache = False
            generate_audio_function_from_child = mock.Mock()
            self.TTSMod.generate_and_play(words=words,
                                          generate_audio_function_from_child=
                                          generate_audio_function_from_child)
            generate_audio_function_from_child.assert_called()

            # with cache True but not existing on system
            self.TTSMod.cache = True
            generate_audio_function_from_child = mock.Mock()
            self.TTSMod.generate_and_play(words=words,
                                          generate_audio_function_from_child=
                                          generate_audio_function_from_child)
            generate_audio_function_from_child.assert_called()

            # with cache True and existing on system
            # create tmp file
            tmp_base_path = "/tmp/brain/tests/TTSModule/tests/default/"
            file_path = os.path.join(tmp_base_path,
                                     "5c186d1e123be2667fb5fd54640e4fd0.tts")
            if os.path.isfile(file_path):
                # Remove the file
                FileManager.remove_file(file_path)
            if not os.path.exists(tmp_base_path):
                os.makedirs(tmp_base_path)
            FileManager.write_in_file(file_path,
                                      "[brain-test] test_generate_and_play")
            self.TTSMod.cache = True
            generate_audio_function_from_child = mock.Mock()
            self.TTSMod.generate_and_play(words=words,
                                          generate_audio_function_from_child=
                                          generate_audio_function_from_child)
            generate_audio_function_from_child.assert_not_called()
            # Remove the tmp file
            FileManager.remove_file(file_path)
    def test_file_is_empty(self):
        """
        Test that the file is empty
        """

        # set up the context
        dir_path = "/tmp/brain/tests/"
        file_name = "test_FileManager_fileIsEmpty"
        file_path = os.path.join(dir_path, file_name)
        if os.path.exists(file_path):
            os.remove(file_path)
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

        # Test FileManager.file_is_empty
        with open(file_path, "wb") as file_open:
            file_open.write(b"")
            file_open.close()
        self.assertTrue(FileManager.file_is_empty(file_path=file_path),
                        "Fail matching to verify that file is empty ")

        # Clean up
        if os.path.exists(file_path):
            os.remove(file_path)
 def create_file_manager(self):
     file_manager = FileManager()
     self.assertIsInstance(FileManager, file_manager)
Exemple #13
0
    def __init__(self, app, port=5000, brain=None, allowed_cors_origin=False):
        """

        :param app: Flask API
        :param port: Port to listen
        :param brain: Brain object
        :type brain: Brain
        """
        super(FlaskAPI, self).__init__()
        self.app = app
        self.port = port
        self.brain = brain
        self.allowed_cors_origin = allowed_cors_origin

        # get current settings
        sl = SettingLoader()
        self.settings = sl.settings

        # api_response sent by the Order Analyser when using the /synapses/start/audio URL
        self.api_response = None
        # boolean used to notify the main process that we get the list of returned synapse
        self.order_analyser_return = False

        # configure the upload folder
        app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
        # create the temp folder
        FileManager.create_directory(UPLOAD_FOLDER)

        # Flask configuration remove default Flask behaviour to encode to ASCII
        self.app.url_map.strict_slashes = False
        self.app.config['JSON_AS_ASCII'] = False

        if self.allowed_cors_origin is not False:
            CORS(app,
                 resources={r"/*": {
                     "origins": allowed_cors_origin
                 }},
                 supports_credentials=True)

        # Add routing rules
        self.app.add_url_rule('/',
                              view_func=self.get_main_page,
                              methods=['GET'])

        # Synapses
        self.app.add_url_rule('/synapses',
                              view_func=self.get_synapses,
                              methods=['GET'])
        self.app.add_url_rule('/synapses/<synapse_name>',
                              view_func=self.get_synapse,
                              methods=['GET'])
        self.app.add_url_rule('/synapses/start/id/<synapse_name>',
                              view_func=self.run_synapse_by_name,
                              methods=['POST'])
        self.app.add_url_rule('/synapses/start/order',
                              view_func=self.run_synapse_by_order,
                              methods=['POST'])
        self.app.add_url_rule('/synapses/start/audio',
                              view_func=self.run_synapse_by_audio,
                              methods=['POST'])

        # Life Cycle
        self.app.add_url_rule('/shutdown/',
                              view_func=self.shutdown_server,
                              methods=['POST'])

        # Settings
        self.app.add_url_rule('/settings',
                              view_func=self.get_current_settings,
                              methods=['GET'])
        self.app.add_url_rule('/settings/deaf/',
                              view_func=self.get_deaf,
                              methods=['GET'])
        self.app.add_url_rule('/settings/deaf/',
                              view_func=self.set_deaf,
                              methods=['POST'])
        self.app.add_url_rule('/settings/mute/',
                              view_func=self.get_mute,
                              methods=['GET'])
        self.app.add_url_rule('/settings/mute/',
                              view_func=self.set_mute,
                              methods=['POST'])
        self.app.add_url_rule('/settings/ambient_noise_second/',
                              view_func=self.get_ambient_noise_second,
                              methods=['GET'])
        self.app.add_url_rule(
            '/settings/ambient_noise_second/',
            view_func=self.set_adjust_for_ambient_noise_second,
            methods=['POST'])
        self.app.add_url_rule('/settings/energy_threshold/',
                              view_func=self.get_energy_threshold,
                              methods=['GET'])
        self.app.add_url_rule('/settings/energy_threshold/',
                              view_func=self.set_energy_threshold,
                              methods=['POST'])
        self.app.add_url_rule('/settings/default_tts/',
                              view_func=self.get_default_tts,
                              methods=['GET'])
        self.app.add_url_rule('/settings/default_tts/',
                              view_func=self.set_default_tts,
                              methods=['POST'])
        self.app.add_url_rule('/settings/default_stt/',
                              view_func=self.get_default_stt,
                              methods=['GET'])
        self.app.add_url_rule('/settings/default_stt/',
                              view_func=self.set_default_stt,
                              methods=['POST'])
        self.app.add_url_rule('/settings/default_player/',
                              view_func=self.get_default_player,
                              methods=['GET'])
        self.app.add_url_rule('/settings/default_player/',
                              view_func=self.set_default_player,
                              methods=['POST'])
        self.app.add_url_rule('/settings/default_trigger/',
                              view_func=self.get_default_trigger,
                              methods=['GET'])
        self.app.add_url_rule('/settings/default_trigger/',
                              view_func=self.set_default_trigger,
                              methods=['POST'])
        self.app.add_url_rule('/settings/hooks/',
                              view_func=self.get_hooks,
                              methods=['GET'])
        self.app.add_url_rule('/settings/hooks/',
                              view_func=self.set_hooks,
                              methods=['POST'])
        self.app.add_url_rule('/settings/variables/',
                              view_func=self.get_variables,
                              methods=['GET'])
        self.app.add_url_rule('/settings/variables/',
                              view_func=self.set_variables,
                              methods=['POST'])