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()
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))
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()
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))
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
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()
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, )
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()
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)
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, )
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()
def __init__(self): self.logger = logging self.console_manager = ConsoleManager()
# 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:
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
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")