diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index a4355df..5ebaebe 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -50,12 +50,15 @@ jobs: ${{ runner.os }}-pip-${{ matrix.python-version }}- ${{ runner.os }}-pip- + - name: Upgrade pip, setuptools, wheel + run: | + python -m pip install --upgrade pip setuptools wheel + - name: Install dependencies run: | - python -m pip install --upgrade pip pip install flake8 pytest pytest-cov black isort mypy # Install project dependencies if requirements.txt exists - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + if [ -f requirements.txt ]; then pip install --prefer-binary -r requirements.txt; fi - name: Code formatting check with Black run: | diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3d0f25c --- /dev/null +++ b/.gitignore @@ -0,0 +1,132 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Project specific +config.py +*.mp3 +*.wav +*.avi +*.mp4 diff --git a/Calculatenumbers.py b/Calculatenumbers.py index 6d0d8dd..0df548a 100644 --- a/Calculatenumbers.py +++ b/Calculatenumbers.py @@ -5,5 +5,3 @@ """ from features.utilities.Calculatenumbers import * # noqa: F401,F403 - - diff --git a/GreetMe.py b/GreetMe.py index de00195..174e5bc 100644 --- a/GreetMe.py +++ b/GreetMe.py @@ -7,16 +7,17 @@ - Uses this module's `datetime.datetime` so tests can patch it. """ -import pyttsx3 import datetime +import pyttsx3 + def Speak(audio: str) -> None: - engine = pyttsx3.init('sapi5') - voices = engine.getProperty('voices') + engine = pyttsx3.init("sapi5") + voices = engine.getProperty("voices") if voices: - engine.setProperty('voice', voices[0].id) - engine.setProperty('rate', 185) + engine.setProperty("voice", voices[0].id) + engine.setProperty("rate", 185) engine.say(audio) engine.runAndWait() @@ -30,6 +31,3 @@ def greetMe() -> None: else: Speak("Good Evening, Master arpit.") Speak("I am Jarvis. How can I help you?") - - - diff --git a/Jarvismain.py b/Jarvismain.py index 2e252a4..3caee85 100644 --- a/Jarvismain.py +++ b/Jarvismain.py @@ -4,5 +4,3 @@ """ from core.Jarvismain import * # noqa: F401,F403 - - diff --git a/TASK_MANAGEMENT_GUIDE.md b/TASK_MANAGEMENT_GUIDE.md new file mode 100644 index 0000000..692c3f2 --- /dev/null +++ b/TASK_MANAGEMENT_GUIDE.md @@ -0,0 +1,190 @@ +# Jarvis Task Management System + +## Overview +The enhanced Task Management System for Jarvis provides comprehensive voice-controlled task organization, tracking, and productivity features. Users can create, manage, and track tasks using natural language voice commands. + +## Features + +### ✅ Core Task Management +- **Add Tasks**: Create tasks with descriptions, deadlines, and priorities +- **Complete Tasks**: Mark tasks as completed via voice commands +- **Delete Tasks**: Remove tasks from the system +- **Search Tasks**: Find tasks by keywords +- **List Tasks**: View tasks by time period (today, week, all) + +### ✅ Advanced Organization +- **Priority Levels**: High, Normal, Low priority tasks +- **Categories**: Organize tasks into custom categories +- **Deadlines**: Natural language deadline parsing +- **Statistics**: Track productivity and completion rates + +### ✅ Smart Features +- **Overdue Detection**: Automatically identify overdue tasks +- **Reminders**: Set custom reminders for tasks +- **Daily Summaries**: Get comprehensive daily task overviews +- **Help System**: Built-in help for all commands + +## Voice Commands + +### Adding Tasks +``` +"Add task: [description]" +"Add urgent task: [description]" +"Create task: [description] by [deadline]" +"New task: [description] at [time]" +``` + +**Examples:** +- "Add task: Buy groceries" +- "Add urgent task: Call mom by 5 PM today" +- "Create task: Submit assignment by Friday" +- "New task: Doctor appointment at 2:30 PM tomorrow" + +### Managing Tasks +``` +"What are my tasks today?" +"Show today's tasks" +"What are my tasks this week?" +"Show this week's tasks" +"List all tasks" +"Show overdue tasks" +``` + +### Completing Tasks +``` +"Mark task completed: [task name]" +"Complete task: [task name]" +"Task completed: [task name]" +"Done with task: [task name]" +"Finish task: [task name]" +``` + +### Task Organization +``` +"Set task priority: [task name] to [high/normal/low]" +"Add task category: [task name] to [category]" +"Show tasks by category: [category]" +"List categories" +``` + +### Searching and Statistics +``` +"Search tasks: [search term]" +"Find task: [search term]" +"Task statistics" +"Task stats" +"Daily summary" +"Task summary" +``` + +### Deleting Tasks +``` +"Delete task: [task name]" +``` + +### Reminders +``` +"Set task reminder: [task name] in [X] minutes" +"What tasks need reminders?" +"Tasks needing reminders" +``` + +### Help +``` +"Task help" +"Help with tasks" +"Task management help" +"How to use tasks" +``` + +## Deadline Formats + +The system supports various natural language deadline formats: + +### Time References +- "today", "tomorrow", "day after tomorrow" +- "this week", "next week", "this weekend" +- "next month", "next year" + +### Weekdays +- "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" +- "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" + +### Specific Times +- "5 PM", "2:30 AM", "8:00 PM" +- "17:30", "14:30" (24-hour format) +- "8am", "5pm" + +### Date Formats +- "12/25", "25/12" (MM/DD or DD/MM) +- "12-25", "25-12" (MM-DD or DD-MM) +- "12.25", "25.12" (MM.DD or DD.MM) + +### Combined Examples +- "by 5 PM today" +- "before Friday" +- "at 2:30 PM tomorrow" +- "on Monday" +- "next week" +- "this weekend" + +## Data Storage + +Tasks are stored in JSON format in `data/tasks.json` with the following structure: + +```json +{ + "id": 1234567890123, + "title": "Task description", + "priority": "high|normal|low", + "deadline": "2024-01-15T17:00:00", + "completed": false, + "created_at": "2024-01-15T10:00:00", + "completed_at": null, + "category": "work", + "reminder_set": true, + "reminder_minutes": 30 +} +``` + +## Integration + +The task management system integrates seamlessly with: +- **Voice Recognition**: All commands work through speech +- **Text-to-Speech**: Responses are spoken back to the user +- **Reminder System**: Tasks can trigger automatic reminders +- **Statistics Tracking**: Productivity insights and completion rates + +## Error Handling + +The system includes comprehensive error handling: +- Input validation for all commands +- Graceful handling of missing tasks +- Clear error messages via voice +- Fallback suggestions for unclear commands + +## Getting Started + +1. **Wake up Jarvis**: Say "Wake up" to start the system +2. **Add your first task**: "Add task: [description]" +3. **Check your tasks**: "What are my tasks today?" +4. **Get help**: "Task help" for a complete command list + +## Tips for Best Results + +1. **Be specific**: Use clear, descriptive task names +2. **Set deadlines**: Include time references for better organization +3. **Use categories**: Group related tasks together +4. **Check regularly**: Use daily summaries to stay on track +5. **Complete tasks**: Mark tasks as done to maintain accurate statistics + +## Troubleshooting + +- **Task not found**: Check the exact spelling of the task name +- **Deadline not recognized**: Try simpler time formats like "5 PM today" +- **No response**: Ensure Jarvis is listening and try again +- **Help needed**: Say "Task help" for command assistance + +--- + +The Task Management System transforms Jarvis into a powerful productivity assistant, helping users stay organized and on track with their daily tasks and goals. diff --git a/__pycache__/Calculatenumbers.cpython-313.pyc b/__pycache__/Calculatenumbers.cpython-313.pyc index a5e9f83..528529d 100644 Binary files a/__pycache__/Calculatenumbers.cpython-313.pyc and b/__pycache__/Calculatenumbers.cpython-313.pyc differ diff --git a/__pycache__/GreetMe.cpython-313.pyc b/__pycache__/GreetMe.cpython-313.pyc index a73b94b..b6fa7c5 100644 Binary files a/__pycache__/GreetMe.cpython-313.pyc and b/__pycache__/GreetMe.cpython-313.pyc differ diff --git a/core/GreetMe.py b/core/GreetMe.py index 8a0e72f..ed29722 100644 --- a/core/GreetMe.py +++ b/core/GreetMe.py @@ -1,28 +1,26 @@ -import pyttsx3 import datetime -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) -rate = engine.setProperty("rate",185) +import pyttsx3 + +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") +engine.setProperty("voice", voices[0].id) +rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() + # *Greet when it started. def greetMe(): hour = int(datetime.datetime.now().hour) - if hour >= 0 and hour<=12: + if hour >= 0 and hour <= 12: Speak("Good Morning, Sir.") - elif hour >= 12 and hour<=18: - Speak("Good Afternoon, Sir.") + elif hour >= 12 and hour <= 18: + Speak("Good Afternoon, Sir.") else: Speak("Good Evening, Master arpit.") - Speak("I am Jarvis. How can I help you?") - - - - - + Speak("I am Jarvis. How can I help you?") diff --git a/core/INTRO.py b/core/INTRO.py index fcdef88..aafa0c2 100644 --- a/core/INTRO.py +++ b/core/INTRO.py @@ -1,15 +1,17 @@ -from tkinter import * -from PIL import Image, ImageTk, ImageSequence import time +from tkinter import * + +import pyautogui import pygame +from PIL import Image, ImageSequence, ImageTk from pygame import mixer -import pyautogui mixer.init() root = Tk() root.geometry("1100x600") + def play_gif(): root.lift() root.attributes("-topmost", True) @@ -19,17 +21,17 @@ def play_gif(): i = 0 mixer.music.load("assets/media/jarvis.mp3") mixer.music.play() - + for img in ImageSequence.Iterator(img): img = img.resize((1100, 600)) img = ImageTk.PhotoImage(img) lbl.config(image=img) root.update() time.sleep(0.05) - + root.quit() - # Exit gracefully without using root.destroy() + # Exit gracefully without using root.destroy() + play_gif() root.mainloop() - diff --git a/core/Jarvismain.py b/core/Jarvismain.py index c0c2cf1..b9fe514 100644 --- a/core/Jarvismain.py +++ b/core/Jarvismain.py @@ -1,57 +1,57 @@ - -#? install all library use in this by cd "pip install _______" -import pyttsx3 -import speech_recognition as sr +# ? install all library use in this by cd "pip install _______" import datetime -import webbrowser -import cv2 import os -import requests import random -import time +import re +import subprocess import sys +import time +import webbrowser +from os import startfile + +import cv2 +import numpy import pyautogui -import speedtest +import pygame +import pyttsx3 import requests -import numpy -import subprocess -from os import startfile +import speech_recognition as sr +import speedtest from bs4 import BeautifulSoup -from plyer import notification from nltk.chat.util import Chat, reflections -from requests import get +from plyer import notification from pygame import mixer from pywikihow import RandomHowTo, search_wikihow -import pygame +from requests import get + +from core.GreetMe import greetMe +from features.communication.sendemail import * from features.communication.Whatsapp import sendMessage -from features.utilities.battery import check_battery +from features.communication.Whatsappmessage import sendwhatsapp +from features.entertainment.game import game_play from features.entertainment.joke import jokes +from features.entertainment.NewsRead import latestnews +from features.search.SearchNow import (searchGoogle, searchwikipedia, + searchyoutube) from features.system.battery import battery +from features.system.Dictapp import * # All system functions +from features.system.keyboard import volumedown, volumeup +from features.utilities.battery import check_battery +from features.utilities.Calculatenumbers import Calc, WolfRamAlpha from features.utilities.FocusGraph import focus_graph -from features.utilities.task_manager import ( - add_task, - list_tasks, - overdue_tasks, - mark_completed, - set_priority, - summary_text, -) -from features.entertainment.game import game_play -from features.search.SearchNow import searchGoogle, searchyoutube, searchwikipedia -from features.utilities.Translator import translategl from features.utilities.Location import My_Location -from features.utilities.Calculatenumbers import WolfRamAlpha, Calc -from features.system.Dictapp import * # All system functions -from features.system.keyboard import volumeup, volumedown -from features.communication.sendemail import * -from features.utilities.sendcall import send_call from features.utilities.reminder import remindme -from features.communication.Whatsappmessage import sendwhatsapp -from features.entertainment.NewsRead import latestnews -from core.GreetMe import greetMe +from features.utilities.sendcall import send_call +from features.utilities.task_manager import (add_task, add_category, delete_task, + format_statistics, get_all_tasks, + get_categories, get_daily_task_summary, + get_task_help, get_task_statistics, + get_tasks_by_category, get_tasks_needing_reminders, + list_tasks, mark_completed, overdue_tasks, + search_tasks, set_priority, set_task_reminder, + summary_text) +from features.utilities.Translator import translategl -import sys -import os project_root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(project_root_dir) # Add feature subdirectories to Python path for dynamic imports used below @@ -59,7 +59,7 @@ for sub in ["communication", "utilities", "entertainment", "system", "search"]: sys.path.insert(0, os.path.join(features_dir, sub)) #! If you want to use password then comment out - + # # Paste this just below your import files # for i in range(3): # a = input("Enter Password to open Jarvis :- ") @@ -68,7 +68,7 @@ # pw_file.close() # if (a==pw): # print("WELCOME SIR ! PLZ SPEAK [WAKE UP] TO LOAD ME UP") - + # break # elif (i==2 and a!=pw): # exit() @@ -77,62 +77,74 @@ # print("Try Again") -#& Initialize the text-to-speech engine using the 'sapi5' speech API. -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') # Available voice in you system. -engine.setProperty('voice', voices[0].id) # Set the voice property to the first voice in the list. -rate = engine.setProperty("rate",185) # Set the speech rate to 185. Higher values will increase the speech rate. +# & Initialize the text-to-speech engine using the 'sapi5' speech API. +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") # Available voice in you system. +engine.setProperty( + "voice", voices[0].id +) # Set the voice property to the first voice in the list. +rate = engine.setProperty( + "rate", 185 +) # Set the speech rate to 185. Higher values will increase the speech rate. + -#* Function to speak the provided audio using pyttsx3 text-to-speech engine. +# * Function to speak the provided audio using pyttsx3 text-to-speech engine. def Speak(audio): engine.say(audio) engine.runAndWait() + # Initialize a boolean variable 'is_paused' and set it to False is_paused = False -#^ For taking all commands and listen the user voices. + +# ^ For taking all commands and listen the user voices. def TakeCommand(): r = sr.Recognizer() with sr.Microphone() as source: print("Listening...") - r.pause_threshold = 1 # Set the pause threshold to 1 second. + r.pause_threshold = 1 # Set the pause threshold to 1 second. # r.energy_threshold = 200 - audio = r.listen(source,0,4) # Listen to the audio from the microphone, with optional timeout of 4 seconds. + audio = r.listen( + source, 0, 4 + ) # Listen to the audio from the microphone, with optional timeout of 4 seconds. try: - print("Understanding...") - query = r.recognize_google(audio, language='en-in') #* Recognize the speech using Google's speech recognition API. + print("Understanding...") + query = r.recognize_google( + audio, language="en-in" + ) # * Recognize the speech using Google's speech recognition API. print(f"Master said: {query}\n") except Exception as e: - print("Say that again please...") + print("Say that again please...") return "None" - return query # Return the recognized speech as the output of the function. + return query # Return the recognized speech as the output of the function. -#? Dictionary to store contact information with names as keys and phone numbers as values. +# ? Dictionary to store contact information with names as keys and phone numbers as values. contact_dict = { "Name": "PHONE_NUMBER", # Add more contacts as needed. } -#// To run alarm.py we use this. + +# // To run alarm.py we use this. def alarm(query): - timehere = open("data/Alarmtext.txt","a") + timehere = open("data/Alarmtext.txt", "a") timehere.write(query) timehere.close() os.startfile("features/utilities/alarm.py") -#// For exit Greeting. -goodbyes = ['You are great!', 'Thanks for using me!', 'Nice meeting with you!'] + +# // For exit Greeting. +goodbyes = ["You are great!", "Thanks for using me!", "Nice meeting with you!"] pygame.init() pygame.mixer.init() coin_sound = pygame.mixer.Sound("assets/media/coin.mp3") - #############################################################################################################^ save_path = "screenshots/Lock Screen photos" @@ -144,13 +156,13 @@ def alarm(query): # cascadePath = "haarcascade_frontalface_default.xml" # faceCascade = cv2.CascadeClassifier(cascadePath) #initializing haar cascade for object detection approach -font = cv2.FONT_HERSHEY_SIMPLEX #denotes the font type +font = cv2.FONT_HERSHEY_SIMPLEX # denotes the font type -id = 2 #number of persons you want to Recognize +id = 2 # number of persons you want to Recognize -names = ['','arpit','raja'] #names, leave first empty bcz counter starts from 0 +names = ["", "arpit", "raja"] # names, leave first empty bcz counter starts from 0 # Camera initialization commented out for testing # cam = cv2.VideoCapture(0, cv2.CAP_DSHOW) #cv2.CAP_DSHOW to remove warning @@ -246,7 +258,7 @@ def alarm(query): exit() """ - + # Do a bit of cleanup print("Face Recognization Succesfull") Speak("Face Recognization Succesfull") @@ -257,67 +269,95 @@ def alarm(query): ########################################################################################################^ subprocess.Popen(["python", "intro.py"], shell=True) -time.sleep(17) #!HERE YOU TYPE SECONDS THAT HAVE BEEN TAKEN TO COMPLETE GIF -pyautogui.hotkey('Alt','f4') +time.sleep(17) #!HERE YOU TYPE SECONDS THAT HAVE BEEN TAKEN TO COMPLETE GIF +pyautogui.hotkey("Alt", "f4") -if __name__ == "__main__": -#! For Executing all tasks. +if __name__ == "__main__": + #! For Executing all tasks. while True: query = TakeCommand().lower() - #* To Wake up Jarvis. - if "wake up" in query or "start" in query or "makeup" in query or "breakup"in query: + # * To Wake up Jarvis. + if ( + "wake up" in query + or "start" in query + or "makeup" in query + or "breakup" in query + ): from GreetMe import greetMe + greetMe() - #* We will use again while True to pause and play jarvis. + # * We will use again while True to pause and play jarvis. while True: - query= TakeCommand().lower() + query = TakeCommand().lower() # Set the path to the Chrome executable # Which browser you want to use to execute you can use here. - chrome_path = 'C:/Program Files/Google/Chrome/Application/chrome.exe' + chrome_path = "C:/Program Files/Google/Chrome/Application/chrome.exe" # Configure the web browser to use. - webbrowser.register('chrome', None, webbrowser.BackgroundBrowser(chrome_path)) - + webbrowser.register( + "chrome", None, webbrowser.BackgroundBrowser(chrome_path) + ) - #* To Pause the jarvis we will use it. + # * To Pause the jarvis we will use it. if "go to sleep" in query: Speak("Ok sir, you can call me anytime.") break elif "translate" in query: from Translator import translategl - query = query.replace("jarvis translate","") - query = query.replace("translate","") + + query = query.replace("jarvis translate", "") + query = query.replace("translate", "") translategl(query) elif "joke" in query: from joke import jokes + jokes() - + #####################################################! elif "change password" in query: Speak("What's the new password") new_pw = input("Enter the new password\n") - new_password = open("data/password.txt","w") + new_password = open("data/password.txt", "w") new_password.write(new_pw) new_password.close() Speak("Done sir") Speak(f"Your new password is{new_pw}") ######################################################! - #^ Normal Conversation. - elif "hello" in query or "yo" in query or "hey there" in query or "hey" in query or "hi " in query or "hi" in query or "hello arvis" in query or "hi arpit" in query or "hlo" in query or "ram ram" in query or "good morning" in query: + # ^ Normal Conversation. + elif ( + "hello" in query + or "yo" in query + or "hey there" in query + or "hey" in query + or "hi " in query + or "hi" in query + or "hello arvis" in query + or "hi arpit" in query + or "hlo" in query + or "ram ram" in query + or "good morning" in query + ): Speak("Hello sir, How are you!") elif "i am fine" in query: Speak("Great! What about yourself?") - elif "how are you" in query or "how r you" in query or "how r u" in query: + elif ( + "how are you" in query or "how r you" in query or "how r u" in query + ): Speak("Perfect sir!") - elif 'namaste' in query or "ram ram" in query: + elif "namaste" in query or "ram ram" in query: Speak("ram ram, Master!") elif "kaise ho" in query or "tum ho kaise" in query: Speak("I am good, thanks for asking!") - elif "Flip a coin" in query or "coin flip" in query or "toss a coin" in query or "toss" in query: + elif ( + "Flip a coin" in query + or "coin flip" in query + or "toss a coin" in query + or "toss" in query + ): outcome = random.choice(["head", "tail"]) # Speak(random.choice(["head", "tail"])) @@ -327,106 +367,136 @@ def alarm(query): coin_sound.play() print(f"The coin landed on {outcome}!") Speak(f"The coin landed on {outcome}!") - elif "thanks" in query or "thank" in query or "thank you" in query or "thanks bro" in query: + elif ( + "thanks" in query + or "thank" in query + or "thank you" in query + or "thanks bro" in query + ): Speak("My pleasure.") elif "you are great" in query: Speak("Thank You!, for your compliment.") - elif "Gm" in query or "good morning" in query or "morning" in query or "subhprabhat" in query: + elif ( + "Gm" in query + or "good morning" in query + or "morning" in query + or "subhprabhat" in query + ): Speak("Good Morning Sir!") elif "good evening" in query or "evening" in query: Speak("Good Evening Sir!") - elif "Good afternoon" in query or "noon" in query or "good afternoon" in query: + elif ( + "Good afternoon" in query + or "noon" in query + or "good afternoon" in query + ): Speak("Good Afternoon Sir!") elif "feeling sleepy" in query or "good night" in query: Speak("Ok sir, if you want to close then speak [exit]") elif "hate" in query: Speak("I'm sorry you have been hurt.") elif "you are lying" in query or "lie" in query: - Speak("Please correct me if i am wrong!, if you can't do then go and correct yourself") + Speak( + "Please correct me if i am wrong!, if you can't do then go and correct yourself" + ) elif "tumhe kisne banaya" in query or "who made you" in query: Speak("The Great Mater Arpit Garg had made me!") elif "fine" in query: Speak("Great!, How may I assist?") elif "good" in query: - Speak("Thanks!. It's always nice talking with people who care about their health :) ") + Speak( + "Thanks!. It's always nice talking with people who care about their health :) " + ) #! By this Function be can know our battery percentage. elif "battery" in query: from battery import battery + battery() #! To Remember jarvis anything. elif "remember that" in query: - rememberMessage = query.replace("remember that","") - rememberMessage = query.replace("jarvis","") - Speak("You told me to"+rememberMessage) - remember = open("data/Remember.txt","a") + rememberMessage = query.replace("remember that", "") + rememberMessage = query.replace("jarvis", "") + Speak("You told me to" + rememberMessage) + remember = open("data/Remember.txt", "a") remember.write(rememberMessage) remember.close() elif "what do you remember" in query: - remember = open("data/Remember.txt","r") - Speak("You told me to" + remember.read()) + remember = open("data/Remember.txt", "r") + Speak("You told me to" + remember.read()) - #*Focus Mode Function. + # *Focus Mode Function. elif "focus mode" in query: - a = int(input("Are you sure that you want to enter focus mode :- [1 for YES / 2 for NO ")) - if (a==1): + a = int( + input( + "Are you sure that you want to enter focus mode :- [1 for YES / 2 for NO " + ) + ) + if a == 1: Speak("Entering the focus mode....") os.startfile("FocusMode.py") exit() else: pass - + elif "show my focus" in query: from FocusGraph import focus_graph + focus_graph() elif "open game" in query: from game import game_play - game_play() - #^ Playing playlist from youtube. - elif 'play playlist' in query: + game_play() + + # ^ Playing playlist from youtube. + elif "play playlist" in query: url = "https://www.youtube.com/watch?v=DbiRVNeZPnw&list=PLpmsNGoQrkhF1nNjDVXAcyVsNnLOdw_1h&pp=gAQBiAQB8AUB" Speak("Music playing...") - webbrowser.get('chrome').open(url) + webbrowser.get("chrome").open(url) print("Music playing...") - elif 'our channel' in query: + elif "our channel" in query: url = "https://www.youtube.com/channel/UCAi-EONczHNaAqr_Ff3HRsA" Speak("Channel opening...") - webbrowser.get('chrome').open(url) + webbrowser.get("chrome").open(url) print("Channel opening...") - elif 'youtube audio library' in query: + elif "youtube audio library" in query: url = "https://studio.youtube.com/channel/UCAi-EONczHNaAqr_Ff3HRsA/music" Speak("opening audio library...") - webbrowser.get('chrome').open(url) + webbrowser.get("chrome").open(url) print("opening audio library...") - #& Finding you current location. - elif 'my location' in query or 'where i am' in query: + # & Finding you current location. + elif "my location" in query or "where i am" in query: from Location import My_Location + My_Location() - #^ To reaching any website or page. + # ^ To reaching any website or page. elif "google" in query: import wikipedia as googlescrap - query = query.replace("jarvis","") - query = query.replace("google search","") - query = query.replace("google","") + + query = query.replace("jarvis", "") + query = query.replace("google search", "") + query = query.replace("google", "") from SearchNow import searchGoogle + searchGoogle(query) elif "youtube" in query: from SearchNow import searchyoutube + searchyoutube(query) - + elif "wikipedia" in query: from SearchNow import searchwikipedia + searchwikipedia(query) - #& Youtube Running Shortcuts. + # & Youtube Running Shortcuts. elif "full screen mode" in query: pyautogui.press("f") print("video played in full screen") @@ -449,167 +519,198 @@ def alarm(query): pyautogui.press("l") print("video forwarded") elif "previous video" in query: - pyautogui.press("Shift","p") + pyautogui.press("Shift", "p") Speak("Switching...") elif "next video" in query: - pyautogui.press("Shift","n") + pyautogui.press("Shift", "n") Speak("Switching...") elif "mute" in query: pyautogui.press("m") Speak("video muted") elif "volume increse" in query: from keyboard import volumeup + Speak("Turning volume up,sir") volumeup() elif "volume down" in query: from keyboard import volumedown + Speak("Turning volume down, sir") volumedown() - #^ open direct Websites. - elif 'speed test by chrome' in query: - webbrowser.get('chrome').open("fast.com") - - elif 'stackoverflow' in query: - webbrowser.get('chrome').open("stackoverflow.com") - - elif 'amazon' in query: - webbrowser.get('chrome').open("amazon.in") - - elif'flipkart' in query: - webbrowser.get('chrome').open("flipkart.com") - - elif 'meesho' in query or 'open me show' in query: - webbrowser.get('chrome').open("meesho.com") - - elif'myntra' in query: - webbrowser.get('chrome').open("myntra.com") - - #* Windows shortcut + # ^ open direct Websites. + elif "speed test by chrome" in query: + webbrowser.get("chrome").open("fast.com") + + elif "stackoverflow" in query: + webbrowser.get("chrome").open("stackoverflow.com") + + elif "amazon" in query: + webbrowser.get("chrome").open("amazon.in") + + elif "flipkart" in query: + webbrowser.get("chrome").open("flipkart.com") + + elif "meesho" in query or "open me show" in query: + webbrowser.get("chrome").open("meesho.com") + + elif "myntra" in query: + webbrowser.get("chrome").open("myntra.com") + + # * Windows shortcut elif "minimise" in query or "minimize" in query: from Dictapp import minimize_window + minimize_window() - elif "stick screen" in query or "unpin screen" in query or "pin screen" in query: + elif ( + "stick screen" in query + or "unpin screen" in query + or "pin screen" in query + ): from Dictapp import pin_screen + pin_screen() elif "switch tab" in query or "switch app" in query: from Dictapp import switchtab + switchtab() elif "screenshot" in query: from Dictapp import take_screenshot + take_screenshot() elif "click photo" in query or "click my photo" in query: from Dictapp import click_photo + click_photo() elif "open search" in query: from Dictapp import open_search + open_search() - + elif "close window" in query or "close tab" in query: from Dictapp import close_window + close_window() elif "close my computer" in query: from Dictapp import lock_pc + lock_pc() elif "home" in query or "close all" in query: from Dictapp import go_to_home_screen + go_to_home_screen() - + elif "reload" in query: from Dictapp import reload_page + reload_page() - + elif "maximize" in query or "maximise" in query: from Dictapp import maximize_window + maximize_window() - + elif "brightness" in query or "screen light" in query: Speak("at which level") from Dictapp import adjust_brightness - adjust_brightness() - + + adjust_brightness() + #! Opening any app and any Software. - elif "open" in query: #EASY METHOD - query = query.replace("open","") - query = query.replace("jarvis","") + elif "open" in query: # EASY METHOD + query = query.replace("open", "") + query = query.replace("jarvis", "") pyautogui.press("super") pyautogui.typewrite(query) pyautogui.sleep(1) Speak("Launching Sir...") - pyautogui.press("enter") + pyautogui.press("enter") #! Closing any app and Software. elif "close" in query: from Dictapp import closeappweb + closeappweb(query) - #& To listen newses. + # & To listen newses. elif "news" in query: from NewsRead import latestnews + latestnews() - #^ Send whatsapp message by pyautogui + # ^ Send whatsapp message by pyautogui elif "whatsapp message" in query: from Whatsappmessage import sendwhatsapp + sendwhatsapp() - #* Send any message by command + # * Send any message by command elif "whatsapp" in query: from Whatsapp import sendMessage + sendMessage(contact_dict) - #~ Direct internet speed. + # ~ Direct internet speed. elif "internet speed" in query: - wifi = speedtest.Speedtest() - upload_net = wifi.upload()/1048576 #Megabyte = 1024*1024 Bytes - download_net = wifi.download()/1048576 + wifi = speedtest.Speedtest() + upload_net = wifi.upload() / 1048576 # Megabyte = 1024*1024 Bytes + download_net = wifi.download() / 1048576 print("Wifi Upload Speed is", upload_net) - print("Wifi download speed is ",download_net) + print("Wifi download speed is ", download_net) Speak(f"Wifi download speed is {download_net}") Speak(f"Wifi Upload speed is {upload_net}") - + #! Send Call by Twilio. elif "send call" in query: from sendcall import send_call - send_call() + send_call() - #* To Speak Current time. - elif 'time' in query: - strTime = datetime.datetime.now().strftime("%H:%M:%S") - print(f"Sir, the time is {strTime}") - Speak(f"Sir, the time is {strTime}") + # * To Speak Current time. + elif "time" in query: + strTime = datetime.datetime.now().strftime("%H:%M:%S") + print(f"Sir, the time is {strTime}") + Speak(f"Sir, the time is {strTime}") - #& For set an alarm. + # & For set an alarm. elif "set an alarm" in query: - strTime = datetime.datetime.now().strftime("%H:%M:%S") - print(f"Sir, the time is {strTime}") + strTime = datetime.datetime.now().strftime("%H:%M:%S") + print(f"Sir, the time is {strTime}") print("input time example:- 10 and 10 and 10") Speak("Set the time") a = input("Please tell the time :- ") alarm(a) Speak("Done, alarm set.") - #*Reminder set. + # *Reminder set. elif "remind me" in query: from reminder import remindme + remindme() # Task management commands - elif "add task" in query or "add urgent task" in query: + elif ("add task" in query or "add urgent task" in query or + "create task" in query or "new task" in query): spoken = query - clean = spoken.replace("jarvis", "").replace("add urgent task", "").replace("add task", "").strip() + clean = ( + spoken.replace("jarvis", "") + .replace("add urgent task", "") + .replace("add task", "") + .replace("create task", "") + .replace("new task", "") + .strip() + ) pr = "high" if "add urgent task" in spoken else "normal" # Try to split on common deadline prepositions deadline_text = None - for kw in [" by ", " before ", " at ", " on "]: + for kw in [" by ", " before ", " at ", " on ", " due "]: if kw in clean: parts = clean.split(kw, 1) description = parts[0].strip() @@ -619,21 +720,36 @@ def alarm(query): description = clean if description: t = add_task(description, deadline_text, pr) - Speak(f"Task added: {t['title']}") + deadline_info = f" due {deadline_text}" if deadline_text else "" + Speak(f"Task added: {t['title']}{deadline_info}") else: Speak("Please say the task description again.") - elif "what are my tasks today" in query: + elif ("what are my tasks today" in query or "today's tasks" in query or + "show today's tasks" in query or "tasks for today" in query): Speak(summary_text("today")) - elif "what are my tasks this week" in query: + elif ("what are my tasks this week" in query or "this week's tasks" in query or + "show this week's tasks" in query or "tasks this week" in query): Speak(summary_text("week")) - elif "show overdue tasks" in query or "overdue tasks" in query: + elif ("show overdue tasks" in query or "overdue tasks" in query or + "what tasks are overdue" in query or "overdue" in query): Speak(summary_text("overdue")) - elif "mark task completed" in query: - title = query.replace("jarvis", "").replace("mark task completed", "").replace(":", "").strip() + elif ("mark task completed" in query or "complete task" in query or + "task completed" in query or "done with task" in query or + "finish task" in query): + title = ( + query.replace("jarvis", "") + .replace("mark task completed", "") + .replace("complete task", "") + .replace("task completed", "") + .replace("done with task", "") + .replace("finish task", "") + .replace(":", "") + .strip() + ) done = mark_completed(title) if done: Speak(f"Marked completed: {done['title']}") @@ -642,42 +758,167 @@ def alarm(query): elif "set task priority" in query: # Example: set task priority: Call mom to high - clean = query.replace("jarvis", "").replace("set task priority", "").replace(":", "").strip() + clean = ( + query.replace("jarvis", "") + .replace("set task priority", "") + .replace(":", "") + .strip() + ) if " to " in clean: title, pr = clean.split(" to ", 1) updated = set_priority(title.strip(), pr.strip()) if updated: - Speak(f"Priority set to {updated['priority']} for {updated['title']}") + Speak( + f"Priority set to {updated['priority']} for {updated['title']}" + ) else: Speak("I could not find that task.") else: Speak("Please specify the task and the priority.") - #^ Web ip address finding + elif "delete task" in query: + title = ( + query.replace("jarvis", "") + .replace("delete task", "") + .replace(":", "") + .strip() + ) + deleted = delete_task(title) + if deleted: + Speak(f"Deleted task: {deleted['title']}") + else: + Speak("I could not find that task.") + + elif "search tasks" in query or "find task" in query: + search_term = ( + query.replace("jarvis", "") + .replace("search tasks", "") + .replace("find task", "") + .replace(":", "") + .strip() + ) + results = search_tasks(search_term) + if results: + Speak(f"Found {len(results)} tasks: " + "; ".join(format_task(t) for t in results[:5])) + else: + Speak("No tasks found matching that search.") + + elif "list all tasks" in query or "show all tasks" in query: + Speak(summary_text("all")) + + elif "task statistics" in query or "task stats" in query: + stats = get_task_statistics() + Speak(format_statistics(stats)) + + elif "add task category" in query: + # Example: add task category: Buy groceries to shopping + clean = ( + query.replace("jarvis", "") + .replace("add task category", "") + .replace(":", "") + .strip() + ) + if " to " in clean: + title, category = clean.split(" to ", 1) + updated = add_category(title.strip(), category.strip()) + if updated: + Speak(f"Added category '{category.strip()}' to task: {updated['title']}") + else: + Speak("I could not find that task.") + else: + Speak("Please specify the task and the category.") + + elif "tasks by category" in query or "show tasks by category" in query: + category = ( + query.replace("jarvis", "") + .replace("tasks by category", "") + .replace("show tasks by category", "") + .replace(":", "") + .strip() + ) + tasks = get_tasks_by_category(category) + if tasks: + Speak(f"Tasks in category '{category}': " + "; ".join(format_task(t) for t in tasks[:5])) + else: + Speak(f"No tasks found in category '{category}'.") + + elif "list categories" in query or "show categories" in query: + categories = get_categories() + if categories: + Speak(f"Available categories: {', '.join(categories)}") + else: + Speak("No categories found.") + + elif ("daily summary" in query or "task summary" in query or + "my task summary" in query or "summary" in query): + summary = get_daily_task_summary() + Speak(summary) + + elif "set task reminder" in query: + # Example: set task reminder: Call mom in 30 minutes + clean = ( + query.replace("jarvis", "") + .replace("set task reminder", "") + .replace(":", "") + .strip() + ) + if " in " in clean: + title, time_part = clean.split(" in ", 1) + # Extract minutes from time part + minutes = 30 # default + time_match = re.search(r"(\d+)", time_part) + if time_match: + minutes = int(time_match.group(1)) + updated = set_task_reminder(title.strip(), minutes) + if updated: + Speak(f"Reminder set for {minutes} minutes before deadline for: {updated['title']}") + else: + Speak("I could not find that task.") + else: + Speak("Please specify the task and reminder time.") + + elif ("what tasks need reminders" in query or + "tasks needing reminders" in query or "reminder tasks" in query): + tasks = get_tasks_needing_reminders() + if tasks: + Speak(f"Tasks needing reminders: " + "; ".join(t["title"] for t in tasks[:5])) + else: + Speak("No tasks currently need reminders.") + + elif ("task help" in query or "help with tasks" in query or + "task management help" in query or "how to use tasks" in query): + help_text = get_task_help() + # Split help text into smaller chunks for better speech output + help_lines = help_text.split('\n') + for line in help_lines: + if line.strip(): + Speak(line.strip()) + + # ^ Web ip address finding elif "ip ad dress" in query: - ip = get('https://api.ipify.org').text + ip = get("https://api.ipify.org").text print(f"your IP address is {ip}") Speak(f"your IP address is {ip}") - #^ To know the current temperature of city. + # ^ To know the current temperature of city. elif "temperature" in query: search = "temperature in rajasthan" url = f"https://www.google.com/search?q={search}" - r = requests.get(url) - data = BeautifulSoup(r.text,"html.parser") - temp = data.find("div", class_ = "BNeawe").text + r = requests.get(url) + data = BeautifulSoup(r.text, "html.parser") + temp = data.find("div", class_="BNeawe").text Speak(f"current{search} is {temp}") - #* To Calculate any digit. + # * To Calculate any digit. elif "calculate" in query: - from Calculatenumbers import WolfRamAlpha - from Calculatenumbers import Calc - query = query.replace("calculate","") - query = query.replace("jarvis","") + from Calculatenumbers import Calc, WolfRamAlpha + + query = query.replace("calculate", "") + query = query.replace("jarvis", "") Calc(query) - + #! For exit from Jarvis. - elif 'exit' in query: + elif "exit" in query: Speak(random.choice(goodbyes)) sys.exit() @@ -694,23 +935,23 @@ def alarm(query): break elif "logout" in query: - Speak('logging out in 5 second') + Speak("logging out in 5 second") time.sleep(5) os.system("shutdown - l") - + elif "schedule my day" in query: - tasks = [] #Empty list + tasks = [] # Empty list Speak("Do you want to clear old tasks (Plz speak YES or NO)") query = TakeCommand().lower() if "yes" in query: - file = open("tasks.txt","w") + file = open("tasks.txt", "w") file.write(f"") file.close() no_tasks = int(input("Enter the no. of tasks :- ")) i = 0 for i in range(no_tasks): tasks.append(input("Enter the task :- ")) - file = open("tasks.txt","a") + file = open("tasks.txt", "a") file.write(f"{i}. {tasks[i]}\n") file.close() elif "no" in query: @@ -718,53 +959,49 @@ def alarm(query): no_tasks = int(input("Enter the no. of tasks :- ")) for i in range(no_tasks): tasks.append(input("Enter the task :- ")) - file = open("tasks.txt","a") + file = open("tasks.txt", "a") file.write(f"{i}. {tasks[i]}\n") file.close() elif "show my schedule" in query: - file = open("tasks.txt","r") + file = open("tasks.txt", "r") content = file.read() file.close() mixer.init() mixer.music.load("assets/media/notification.mp3") mixer.music.play() notification.notify( - title = "My schedule :-", - messageschedule = content, - timeout = 15 - ) - - - #* send email Function. + title="My schedule :-", messageschedule=content, timeout=15 + ) + + # * send email Function. if "write an email" in query: print("To whom do you want to send the email?") Speak("To whom do you want to send the email?") - + recipient_name = TakeCommand().lower() from sendemail import recipient_mapping + recipient_email = recipient_mapping.get(recipient_name) - + if recipient_email: print("What's the subject of the email?") Speak("What's the subject of the email?") subject = TakeCommand().lower() - from sendemail import send_email - from sendemail import sender_email - from sendemail import sender_password - + from sendemail import (send_email, sender_email, + sender_password) + print("What's the content of the email?") Speak("What's the content of the email?") content = TakeCommand().lower() - - - send_email(sender_email, sender_password, recipient_email, subject, content) + + send_email( + sender_email, + sender_password, + recipient_email, + subject, + content, + ) else: print("Sorry, the recipient's email address is not found.") - Speak("Sorry, the recipient's email address is not found.") - - - - - - + Speak("Sorry, the recipient's email address is not found.") diff --git a/core/installer.py b/core/installer.py index bc2ef47..24b09f9 100644 --- a/core/installer.py +++ b/core/installer.py @@ -1,45 +1,45 @@ import subprocess libraries = [ - 'pyttsx3', - 'SpeechRecognition', - 'datetime', - 'webbrowser', - 'opencv-python-headless', - 'requests', - 'random2', - 'pyautogui', - 'speedtest-cli', - 'numpy', - 'beautifulsoup4', - 'plyer', - 'nltk', - 'pygame', - 'win10toast', - 'psutil', - 'wolframalpha', - 'wmi', - 'time', - 'ctypes', - 'sys', - 'tkinter', - 'PIL', - 'pygame', - 'pyjokes', - 'pynput', - 'cv2', - 'googletrans', - 'gtts', - 'pywhatkit', - 'wikipedia', - 'twilio', - 'smtplib', - 'fnmatch', - 'playsound', - 'mouse', + "pyttsx3", + "SpeechRecognition", + "datetime", + "webbrowser", + "opencv-python-headless", + "requests", + "random2", + "pyautogui", + "speedtest-cli", + "numpy", + "beautifulsoup4", + "plyer", + "nltk", + "pygame", + "win10toast", + "psutil", + "wolframalpha", + "wmi", + "time", + "ctypes", + "sys", + "tkinter", + "PIL", + "pygame", + "pyjokes", + "pynput", + "cv2", + "googletrans", + "gtts", + "pywhatkit", + "wikipedia", + "twilio", + "smtplib", + "fnmatch", + # "playsound", # Optional - causes CI issues + "mouse", ] for library in libraries: - subprocess.call(['pip', 'install', library]) + subprocess.call(["pip", "install", library]) print("Libraries installed successfully.") diff --git a/data/tasks.json b/data/tasks.json new file mode 100644 index 0000000..5e8c7be --- /dev/null +++ b/data/tasks.json @@ -0,0 +1,20 @@ +[ + { + "id": 1759580495136, + "title": "Buy groceries", + "priority": "high", + "deadline": "2025-10-04T17:00:00", + "completed": true, + "created_at": "2025-10-04T17:51:35.137642", + "completed_at": "2025-10-04T17:51:35.216119" + }, + { + "id": 1759580495185, + "title": "Submit assignment", + "priority": "high", + "deadline": "2025-10-10T09:00:00", + "completed": false, + "created_at": "2025-10-04T17:51:35.186093", + "completed_at": null + } +] \ No newline at end of file diff --git a/features/ai/Model Trainer.py b/features/ai/Model Trainer.py index 5101c7a..35c588c 100644 --- a/features/ai/Model Trainer.py +++ b/features/ai/Model Trainer.py @@ -1,40 +1,42 @@ +import os + import cv2 import numpy as np -from PIL import Image #pillow package -import os +from PIL import Image # pillow package -path = 'samples' # Path for samples already taken +path = "samples" # Path for samples already taken -recognizer = cv2.face.LBPHFaceRecognizer_create() # Local Binary Patterns Histograms +recognizer = cv2.face.LBPHFaceRecognizer_create() # Local Binary Patterns Histograms detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") -#Haar Cascade classifier is an effective object detection approach +# Haar Cascade classifier is an effective object detection approach -def Images_And_Labels(path): # function to fetch the images and labels +def Images_And_Labels(path): # function to fetch the images and labels - imagePaths = [os.path.join(path,f) for f in os.listdir(path)] - faceSamples=[] + imagePaths = [os.path.join(path, f) for f in os.listdir(path)] + faceSamples = [] ids = [] - for imagePath in imagePaths: # to iterate particular image path + for imagePath in imagePaths: # to iterate particular image path - gray_img = Image.open(imagePath).convert('L') # convert it to grayscale - img_arr = np.array(gray_img,'uint8') #creating an array + gray_img = Image.open(imagePath).convert("L") # convert it to grayscale + img_arr = np.array(gray_img, "uint8") # creating an array id = int(os.path.split(imagePath)[-1].split(".")[1]) faces = detector.detectMultiScale(img_arr) - for (x,y,w,h) in faces: - faceSamples.append(img_arr[y:y+h,x:x+w]) + for x, y, w, h in faces: + faceSamples.append(img_arr[y : y + h, x : x + w]) ids.append(id) - return faceSamples,ids + return faceSamples, ids + -print ("Training faces. It will take a few seconds. Wait ...") +print("Training faces. It will take a few seconds. Wait ...") -faces,ids = Images_And_Labels(path) +faces, ids = Images_And_Labels(path) recognizer.train(faces, np.array(ids)) -recognizer.write('trainer\\trainer.yml') # Save the trained model as trainer.yml +recognizer.write("trainer\\trainer.yml") # Save the trained model as trainer.yml print("Model trained, Now we can recognize your face.") diff --git a/features/ai/Sample generator.py b/features/ai/Sample generator.py index c5e9633..b60dd3b 100644 --- a/features/ai/Sample generator.py +++ b/features/ai/Sample generator.py @@ -1,41 +1,49 @@ import cv2 -cam = cv2.VideoCapture(0, cv2.CAP_DSHOW) #create a video capture object which is helpful to capture videos through webcam -cam.set(3, 640) # set video FrameWidth -cam.set(4, 480) # set video FrameHeight +cam = cv2.VideoCapture( + 0, cv2.CAP_DSHOW +) # create a video capture object which is helpful to capture videos through webcam +cam.set(3, 640) # set video FrameWidth +cam.set(4, 480) # set video FrameHeight -detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') -#Haar Cascade classifier is an effective object detection approach +detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") +# Haar Cascade classifier is an effective object detection approach face_id = input("Enter a Numeric user ID here: ") -#Use integer ID for every new face (0,1,2,3,4,5,6,7,8,9........) +# Use integer ID for every new face (0,1,2,3,4,5,6,7,8,9........) print("Taking samples, look at camera ....... ") -count = 0 # Initializing sampling face count +count = 0 # Initializing sampling face count while True: - ret, img = cam.read() #read the frames using the above created object - converted_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #The function converts an input image from one color space to another + ret, img = cam.read() # read the frames using the above created object + converted_image = cv2.cvtColor( + img, cv2.COLOR_BGR2GRAY + ) # The function converts an input image from one color space to another faces = detector.detectMultiScale(converted_image, 1.3, 5) - for (x,y,w,h) in faces: + for x, y, w, h in faces: - cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2) #used to draw a rectangle on any image + cv2.rectangle( + img, (x, y), (x + w, y + h), (255, 0, 0), 2 + ) # used to draw a rectangle on any image count += 1 - - cv2.imwrite("samples\\face." + str(face_id) + '.' + str(count) + ".jpg", converted_image[y:y+h,x:x+w]) + cv2.imwrite( + "samples\\face." + str(face_id) + "." + str(count) + ".jpg", + converted_image[y : y + h, x : x + w], + ) # To capture & Save images into the datasets folder - cv2.imshow('image', img) #Used to display an image in a window + cv2.imshow("image", img) # Used to display an image in a window - k = cv2.waitKey(100) & 0xff # Waits for a pressed key - if k == 27: # Press 'ESC' to stop + k = cv2.waitKey(100) & 0xFF # Waits for a pressed key + if k == 27: # Press 'ESC' to stop + break + elif count >= 10: # Take 50 sample (More sample --> More accuracy) break - elif count >= 10: # Take 50 sample (More sample --> More accuracy) - break print("Samples taken now closing the program....") cam.release() diff --git a/features/communication/Whatsapp.py b/features/communication/Whatsapp.py index 338aae6..3a10a11 100644 --- a/features/communication/Whatsapp.py +++ b/features/communication/Whatsapp.py @@ -1,26 +1,27 @@ -import pywhatkit -import pyttsx3 -import speech_recognition as sr +import os +import time import webbrowser -from bs4 import BeautifulSoup +from datetime import datetime, timedelta from time import sleep -import os -from datetime import timedelta -from datetime import datetime -import time + import pyautogui +import pyttsx3 +import pywhatkit +import speech_recognition as sr +from bs4 import BeautifulSoup engine = pyttsx3.init("sapi5") voices = engine.getProperty("voices") engine.setProperty("voice", voices[0].id) -rate = engine.setProperty("rate",185) +rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() -#^ For taking all commands and listen the user voices. +# ^ For taking all commands and listen the user voices. def TakeCommand(): r = sr.Recognizer() @@ -28,18 +29,19 @@ def TakeCommand(): print("Listening...") r.pause_threshold = 1 # r.energy_threshold = 200 - audio = r.listen(source,0,4) + audio = r.listen(source, 0, 4) try: - print("Understanding...") - query = r.recognize_google(audio, language='en-in') + print("Understanding...") + query = r.recognize_google(audio, language="en-in") print(f"Master said: {query}\n") except Exception as e: - print("Say that again please...") + print("Say that again please...") return "None" return query + def sendMessage(contact_dict): strTime = int(datetime.now().strftime("%H")) @@ -52,13 +54,12 @@ def sendMessage(contact_dict): Speak("What's the message?") message = TakeCommand() contact_number = contact_dict[contact_name] - pywhatkit.sendwhatmsg(contact_number, message, time_hour=strTime, time_min=update) - + pywhatkit.sendwhatmsg( + contact_number, message, time_hour=strTime, time_min=update + ) + Speak("Message delivered!") - pyautogui.hotkey('Alt','f4') + pyautogui.hotkey("Alt", "f4") else: Speak("Sorry, I couldn't find the contact.") - - - diff --git a/features/communication/Whatsappmessage.py b/features/communication/Whatsappmessage.py index 3335178..c414e3d 100644 --- a/features/communication/Whatsappmessage.py +++ b/features/communication/Whatsappmessage.py @@ -1,14 +1,16 @@ import os -import pyautogui +import time import webbrowser +from time import sleep + +import pyautogui +import pynput import pyttsx3 -import wmi import speech_recognition as sr -from time import sleep -import time -import pynput -from pynput.mouse import Button, Controller +import wmi from pynput import mouse +from pynput.mouse import Button, Controller + def TakeCommand(): @@ -17,27 +19,30 @@ def TakeCommand(): print("Listening...") r.pause_threshold = 1 # r.energy_threshold = 200 - audio = r.listen(source,0,4) + audio = r.listen(source, 0, 4) try: - print("Understanding...") - query = r.recognize_google(audio, language='en-in') + print("Understanding...") + query = r.recognize_google(audio, language="en-in") print(f"Master said: {query}\n") except Exception as e: - print("Say that again please...") + print("Say that again please...") return "None" return query -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) -rate = engine.setProperty("rate",185) + +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") +engine.setProperty("voice", voices[0].id) +rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() + phone_book = { "Name": "PHONE_NUMBER", # ADD MORE CONTACTS. @@ -47,16 +52,16 @@ def Speak(audio): def sendwhatsapp(): query = TakeCommand().lower() message = phone_book - pyautogui.hotkey('win', 's') + pyautogui.hotkey("win", "s") pyautogui.sleep(1) pyautogui.typewrite("whatsapp") pyautogui.sleep(1) - pyautogui.press("enter") + pyautogui.press("enter") pyautogui.sleep(2) Speak("Whom do you want to Message") pyautogui.typewrite(phone_book) pyautogui.sleep(2) - pyautogui.moveTo(230,205) + pyautogui.moveTo(230, 205) pyautogui.click() pyautogui.sleep(1) Speak("what is the Meassage...") @@ -64,4 +69,4 @@ def sendwhatsapp(): pyautogui.press("enter") Speak("Message send, Sir!") pyautogui.sleep(1) - pyautogui.hotkey('alt', 'f4') \ No newline at end of file + pyautogui.hotkey("alt", "f4") diff --git a/features/communication/sendemail.py b/features/communication/sendemail.py index 806a891..3c1701e 100644 --- a/features/communication/sendemail.py +++ b/features/communication/sendemail.py @@ -1,25 +1,29 @@ -import pyttsx3 import smtplib -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) -rate = engine.setProperty("rate",185) +import pyttsx3 + +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") +engine.setProperty("voice", voices[0].id) +rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() -#^ Function to send an email. + +# ^ Function to send an email. def send_email(sender_email, sender_password, recipient_email, subject, content): from email.message import EmailMessage + msg = EmailMessage() - msg['From'] = sender_email - msg['To'] = recipient_email - msg['Subject'] = subject + msg["From"] = sender_email + msg["To"] = recipient_email + msg["Subject"] = subject msg.set_content(content) - with smtplib.SMTP('smtp.gmail.com', 587) as server: + with smtplib.SMTP("smtp.gmail.com", 587) as server: server.starttls() server.login(sender_email, sender_password) server.send_message(msg) @@ -27,6 +31,7 @@ def send_email(sender_email, sender_password, recipient_email, subject, content) print("Email sent successfully.") Speak("Email sent successfully.") + # ~Using Dictionary to map recipient names and their email ids. recipient_mapping = { @@ -34,15 +39,10 @@ def send_email(sender_email, sender_password, recipient_email, subject, content) # Add more recipient mappings as needed. } -# & Fetch sender's email and password +# & Fetch sender's email and password # & Here you will add your email id and password which you want to use to send email to other recipients. # & You make sure that you can't use your original password for privacy concerns. # & You can use Google 'less secure apps' feature. sender_email = "Your email id" sender_password = "your password" - - - - - diff --git a/features/entertainment/NewsRead.py b/features/entertainment/NewsRead.py index bddcebe..8a0eb84 100644 --- a/features/entertainment/NewsRead.py +++ b/features/entertainment/NewsRead.py @@ -1,17 +1,20 @@ -import requests import json + import pyttsx3 +import requests import speech_recognition as sr engine = pyttsx3.init("sapi5") voices = engine.getProperty("voices") engine.setProperty("voice", voices[0].id) -rate = engine.setProperty("rate",185) +rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() + def TakeCommand(): r = sr.Recognizer() @@ -19,34 +22,38 @@ def TakeCommand(): print("Listening...") r.pause_threshold = 1 # r.energy_threshold = 200 - audio = r.listen(source,0,4) + audio = r.listen(source, 0, 4) try: - print("Understanding...") - query = r.recognize_google(audio, language='en-in') + print("Understanding...") + query = r.recognize_google(audio, language="en-in") print(f"Master said: {query}\n") except Exception as e: - print("Say that again please...") + print("Say that again please...") return "None" return query -#! In latestnews we use in link after "=" sign our api key. + +#! In latestnews we use in link after "=" sign our api key. def latestnews(): - api_dict = {"business" : "https://newsapi.org/v2/top-headlines?country=in&category=business&apiKey=518914f375d14a61899bd1d83f52cf09", - "entertainment" : "https://newsapi.org/v2/top-headlines?country=in&category=entertainment&apiKey=518914f375d14a61899bd1d83f52cf09", - "health" : "https://newsapi.org/v2/top-headlines?country=in&category=health&apiKey=518914f375d14a61899bd1d83f52cf09", - "science" :"https://newsapi.org/v2/top-headlines?country=in&category=science&apiKey=518914f375d14a61899bd1d83f52cf09", - "sports" :"https://newsapi.org/v2/top-headlines?country=in&category=sports&apiKey=518914f375d14a61899bd1d83f52cf09", - "technology" :"https://newsapi.org/v2/top-headlines?country=in&category=technology&apiKey=518914f375d14a61899bd1d83f52cf09" -} + api_dict = { + "business": "https://newsapi.org/v2/top-headlines?country=in&category=business&apiKey=518914f375d14a61899bd1d83f52cf09", + "entertainment": "https://newsapi.org/v2/top-headlines?country=in&category=entertainment&apiKey=518914f375d14a61899bd1d83f52cf09", + "health": "https://newsapi.org/v2/top-headlines?country=in&category=health&apiKey=518914f375d14a61899bd1d83f52cf09", + "science": "https://newsapi.org/v2/top-headlines?country=in&category=science&apiKey=518914f375d14a61899bd1d83f52cf09", + "sports": "https://newsapi.org/v2/top-headlines?country=in&category=sports&apiKey=518914f375d14a61899bd1d83f52cf09", + "technology": "https://newsapi.org/v2/top-headlines?country=in&category=technology&apiKey=518914f375d14a61899bd1d83f52cf09", + } content = None url = None - Speak("Which field news do you want, [business] , [health] , [technology], [sports] , [entertainment] , [science]") + Speak( + "Which field news do you want, [business] , [health] , [technology], [sports] , [entertainment] , [science]" + ) field = TakeCommand().lower() - for key ,value in api_dict.items(): + for key, value in api_dict.items(): if key.lower() in field.lower(): url = value print(url) @@ -62,7 +69,7 @@ def latestnews(): Speak("Here is the first news.") arts = news["articles"] - for articles in arts : + for articles in arts: article = articles["title"] print(article) Speak(article) @@ -75,5 +82,5 @@ def latestnews(): pass elif str(a) == "stop": break - + Speak("thats all") diff --git a/features/entertainment/game.py b/features/entertainment/game.py index 7a8223d..a6472c4 100644 --- a/features/entertainment/game.py +++ b/features/entertainment/game.py @@ -1,48 +1,52 @@ +import random + import pyttsx3 import speech_recognition as sr -import random -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") +engine.setProperty("voice", voices[0].id) engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() + def takeCommand(): r = sr.Recognizer() with sr.Microphone() as source: print("Listening.....") r.pause_threshold = 1 r.energy_threshold = 300 - audio = r.listen(source,0,4) + audio = r.listen(source, 0, 4) try: print("Recognizing..") - query = r.recognize_google(audio , language= 'en-in') + query = r.recognize_google(audio, language="en-in") print(f"You Said : {query}\n") except Exception as e: print("Say that again") return "None" return query + def game_play(): Speak("Lets Play ROCK PAPER SCISSORS !!") print("LETS PLAYYYYYYYYYYYYYY") i = 0 Me_score = 0 Com_score = 0 - while(i<5): - choose = ("rock","paper","scissors") #Tuple + while i < 5: + choose = ("rock", "paper", "scissors") # Tuple com_choose = random.choice(choose) query = takeCommand().lower() - if (query == "rock"): - if (com_choose == "rock"): + if query == "rock": + if com_choose == "rock": Speak("ROCK") print(f"Score:- ME :- {Me_score} : COM :- {Com_score}") - elif (com_choose == "paper"): + elif com_choose == "paper": Speak("paper") Com_score += 1 print(f"Score:- ME :- {Me_score} : COM :- {Com_score}") @@ -51,13 +55,13 @@ def game_play(): Me_score += 1 print(f"Score:- ME :- {Me_score} : COM :- {Com_score}") - elif (query == "paper" ): - if (com_choose == "rock"): + elif query == "paper": + if com_choose == "rock": Speak("ROCK") Me_score += 1 print(f"Score:- ME :- {Me_score+1} : COM :- {Com_score}") - elif (com_choose == "paper"): + elif com_choose == "paper": Speak("paper") print(f"Score:- ME :- {Me_score} : COM :- {Com_score}") else: @@ -65,12 +69,12 @@ def game_play(): Com_score += 1 print(f"Score:- ME :- {Me_score} : COM :- {Com_score}") - elif (query == "scissors" or query == "scissor"): - if (com_choose == "rock"): + elif query == "scissors" or query == "scissor": + if com_choose == "rock": Speak("ROCK") Com_score += 1 print(f"Score:- ME :- {Me_score} : COM :- {Com_score}") - elif (com_choose == "paper"): + elif com_choose == "paper": Speak("paper") Me_score += 1 print(f"Score:- ME :- {Me_score} : COM :- {Com_score}") @@ -78,5 +82,5 @@ def game_play(): Speak("Scissors") print(f"Score:- ME :- {Me_score} : COM :- {Com_score}") i += 1 - - print(f"FINAL SCORE :- ME :- {Me_score} : COM :- {Com_score}") \ No newline at end of file + + print(f"FINAL SCORE :- ME :- {Me_score} : COM :- {Com_score}") diff --git a/features/entertainment/joke.py b/features/entertainment/joke.py index c34d4ad..19edf03 100644 --- a/features/entertainment/joke.py +++ b/features/entertainment/joke.py @@ -1,15 +1,17 @@ import pyjokes import pyttsx3 -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) -rate = engine.setProperty("rate",185) +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") +engine.setProperty("voice", voices[0].id) +rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() + def jokes(): My_joke = pyjokes.get_joke(language="en", category="neutral") print(My_joke) diff --git a/features/search/SearchNow.py b/features/search/SearchNow.py index 907aceb..2d7c69e 100644 --- a/features/search/SearchNow.py +++ b/features/search/SearchNow.py @@ -1,8 +1,10 @@ -import speech_recognition as sr +import webbrowser + import pyttsx3 import pywhatkit +import speech_recognition as sr import wikipedia -import webbrowser + def TakeCommand(): @@ -11,60 +13,66 @@ def TakeCommand(): print("Listening...") r.pause_threshold = 1 # r.energy_threshold = 200 - audio = r.listen(source,0,4) + audio = r.listen(source, 0, 4) try: - print("Understanding...") - query = r.recognize_google(audio, language='en-in') + print("Understanding...") + query = r.recognize_google(audio, language="en-in") print(f"Master said: {query}\n") except Exception as e: - print("Say that again please...") + print("Say that again please...") return "None" return query + query = TakeCommand().lower() -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) -rate = engine.setProperty("rate",185) +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") +engine.setProperty("voice", voices[0].id) +rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() + def searchGoogle(query): import wikipedia as googlescrap + Speak("According to google") try: pywhatkit.search(query) - result = googlescrap.summary(query,1) + result = googlescrap.summary(query, 1) Speak(result) except: Speak("No speakable output available") + def searchyoutube(query): if "youtube" in query: Speak("This is what i found on search!") - query = query.replace("jarvis","") - query = query.replace("youtube search","") - query = query.replace("search on youtube","") + query = query.replace("jarvis", "") + query = query.replace("youtube search", "") + query = query.replace("search on youtube", "") web = "https://www.youtube.com/results?search_query=" + query webbrowser.open(web) Speak("Done") elif "youtube home page" in query: Speak("opening...") - webbrowser.get('chrome').open("youtube.com") + webbrowser.get("chrome").open("youtube.com") + def searchwikipedia(query): -# *Logic for executing tasks based on query - if 'wikipedia' in query: - Speak('Searching from Wikipedia...') + # *Logic for executing tasks based on query + if "wikipedia" in query: + Speak("Searching from Wikipedia...") query = query.replace("wikipedia", "") query = query.replace("jarvis", "") query = query.replace("search on wikipedia", "") @@ -72,6 +80,3 @@ def searchwikipedia(query): Speak("According to Wikipedia") print(results) Speak(results) - - - diff --git a/features/system/Dictapp.py b/features/system/Dictapp.py index ab3a580..18a07ab 100644 --- a/features/system/Dictapp.py +++ b/features/system/Dictapp.py @@ -1,10 +1,12 @@ import os -import pyautogui import webbrowser +from time import sleep + +import pyautogui import pyttsx3 -import wmi import speech_recognition as sr -from time import sleep +import wmi + def TakeCommand(): @@ -13,28 +15,31 @@ def TakeCommand(): print("Listening...") r.pause_threshold = 1 # r.energy_threshold = 200 - audio = r.listen(source,0,4) + audio = r.listen(source, 0, 4) try: - print("Understanding...") - query = r.recognize_google(audio, language='en-in') + print("Understanding...") + query = r.recognize_google(audio, language="en-in") print(f"Master said: {query}\n") except Exception as e: - print("Say that again please...") + print("Say that again please...") return "None" return query -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) -rate = engine.setProperty("rate",185) + +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") +engine.setProperty("voice", voices[0].id) +rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() -#^ Adjusting brightness at fixed level. + +# ^ Adjusting brightness at fixed level. def adjust_brightness(): query = TakeCommand().lower() @@ -75,22 +80,26 @@ def adjust_brightness(): else: print("Command not understanding...") -#* Keyboard Shortcuts + +# * Keyboard Shortcuts def minimize_window(): - pyautogui.hotkey('win', 'down') + pyautogui.hotkey("win", "down") + def switchtab(): - pyautogui.hotkey('Alt', 'Tab') + pyautogui.hotkey("Alt", "Tab") + # Function to capture a screenshot def take_screenshot(): screenshot = pyautogui.screenshot() - save_path = r"C:\Users\gomti\OneDrive\Pictures\Screenshots" #add the folder location of taking screenshot + save_path = r"C:\Users\gomti\OneDrive\Pictures\Screenshots" # add the folder location of taking screenshot filename = "screenshot.png" screenshot.save(os.path.join(save_path, filename)) Speak("Screenshot saved.") print(f"Screenshot saved as {os.path.join(save_path, filename)}") + def click_photo(): pyautogui.press("super") pyautogui.typewrite("camera") @@ -99,81 +108,88 @@ def click_photo(): Speak("SMILE") pyautogui.press("enter") Speak("Your photo is captured, you looking Good.") - pyautogui.hotkey('Alt','f4') + pyautogui.hotkey("Alt", "f4") + # Function to open search def open_search(): - pyautogui.hotkey('win', 's') + pyautogui.hotkey("win", "s") + # Function to pin screen def pin_screen(): Speak("Done Sir") - pyautogui.hotkey('win', 'ctrl', 't') + pyautogui.hotkey("win", "ctrl", "t") + # Function to close window def close_window(): Speak("window closed") - pyautogui.hotkey('Alt','f4') + pyautogui.hotkey("Alt", "f4") + # Function to lock PC def lock_pc(): - pyautogui.hotkey('win', 'l') + pyautogui.hotkey("win", "l") Speak("PC is locked") + # Function to go to the home screen def go_to_home_screen(): Speak("You are on home screen now!") - pyautogui.hotkey('win', 'd') + pyautogui.hotkey("win", "d") + # Function to reload or refresh def reload_page(): - pyautogui.hotkey('ctrl', 'r') + pyautogui.hotkey("ctrl", "r") + # Function to maximize the active window def maximize_window(): - pyautogui.hotkey('win', 'up') - + pyautogui.hotkey("win", "up") + + # Function to adjust brightness of your pc def set_brightness(percentage): - wmi.WMI(namespace='wmi').WmiMonitorBrightnessMethods()[0].WmiSetBrightness(percentage, 0) + wmi.WMI(namespace="wmi").WmiMonitorBrightnessMethods()[0].WmiSetBrightness( + percentage, 0 + ) + def closeappweb(query): Speak("Closing sir") if "one tab" in query or "1 tab" in query: - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") elif "two tab" in query or "2 tab " in query: - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") sleep(0.5) - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") Speak("All tabs closed") elif "3 tab" in query: - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") sleep(0.5) - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") sleep(0.5) - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") Speak("All tabs closed") elif "4 tab" in query: - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") sleep(0.5) - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") sleep(0.5) - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") sleep(0.5) - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") Speak("All tabs closed") elif "5 tab" in query: - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") sleep(0.5) - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") sleep(0.5) - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") sleep(0.5) - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") sleep(0.5) - pyautogui.hotkey("ctrl","w") + pyautogui.hotkey("ctrl", "w") Speak("All tabs closed") - - - - diff --git a/features/system/FocusMode.py b/features/system/FocusMode.py index 3bc1249..9d5155b 100644 --- a/features/system/FocusMode.py +++ b/features/system/FocusMode.py @@ -1,34 +1,42 @@ -import time +import ctypes import datetime -import ctypes,sys import os +import sys +import time + def is_admin(): try: return ctypes.windll.shell32.IsUserAnAdmin() except: return False + + if is_admin(): current_time = datetime.datetime.now().strftime("%H:%M") - Stop_time = os.popen('cmd /c echo|set /p="Enter time example [10:10]: "').read().strip() - a = current_time.replace(":",".") + Stop_time = ( + os.popen('cmd /c echo|set /p="Enter time example [10:10]: "').read().strip() + ) + a = current_time.replace(":", ".") a = float(a) - b = Stop_time.replace(":",".") + b = Stop_time.replace(":", ".") b = float(b) - Focus_Time = b-a - Focus_Time = round(Focus_Time,3) - host_path ='C:\\Windows\\System32\\drivers\\etc\\hosts' - redirect = '127.0.0.1' + Focus_Time = b - a + Focus_Time = round(Focus_Time, 3) + host_path = "C:\\Windows\\System32\\drivers\\etc\\hosts" + redirect = "127.0.0.1" - print(current_time) time.sleep(2) - website_list = ["www.facebook.com","facebook.com"] #Enter the websites that you want to block - if (current_time < Stop_time): - with open(host_path,"r+") as file: #r+ is writing+ reading + website_list = [ + "www.facebook.com", + "facebook.com", + ] # Enter the websites that you want to block + if current_time < Stop_time: + with open(host_path, "r+") as file: # r+ is writing+ reading content = file.read() time.sleep(2) - for website in website_list: + for website in website_list: if website in content: pass else: @@ -37,13 +45,15 @@ def is_admin(): time.sleep(1) print("FOCUS MODE TURNED ON !!!!") + while True: - while True: - current_time = datetime.datetime.now().strftime("%H:%M") - website_list = ["www.facebook.com","facebook.com"] #Enter the websites that you want to block - if (current_time >= Stop_time): - with open(host_path,"r+") as file: + website_list = [ + "www.facebook.com", + "facebook.com", + ] # Enter the websites that you want to block + if current_time >= Stop_time: + with open(host_path, "r+") as file: content = file.readlines() file.seek(0) @@ -54,12 +64,14 @@ def is_admin(): file.truncate() print("Websites are unblocked !!") - file = open("focus.txt","a") - file.write(f",{Focus_Time}") #Write a 0 in focus.txt before starting + file = open("focus.txt", "a") + file.write(f",{Focus_Time}") # Write a 0 in focus.txt before starting file.close() - break + break else: - ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1) + ctypes.windll.shell32.ShellExecuteW( + None, "runas", sys.executable, " ".join(sys.argv), None, 1 + ) -is_admin() \ No newline at end of file +is_admin() diff --git a/features/system/battery.py b/features/system/battery.py index 00b7dde..ef1437f 100644 --- a/features/system/battery.py +++ b/features/system/battery.py @@ -1,13 +1,14 @@ -import pyttsx3 -from win10toast import ToastNotifier import time + import psutil +import pyttsx3 +from win10toast import ToastNotifier +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") +engine.setProperty("voice", voices[0].id) +rate = engine.setProperty("rate", 185) -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) -rate = engine.setProperty("rate",185) def Speak(audio): engine.say(audio) @@ -15,23 +16,25 @@ def Speak(audio): def battery(): - battery= psutil.sensors_battery() + battery = psutil.sensors_battery() percentage = battery.percent Speak(f"sir our system have {percentage} percent battery") - if percentage>=75: + if percentage >= 75: Speak("we have enough power to continue work.") - elif percentage>=40 and percentage<=75: + elif percentage >= 40 and percentage <= 75: Speak("Battery is not more!,you should connect to Power source") - elif percentage>=15 and percentage<=30: + elif percentage >= 15 and percentage <= 30: Speak("Battery running low, you should connect to power source") - elif percentage>=15: + elif percentage >= 15: Speak("Batterysaver is running on, you must connect to power source") - + def check_battery(): toaster = ToastNotifier() while True: battery = psutil.sensors_battery() if battery.percent == 100 and not battery.power_plugged: - toaster.show_toast("Battery Alert", "Battery is fully charged!", duration=10) - time.sleep(300) # Check the battery level every 60 seconds \ No newline at end of file + toaster.show_toast( + "Battery Alert", "Battery is fully charged!", duration=10 + ) + time.sleep(300) # Check the battery level every 60 seconds diff --git a/features/system/keyboard.py b/features/system/keyboard.py index d6b41ca..19af72f 100644 --- a/features/system/keyboard.py +++ b/features/system/keyboard.py @@ -1,15 +1,19 @@ -from pynput.keyboard import Key,Controller from time import sleep +from pynput.keyboard import Controller, Key + keyboard = Controller() + def volumeup(): for i in range(5): keyboard.press(Key.media_volume_up) keyboard.release(Key.media_volume_up) sleep(0.1) + + def volumedown(): for i in range(5): keyboard.press(Key.media_volume_down) keyboard.release(Key.media_volume_down) - sleep(0.1) \ No newline at end of file + sleep(0.1) diff --git a/features/utilities/Calculatenumbers.py b/features/utilities/Calculatenumbers.py index f356d38..81c6161 100644 --- a/features/utilities/Calculatenumbers.py +++ b/features/utilities/Calculatenumbers.py @@ -1,16 +1,18 @@ -import wolframalpha import pyttsx3 import speech_recognition as sr +import wolframalpha engine = pyttsx3.init("sapi5") voices = engine.getProperty("voices") engine.setProperty("voice", voices[0].id) -rate = engine.setProperty("rate",185) +rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() + def WolfRamAlpha(query): apikey = "WGKT3V-R88U56Q4T6" requester = wolframalpha.Client(apikey) @@ -22,13 +24,14 @@ def WolfRamAlpha(query): except: Speak("The value is not answerable") + def Calc(query): Term = str(query) - Term = Term.replace("jarvis","") - Term = Term.replace("multiply","*") - Term = Term.replace("plus","+") - Term = Term.replace("minus","-") - Term = Term.replace("divide","/") + Term = Term.replace("jarvis", "") + Term = Term.replace("multiply", "*") + Term = Term.replace("plus", "+") + Term = Term.replace("minus", "-") + Term = Term.replace("divide", "/") Final = str(Term) try: @@ -37,4 +40,4 @@ def Calc(query): Speak(result) except: - Speak("The value is not answerable") \ No newline at end of file + Speak("The value is not answerable") diff --git a/features/utilities/FocusGraph.py b/features/utilities/FocusGraph.py index d83e00b..35ddb66 100644 --- a/features/utilities/FocusGraph.py +++ b/features/utilities/FocusGraph.py @@ -1,23 +1,24 @@ -#pip install matplotlib +# pip install matplotlib import matplotlib.pyplot as pt + def focus_graph(): - file = open("focus.txt","r") + file = open("focus.txt", "r") content = file.read() file.close() content = content.split(",") x1 = [] - for i in range(0,len(content)): + for i in range(0, len(content)): content[i] = float(content[i]) x1.append(i) print(content) y1 = content - pt.plot(x1,y1,color = "red",marker = "o") - pt.title("YOUR FOCUSED TIME",fontsize = 16) - pt.xlabel("Times",fontsize = 14) - pt.ylabel("Focus Time", fontsize = 14) + pt.plot(x1, y1, color="red", marker="o") + pt.title("YOUR FOCUSED TIME", fontsize=16) + pt.xlabel("Times", fontsize=14) + pt.ylabel("Focus Time", fontsize=14) pt.grid() - pt.show() \ No newline at end of file + pt.show() diff --git a/features/utilities/Location.py b/features/utilities/Location.py index 5514ef3..4e45fbc 100644 --- a/features/utilities/Location.py +++ b/features/utilities/Location.py @@ -1,37 +1,31 @@ -import pyttsx3 import webbrowser + +import pyttsx3 import requests +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") +engine.setProperty("voice", voices[0].id) +rate = engine.setProperty("rate", 185) -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) -rate = engine.setProperty("rate",185) def Speak(audio): engine.say(audio) engine.runAndWait() -#& Using For location finding by google. +# & Using For location finding by google. def My_Location(): op = "https://www.google.com/maps/place/India/@19.7291131,61.000837,4z/data=!3m1!4b1!4m6!3m5!1s0x30635ff06b92b791:0xd78c4fa1854213a6!8m2!3d20.593684!4d78.96288!16zL20vMDNyazA?entry=ttu" Speak("Checking....") webbrowser.open(op) - ip_add = requests.get('https://api.ipify.org').text - url = 'https://get.geojs.io/v1/ip/geo/' + ip_add + '.json' + ip_add = requests.get("https://api.ipify.org").text + url = "https://get.geojs.io/v1/ip/geo/" + ip_add + ".json" geo_q = requests.get(url) geo_d = geo_q.json() - state = geo_d['city'] - country = geo_d['country'] + state = geo_d["city"] + country = geo_d["country"] Speak("Your LOcation is on screen!") print("Your LOcation is on screen!") - - - - - - - diff --git a/features/utilities/Translator.py b/features/utilities/Translator.py index 2bb926d..38c26e3 100644 --- a/features/utilities/Translator.py +++ b/features/utilities/Translator.py @@ -1,56 +1,72 @@ +import os +import time from fnmatch import translate from time import sleep + +import googletrans # pip install googletrans +import pyttsx3 +import speech_recognition from googletrans import Translator -import googletrans #pip install googletrans from gtts import gTTS -import pyttsx3 -import speech_recognition -import os -from playsound import playsound -import time +try: + from playsound import playsound + PLAYSOUND_AVAILABLE = True +except ImportError: + PLAYSOUND_AVAILABLE = False + print("Warning: playsound not available, audio playback will be skipped") engine = pyttsx3.init("sapi5") voices = engine.getProperty("voices") engine.setProperty("voice", voices[0].id) -rate = engine.setProperty("rate",185) +rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() + def takeCommand(): r = speech_recognition.Recognizer() with speech_recognition.Microphone() as source: print("Listening.....") r.pause_threshold = 1 r.energy_threshold = 300 - audio = r.listen(source,0,4) + audio = r.listen(source, 0, 4) try: print("Understanding..") - query = r.recognize_google(audio,language='en-in') + query = r.recognize_google(audio, language="en-in") print(f"You Said: {query}\n") except Exception as e: print("Say that again") return "None" return query + def translategl(query): Speak("SURE SIR") print(googletrans.LANGUAGES) translator = Translator() Speak("Choose the language in which you want to translate") - b = input("To_Lang :- ") - text_to_translate = translator.translate(query,src = "auto",dest= b,) + b = input("To_Lang :- ") + text_to_translate = translator.translate( + query, + src="auto", + dest=b, + ) text = text_to_translate.text - try : - speakgl = gTTS(text=text, lang=b, slow= False) + try: + speakgl = gTTS(text=text, lang=b, slow=False) speakgl.save("voice.mp3") - playsound("VOICE.mp3") - time.sleep(5) + if PLAYSOUND_AVAILABLE: + playsound("voice.mp3") + time.sleep(5) + else: + print("Audio playback skipped (playsound not available)") + time.sleep(2) + os.remove("voice.mp3") - except: - print("Unable to translate") - - + except Exception as e: + print(f"Unable to translate: {e}") diff --git a/features/utilities/__pycache__/Calculatenumbers.cpython-313.pyc b/features/utilities/__pycache__/Calculatenumbers.cpython-313.pyc index 6bff745..21f4d5a 100644 Binary files a/features/utilities/__pycache__/Calculatenumbers.cpython-313.pyc and b/features/utilities/__pycache__/Calculatenumbers.cpython-313.pyc differ diff --git a/features/utilities/alarm.py b/features/utilities/alarm.py index 47b67c0..ee41fd0 100644 --- a/features/utilities/alarm.py +++ b/features/utilities/alarm.py @@ -1,39 +1,43 @@ -import pyttsx3 import datetime -import os +import os + +import pyttsx3 engine = pyttsx3.init("sapi5") voices = engine.getProperty("voices") engine.setProperty("voice", voices[0].id) -engine.setProperty("rate",185) +engine.setProperty("rate", 185) + def speak(audio): engine.say(audio) engine.runAndWait() -extractedtime = open("Alarmtext.txt","rt") +extractedtime = open("Alarmtext.txt", "rt") time = extractedtime.read() Time = str(time) extractedtime.close() -deletetime = open("Alarmtext.txt","r+") +deletetime = open("Alarmtext.txt", "r+") deletetime.truncate(0) deletetime.close() + def ring(time): timeset = str(time) - timenow = timeset.replace("jarvis","") - timenow = timenow.replace("set an alarm","") - timenow = timenow.replace(" and ",":") + timenow = timeset.replace("jarvis", "") + timenow = timenow.replace("set an alarm", "") + timenow = timenow.replace(" and ", ":") Alarmtime = str(timenow) print(Alarmtime) while True: currenttime = datetime.datetime.now().strftime("%H:%M:%S") if currenttime == Alarmtime: speak("Alarm ringing,sir") - os.startfile("music.mp3") #! You can choose any music or ringtone + os.startfile("music.mp3") #! You can choose any music or ringtone elif currenttime + "00:00:30" == Alarmtime: exit() + ring(time) diff --git a/features/utilities/reminder.py b/features/utilities/reminder.py index 7c5e919..2b1e364 100644 --- a/features/utilities/reminder.py +++ b/features/utilities/reminder.py @@ -1,8 +1,10 @@ +import os +import time + import pyttsx3 import speech_recognition as sr from win10toast import ToastNotifier -import time -import os + def TakeCommand(): @@ -11,48 +13,45 @@ def TakeCommand(): print("Listening...") r.pause_threshold = 1 # r.energy_threshold = 200 - audio = r.listen(source,0,4) + audio = r.listen(source, 0, 4) try: - print("Understanding...") - query = r.recognize_google(audio, language='en-in') + print("Understanding...") + query = r.recognize_google(audio, language="en-in") print(f"Master said: {query}\n") except Exception as e: - print("Say that again please...") + print("Say that again please...") return "None" return query -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) -rate = engine.setProperty("rate",185) + +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") +engine.setProperty("voice", voices[0].id) +rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() -def remindme(): - toaster = ToastNotifier() - Speak("what is the tittle of reminder sir!") - Toasttitle = TakeCommand().lower() - Speak("What should i remind sir!") - msg = TakeCommand().lower() - minutes = float(input("How Many Minutes: ")) - seconds = minutes * 60 - print("\nRemainder Set Successfully! \n") - Speak("Reminder set Succesfully!") - time.sleep(seconds) - os.startfile("jarvisremind.mp3") - toaster.show_toast(Toasttitle, msg, duration=10, threaded=True) - while toaster.notification_active: - time.sleep(0.1) -remindme() - - - - - +def remindme(): + toaster = ToastNotifier() + Speak("what is the tittle of reminder sir!") + Toasttitle = TakeCommand().lower() + Speak("What should i remind sir!") + msg = TakeCommand().lower() + minutes = float(input("How Many Minutes: ")) + seconds = minutes * 60 + print("\nRemainder Set Successfully! \n") + Speak("Reminder set Succesfully!") + time.sleep(seconds) + os.startfile("jarvisremind.mp3") + toaster.show_toast(Toasttitle, msg, duration=10, threaded=True) + while toaster.notification_active: + time.sleep(0.1) +remindme() diff --git a/features/utilities/sendcall.py b/features/utilities/sendcall.py index 55a25e3..3394554 100644 --- a/features/utilities/sendcall.py +++ b/features/utilities/sendcall.py @@ -1,18 +1,19 @@ - import pyttsx3 import speech_recognition as sr -from twilio.rest import Client from twilio.base.exceptions import TwilioRestException +from twilio.rest import Client -engine = pyttsx3.init('sapi5') -voices = engine.getProperty('voices') -engine.setProperty('voice', voices[0].id) +engine = pyttsx3.init("sapi5") +voices = engine.getProperty("voices") +engine.setProperty("voice", voices[0].id) rate = engine.setProperty("rate", 185) + def Speak(audio): engine.say(audio) engine.runAndWait() + def TakeCommand(): r = sr.Recognizer() with sr.Microphone() as source: @@ -22,13 +23,14 @@ def TakeCommand(): try: print("Understanding...") - query = r.recognize_google(audio, language='en-in') + query = r.recognize_google(audio, language="en-in") print(f"Master said: {query}\n") except Exception as e: print("Say that again please...") return "None" return query + def send_call(): # Your Twilio account SID and auth token @@ -36,13 +38,12 @@ def send_call(): auth_token = "Your_account auth_token" client = Client(account_sid, auth_token) - call = client.calls.create( - twiml=f'', - from_='your_twillo_number', - to='whom_you_want_to_sent' + twiml=f"", + from_="your_twillo_number", + to="whom_you_want_to_sent", ) -if __name__ == '__main__': - send_call() \ No newline at end of file +if __name__ == "__main__": + send_call() diff --git a/features/utilities/task_manager.py b/features/utilities/task_manager.py index fe17fa9..eb8e53e 100644 --- a/features/utilities/task_manager.py +++ b/features/utilities/task_manager.py @@ -4,8 +4,11 @@ from datetime import datetime, timedelta from typing import Dict, List, Optional - -TASKS_FILE = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "data", "tasks.json") +TASKS_FILE = os.path.join( + os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), + "data", + "tasks.json", +) def _ensure_storage() -> None: @@ -46,24 +49,47 @@ def _parse_deadline(text: str) -> Optional[str]: now = datetime.now() - # today / tomorrow - if "today" in text: + # Handle relative days + if "next week" in text: + base = now + timedelta(days=7) + elif "next month" in text: + # Simple approximation - add 30 days + base = now + timedelta(days=30) + elif "next year" in text: + # Simple approximation - add 365 days + base = now + timedelta(days=365) + elif "today" in text: base = now elif "tomorrow" in text: base = now + timedelta(days=1) + elif "day after tomorrow" in text: + base = now + timedelta(days=2) + elif "this week" in text: + # Find next occurrence of the same weekday + days_ahead = (6 - now.weekday()) % 7 + if days_ahead == 0: + days_ahead = 7 + base = now + timedelta(days=days_ahead) + elif "this weekend" in text: + # Find next Saturday + days_ahead = (5 - now.weekday()) % 7 + if days_ahead == 0: + days_ahead = 7 + base = now + timedelta(days=days_ahead) else: base = None # weekday names weekdays = { - "monday": 0, - "tuesday": 1, - "wednesday": 2, - "thursday": 3, - "friday": 4, - "saturday": 5, - "sunday": 6, + "monday": 0, "mon": 0, + "tuesday": 1, "tue": 1, "tues": 1, + "wednesday": 2, "wed": 2, + "thursday": 3, "thu": 3, "thur": 3, "thurs": 3, + "friday": 4, "fri": 4, + "saturday": 5, "sat": 5, + "sunday": 6, "sun": 6, } + for name, idx in weekdays.items(): if name in text: days_ahead = (idx - now.weekday()) % 7 @@ -72,19 +98,48 @@ def _parse_deadline(text: str) -> Optional[str]: base = now + timedelta(days=days_ahead) break - # time like 5 pm, 17:30, 8:00 am + # Handle specific dates (basic patterns) + date_patterns = [ + r"(\d{1,2})/(\d{1,2})", # MM/DD or DD/MM + r"(\d{1,2})-(\d{1,2})", # MM-DD or DD-MM + r"(\d{1,2})\.(\d{1,2})", # MM.DD or DD.MM + ] + + for pattern in date_patterns: + date_match = re.search(pattern, text) + if date_match: + month, day = int(date_match.group(1)), int(date_match.group(2)) + # Assume current year + try: + base = now.replace(month=month, day=day) + # If the date has already passed this year, assume next year + if base < now: + base = base.replace(year=base.year + 1) + except ValueError: + # Invalid date, skip + continue + break + + # time like 5 pm, 17:30, 8:00 am, 8:30, 8am, 5pm hour = 9 minute = 0 - time_match = re.search(r"(\d{1,2})(?::(\d{2}))?\s*(am|pm)?", text) - if time_match: - hour = int(time_match.group(1)) - minute = int(time_match.group(2) or 0) - meridiem = (time_match.group(3) or "").lower() - if meridiem: - if meridiem == "pm" and hour < 12: - hour += 12 - if meridiem == "am" and hour == 12: - hour = 0 + time_patterns = [ + r"(\d{1,2})(?::(\d{2}))?\s*(am|pm)", # 5:30 pm, 8am + r"(\d{1,2})(?::(\d{2}))?(?!\s*(am|pm))", # 17:30, 8:30 (24-hour format) + ] + + for pattern in time_patterns: + time_match = re.search(pattern, text) + if time_match: + hour = int(time_match.group(1)) + minute = int(time_match.group(2) or 0) + meridiem = (time_match.group(3) or "").lower() + if meridiem: + if meridiem == "pm" and hour < 12: + hour += 12 + if meridiem == "am" and hour == 12: + hour = 0 + break if base is None: # If only time is present, assume today (or tomorrow if time already passed) @@ -97,20 +152,32 @@ def _parse_deadline(text: str) -> Optional[str]: return candidate.isoformat() -def add_task(description: str, deadline_text: Optional[str] = None, priority: Optional[str] = None) -> Dict: - tasks = _load_tasks() - task = { - "id": int(datetime.now().timestamp() * 1000), - "title": description.strip(), - "priority": _normalize_priority(priority), - "deadline": _parse_deadline(deadline_text) if deadline_text else None, - "completed": False, - "created_at": datetime.now().isoformat(), - "completed_at": None, - } - tasks.append(task) - _save_tasks(tasks) - return task +def add_task( + description: str, + deadline_text: Optional[str] = None, + priority: Optional[str] = None, +) -> Dict: + """Add a new task with enhanced error handling""" + try: + if not description or not description.strip(): + raise ValueError("Task description cannot be empty") + + tasks = _load_tasks() + task = { + "id": int(datetime.now().timestamp() * 1000), + "title": description.strip(), + "priority": _normalize_priority(priority), + "deadline": _parse_deadline(deadline_text) if deadline_text else None, + "completed": False, + "created_at": datetime.now().isoformat(), + "completed_at": None, + } + tasks.append(task) + _save_tasks(tasks) + return task + except Exception as e: + print(f"Error adding task: {e}") + raise def list_tasks(period: Optional[str] = None) -> List[Dict]: @@ -130,7 +197,9 @@ def list_tasks(period: Optional[str] = None) -> List[Dict]: result.append(t) return result if period == "week": - start = (now - timedelta(days=now.weekday())).replace(hour=0, minute=0, second=0, microsecond=0) + start = (now - timedelta(days=now.weekday())).replace( + hour=0, minute=0, second=0, microsecond=0 + ) end = start + timedelta(days=7) result = [] for t in tasks: @@ -163,14 +232,22 @@ def overdue_tasks() -> List[Dict]: def mark_completed(title_query: str) -> Optional[Dict]: - tasks = _load_tasks() - for t in tasks: - if t["title"].lower() == title_query.lower() and not t.get("completed"): - t["completed"] = True - t["completed_at"] = datetime.now().isoformat() - _save_tasks(tasks) - return t - return None + """Mark a task as completed with enhanced error handling""" + try: + if not title_query or not title_query.strip(): + return None + + tasks = _load_tasks() + for t in tasks: + if t["title"].lower() == title_query.lower() and not t.get("completed"): + t["completed"] = True + t["completed_at"] = datetime.now().isoformat() + _save_tasks(tasks) + return t + return None + except Exception as e: + print(f"Error marking task as completed: {e}") + return None def set_priority(title_query: str, priority: str) -> Optional[Dict]: @@ -192,6 +269,81 @@ def format_task(t: Dict) -> str: return f"[{pr}] {title} — {when} ({status})" +def delete_task(title_query: str) -> Optional[Dict]: + """Delete a task by title""" + tasks = _load_tasks() + for i, t in enumerate(tasks): + if t["title"].lower() == title_query.lower(): + deleted_task = tasks.pop(i) + _save_tasks(tasks) + return deleted_task + return None + + +def search_tasks(search_query: str) -> List[Dict]: + """Search tasks by title or description""" + tasks = _load_tasks() + query_lower = search_query.lower() + return [t for t in tasks if query_lower in t["title"].lower()] + + +def get_all_tasks() -> List[Dict]: + """Get all tasks (completed and pending)""" + return _load_tasks() + + +def get_task_statistics() -> Dict: + """Get task statistics for productivity insights""" + tasks = _load_tasks() + total = len(tasks) + completed = sum(1 for t in tasks if t.get("completed")) + pending = total - completed + overdue = len(overdue_tasks()) + + # Priority breakdown + high_priority = sum(1 for t in tasks if t.get("priority") == "high" and not t.get("completed")) + normal_priority = sum(1 for t in tasks if t.get("priority") == "normal" and not t.get("completed")) + low_priority = sum(1 for t in tasks if t.get("priority") == "low" and not t.get("completed")) + + return { + "total_tasks": total, + "completed_tasks": completed, + "pending_tasks": pending, + "overdue_tasks": overdue, + "completion_rate": (completed / total * 100) if total > 0 else 0, + "high_priority_pending": high_priority, + "normal_priority_pending": normal_priority, + "low_priority_pending": low_priority + } + + +def add_category(title_query: str, category: str) -> Optional[Dict]: + """Add a category to a task""" + tasks = _load_tasks() + for t in tasks: + if t["title"].lower() == title_query.lower(): + t["category"] = category.strip().lower() + _save_tasks(tasks) + return t + return None + + +def get_tasks_by_category(category: str) -> List[Dict]: + """Get tasks filtered by category""" + tasks = _load_tasks() + return [t for t in tasks if t.get("category", "").lower() == category.lower()] + + +def get_categories() -> List[str]: + """Get all unique categories""" + tasks = _load_tasks() + categories = set() + for t in tasks: + if "category" in t and t["category"]: + categories.add(t["category"]) + return sorted(list(categories)) + + def summary_text(period: str) -> str: if period == "today": items = list_tasks("today") @@ -208,6 +360,134 @@ def summary_text(period: str) -> str: if not items: return "You have no overdue tasks." return "Overdue tasks: " + "; ".join(format_task(t) for t in items[:10]) + if period == "all": + items = get_all_tasks() + if not items: + return "You have no tasks." + return "All tasks: " + "; ".join(format_task(t) for t in items[:10]) return "" +def format_statistics(stats: Dict) -> str: + """Format task statistics for voice output""" + completion_rate = round(stats["completion_rate"], 1) + return f"""Task Statistics: + Total tasks: {stats['total_tasks']} + Completed: {stats['completed_tasks']} + Pending: {stats['pending_tasks']} + Overdue: {stats['overdue_tasks']} + Completion rate: {completion_rate}% + High priority pending: {stats['high_priority_pending']} + Normal priority pending: {stats['normal_priority_pending']} + Low priority pending: {stats['low_priority_pending']}""" + + +def set_task_reminder(title_query: str, reminder_minutes: int = 30) -> Optional[Dict]: + """Set a reminder for a task""" + tasks = _load_tasks() + for t in tasks: + if t["title"].lower() == title_query.lower() and not t.get("completed"): + # Add reminder info to task + t["reminder_minutes"] = reminder_minutes + t["reminder_set"] = True + _save_tasks(tasks) + return t + return None + + +def get_tasks_needing_reminders() -> List[Dict]: + """Get tasks that need reminders based on their deadlines""" + tasks = _load_tasks() + now = datetime.now() + tasks_needing_reminders = [] + + for t in tasks: + if t.get("completed") or not t.get("deadline"): + continue + + try: + deadline = datetime.fromisoformat(t["deadline"]) + time_until_deadline = deadline - now + + # If task is due within the next hour and no reminder has been set + if (0 < time_until_deadline.total_seconds() <= 3600 and + not t.get("reminder_set")): + tasks_needing_reminders.append(t) + except Exception: + continue + + return tasks_needing_reminders + + +def get_daily_task_summary() -> str: + """Get a comprehensive daily task summary""" + today_tasks = list_tasks("today") + overdue_tasks_list = overdue_tasks() + stats = get_task_statistics() + + summary = f"Daily Task Summary:\n" + summary += f"You have {len(today_tasks)} tasks for today.\n" + + if overdue_tasks_list: + summary += f"You have {len(overdue_tasks_list)} overdue tasks.\n" + + if today_tasks: + summary += "Today's tasks:\n" + for i, task in enumerate(today_tasks[:5], 1): + priority_emoji = {"high": "🔴", "normal": "🟡", "low": "🟢"}.get(task.get("priority", "normal"), "🟡") + summary += f"{i}. {priority_emoji} {task['title']}\n" + + summary += f"\nOverall: {stats['completed_tasks']} completed, {stats['pending_tasks']} pending" + return summary + + +def get_task_help() -> str: + """Get help information for task management commands""" + help_text = """Task Management Commands: + +Adding Tasks: +- "Add task: [description]" +- "Add urgent task: [description]" +- "Create task: [description] by [deadline]" +- "New task: [description] at [time]" + +Managing Tasks: +- "What are my tasks today?" +- "Show today's tasks" +- "What are my tasks this week?" +- "Show overdue tasks" +- "List all tasks" + +Completing Tasks: +- "Mark task completed: [task name]" +- "Complete task: [task name]" +- "Finish task: [task name]" + +Task Organization: +- "Set task priority: [task name] to [high/normal/low]" +- "Add task category: [task name] to [category]" +- "Show tasks by category: [category]" +- "List categories" + +Searching and Statistics: +- "Search tasks: [search term]" +- "Find task: [search term]" +- "Task statistics" +- "Daily summary" + +Deleting Tasks: +- "Delete task: [task name]" + +Reminders: +- "Set task reminder: [task name] in [X] minutes" +- "What tasks need reminders?" + +Deadline Examples: +- "by 5 PM today" +- "before Friday" +- "at 2:30 PM tomorrow" +- "on Monday" +- "next week" +- "this weekend" +""" + return help_text diff --git a/main.py b/main.py index 7a1eeb3..82416ef 100644 --- a/main.py +++ b/main.py @@ -4,8 +4,8 @@ Main entry point for the voice assistant """ -import sys import os +import sys project_root = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, project_root) @@ -15,4 +15,4 @@ if __name__ == "__main__": print("Starting Jarvis...") - # The main execution is already handled in Jarvismain.py \ No newline at end of file + # The main execution is already handled in Jarvismain.py diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..de8cd0f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,24 @@ +# Core dependencies for Jarvis voice assistant +pyttsx3>=2.90 +SpeechRecognition>=3.10.0 +opencv-python-headless>=4.8.0 +requests>=2.31.0 +pyautogui>=0.9.54 +speedtest-cli>=2.1.3 +numpy>=1.24.0 +beautifulsoup4>=4.12.0 +plyer>=2.1.0 +nltk>=3.8.1 +pygame>=2.5.0 +psutil>=5.9.0 +wolframalpha>=5.0.0 +Pillow>=10.0.0 +pyjokes>=0.6.0 +pynput>=1.7.6 +googletrans>=4.0.0 +gtts>=2.3.0 +pywhatkit>=5.4 +wikipedia>=1.4.0 +twilio>=8.5.0 +# playsound==1.2.2 # Optional - causes CI build issues, handled gracefully in code +pywikihow>=0.5.0 diff --git a/run_tests.py b/run_tests.py index 35a4879..e2ad51b 100644 --- a/run_tests.py +++ b/run_tests.py @@ -4,10 +4,10 @@ This script runs all tests and code quality checks """ +import argparse import os -import sys import subprocess -import argparse +import sys from pathlib import Path @@ -17,9 +17,11 @@ def run_command(command, description): print(f"Running: {description}") print(f"Command: {command}") print(f"{'='*50}") - + try: - result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True) + result = subprocess.run( + command, shell=True, check=True, capture_output=True, text=True + ) print(result.stdout) if result.stderr: print("STDERR:", result.stderr) @@ -34,64 +36,78 @@ def run_command(command, description): def main(): parser = argparse.ArgumentParser(description="Run tests and code quality checks") - parser.add_argument("--skip-install", action="store_true", help="Skip installing dependencies") - parser.add_argument("--skip-format", action="store_true", help="Skip code formatting checks") + parser.add_argument( + "--skip-install", action="store_true", help="Skip installing dependencies" + ) + parser.add_argument( + "--skip-format", action="store_true", help="Skip code formatting checks" + ) parser.add_argument("--skip-lint", action="store_true", help="Skip linting") parser.add_argument("--skip-tests", action="store_true", help="Skip running tests") - parser.add_argument("--skip-security", action="store_true", help="Skip security checks") - parser.add_argument("--fix", action="store_true", help="Fix formatting issues automatically") - + parser.add_argument( + "--skip-security", action="store_true", help="Skip security checks" + ) + parser.add_argument( + "--fix", action="store_true", help="Fix formatting issues automatically" + ) + args = parser.parse_args() - + # Change to project root directory project_root = Path(__file__).parent os.chdir(project_root) - + success = True - + # Install dependencies if not args.skip_install: print("Installing development dependencies...") if not run_command( "python -m pip install -r requirements-dev.txt", - "Installing development dependencies" + "Installing development dependencies", ): print("Warning: Failed to install some dependencies, continuing...") - + # Code formatting if not args.skip_format: if args.fix: run_command("black .", "Auto-formatting code with Black") run_command("isort . --profile black", "Auto-sorting imports with isort") else: - success &= run_command("black --check .", "Checking code formatting with Black") - success &= run_command("isort --check-only .", "Checking import sorting with isort") - + success &= run_command( + "black --check .", "Checking code formatting with Black" + ) + success &= run_command( + "isort --check-only .", "Checking import sorting with isort" + ) + # Linting if not args.skip_lint: success &= run_command( "flake8 . --exclude=venv,env,.venv,.env,__pycache__ --max-line-length=127", - "Linting with flake8" + "Linting with flake8", ) - + # Type checking (optional, don't fail on this) if not args.skip_lint: run_command( "mypy . --ignore-missing-imports --exclude='venv|env|\\.venv|\\.env' || true", - "Type checking with mypy (optional)" + "Type checking with mypy (optional)", ) - + # Security checks if not args.skip_security: run_command( "bandit -r . --exclude ./venv,./env,./.venv,./.env,./tests || true", - "Security check with bandit (optional)" + "Security check with bandit (optional)", ) - + # Run tests if not args.skip_tests: - success &= run_command("python -m pytest tests/ -v", "Running tests with pytest") - + success &= run_command( + "python -m pytest tests/ -v", "Running tests with pytest" + ) + # Summary print(f"\n{'='*50}") print("SUMMARY") diff --git a/tests/__init__.py b/tests/__init__.py index c20be4a..5d3896a 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,6 +1,6 @@ # Test configuration for pytest -import sys import os +import sys # Add the project root to the Python path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/tests/__pycache__/__init__.cpython-313.pyc b/tests/__pycache__/__init__.cpython-313.pyc index 103420f..e118231 100644 Binary files a/tests/__pycache__/__init__.cpython-313.pyc and b/tests/__pycache__/__init__.cpython-313.pyc differ diff --git a/tests/__pycache__/test_calculatenumbers.cpython-313-pytest-8.4.2.pyc b/tests/__pycache__/test_calculatenumbers.cpython-313-pytest-8.4.2.pyc index 696b9eb..e0d050e 100644 Binary files a/tests/__pycache__/test_calculatenumbers.cpython-313-pytest-8.4.2.pyc and b/tests/__pycache__/test_calculatenumbers.cpython-313-pytest-8.4.2.pyc differ diff --git a/tests/__pycache__/test_greetme.cpython-313-pytest-8.4.2.pyc b/tests/__pycache__/test_greetme.cpython-313-pytest-8.4.2.pyc index 2842a39..c6a7dc1 100644 Binary files a/tests/__pycache__/test_greetme.cpython-313-pytest-8.4.2.pyc and b/tests/__pycache__/test_greetme.cpython-313-pytest-8.4.2.pyc differ diff --git a/tests/__pycache__/test_integration.cpython-313-pytest-8.4.2.pyc b/tests/__pycache__/test_integration.cpython-313-pytest-8.4.2.pyc index 6240190..5cc2d66 100644 Binary files a/tests/__pycache__/test_integration.cpython-313-pytest-8.4.2.pyc and b/tests/__pycache__/test_integration.cpython-313-pytest-8.4.2.pyc differ diff --git a/tests/test_calculatenumbers.py b/tests/test_calculatenumbers.py index 25a8035..759b493 100644 --- a/tests/test_calculatenumbers.py +++ b/tests/test_calculatenumbers.py @@ -1,10 +1,11 @@ """ Test cases for Calculatenumbers module """ -import unittest -from unittest.mock import patch, MagicMock -import sys + import os +import sys +import unittest +from unittest.mock import MagicMock, patch # Add the project root to the Python path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) @@ -14,66 +15,69 @@ except ImportError: # Skip tests if dependencies are not available import pytest - pytest.skip("Calculatenumbers module dependencies not available", allow_module_level=True) + + pytest.skip( + "Calculatenumbers module dependencies not available", allow_module_level=True + ) class TestCalculatenumbers(unittest.TestCase): """Test cases for calculator functionality""" - @patch('Calculatenumbers.WolfRamAlpha') - @patch('Calculatenumbers.Speak') + @patch("Calculatenumbers.WolfRamAlpha") + @patch("Calculatenumbers.Speak") def test_calc_basic_operations(self, mock_speak, mock_wolfram): """Test basic calculation operations""" # Mock WolfRamAlpha to return a result mock_wolfram.return_value = "42" - + # Test the Calc function Calc("jarvis what is 2 plus 2") - + # Verify WolfRamAlpha was called mock_wolfram.assert_called_once() # Verify Speak was called with the result mock_speak.assert_called_with("42") - @patch('Calculatenumbers.WolfRamAlpha') - @patch('Calculatenumbers.Speak') + @patch("Calculatenumbers.WolfRamAlpha") + @patch("Calculatenumbers.Speak") def test_calc_term_replacement(self, mock_speak, mock_wolfram): """Test that mathematical terms are correctly replaced""" mock_wolfram.return_value = "10" - + # Test various term replacements Calc("jarvis multiply 2 plus 3") - + # Get the call arguments to WolfRamAlpha call_args = mock_wolfram.call_args[0][0] - + # Verify that terms were replaced correctly self.assertNotIn("jarvis", call_args) self.assertNotIn("multiply", call_args) self.assertNotIn("plus", call_args) - @patch('Calculatenumbers.wolframalpha.Client') + @patch("Calculatenumbers.wolframalpha.Client") def test_wolfram_alpha_success(self, mock_client): """Test successful WolfRamAlpha query""" # Mock the client and result mock_result = MagicMock() mock_result.text = "42" mock_client.return_value.query.return_value.results = iter([mock_result]) - + result = WolfRamAlpha("2+2") self.assertEqual(result, "42") - @patch('Calculatenumbers.wolframalpha.Client') - @patch('Calculatenumbers.Speak') + @patch("Calculatenumbers.wolframalpha.Client") + @patch("Calculatenumbers.Speak") def test_wolfram_alpha_failure(self, mock_speak, mock_client): """Test WolfRamAlpha query failure""" # Mock the client to raise an exception mock_client.return_value.query.side_effect = Exception("API Error") - + result = WolfRamAlpha("invalid query") self.assertIsNone(result) mock_speak.assert_called_with("The value is not answerable") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_greetme.py b/tests/test_greetme.py index 49ef7bf..8f31a9d 100644 --- a/tests/test_greetme.py +++ b/tests/test_greetme.py @@ -1,96 +1,99 @@ """ Test cases for GreetMe module """ -import unittest -from unittest.mock import patch, MagicMock + import datetime -import sys import os +import sys +import unittest +from unittest.mock import MagicMock, patch # Add the project root to the Python path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) try: - from GreetMe import greetMe, Speak + from GreetMe import Speak, greetMe except ImportError: # Skip tests if dependencies are not available import unittest + raise unittest.SkipTest("GreetMe module dependencies not available") class TestGreetMe(unittest.TestCase): """Test cases for greeting functionality""" - @patch('GreetMe.Speak') - @patch('GreetMe.datetime.datetime') + @patch("GreetMe.Speak") + @patch("GreetMe.datetime.datetime") def test_greet_morning(self, mock_datetime, mock_speak): """Test morning greeting""" # Mock datetime to return morning hour mock_datetime.now.return_value.hour = 10 - + greetMe() - + # Check that the correct greeting was spoken calls = mock_speak.call_args_list self.assertTrue(any("Good Morning" in str(call) for call in calls)) self.assertTrue(any("I am Jarvis" in str(call) for call in calls)) - @patch('GreetMe.Speak') - @patch('GreetMe.datetime.datetime') + @patch("GreetMe.Speak") + @patch("GreetMe.datetime.datetime") def test_greet_afternoon(self, mock_datetime, mock_speak): """Test afternoon greeting""" # Mock datetime to return afternoon hour mock_datetime.now.return_value.hour = 15 - + greetMe() - + # Check that the correct greeting was spoken calls = mock_speak.call_args_list self.assertTrue(any("Good Afternoon" in str(call) for call in calls)) self.assertTrue(any("I am Jarvis" in str(call) for call in calls)) - @patch('GreetMe.Speak') - @patch('GreetMe.datetime.datetime') + @patch("GreetMe.Speak") + @patch("GreetMe.datetime.datetime") def test_greet_evening(self, mock_datetime, mock_speak): """Test evening greeting""" # Mock datetime to return evening hour mock_datetime.now.return_value.hour = 20 - + greetMe() - + # Check that the correct greeting was spoken calls = mock_speak.call_args_list self.assertTrue(any("Good Evening" in str(call) for call in calls)) self.assertTrue(any("I am Jarvis" in str(call) for call in calls)) - @patch('GreetMe.Speak') - @patch('GreetMe.datetime.datetime') + @patch("GreetMe.Speak") + @patch("GreetMe.datetime.datetime") def test_greet_midnight(self, mock_datetime, mock_speak): """Test midnight greeting (should be morning)""" # Mock datetime to return midnight hour mock_datetime.now.return_value.hour = 0 - + greetMe() - + # Check that the correct greeting was spoken calls = mock_speak.call_args_list self.assertTrue(any("Good Morning" in str(call) for call in calls)) - @patch('GreetMe.pyttsx3.init') + @patch("GreetMe.pyttsx3.init") def test_speak_function(self, mock_pyttsx3): """Test the Speak function""" # Mock the engine mock_engine = MagicMock() mock_pyttsx3.return_value = mock_engine - + # Import and test Speak function from GreetMe import Speak + Speak("Test message") - + # Verify engine methods were called mock_engine.say.assert_called_with("Test message") mock_engine.runAndWait.assert_called_once() -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests/test_integration.py b/tests/test_integration.py index 9077718..1869052 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -2,10 +2,11 @@ Integration tests for Jarvis modules Tests basic functionality and module imports """ -import unittest -import sys + import os -from unittest.mock import patch, MagicMock +import sys +import unittest +from unittest.mock import MagicMock, patch # Add the project root to the Python path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) @@ -18,8 +19,9 @@ def test_import_greetme(self): """Test that GreetMe module can be imported""" try: import GreetMe - self.assertTrue(hasattr(GreetMe, 'greetMe')) - self.assertTrue(hasattr(GreetMe, 'Speak')) + + self.assertTrue(hasattr(GreetMe, "greetMe")) + self.assertTrue(hasattr(GreetMe, "Speak")) except ImportError as e: self.skipTest(f"GreetMe module not available: {e}") @@ -27,8 +29,9 @@ def test_import_calculatenumbers(self): """Test that Calculatenumbers module can be imported""" try: import Calculatenumbers - self.assertTrue(hasattr(Calculatenumbers, 'Calc')) - self.assertTrue(hasattr(Calculatenumbers, 'WolfRamAlpha')) + + self.assertTrue(hasattr(Calculatenumbers, "Calc")) + self.assertTrue(hasattr(Calculatenumbers, "WolfRamAlpha")) except ImportError as e: self.skipTest(f"Calculatenumbers module not available: {e}") @@ -36,8 +39,9 @@ def test_import_joke(self): """Test that joke module can be imported""" try: import joke + # Check if the module has expected functions - self.assertTrue(hasattr(joke, '__name__')) + self.assertTrue(hasattr(joke, "__name__")) except ImportError as e: self.skipTest(f"joke module not available: {e}") @@ -45,8 +49,9 @@ def test_import_translator(self): """Test that Translator module can be imported""" try: import Translator + # Check if the module loads without errors - self.assertTrue(hasattr(Translator, '__name__')) + self.assertTrue(hasattr(Translator, "__name__")) except ImportError as e: self.skipTest(f"Translator module not available: {e}") @@ -54,74 +59,78 @@ def test_import_translator(self): class TestBasicFunctionality(unittest.TestCase): """Test basic functionality that doesn't require external APIs""" - @patch('GreetMe.pyttsx3.init') + @patch("GreetMe.pyttsx3.init") def test_speak_function_exists(self, mock_pyttsx3): """Test that Speak function exists and can be called""" try: from GreetMe import Speak - + # Mock the engine mock_engine = MagicMock() mock_pyttsx3.return_value = mock_engine - + # Test the function Speak("test") - + # Verify it was called mock_engine.say.assert_called_with("test") mock_engine.runAndWait.assert_called_once() - + except ImportError: self.skipTest("GreetMe module not available") def test_file_structure(self): """Test that expected files exist in the project""" project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - + # Check for main files expected_files = [ - 'GreetMe.py', - 'Calculatenumbers.py', - 'Jarvismain.py', - 'README.md' + "GreetMe.py", + "Calculatenumbers.py", + "Jarvismain.py", + "README.md", ] - + for file_name in expected_files: file_path = os.path.join(project_root, file_name) self.assertTrue( os.path.exists(file_path), - f"Expected file {file_name} not found at {file_path}" + f"Expected file {file_name} not found at {file_path}", ) def test_no_syntax_errors_in_python_files(self): """Test that Python files have no syntax errors""" project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - + # Get all Python files (excluding tests and virtual environments) python_files = [] for root, dirs, files in os.walk(project_root): # Skip virtual environments and test directories - dirs[:] = [d for d in dirs if d not in ['venv', 'env', '.venv', '.env', '__pycache__', '.git']] - + dirs[:] = [ + d + for d in dirs + if d not in ["venv", "env", ".venv", ".env", "__pycache__", ".git"] + ] + for file in files: - if file.endswith('.py') and not file.startswith('test_'): + if file.endswith(".py") and not file.startswith("test_"): python_files.append(os.path.join(root, file)) - + syntax_errors = [] for file_path in python_files[:10]: # Test first 10 files to avoid timeout try: - with open(file_path, 'r', encoding='utf-8', errors='ignore') as f: + with open(file_path, "r", encoding="utf-8", errors="ignore") as f: source_code = f.read() - compile(source_code, file_path, 'exec') + compile(source_code, file_path, "exec") except SyntaxError as e: syntax_errors.append(f"{file_path}: {e}") except Exception as e: # Skip files that can't be read or compiled for other reasons pass - + if syntax_errors: self.fail(f"Syntax errors found in files:\n" + "\n".join(syntax_errors)) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main()