diff --git a/.gitignore b/.gitignore index 08a57f9..ac44d2d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ conversations/audio/ tests/audio/ tests/mochawesome-report package-lock.json -service/subprocesses/node_modules/ \ No newline at end of file +service/subprocesses/node_modules/ +service/jarvis.db \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 1a276f5..8df5135 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,13 @@ before-install: - . $HOME/.nvm/nvm.sh - nvm install stable - nvm use stable - - go get -u -v -d ./... + - go get -u github.com/Harkishen-Singh/Jarvis-personal-assistant/service/controllers + - go get -u github.com/Harkishen-Singh/Jarvis-personal-assistant/service/utils + - go get -u github.com/hegedustibor/htgo-tts + - go get -u github.com/mattn/go-sqlite3 + - go get -u github.com/op/go-logging + - go get -u github.com/Harkishen-Singh/Jarvis-personal-assistant/service/messages + - go get -u github.com/Harkishen-Singh/Jarvis-personal-assistant/service/messages - cd tests/ - cd npm install @@ -51,4 +57,3 @@ script: - cd tests/ - npm install - xvfb-run -s "-screen 0 1920x1080x16" -a mocha test.js - diff --git a/Readme.md b/Readme.md index db8ad91..fe0dda7 100644 --- a/Readme.md +++ b/Readme.md @@ -6,13 +6,13 @@ ## Introduction -The project aims to develop a personal-assistant for Linux-based systems. Jarvis draws its inspiration from virtual assistants like Cortana for Windows, and Siri for iOS. It has been designed to provide a user-friendly interface for carrying out a variety of tasks by employing certain well-defined commands. Users can interact with the assistant either through voice commands or using a keyboard input. +The project aims to develop a personal-assistant for Linux-based systems. Jarvis draws its inspiration from virtual assistants like Cortana for Windows, and Siri for iOS. It has been designed to provide a user-friendly interface for carrying out a variety of tasks by employing certain well-defined commands. Users can interact with the assistant either through ***voice commands or using a keyboard input***. To know the steps to install and run the project click [here](https://github.com/Harkishen-Singh/Jarvis-personal-assistant/blob/master/INSTALL.md) ## What Jarvis can do? -As a personal assistant, Jarvis assists the end-user with day-to-day activities like general human conversation, searching queries in google, bing or yahoo, searching for videos, retrieving images, live weather conditions, word meanings, searching for medicine details, health recommendations based on symptoms and reminding the user about the scheduled events and tasks. The user statements/commands are analysed with the help of machine learning to give an optimal solution. +As a personal assistant, Jarvis assists the end-user with day-to-day activities like *general human conversation, searching queries in google, bing or yahoo, searching for videos, retrieving images, live weather conditions, word meanings, searching for medicine details, health recommendations based on symptoms and reminding the user about the scheduled events and tasks*. The user statements/commands are analysed with the help of **machine learning** to give an optimal solution. ## Features @@ -38,6 +38,20 @@ Image “image you want to search” For getting meaning of a word format is,
meaning "word you are searching for" +**Medicine Details**
+Get the complete details of the medicine, including : +1. Indications +2. Contradictions +3. Trade/Brand Names +4. Indications +5. Dosage +6. Process of consumption +7. Warnings and Precautions related to the medicine +8. Storage conditions + +**Medicine Help based on symptoms**
+List your noticed symptoms and get immediate help on the medicines that could be taken. + ## Technology used
**Front-end**
diff --git a/service/controllers/messages.go b/service/controllers/messages.go index 4a29992..2792056 100644 --- a/service/controllers/messages.go +++ b/service/controllers/messages.go @@ -26,6 +26,12 @@ type messageQueryBody struct { // Link string `json:"link"` // } +type reminderResponse struct { + Status bool `json:"status"` + Message string `json:"message"` + Result []reminder `json:"result"` +} + type jsonResponseQuery struct { Status bool `json:"status"` Message string `json:"message"` @@ -72,7 +78,7 @@ type jsonResponseMeaning struct { } // MessagesController controls messages handling func MessagesController(w http.ResponseWriter, r *http.Request) { - + w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Headers", "Content-Type") r.ParseForm() @@ -328,6 +334,19 @@ func routes(routeObject response, w http.ResponseWriter) { result := messages.HealthController(med, w) TextToSpeech(result, 0) } + } else if strings.HasPrefix(strings.ToLower(message),"set reminder") { + w.Write([]byte(`{"status": "success", "message": "Enter Reminder details : ", "result": ""}`)) + } else if strings.HasPrefix(strings.ToLower(message),"show reminder") { + result := ShowReminder() + fmt.Println(result) + responseJSON := reminderResponse { + Status: true, + Message: "Here are your reminders : ", + Result: result, + } + jData, _ := json.Marshal(responseJSON) + w.Write(jData) + TextToSpeech("Here are your reminders.", 0) } else { // general conversation speech := messages.GeneralConvHandler(routeObject.message, routeObject.username, w) @@ -338,6 +357,19 @@ func routes(routeObject response, w http.ResponseWriter) { if strings.ToLower(firstPars) == "google" || strings.ToLower(firstPars) == "yahoo" || strings.ToLower(firstPars) == "bing" || strings.ToLower(firstPars) == "youtube" || strings.ToLower(firstPars) == "image" || strings.ToLower(firstPars) == "weather" { w.Write([]byte(`{"status": "success", "message": "Services unavailable at the moment ! Check your Internet Connection and try again.", "result": ""}`)) TextToSpeech("Services unavailable at the moment!", 0) + } else if strings.HasPrefix(strings.ToLower(message),"set reminder") { + w.Write([]byte(`{"status": "success", "message": "Enter Reminder details : ", "result": ""}`)) + } else if strings.HasPrefix(strings.ToLower(message),"show reminder") { + result := ShowReminder() + fmt.Println(result) + responseJSON := reminderResponse { + Status: true, + Message: "Here are your reminders : ", + Result: result, + } + jData, _ := json.Marshal(responseJSON) + w.Write(jData) + TextToSpeech("Here are your reminders.", 0) } else { // general conversation speech := messages.GeneralConvHandler(routeObject.message, routeObject.username, w) diff --git a/service/controllers/set_reminder.go b/service/controllers/set_reminder.go new file mode 100644 index 0000000..9aab083 --- /dev/null +++ b/service/controllers/set_reminder.go @@ -0,0 +1,100 @@ +package controllers + +import ( + "net/http" + "database/sql" + "fmt" + "log" + + _ "github.com/mattn/go-sqlite3" +) + +type reminder struct { + Id int `json:"id"` + Title string `json:"title"` + Description string `json:"description"` + Time string `json:"time"` +} + +// ReminderController controls reminder operations +func ReminderController(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Headers", "Content-Type") + r.ParseForm() + + request := reminder{ + Title: r.FormValue("title"), + Description: r.FormValue("description"), + Time: r.FormValue("time"), + } + fmt.Println(request) + + addReminder(request, w) + +} + +func addReminder(reminderObject reminder, w http.ResponseWriter) { + + db, err := sql.Open("sqlite3", "./jarvis.db") + checkErr(err) + defer db.Close() + + sqlStmt := `CREATE TABLE IF NOT EXISTS reminder (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, description TEXT, time TEXT);` + _, err = db.Exec(sqlStmt) + if err != nil { + log.Printf("%q: %s\n", err, sqlStmt) + return + } + + tx, err := db.Begin() + checkErr(err) + + stmt, err := tx.Prepare("insert into reminder(title, description, time) values(?, ?, ?)") + checkErr(err) + defer stmt.Close() + + _, err = stmt.Exec(reminderObject.Title, reminderObject.Description, reminderObject.Time) + checkErr(err) + tx.Commit() + + w.Write([]byte(`{"status": "success", "message": "Reminder has been set !"}`)) +} + +func ShowReminder() []reminder{ + var result []reminder + + db, err := sql.Open("sqlite3", "./jarvis.db") + checkErr(err) + defer db.Close() + + rows, err := db.Query("select id, title, description, time from reminder") + checkErr(err) + + defer rows.Close() + for rows.Next() { + var id int + var title string + var description string + var time string + err = rows.Scan(&id, &title, &description, &time) + checkErr(err) + + r := reminder { + Id: id, + Title: title, + Description: description, + Time: time, + } + result = append(result, r) + } + err = rows.Err() + checkErr(err) + + return result +} + +func checkErr(err error) { + if err != nil { + log.Fatal(err) + } +} \ No newline at end of file diff --git a/service/utils/service.go b/service/utils/service.go index 584fa12..3a0b7e4 100644 --- a/service/utils/service.go +++ b/service/utils/service.go @@ -9,6 +9,7 @@ import ( func routes() { http.HandleFunc("/", controllers.HomeController) http.HandleFunc("/message", controllers.MessagesController) + http.HandleFunc("/reminder", controllers.ReminderController) } // Server service server for Jarvis diff --git a/view/app-jarvis.js b/view/app-jarvis.js index c5d9b5a..482b0b8 100644 --- a/view/app-jarvis.js +++ b/view/app-jarvis.js @@ -95,6 +95,7 @@ app.controller('MainController', function($scope,$location,$rootScope,$http) { show: false, length: null }; + console.log(messageObj) console.log(res); setTimeout(() => { $scope.scrollDown(); @@ -131,6 +132,21 @@ app.controller('MainController', function($scope,$location,$rootScope,$http) { messageObj.result = result; $scope.messageStack.push(messageObj); $scope.showLoading = false; + } else if ((status === 'success' || status) && message === 'Enter Reminder details : ') { + messageObj.sender = 'jarvis-bot'; + messageObj.time = String(new Date().getHours() + ':' + new Date().getMinutes()); + messageObj.length = message.length; + messageObj.message = message; + $scope.messageStack.push(messageObj); + } else if ((status === 'success' || status) && message === 'Here are your reminders : ') { + console.log("In show reminder"); + messageObj.sender = 'jarvis-bot'; + messageObj.time = String(new Date().getHours() + ':' + new Date().getMinutes()); + messageObj.length = message.length; + messageObj.message = message; + messageObj.result = result; + $scope.messageStack.push(messageObj); + console.log(messageObj); } else if ((status === 'success' || status) && !show) { messageObj.sender = 'jarvis-bot'; messageObj.time = String(new Date().getHours() + ':' + new Date().getMinutes()); @@ -162,6 +178,67 @@ app.controller('MainController', function($scope,$location,$rootScope,$http) { } }; + $scope.formData = {}; + $scope.setReminder = function() { + $scope.messageStack.pop(); + let reminder_title = $scope.formData.remTitle, + reminder_description = $scope.formData.remDescription, + reminder_time = $scope.formData.remTime, + + reminderObj = { + title: '', + description: '', + time: '' + }, + data = null; + + reminderObj.title = reminder_title; + reminderObj.description = reminder_description; + reminderObj.time = reminder_time; + + console.log(reminderObj); + + data = 'title='+reminderObj.title+'&description='+reminderObj.description+'&time='+reminderObj.time; + + console.log(data); + + $http({ + url:URL+'/reminder', + method:'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, + data:data + }).then(resp => { + let res = (resp.data), + message = res['message'], + status = res['status'], + messageObj = { + message: '', + sender: '', + time: '', + show: false, + length: null + }; + setTimeout(() => { + $scope.scrollDown(); + }, 100); + if ((status === 'success' || status) && message === 'Reminder has been set !') { + messageObj.sender = 'jarvis-bot'; + messageObj.time = String(new Date().getHours() + ':' + new Date().getMinutes()); + messageObj.length = message.length; + messageObj.message = message; + $scope.messageStack.push(messageObj); + } else { + console.error('[JARVIS] error fetching from service.'); + } + }).catch(e => { + throw e; + }); + $scope.formData.remTitle = ''; + $scope.formData.remDescription = ''; + } + $scope.scrollDown = function() { var elem = document.getElementById('stackArea-parent'); elem.scrollTop = elem.scrollHeight; diff --git a/view/components/main.html b/view/components/main.html index b6c40a6..345a9f1 100644 --- a/view/components/main.html +++ b/view/components/main.html @@ -101,6 +101,63 @@

{{$index + 1}}. {{objectQuery.head}}

+
+
+ {{message.message}} + + + {{message.sender}} + {{message.time}} + + +
+
+
+
+
+ + +
+ +
+ + +
+ + +
+ + +
+ + + +
+
+
+
+
+ {{message.message}} + + + {{message.sender}} + {{message.time}} + + +
+
+
+
+

{{objectQuery.id}}. {{objectQuery.title}}

+

{{objectQuery.description}}

+
+

Due: {{objectQuery.time}}

+
+
+
+
{{message.message}}