Esempio n. 1
0
def main():
    """
    Do initial checks, clear the console and print the assistant logo.

    STEP 1: Clear log file in each assistant fresh start
    STEP 2: Checks for internet connectivity
    STEP 3: Configuare MongoDB, load skills and settings
    STEP 4: Clear console
    """

    # STEP 1
    with open(ROOT_LOG_CONF['handlers']['file']['filename'], 'r+') as f:
        f.truncate(0)

    logging.info('Startup checks..')

    # STEP 2
    if not internet_connectivity_check():
        logging.warning('Skills with internet connection will not work :-(')
        time.sleep(3)

    # STEP 3
    configure_MongoDB(db, settings)

    # STEP 4
    console_manager = ConsoleManager()
    logging.info('Application started')
    console_manager.console_output()

    processor = Processor(settings, db)

    while True:
        processor.run()
Esempio n. 2
0
class TTTEngine:
    """
    Text To Text Engine (TTT)
    """
    def __init__(self):
        self.logger = logging
        self.console_manager = ConsoleManager()

    def recognize_input(self):
        self.logger.info("Waiting for user input.")
        try:
            text_transcript = input('>> ').lower()
            while text_transcript == '':
                self.logger.info("User didn't said something")
                text_transcript = input('>> ').lower()
            return text_transcript
        except EOFError as e:
            logging.error(e)
            return ''

    def assistant_response(self, message):
        """
        Assistant response in voice or/and in text.
        :param message: string
        """
        try:
            if message:
                self.console_manager.console_output(message)
        except RuntimeError as e:
            self.logger.error(
                'Error in assistant response with message {0}'.format(e))
Esempio n. 3
0
 def __init__(self):
     super().__init__()
     self.logger = logging
     self.message_queue = queue.Queue(
         maxsize=5
     )  # Maxsize is the size of the queue / capacity of messages
     self.stop_speaking = False
     self.console_manager = ConsoleManager()
Esempio n. 4
0
class TTTEngine:
    """
    Text To Text Engine (TTT)
    """
    def __init__(self):
        self.logger = logging
        self.console_manager = ConsoleManager()

    def recognize_input(self):
        """
        Recognize input from console and returns transcript if its not empty string.
        """
        try:
            text_transcript = input('>> ').lower()
            while text_transcript == '':
                self.console_manager.console_output(info_log="User didn't said something")
                text_transcript = input('>> ').lower()
            return text_transcript
        except EOFError as e:
            self.console_manager.console_output(error_log='Failed to recognize user input with message: {0}'.format(e))

    def assistant_response(self, message):
        """
        Assistant response in voice or/and in text.
        :param message: string
        """
        try:
            if message:
                self.console_manager.console_output(message)
        except RuntimeError as e:
            self.console_manager.console_output(error_log='Error in assistant response with message: {0}'.format(e))
Esempio n. 5
0
class STTEngine:
    """
    Speech To Text Engine (STT)

    Google API Speech recognition settings
    SpeechRecognition API : https://pypi.org/project/SpeechRecognition/2.1.3
    """

    def __init__(self):
        super().__init__()
        self.recognizer = sr.Recognizer()
        self.microphone = sr.Microphone()
        self.console_manager = ConsoleManager()
        self.console_manager.console_output(info_log="Microphone configured")

    def recognize_input(self, already_activated=False):
        """
        Recognize input from mic and returns transcript if activation tag (assistant name) exist
        """

        while True:
            transcript = self._recognize_speech_from_mic()
            if already_activated or self._activation_name_exist(transcript):
                return transcript

    def _recognize_speech_from_mic(self, ):
        """
        Capture the words from the recorded audio (audio stream --> free text).
        Transcribe speech from recorded from `microphone`.
        """

        with self.microphone as source:
            self.recognizer.adjust_for_ambient_noise(source)
            audio = self.recognizer.listen(source)

        try:
            transcript = self.recognizer.recognize_google(audio).lower()
            self.console_manager.console_output(info_log='User said: {0}'.format(transcript))
        except sr.UnknownValueError:
            # speech was unintelligible
            transcript = ''
            self.console_manager.console_output(info_log='Unable to recognize speech')
        except sr.RequestError:
            # API was unreachable or unresponsive
            transcript = ''
            self.console_manager.console_output(error_log='Google API was unreachable')
        return transcript

    @staticmethod
    def _activation_name_exist(transcript):
        """
        Identifies the assistant name in the input transcript.
        """

        if transcript:
            transcript_words = transcript.split()
            return bool(set(transcript_words).intersection([jarvis.assistant_name]))
        else:
            return False
Esempio n. 6
0
    def __init__(self, settings_):
        self.settings = settings_
        self.input_engine = STTEngine(
            pause_threshold=self.settings.SPEECH_RECOGNITION.get(
                'pause_threshold'),
            energy_theshold=self.settings.SPEECH_RECOGNITION.get(
                'energy_threshold'),
            ambient_duration=self.settings.SPEECH_RECOGNITION.get(
                'ambient_duration'),
            dynamic_energy_threshold=self.settings.SPEECH_RECOGNITION.get(
                'dynamic_energy_threshold'),
            sr=sr) if self.settings.GENERAL_SETTINGS.get(
                'input_mode') == InputMode.VOICE.value else TTTEngine()

        self.console_manager = ConsoleManager(
            log_settings=self.settings.ROOT_LOG_CONF, )
        self.output_engine = TTSEngine(
            console_manager=self.console_manager,
            speech_response_enabled=self.settings.GENERAL_SETTINGS.get(
                'response_in_speech'))
        self.response_creator = ResponseCreator()

        self.skill_analyzer = SkillAnalyzer(
            weight_measure=TfidfVectorizer,
            similarity_measure=cosine_similarity,
            args=self.settings.SKILL_ANALYZER.get('args'),
            skills_=SKILLS,
            sensitivity=self.settings.SKILL_ANALYZER.get('sensitivity'))
class AssistantSkill:
    """
    This class is the parent of all skill classes.
    """
    first_activation = True
    console_manager = ConsoleManager()
    engine = engines.TTSEngine() if GENERAL_SETTINGS.get(
        'response_in_speech') else engines.TTTEngine()

    @classmethod
    def response(cls, text):
        cls.engine.assistant_response(text)

    @classmethod
    def extract_tags(cls, voice_transcript, tags):
        """
        This method identifies the tags from the user transcript for a specific skill.

        e.x
        Let's that the user says "hi jarvis!".
        The skill analyzer will match it with enable_assistant skill which has tags 'hi, hello ..'
        This method will identify the that the enabled word was the 'hi' not the hello.

        :param voice_transcript: string
        :param tags: string
        :return: set
        """
        try:
            transcript_words = voice_transcript.split()
            tags = tags.split(',')
            return set(transcript_words).intersection(tags)
        except Exception as e:
            logging.error("Failed to extract tags with message {0}".format(e))
            return set()
Esempio n. 8
0
    def __init__(self):
        self.input_engine = STTEngine(
            pause_threshold=SPEECH_RECOGNITION['pause_threshold'],
            energy_theshold=SPEECH_RECOGNITION['energy_threshold'],
            ambient_duration=SPEECH_RECOGNITION['ambient_duration'],
            dynamic_energy_threshold=SPEECH_RECOGNITION[
                'dynamic_energy_threshold'],
            sr=sr) if GENERAL_SETTINGS['user_voice_input'] else TTTEngine()

        self.console_manager = ConsoleManager(log_settings=ROOT_LOG_CONF, )
        self.output_engine = TTSEngine(
            console_manager=self.console_manager,
            speech_response_enabled=GENERAL_SETTINGS['response_in_speech'])
        self.response_creator = ResponseCreator()

        self.skill_analyzer = SkillAnalyzer(
            weight_measure=TfidfVectorizer,
            similarity_measure=cosine_similarity,
            args=ANALYZER['args'],
            skills_=SKILLS,
            sensitivity=ANALYZER['sensitivity'])

        self.skill_controller = SkillController(
            settings_=GENERAL_SETTINGS,
            input_engine=self.input_engine,
            analyzer=self.skill_analyzer,
            control_skills=CONTROL_SKILLS,
        )
Esempio n. 9
0
class AssistantSkill:
    """
    This class is the parent of all skill classes.
    """
    first_activation = True
    console_manager = ConsoleManager()

    @classmethod
    def console(cls, text):
        """
        Prints the text only in console and update the console info.
        """
        cls.console_manager.console_output(text)

    @classmethod
    def response(cls, text):
        """
        The mode of the response depends on the output engine:
            - TTT Engine: The response is only in text
            - TTS Engine: The response is in voice and text
        """
        jarvis.output_engine.assistant_response(text)

    @classmethod
    def extract_tags(cls, voice_transcript, tags):
        """
        This method identifies the tags from the user transcript for a specific skill.

        e.x
        Let's that the user says "hi jarvis!".
        The skill analyzer will match it with enable_assistant skill which has tags 'hi, hello ..'
        This method will identify the that the enabled word was the 'hi' not the hello.

        :param voice_transcript: string
        :param tags: string
        :return: set
        """
        try:
            transcript_words = voice_transcript.split()
            tags = tags.split(',')
            return set(transcript_words).intersection(tags)
        except Exception as e:
            cls.console_manager.console_output(
                info_log='Failed to extract tags with message: {0}'.format(e))
            return set()
Esempio n. 10
0
class AssistantSkill:
    first_activation = True
    console_manager = ConsoleManager(
                                     log_settings=ROOT_LOG_CONF,
                                    )
    tts_engine = TTSEngine(
                           console_manager=console_manager,
                           speech_response_enabled=GENERAL_SETTINGS['response_in_speech']
                           )

    @classmethod
    def response(cls, text):
        cls.tts_engine.assistant_response(text)

    @classmethod
    def _extract_tags(cls, voice_transcript, skill_tags):
        transcript_words = voice_transcript.split()
        return set(transcript_words).intersection(skill_tags)
Esempio n. 11
0
    def __init__(self):
        self.input_engine = SPEECH_ENGINES[SPEECH_RECOGNITION['recognizer']]()

        self.console_manager = ConsoleManager(log_settings=ROOT_LOG_CONF, )
        self.output_engine = TTSEngine(
            console_manager=self.console_manager,
            speech_response_enabled=GENERAL_SETTINGS['response_in_speech'])
        self.response_creator = ResponseCreator()

        self.skill_analyzer = SkillAnalyzer(
            weight_measure=TfidfVectorizer,
            similarity_measure=cosine_similarity,
            args=ANALYZER['args'],
            skills_=SKILLS,
            sensitivity=ANALYZER['sensitivity'])

        self.skill_controller = SkillController(
            settings_=GENERAL_SETTINGS,
            input_engine=self.input_engine,
            analyzer=self.skill_analyzer,
            control_skills=CONTROL_SKILLS,
        )
Esempio n. 12
0
def main():
    """
    Do initial checks, clear the console and print the assistant logo.
    """

    console_manager = ConsoleManager()

    console_manager.console_output(info_log='Startup checks..')

    internet_connectivity_check()

    console_manager.console_output(info_log='Application started')

    processor = Processor(console_manager=console_manager, settings_=settings)

    while True:
        processor.run()
Esempio n. 13
0
 def __init__(self):
     self.logger = logging
     self.console_manager = ConsoleManager()
Esempio n. 14
0
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import jarvis
from jarvis.core.console_manager import ConsoleManager

console_manager = ConsoleManager()


def validate_digits_input(message, values_range=None):
    """
    Checks users input to be only numbers else it will be in infinite loop for a right value.
    Extra parameter 'values_range' checks the input to be between a range.
    """
    input_number = None
    while True:
        jarvis.output_engine.assistant_response(message)
        user_input = jarvis.input_engine.recognize_input(
            already_activated=True)
        try:
            input_number = int(user_input)
        except ValueError:
Esempio n. 15
0
class TTSEngine(TTS):
    def __init__(self):
        super().__init__()
        self.logger = logging
        self.message_queue = queue.Queue(
            maxsize=5
        )  # Maxsize is the size of the queue / capacity of messages
        self.stop_speaking = False
        self.console_manager = ConsoleManager()

    def assistant_response(self, message):
        """
        Assistant response in voice.
        :param message: string
        """
        self._insert_into_message_queue(message)
        try:
            speech_tread = threading.Thread(target=self._speech_and_console)
            speech_tread.start()
        except RuntimeError as e:
            self.logger.error(
                'Error in assistant response thread with message {0}'.format(
                    e))

    def _insert_into_message_queue(self, message):
        try:
            self.message_queue.put(message)
        except Exception as e:
            self.logger.error(
                "Unable to insert message to queue with error message: {0}".
                format(e))

    def _speech_and_console(self):
        """
        Speech method translate text batches to speech and print them in the console.
        :param text: string (e.g 'tell me about google')
        """
        try:
            while not self.message_queue.empty():

                cumulative_batch = ''
                message = self.message_queue.get()
                if message:
                    batches = self._create_text_batches(raw_text=message)
                    for batch in batches:
                        self.tts_engine.say(batch)
                        cumulative_batch += batch
                        self.console_manager.console_output(cumulative_batch)
                        self.run_engine()
                        if self.stop_speaking:
                            self.logger.debug('Speech interruption triggered')
                            self.stop_speaking = False
                            break
        except Exception as e:
            self.logger.error(
                "Speech and console error message: {0}".format(e))

    @staticmethod
    def _create_text_batches(raw_text, number_of_words_per_batch=8):
        """
        Splits the user speech message into batches and return a list with the split batches
        :param raw_text: string
        :param number_of_words_per_batch: int
        :return: list
        """
        raw_text = raw_text + ' '
        list_of_batches = []
        total_words = raw_text.count(' ')
        letter_id = 0

        for split in range(0, int(total_words / number_of_words_per_batch)):
            batch = ''
            words_count = 0
            while words_count < number_of_words_per_batch:
                batch += raw_text[letter_id]
                if raw_text[letter_id] == ' ':
                    words_count += 1
                letter_id += 1
            list_of_batches.append(batch)

        if letter_id < len(raw_text):  # Add the rest of word in a batch
            list_of_batches.append(raw_text[letter_id:])
        return list_of_batches
Esempio n. 16
0
 def __init__(self):
     super().__init__()
     self.recognizer = sr.Recognizer()
     self.microphone = sr.Microphone()
     self.console_manager = ConsoleManager()
     self.console_manager.console_output(info_log="Microphone configured")