diff --git a/.theia/settings.json b/.theia/settings.json new file mode 100644 index 000000000..e9dbffc6b --- /dev/null +++ b/.theia/settings.json @@ -0,0 +1,8 @@ +{ + "php.suggest.basic": false, + "java.errors.incompleteClasspath.severity": "ignore", + "security.workspace.trust.enabled": true, + "security.workspace.trust.startupPrompt": "never", + "security.workspace.trust.untrustedFiles": "open", + "liveServer.settings.donotShowInfoMsg": false, +} diff --git a/EmotionDetection/__init__.py b/EmotionDetection/__init__.py new file mode 100644 index 000000000..0b7bf8661 --- /dev/null +++ b/EmotionDetection/__init__.py @@ -0,0 +1 @@ +from .emotion_detection import emotion_detector diff --git a/EmotionDetection/emotion_detection.py b/EmotionDetection/emotion_detection.py new file mode 100644 index 000000000..6fe3c5a72 --- /dev/null +++ b/EmotionDetection/emotion_detection.py @@ -0,0 +1,52 @@ +import requests +import json + +def emotion_detector(text_to_analyse): + url = 'https://sn-watson-emotion.labs.skills.network/v1/watson.runtime.nlp.v1/NlpService/EmotionPredict' + headers = {"grpc-metadata-mm-model-id": "emotion_aggregated-workflow_lang_en_stock"} + payload = {"raw_document": {"text": text_to_analyse}} + + try: + # Send the POST request + response = requests.post(url, headers=headers, json=payload) + + # Check if the request was successful + if response.status_code == 200: + # Print the full response for debugging + print("Raw response:", response.text) + + # Parse the response text into a dictionary + response_dict = json.loads(response.text) + + # Check if emotionPredictions exists in the response + if 'emotionPredictions' not in response_dict or not response_dict['emotionPredictions']: + return {"error": "No emotion predictions found in the response."} + + # Extract the emotion predictions + emotions = response_dict['emotionPredictions'][0]['emotion'] + + # List of required emotions + required_emotions = ['anger', 'disgust', 'fear', 'joy', 'sadness'] + + # Extract the scores for each emotion + emotion_scores = {emotion: emotions.get(emotion, 0.0) for emotion in required_emotions} + + # Find the dominant emotion (the one with the highest score) + dominant_emotion = max(emotion_scores, key=emotion_scores.get) + + # Return the result in the desired format + return { + 'anger': emotion_scores['anger'], + 'disgust': emotion_scores['disgust'], + 'fear': emotion_scores['fear'], + 'joy': emotion_scores['joy'], + 'sadness': emotion_scores['sadness'], + 'dominant_emotion': dominant_emotion + } + else: + return {"error": f"Request failed with status code {response.status_code}"} + + except requests.exceptions.RequestException as e: + return {"error": f"Request failed: {str(e)}"} + except json.JSONDecodeError: + return {"error": "Failed to parse the response as JSON"} diff --git a/server.py b/server.py new file mode 100644 index 000000000..3e49b41ed --- /dev/null +++ b/server.py @@ -0,0 +1,64 @@ +""" +Emotion Detection Flask Application. + +This module defines a Flask web application that exposes an API for emotion detection. +It receives a text input via a POST request and returns the emotional analysis, including +emotion scores (anger, disgust, fear, joy, sadness) and the dominant emotion. + +The application communicates with an external emotion detection service to classify the +emotions present in the provided text. + +Modules: + - Flask: Web framework for handling HTTP requests. + - requests: For sending HTTP requests to the external emotion detection service. + - json: For parsing JSON responses. + +""" + + +from flask import Flask, request, jsonify +from EmotionDetection.emotion_detection import emotion_detector + +# Initialize the Flask application +app = Flask(__name__) + +@app.route("/emotionDetector", methods=["POST"]) +def emotion_detector_route(): + """ + Handle the emotion detection request. + + This function accepts a POST request containing the text to analyze. + It returns the emotion detection result or an error message if the input is invalid. + + Returns: + Response: A JSON object containing the emotion detection results or an error message. + """ + # Get the text to analyze from the request + data = request.get_json() + text_to_analyse = data.get("text", "") + + # Validate if the text is provided + if not text_to_analyse: + return jsonify({"error": "No text provided"}), 400 + + # Call the emotion detector function + result = emotion_detector(text_to_analyse) + + # Check if dominant_emotion is None and return error message + if result.get("dominant_emotion") is None: + return jsonify({"response": "Invalid text! Please try again."}), 400 + + # Format the response as required by the customer + emotion_summary = ( + f"For the given statement, the system response is " + f"'anger': {result['anger']}, 'disgust': {result['disgust']}, " + f"'fear': {result['fear']}, 'joy': {result['joy']} and " + f"'sadness': {result['sadness']}. The dominant emotion is {result['dominant_emotion']}." + ) + + # Return the formatted response + return jsonify({"response": emotion_summary}) + +if __name__ == '__main__': + # Run the application + app.run(host='0.0.0.0', port=5000, debug=True) diff --git a/static/mywebscript.js b/static/mywebscript.js index 53d424977..9115ef940 100644 --- a/static/mywebscript.js +++ b/static/mywebscript.js @@ -1,12 +1,30 @@ -let RunSentimentAnalysis = ()=>{ - textToAnalyze = document.getElementById("textToAnalyze").value; +let RunSentimentAnalysis = () => { + // Get the text to analyze from the input field + let textToAnalyze = document.getElementById("textToAnalyze").value; + // Create a new XMLHttpRequest object let xhttp = new XMLHttpRequest(); + + // Define what happens when the request is completed xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { - document.getElementById("system_response").innerHTML = xhttp.responseText; + // Parse the JSON response from the server + let response = JSON.parse(xhttp.responseText); + // Display the response text in the 'system_response' div + document.getElementById("system_response").innerHTML = response.response; + } else if (this.readyState == 4 && this.status == 400) { + // Handle status code 400 (invalid text) + document.getElementById("system_response").innerHTML = "Invalid text! Please try again."; + } else if (this.readyState == 4) { + // Handle other error responses + document.getElementById("system_response").innerHTML = "Error: " + xhttp.responseText; } }; - xhttp.open("GET", "emotionDetector?textToAnalyze"+"="+textToAnalyze, true); - xhttp.send(); -} + + // Prepare the POST request + xhttp.open("POST", "/emotionDetector", true); + xhttp.setRequestHeader("Content-Type", "application/json"); + + // Send the text data as JSON in the request body + xhttp.send(JSON.stringify({ text: textToAnalyze })); +}; \ No newline at end of file diff --git a/test_emotion_detection.py b/test_emotion_detection.py new file mode 100644 index 000000000..195cdb53a --- /dev/null +++ b/test_emotion_detection.py @@ -0,0 +1,32 @@ +import unittest +from EmotionDetection import emotion_detector + +class TestEmotionDetection(unittest.TestCase): + + def test_joy(self): + statement = "I am glad this happened" + result = emotion_detector(statement) + self.assertEqual(result['dominant_emotion'], 'joy') + + def test_anger(self): + statement = "I am really mad about this" + result = emotion_detector(statement) + self.assertEqual(result['dominant_emotion'], 'anger') + + def test_disgust(self): + statement = "I feel disgusted just hearing about this" + result = emotion_detector(statement) + self.assertEqual(result['dominant_emotion'], 'disgust') + + def test_sadness(self): + statement = "I am so sad about this" + result = emotion_detector(statement) + self.assertEqual(result['dominant_emotion'], 'sadness') + + def test_fear(self): + statement = "I am really afraid that this will happen" + result = emotion_detector(statement) + self.assertEqual(result['dominant_emotion'], 'fear') + +if __name__ == '__main__': + unittest.main()