diff --git a/Jarvis2.py b/Jarvis2.py
index b6736e5..719003c 100755
--- a/Jarvis2.py
+++ b/Jarvis2.py
@@ -15,7 +15,7 @@ import wikipedia
import gui
print("Initializing Jarvis....")
-MASTER = getpass.getuser()
+master = getpass.getuser()
engine = pyttsx3.init("nsss")
voices = engine.getProperty("voices")
@@ -61,11 +61,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")
@@ -180,4 +180,4 @@ def execute_the_command_said_by_user():
gui.set_speak_command(execute_the_command_said_by_user)
-gui.mainloop()
+gui.mainloop()
\ No newline at end of file
diff --git a/Jarvis2_4windows.py b/Jarvis2_4windows.py
index 82d5dac..51443eb 100644
--- a/Jarvis2_4windows.py
+++ b/Jarvis2_4windows.py
@@ -1,49 +1,96 @@
-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
import gui
+
mixer.init()
+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,
+)
-print("Initializing Jarvis....")
-MASTER = "Tony Stark"
-
-engine = pyttsx3.init("sapi5")
-voices = engine.getProperty("voices")
-engine.setProperty("voice", voices[0].id)
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 open_url(url):
- webbrowser.open(url)
- chrome_path = r"open -a /Applications/Google\ Chrome.app %s"
- webbrowser.get(chrome_path).open(url)
+def main(search_engine, take_command, debug):
+ def execute_the_command_said_by_user():
+ 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()
-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}")
+ # 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)
+
+ elif "change rate" in query:
+ change_rate(query, take_command)
+
+ elif "change voice" in query.lower():
+ change_voice(query, take_command)
+
+ elif "change volume" in query.lower():
+ change_volume(query, take_command)
+
+ speak("Next Command! Sir!")
+ gui.set_speak_command(execute_the_command_said_by_user)
+ gui.mainloop()
def speak(text):
@@ -52,132 +99,56 @@ def speak(text):
engine.runAndWait()
-def wish_me():
- hour = datetime.datetime.now().hour
- # print(hour)
- if hour >= 0 and hour < 12:
- speak("Good Morning" + MASTER)
+def run():
+ master = config['DEFAULT']['master']
- elif hour >= 12 and hour < 18:
- speak("Good Afternoon" + MASTER)
+ search_engine = search_engine_selector(config)
+ debug = config['DEFAULT']['debug']
+
+ if debug == "True":
+ def take_command():
+ return input("Command |--> ")
else:
- speak("Good Evening" + MASTER)
+ def take_command():
+ r = sr.Recognizer()
+ with sr.Microphone() as source:
+ print("Listening....")
+ r.pause_threshold = 0.5
+ audio = r.listen(source)
- # 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()
-
-
-def execute_the_command_said_by_user():
- 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:
+ query = " "
try:
- speak("What should I say? ")
- content = take_command()
+ print("Recognizing....")
+ query = r.recognize_google(audio, language="en-in")
+ print("user said: " + query)
- 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!")
+ except sr.UnknownValueError:
+ if debug == "True":
+ print("Sorry Could You please try again")
+ else:
+ pass
+ speak("Sorry Could You please try again")
- elif "nothing" in query or "abort" in query or "stop" in query:
- speak("okay")
- speak("Bye Sir, have a good day.")
- sys.exit()
+ except Exception as e:
+ if debug == "True":
+ print(e)
+ print("Say That Again Please")
+ else:
+ pass
- elif "hello" in query:
- speak("Hello Sir")
+ return query
- 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!")
+ speak(text="Initializing Jarvis....")
+ wish_me(master)
+ main(search_engine, take_command, debug)
-gui.set_speak_command(execute_the_command_said_by_user)
-gui.mainloop()
+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/README.md b/README.md
index 2101d9c..f3d309c 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,17 @@ A Virtual Desktop Assistant Written in Python.
The basic purpose of this is to make work easier as it re-directs you to various main sites and performs various important functions for your PC as well just install it for your system and run it in your code editor or IDE. I will be soon updating it as an application for MacOS, Linux and Windows. Until then you can follow the Contributing Guidelines and Contribute into this Desktop Assistant.
+
+Steps to run the Assistant on your pc------------------(use python 3.9)
+
+Step1. Installing all the necessary python module as mentioned in the requirements.txt file one by one as from the terminal pip install
+ or
+ Install all the required module all at once by using the command pip install -r requirements.txt
+
+Step2. For windows user run Jarvis2_4windows.py script.
+
+Wow All done! Now give the command to jarvis.
+
# Installing :
- Clone the repo to make it available on your local system by using ```git clone ```
@@ -13,6 +24,7 @@ The basic purpose of this is to make work easier as it re-directs you to various
+
# Contributing Guidelines :
- We are Open for Pull Requests
- Please contribute and add value to the code
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 =
+
diff --git a/requirements.txt b/requirements.txt
index 83f9283..ce28810 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,10 @@
+pygame==2.0.1
+pyttsx3==2.90
+SpeechRecognition==3.8.1
+wikipedia==1.4.0
PyAudio==0.2.11
pygame==2.0.1
pyttsx3==2.90
SpeechRecognition==3.8.1
wikipedia==1.4.0
+