diff --git a/Jarvis2.py b/Jarvis2.py index b37d890..a86f25c 100755 --- a/Jarvis2.py +++ b/Jarvis2.py @@ -13,7 +13,7 @@ import wikipedia print("Initializing Jarvis....") -MASTER = getpass.getuser() +master = getpass.getuser() engine = pyttsx3.init("nsss") voices = engine.getProperty("voices") @@ -58,11 +58,11 @@ def print_and_speak(text): def wish_me(): hour = datetime.datetime.now().hour if hour < 12: - speak("Good Morning" + MASTER) + speak("Good Morning" + master) elif hour < 18: - speak("Good Afternoon" + MASTER) + speak("Good Afternoon" + master) else: - speak("Good Evening" + MASTER) + speak("Good Evening" + master) # speak("Hey I am Jarvis. How may I help you") @@ -148,7 +148,9 @@ def take_command(): server.close() speak("Email sent!") except Exception: - speak("Sorry Sir! I am unable to send your message at this moment!") + speak( + "Sorry, Sir! I am unable to send your message at this moment!" + ) elif "nothing" in query or "abort" in query or "stop" in query: speak("okay") diff --git a/Jarvis2_4windows.py b/Jarvis2_4windows.py index f2a07cf..5dfef30 100644 --- a/Jarvis2_4windows.py +++ b/Jarvis2_4windows.py @@ -1,200 +1,142 @@ -import datetime -import random -import smtplib -import sys -import webbrowser +import configparser +import os -import pyttsx3 import speech_recognition as sr -import wikipedia -from pygame import mixer - -mixer.init() - -print("Initializing Jarvis....") -MASTER = "Tony Stark" - - -engine = pyttsx3.init('sapi5') # -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) #for male voices -# engine.setProperty('voice', voices[1].id) #for female voice - -""" RATE""" -rate = engine.getProperty('rate') # getting details of current speaking rate -print ("current voice rate is: ",rate) #printing current voice rate -engine.setProperty('rate',170) # setting up new voice rate -engine.runAndWait() - -"""VOLUME""" -volume = engine.getProperty('volume') #getting to know current volume level (min=0 and max=1) -print ("volume level is at : ",volume) #printing current volume level -engine.setProperty('volume',1.0) # setting up volume level between 0 and 1 - -popular_websites = {'google': 'https://www.google.com', - 'youtube': 'https://www.youtube.com', - 'wikipedia': 'https://www.wikipedia.org', - 'amazon': 'https://www.amazon.com'} -search_engines = {'google': 'https://www.google.com', - 'youtube': 'https://www.youtube.com', - 'bing': 'https://www.bing.com'} - -engine = pyttsx3.init("sapi5") -voices = engine.getProperty("voices") -engine.setProperty("voice", voices[0].id) + +from actions import ( + change_rate, + change_voice, + change_volume, + search_engine_selector, + speak, + wish_me, +) +from commands import ( + command_bye, + command_hello, + command_mail, + command_nothing, + command_open, + command_pause_music, + command_play_music, + command_search, + command_stop_music, + command_unpause_music, + command_whatsup, + command_wikipedia, +) + popular_websites = { "google": "https://www.google.com", "youtube": "https://www.youtube.com", "wikipedia": "https://www.wikipedia.org", "amazon": "https://www.amazon.com", - "GitHub": "https://www.github.com", -} -search_engines = { - "google": "https://www.google.com", - "youtube": "https://www.youtube.com", - "bing": "https://www.bing.com", + "github": "https://www.github.com", } +def main(search_engine, take_command, debug): + while True: + query = take_command() + + # logic for executing commands without arguments + phrases = { + "what's up": command_whatsup, + "nothing": command_nothing, + "abort": command_nothing, + "stop": command_nothing, + "hello": command_hello, + "bye": command_bye, + "play music": command_play_music, + "unpause": command_unpause_music, + "pause music": command_pause_music, + "stop music": command_stop_music + } + for phrase, command in phrases.items(): + if phrase in query: + command() + + # logic for executing commands with arguments + if "wikipedia" in query: + command_wikipedia(speak, debug, query) + + elif "open" in query: + command_open( + query, + popular_websites, + debug, + search_engine, + take_command + ) + + elif "search" in query: + command_search(query, search_engine) + + elif "mail" in query: + command_mail(take_command) -def open_url(url): - webbrowser.open(url) - chrome_path = r"open -a /Applications/Google\ Chrome.app %s" - webbrowser.get(chrome_path).open(url) + elif "change rate" in query: + change_rate(query, take_command) + elif "change voice" in query.lower(): + change_voice(query, take_command) -def search(search_query, search_engine): - try: - open_url(f"{search_engines[search_engine]}/search?q={search_query}") - except IndexError: - open_url(f"https://www.google.com/search?q={search_query}") + elif "change volume" in query.lower(): + change_volume(query, take_command) + speak("Next Command! Sir!") -def speak(text): - engine.say(text) - engine.runAndWait() +def run(): + master = config['DEFAULT']['master'] -def wish_me(): - hour = datetime.datetime.now().hour - # print(hour) - if hour >= 0 and hour < 12: - speak("Good Morning" + MASTER) + search_engine = search_engine_selector(config) - elif hour >= 12 and hour < 18: - speak("Good Afternoon" + MASTER) + debug = config['DEFAULT']['debug'] + if debug == "True": + def take_command(): + return input("Command |--> ") else: - speak("Good Evening" + MASTER) - - # speak("Hey I am Jarvis. How may I help you") - - -# This is where our programme begins.... -def take_command(): - r = sr.Recognizer() - with sr.Microphone() as source: - print("Listening....") - r.pause_threshold = 0.5 - audio = r.listen(source) - - query = "" - try: - print("Recognizing....") - query = r.recognize_google(audio, language="en-in") - print("user said: " + query) - - except sr.UnknownValueError: - print("Sorry Could You please try again") - - except Exception as e: - print(e) - print("Say That Again Please") - - return query - - -speak("Initializing Jarvis....") -wish_me() -while True: - query = take_command() - - # logic for executing basic tasks - if "wikipedia" in query.lower(): - speak("Searching wikipedia....") - query = query.replace("wikipedia", "") - results = wikipedia.summary(query, sentences=2) - print(results) - speak(results) - - elif "what's up" in query or "how are you" in query: - st_msgs = [ - "Just doing my thing!", - "I am fine!", - "Nice!", - "I am nice and full of energy", - ] - speak(random.choice(st_msgs)) - - elif "open" in query.lower(): - website = query.replace("open", "").strip().lower() - try: - open_url(popular_websites[website]) - except IndexError: # If the website is unknown - print(f"Unknown website: {website}") - speak(f"Sorry, i don't know the website {website}") - - elif "search" in query.lower(): - search_query = query.split("for")[-1] - search_engine = query.split("for")[0].replace("search", "").strip().lower() - search(search_query, search_engine) - - elif "mail" in query: - speak("Who is the recipient? ") - recipient = take_command() - - if "me" in recipient: + def take_command(): + r = sr.Recognizer() + with sr.Microphone() as source: + print("Listening....") + r.pause_threshold = 0.5 + audio = r.listen(source) + + query = " " try: - speak("What should I say? ") - content = take_command() - - server = smtplib.SMTP("smtp.gmail.com", 587) - server.ehlo() - server.starttls() - server.login("Your_Username", "Your_Password") - server.sendmail("Your_Username", "Recipient_Username", content) - server.close() - speak("Email sent!") - except Exception: - speak("Sorry Sir! I am unable to send your message at this moment!") - - elif "nothing" in query or "abort" in query or "stop" in query: - speak("okay") - speak("Bye Sir, have a good day.") - sys.exit() - - elif "hello" in query: - speak("Hello Sir") - - elif "bye" in query: - speak("Bye Sir, have a good day.") - sys.exit() - - elif "play music" in query: - music_folder = "Your_music_folder_path(absolute_path)" - music = ("music1", "music2", "music3", "music4") - random_music = music_folder + random.choice(music) + ".mp3" - speak("Playing your request") - mixer.music.load(random_music) - mixer.music.play() - - elif "pause music" in query: - mixer.music.pause() - - elif "stop music" in query: - mixer.music.stop() - - elif "unpause" in query: - mixer.music.unpause() - - speak("Next Command! Sir!") + print("Recognizing....") + query = r.recognize_google(audio, language="en-in") + print("user said: " + query) + + except sr.UnknownValueError: + if debug == "True": + print("Sorry Could You please try again") + else: + pass + speak("Sorry Could You please try again") + + except Exception as e: + if debug == "True": + print(e) + print("Say That Again Please") + else: + pass + + return query + + speak(text="Initializing Jarvis....") + wish_me(master) + main(search_engine, take_command, debug) + + +if os.path.isfile('./config.ini'): # Checks if config.ini exists. + config = configparser.ConfigParser() # if exists loads library. + config.read('config.ini') # and also the file. + run() # Then it launches the main program +else: + # if it doesn't exist it drops an error message and exits. + print('You need a config.ini file.') + print('Check the documentation in the Github Repository.') diff --git a/__pycache__/Jarvis2.cpython-37.pyc b/__pycache__/Jarvis2.cpython-37.pyc new file mode 100644 index 0000000..7b0c0c8 Binary files /dev/null and b/__pycache__/Jarvis2.cpython-37.pyc differ diff --git a/__pycache__/Jarvis2_4windows.cpython-37.pyc b/__pycache__/Jarvis2_4windows.cpython-37.pyc new file mode 100644 index 0000000..c7c1026 Binary files /dev/null and b/__pycache__/Jarvis2_4windows.cpython-37.pyc differ diff --git a/__pycache__/actions.cpython-37.pyc b/__pycache__/actions.cpython-37.pyc new file mode 100644 index 0000000..e6259f8 Binary files /dev/null and b/__pycache__/actions.cpython-37.pyc differ diff --git a/__pycache__/commands.cpython-37.pyc b/__pycache__/commands.cpython-37.pyc new file mode 100644 index 0000000..1f8d27a Binary files /dev/null and b/__pycache__/commands.cpython-37.pyc differ diff --git a/__pycache__/gui.cpython-37.pyc b/__pycache__/gui.cpython-37.pyc new file mode 100644 index 0000000..67ff71c Binary files /dev/null and b/__pycache__/gui.cpython-37.pyc differ diff --git a/__pycache__/tkscrolledframe.cpython-37.pyc b/__pycache__/tkscrolledframe.cpython-37.pyc new file mode 100644 index 0000000..d139d4e Binary files /dev/null and b/__pycache__/tkscrolledframe.cpython-37.pyc differ diff --git a/actions.py b/actions.py new file mode 100644 index 0000000..4dea1e3 --- /dev/null +++ b/actions.py @@ -0,0 +1,145 @@ +import configparser +import datetime +import webbrowser + +import pyttsx3 +import requests + + +def search_engine_selector(config): + if config['DEFAULT']['search_engine'] == 'Google': + return "https://www.google.com" + elif config['DEFAULT']['search_engine'] == 'Bing': + return "https://www.bing.com" + elif config['DEFAULT']['search_engine'] == 'DuckDuckGo': + return "https://www.duckduckgo.com" + elif config['DEFAULT']['search_engine'] == 'Youtube': + return "https://www.youtube.com" + else: + # If none of default ones selected triesto fetch https://example.com + # to see if its valid as search engine and if its valid it uses it. + # If not valid it uses Google. + try: + if requests.get( + f"https://{config['DEFAULT']['search_engine'].lower()}.com", + params={'q': 'example'} + ).status_code == 200: + return ( + f"https://{config['DEFAULT']['search_engine'].lower()}.com" + ) + else: + return "https://www.google.com" + except Exception as e: + print(e) + return "https://www.google.com" + + +def open_url(url): + webbrowser.open(url) + chrome_path = r"open -a /Applications/Google\ Chrome.app %s" + webbrowser.get(chrome_path).open(url) + + +def search(search_query, search_engine): + open_url(f"{search_engine}/search?q={search_query}") + + +def speak(text): + engine.say(text) + engine.runAndWait() + + +def wish_me(master): + hour = datetime.datetime.now().hour + # print(hour) + if hour >= 0 and hour < 12: + speak("Good Morning" + master) + + elif hour >= 12 and hour < 18: + speak("Good Afternoon" + master) + + else: + speak("Good Evening" + master) + + # speak("Hey I am Jarvis. How may I help you") + + +def change_rate(query, take_command): + try: + rate = query.split('to')[-1] + engine.setProperty('rate', int(rate)) + speak("¿Do you want to keep this config?") + answer = take_command() + if answer == "yes": + config['DEFAULT']['rate'] = rate + with open('config.ini', 'w') as configfile: + config.write(configfile) + else: + pass + except Exception: + speak("Invalid value. Please try again.") + + +def change_voice(query, take_command): + try: + voice = query.split('to')[-1] + if voice == "male": + engine.setProperty('voice', voices[0].id) + speak("¿Do you want to keep this config?") + if take_command() == "yes": + config['DEFAULT']['voice'] = 'Male' + with open('config.ini', 'w') as configfile: + config.write(configfile) + else: + pass + + elif voice == "female": + engine.setProperty('voice', voices[1].id) + speak("¿Do you want to keep this config?") + answer = take_command() + print(answer) + if answer == "yes": + config['DEFAULT']['voice'] = 'Female' + with open('config.ini', 'w') as configfile: + config.write(configfile) + else: + pass + else: + speak("Invalid value. Please try again.") + except Exception: + speak("Invalid value. Please try again.") + + +def change_volume(query, take_command): + try: + volume = query.split('to')[-1] + engine.setProperty('volume', int(volume)/100) + speak("¿Do you want to keep this config?") + answer = take_command() + if answer == "yes": + config['DEFAULT']['volume'] = volume + with open('config.ini', 'w') as configfile: + config.write(configfile) + else: + pass + except Exception: + speak("Invalid value. Please try again.") + + +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") + +config = configparser.ConfigParser() +config.read('config.ini') + +if config['DEFAULT']['voice'] == 'Male': + engine.setProperty('voice', voices[0].id) +else: + engine.setProperty('voice', voices[1].id) + +try: + engine.setProperty('rate', int(config['DEFAULT']['rate'])) + engine.setProperty('volume', int(config['DEFAULT']['volume'])/100) + +except Exception: + speak("Bad config. Setting up default values") diff --git a/commands.py b/commands.py new file mode 100644 index 0000000..c930b71 --- /dev/null +++ b/commands.py @@ -0,0 +1,115 @@ +import configparser +import random +import smtplib +import sys + +import wikipedia +from pygame import mixer + +from actions import open_url, search, speak + +config = configparser.ConfigParser() # if exists loads library. +config.read('config.ini') + + +def command_wikipedia(debug, query): + speak("Searching wikipedia....") + query = query.replace("wikipedia", "") + results = wikipedia.summary(query, sentences=2) + if debug == "True": + print(results) + else: + pass + speak(results) + + +def command_whatsup(): + st_msgs = [ + "Just doing my thing!", + "I am fine!", + "Nice!", + "I am nice and full of energy", + ] + speak(random.choice(st_msgs)) + + +def command_open(query, popular_websites, debug, search_engine, take_command): + website = query.replace("open", "").strip().lower() + try: + open_url(popular_websites[website]) + except KeyError: # If the website is unknown + if debug == "True": + print(f"Unknown website: {website}") + else: + pass + speak(f"Sorry, i don't know the website {website}") + speak(f"¿Do you want me to search {website} in the web?") + if take_command() == "yes": + search(website, search_engine) + else: + pass + + +def command_search(query, search_engine): + search_query = query.split("for")[-1] + search(search_query, search_engine) + + +def command_mail(take_command): + speak("Who is the recipient? ") + recipient = take_command() + + try: + speak("What should I say? ") + content = take_command() + + email = config['EMAIL'] + server = smtplib.SMTP(email['server'], email['port']) + server.ehlo() + server.starttls() + server.login(email['username'], email['password']) + server.sendmail(email['username'], recipient, content) + server.close() + speak("Email sent!") + except Exception: + speak("Sorry Sir!") + speak("I am unable to send your message at this moment!") + + +def command_nothing(): + speak("okay") + speak("Bye Sir, have a good day.") + sys.exit() + + +def command_hello(): + speak("Hello Sir") + + +def command_bye(): + speak("Bye Sir, have a good day.") + sys.exit() + + +def command_play_music(): + try: + music_folder = config['DEFAULT']['musicPath'] + music = ("music1", "music2", "music3", "music4") + random_music = music_folder + random.choice(music) + ".mp3" + speak("Playing your request") + mixer.music.load(random_music) + mixer.music.play() + except Exception as e: + speak(e) + + +def command_pause_music(): + mixer.music.pause() + + +def command_stop_music(): + mixer.music.stop() + + +def command_unpause_music(): + mixer.music.unpause() diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..2765b59 --- /dev/null +++ b/config.ini @@ -0,0 +1,15 @@ +[DEFAULT] +master = YourName +search_engine = Google +debug = False +musicpath = +voice = Male +rate = 150 +volume = 100 + +[EMAIL] +server = smtp.gmail.com +port = 587 +username = +password = +