def volume(phrase: str = None, level: int = None) -> None: """Controls volume from the numbers received. Defaults to 50%. See Also: SetVolume for Windows: https://rlatour.com/setvol/ Args: phrase: Takes the phrase spoken as an argument. level: Level of volume to which the system has to set. """ if not level: if 'mute' in phrase.lower(): level = 0 elif 'max' in phrase.lower() or 'full' in phrase.lower(): level = 100 else: level = support.extract_nos(input_=phrase, method=int) if level is None: level = env.volume support.flush_screen() if env.macos: os.system(f'osascript -e "set Volume {round((8 * level) / 100)}"') else: os.system(f'SetVol.exe {level}') support.flush_screen() if phrase: speaker.speak(text=f"{random.choice(conversation.acknowledgement)}!")
def listen(timeout: Union[int, float], phrase_limit: Union[int, float], sound: bool = True, stdout: bool = True) -> Union[str, None]: """Function to activate listener, this function will be called by most upcoming functions to listen to user input. Args: timeout: Time in seconds for the overall listener to be active. phrase_limit: Time in seconds for the listener to actively listen to a sound. sound: Flag whether to play the listener indicator sound. Defaults to True unless set to False. stdout: Flag whether to print the listener status on screen. Returns: str: - Returns recognized statement from the microphone. """ with Microphone() as source: try: playsound(sound=indicators.start, block=False) if sound else None sys.stdout.write("\rListener activated...") if stdout else None listened = recognizer.listen(source=source, timeout=timeout, phrase_time_limit=phrase_limit) playsound(sound=indicators.end, block=False) if sound else None support.flush_screen() recognized = recognizer.recognize_google(audio_data=listened) logger.info(recognized) return recognized except (UnknownValueError, RequestError, WaitTimeoutError): return except (ConnectionError, TimeoutError, requests.exceptions.RequestException, requests.exceptions.Timeout) as \ error: logger.error(error)
def sentry_mode() -> NoReturn: """Listens forever and invokes ``initiator()`` when recognized. Stops when ``restart`` table has an entry. See Also: - Gets invoked only when run from Mac-OS older than 10.14. - A regular listener is used to convert audio to text. - The text is then condition matched for wake-up words. - Additional wake words can be passed in a list as an env var ``LEGACY_KEYWORDS``. """ try: while True: sys.stdout.write("\rSentry Mode") if wake_word := listener.listen(timeout=10, phrase_limit=2.5, sound=False, stdout=False): support.flush_screen() if any(word in wake_word.lower() for word in env.legacy_keywords): playsound(sound=indicators.acknowledgement, block=False) if phrase := listener.listen(timeout=env.timeout, phrase_limit=env.phrase_limit, sound=False): initiator(phrase=phrase, should_return=True) speaker.speak(run=True) if flag := support.check_restart(): logger.info(f"Restart condition is set to {flag[0]} by {flag[1]}") if flag[1] == "OFFLINE": stop_processes() for _handler in logger.handlers: if isinstance(_handler, logging.FileHandler): logger.removeHandler(hdlr=_handler) handler = custom_handler() logger.info(f"Switching to {handler.baseFilename}") logger.addHandler(hdlr=handler) shared.processes = start_processes() else: stop_processes(func_name=flag[1]) shared.processes[flag[1]] = start_processes(flag[1])
def save_audio(frames: list, sample_rate: int) -> NoReturn: """Converts audio frames into a recording to store it in a wav file. Args: frames: List of frames. sample_rate: Sample rate. """ recordings_location = os.path.join(os.getcwd(), 'recordings') if not os.path.isdir(recordings_location): os.makedirs(recordings_location) filename = os.path.join(recordings_location, f"{datetime.now().strftime('%B_%d_%Y_%H%M')}.wav") logger.info(f"Saving {len(frames)} audio frames into {filename}") sys.stdout.write(f"\rSaving {len(frames)} audio frames into {filename}") recorded_audio = numpy.concatenate(frames, axis=0).astype(dtype=numpy.int16) soundfile.write(file=filename, data=recorded_audio, samplerate=sample_rate, subtype='PCM_16') support.flush_screen()
def initiator(phrase: str = None, should_return: bool = False) -> None: """When invoked by ``Activator``, checks for the right keyword to wake up and gets into action. Args: phrase: Takes the processed string from ``SentryMode`` as input. should_return: Flag to return the function if nothing is heard. """ if not phrase and should_return: return support.flush_screen() if [ word for word in phrase.lower().split() if word in [ 'morning', 'night', 'afternoon', 'after noon', 'evening', 'goodnight' ] ]: shared.called['time_travel'] = True if (event := support.celebrate()) and 'night' not in phrase.lower(): speaker.speak(text=f'Happy {event}!') if 'night' in phrase.split() or 'goodnight' in phrase.split(): Thread(target=pc_sleep).start() if env.macos else None time_travel() shared.called['time_travel'] = False
def music(phrase: str = None) -> NoReturn: """Scans music directory in the user profile for ``.mp3`` files and plays using default player. Args: phrase: Takes the phrase spoken as an argument. """ sys.stdout.write("\rScanning music files...") get_all_files = (os.path.join( root, f) for root, _, files in os.walk(os.path.join(env.home, "Music")) for f in files) if music_files := [ file for file in get_all_files if os.path.splitext(file)[1] == '.mp3' ]: chosen = random.choice(music_files) if phrase and 'speaker' in phrase: google_home(device=phrase, file=chosen) else: if env.macos: subprocess.call(["open", chosen]) else: os.system(f'start wmplayer "{chosen}"') support.flush_screen() speaker.speak(text=f"Enjoy your music {env.title}!")
def system_vitals() -> None: """Reads system vitals on macOS. See Also: - Jarvis will suggest a reboot if the system uptime is more than 2 days. - If confirmed, invokes `restart <https://thevickypedia.github.io/Jarvis/#jarvis.restart>`__ function. """ output = "" if env.macos: if not env.root_password: speaker.speak( text= f"You haven't provided a root password for me to read system vitals {env.title}! " "Add the root password as an environment variable for me to read." ) return logger.info('Fetching system vitals') cpu_temp, gpu_temp, fan_speed, output = None, None, None, "" # Tested on 10.13, 10.14, 11.6 and 12.3 versions if not shared.hosted_device or not shared.hosted_device.get( 'os_version'): logger.warning( "hosted_device information was not loaded during startup. Reloading now." ) shared.hosted_device = hosted_device_info() if packaging.version.parse(shared.hosted_device.get( 'os_version')) > packaging.version.parse('10.14'): critical_info = [ each.strip() for each in (os.popen( f'echo {env.root_password} | sudo -S powermetrics --samplers smc -i1 -n1' )).read().split('\n') if each != '' ] support.flush_screen() for info in critical_info: if 'CPU die temperature' in info: cpu_temp = info.strip('CPU die temperature: ').replace( ' C', '').strip() if 'GPU die temperature' in info: gpu_temp = info.strip('GPU die temperature: ').replace( ' C', '').strip() if 'Fan' in info: fan_speed = info.strip('Fan: ').replace(' rpm', '').strip() else: fan_speed = subprocess.check_output( f'echo {env.root_password} | sudo -S spindump 1 1 -file /tmp/spindump.txt > /dev/null 2>&1;grep ' f'"Fan speed" /tmp/spindump.txt;sudo rm /tmp/spindump.txt', shell=True).decode('utf-8') if cpu_temp: cpu = f'Your current average CPU temperature is ' \ f'{support.format_nos(input_=temperature.c2f(arg=support.extract_nos(input_=cpu_temp)))}' \ f'\N{DEGREE SIGN}F. ' output += cpu speaker.speak(text=cpu) if gpu_temp: gpu = f'GPU temperature is {support.format_nos(temperature.c2f(support.extract_nos(gpu_temp)))}' \ f'\N{DEGREE SIGN}F. ' output += gpu speaker.speak(text=gpu) if fan_speed: fan = f'Current fan speed is {support.format_nos(support.extract_nos(fan_speed))} RPM. ' output += fan speaker.speak(text=fan) restart_time = datetime.fromtimestamp(psutil.boot_time()) second = (datetime.now() - restart_time).total_seconds() restart_time = datetime.strftime(restart_time, "%A, %B %d, at %I:%M %p") restart_duration = support.time_converter(seconds=second) output += f'Restarted on: {restart_time} - {restart_duration} ago from now.' if shared.called_by_offline: speaker.speak(text=output) return sys.stdout.write(f'\r{output}') speaker.speak( text= f"Your {shared.hosted_device.get('device')} was last booted on {restart_time}. " f"Current boot time is: {restart_duration}.") if second >= 259_200: # 3 days if boot_extreme := re.search('(.*) days', restart_duration): warn = int(boot_extreme.group().replace(' days', '').strip()) speaker.speak( text= f"{env.title}! your {shared.hosted_device.get('device')} has been running for more " f"than {warn} days. You must consider a reboot for better performance. Would you like " f"me to restart it for you {env.title}?", run=True) response = listener.listen(timeout=3, phrase_limit=3) if any(word in response.lower() for word in keywords.ok): logger.info( f'JARVIS::Restarting {shared.hosted_device.get("device")}') restart(ask=False)
pass devices = [] with ThreadPoolExecutor(max_workers=100) as executor: for info in executor.map( ip_scan, range(1, 101) ): # scans host IDs 1 to 255 (eg: 192.168.1.1 to 192.168.1.255) devices.append( info ) # this includes all the NoneType values returned by unassigned host IDs devices = dict( [i for i in devices if i] ) # removes None values and converts list to dictionary of name and ip pair if not device or not file: support.flush_screen() speaker.speak( text= f"You have {len(devices)} devices in your IP range {env.title}! " f"{support.comma_separator(list(devices.keys()))}. You can choose one and ask me to play " f"some music on any of these.") return else: chosen = [ value for key, value in devices.items() if key.lower() in device.lower() ] if not chosen: speaker.speak( text= f"I don't see any matching devices {env.title}!. Let me help you. "
def face_detection() -> None: """Initiates face recognition script and looks for images stored in named directories within ``train`` directory.""" support.flush_screen() train_dir = 'train' os.mkdir(train_dir) if not os.path.isdir(train_dir) else None speaker.speak( text= 'Initializing facial recognition. Please smile at the camera for me.', run=True) sys.stdout.write('\rLooking for faces to recognize.') try: result = Face().face_recognition() except CameraError: support.flush_screen() logger.error('Unable to access the camera.') speaker.speak( text= "I was unable to access the camera. Facial recognition can work only when cameras are " "present and accessible.") return if not result: sys.stdout.write('\rLooking for faces to detect.') speaker.speak( text="No faces were recognized. Switching on to face detection.", run=True) result = Face().face_detection() if not result: sys.stdout.write('\rNo faces were recognized nor detected.') speaker.speak( text= 'No faces were recognized. nor detected. Please check if your camera is working, ' 'and look at the camera when you retry.') return sys.stdout.write( '\rNew face has been detected. Like to give it a name?') speaker.speak( text='I was able to detect a face, but was unable to recognize it.' ) Image.open('cv2_open.jpg').show() speaker.speak( text= "I've taken a photo of you. Preview on your screen. Would you like to give it a name, " "so that I can add it to my database of known list? If you're ready, please tell me a name, " "or simply say exit.", run=True) phrase = listener.listen(timeout=3, phrase_limit=5) if not phrase or 'exit' in phrase or 'quit' in phrase or 'Xzibit' in phrase: os.remove('cv2_open.jpg') speaker.speak(text="I've deleted the image.", run=True) else: phrase = phrase.replace(' ', '_') # creates a named directory if it is not found already if not os.path.exists(f'{train_dir}/{phrase}'): os.makedirs(f'{train_dir}/{phrase}') c_time = datetime.now().strftime("%I_%M_%p") img_name = f"{phrase}_{c_time}.jpg" # adds current time to image name to avoid overwrite os.rename('cv2_open.jpg', img_name) # renames the files shutil.move(src=img_name, dst=f'{train_dir}/{phrase}' ) # move files into named directory within train_dir speaker.speak( text= f"Image has been saved as {img_name}. I will be able to recognize {phrase} in future." ) else: speaker.speak(text=f'Hi {result}! How can I be of service to you?')