File size: 8,684 Bytes
408a4d8
de42bf3
5e1848a
 
de42bf3
cce0f39
 
408a4d8
 
cce0f39
 
b1431be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0af1f1a
f73965a
cce0f39
408a4d8
 
 
 
 
 
 
 
 
 
b1431be
408a4d8
 
 
 
 
0347f6c
 
 
 
 
 
 
 
 
 
b1431be
408a4d8
 
 
 
 
 
0347f6c
b1431be
408a4d8
 
0347f6c
408a4d8
 
af79f32
717f735
0347f6c
af79f32
 
b1431be
283764f
 
717f735
b1431be
 
 
 
 
d5b9194
b1431be
283764f
717f735
b1431be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283764f
b1431be
 
408a4d8
b1431be
 
 
 
 
 
 
 
 
 
283764f
408a4d8
 
 
 
 
b1431be
408a4d8
 
 
b1431be
408a4d8
 
b1431be
cce0f39
 
 
 
5e1848a
cce0f39
 
 
de42bf3
30e1c24
b1431be
 
 
30e1c24
408a4d8
30e1c24
408a4d8
646145e
 
 
b1431be
 
30e1c24
5e1848a
cce0f39
 
b1431be
408a4d8
b1431be
cce0f39
b1431be
 
cce0f39
408a4d8
b1431be
408a4d8
d54e93f
b1431be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9397cbf
b1431be
d54e93f
b1431be
 
 
 
408a4d8
b1431be
713e663
408a4d8
9397cbf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
from flask import Flask, render_template_string, request, jsonify
import speech_recognition as sr
from tempfile import NamedTemporaryFile
import os
import ffmpeg
import logging
from werkzeug.exceptions import BadRequest

app = Flask(__name__)
logging.basicConfig(level=logging.INFO)

# Global variables
cart = []  # To store items and prices
MENU = {
    "Biryani": {"Chicken Biryani": 250, "Veg Biryani": 200, "Mutton Biryani": 300},
    "Starters": {
        "Chicken Wings": 220,
        "Paneer Tikka": 180,
        "Fish Fingers": 250,
        "Spring Rolls": 160,
    },
    "Breads": {
        "Butter Naan": 50,
        "Garlic Naan": 60,
        "Roti": 40,
        "Lachha Paratha": 70,
    },
    "Curries": {
        "Butter Chicken": 300,
        "Paneer Butter Masala": 250,
        "Dal Tadka": 200,
        "Chicken Tikka Masala": 320,
    },
    "Drinks": {"Coke": 60, "Sprite": 60, "Mango Lassi": 80, "Masala Soda": 70},
    "Desserts": {
        "Gulab Jamun": 100,
        "Rasgulla": 90,
        "Ice Cream": 120,
        "Brownie with Ice Cream": 180,
    },
}

# HTML Template for Frontend
html_code = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI Dining Assistant</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            background-color: #f4f4f9;
        }
        h1 {
            color: #333;
        }
        .mic-button {
            width: 80px;
            height: 80px;
            border-radius: 50%;
            background-color: #007bff;
            color: white;
            font-size: 24px;
            border: none;
            cursor: pointer;
        }
        .status, .response {
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>AI Dining Assistant</h1>
    <button class="mic-button" id="mic-button">🎤</button>
    <div class="status" id="status">Press the mic button to start...</div>
    <div class="response" id="response" style="display: none;">Response will appear here...</div>
    <script>
        const micButton = document.getElementById('mic-button');
        const status = document.getElementById('status');
        const response = document.getElementById('response');
        let isListening = false;

        micButton.addEventListener('click', () => {
            if (!isListening) {
                isListening = true;
                greetUser();
            }
        });

        function greetUser() {
            const utterance = new SpeechSynthesisUtterance("Hi. Welcome to Biryani Hub. Can I show you the menu?");
            speechSynthesis.speak(utterance);
            utterance.onend = () => {
                status.textContent = "Listening...";
                startListening();
            };
        }

        async function startListening() {
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
            const mediaRecorder = new MediaRecorder(stream, { mimeType: "audio/webm;codecs=opus" });
            const audioChunks = [];

            mediaRecorder.ondataavailable = (event) => audioChunks.push(event.data);
            mediaRecorder.onstop = async () => {
                const audioBlob = new Blob(audioChunks, { type: "audio/webm" });
                const formData = new FormData();
                formData.append("audio", audioBlob);

                status.textContent = "Processing...";
                try {
                    const result = await fetch("/process-audio", { method: "POST", body: formData });
                    const data = await result.json();
                    response.textContent = data.response;
                    response.style.display = "block";

                    const utterance = new SpeechSynthesisUtterance(data.response);
                    speechSynthesis.speak(utterance);
                    utterance.onend = () => {
                        if (!data.response.includes("Goodbye") && !data.response.includes("final order")) {
                            startListening(); // Continue listening
                        } else {
                            status.textContent = "Conversation ended.";
                            isListening = false;
                        }
                    };
                } catch (error) {
                    response.textContent = "Error processing your request. Please try again.";
                    status.textContent = "Press the mic button to restart.";
                    isListening = false;
                }
            };

            mediaRecorder.start();
            setTimeout(() => mediaRecorder.stop(), 5000); // Stop recording after 5 seconds
        }
    </script>
</body>
</html>
"""

@app.route("/")
def index():
    return render_template_string(html_code)

@app.route("/process-audio", methods=["POST"])
def process_audio():
    try:
        audio_file = request.files.get("audio")
        if not audio_file:
            raise BadRequest("No audio file provided.")

        temp_file = NamedTemporaryFile(delete=False, suffix=".webm")
        audio_file.save(temp_file.name)

        if os.path.getsize(temp_file.name) == 0:
            raise BadRequest("Uploaded audio file is empty.")

        converted_file = NamedTemporaryFile(delete=False, suffix=".wav")
        ffmpeg.input(temp_file.name).output(
            converted_file.name, acodec="pcm_s16le", ac=1, ar="16000"
        ).run(overwrite_output=True)

        recognizer = sr.Recognizer()
        with sr.AudioFile(converted_file.name) as source:
            audio_data = recognizer.record(source)
            try:
                command = recognizer.recognize_google(audio_data)
                response = process_command(command)
            except sr.UnknownValueError:
                response = "Sorry, I could not understand. Please try again."

        return jsonify({"response": response})

    except BadRequest as br:
        return jsonify({"response": f"Bad Request: {str(br)}"}), 400
    except Exception as e:
        return jsonify({"response": f"An error occurred: {str(e)}"}), 500
    finally:
        os.unlink(temp_file.name)
        os.unlink(converted_file.name)

def process_command(command):
    global cart, MENU
    command = command.lower()

    # Handle specific category requests
    for category in MENU.keys():
        if category.lower() in command:
            items = MENU[category]
            item_list = ", ".join([f"{item} (₹{price})" for item, price in items.items()])
            return f"{category} menu: {item_list}. What would you like to order?"

    # Handle full menu request
    if "menu" in command:
        categories = ", ".join(MENU.keys())
        return f"We have the following categories: {categories}. Which one would you like to explore?"

    # Add items to the cart
    all_items = {item.lower(): (category, price) for category, items in MENU.items() for item, price in items.items()}
    if command in all_items.keys():
        category, price = all_items[command]
        cart.append((command.title(), price))
        total = sum(item[1] for item in cart)
        cart_summary = ", ".join([f"{i[0]} (₹{i[1]})" for i in cart])
        return f"{command.title()} added to your cart. Your cart: {cart_summary}. Total: ₹{total}. Do you want to order anything else?"

    # Remove items from the cart
    if "remove" in command:
        for item in cart:
            if item[0].lower() in command:
                cart.remove(item)
                total = sum(i[1] for i in cart)
                cart_summary = ", ".join([f"{i[0]} (₹{i[1]})" for i in cart])
                return f"{item[0]} removed from your cart. Updated cart: {cart_summary}. Total: ₹{total}."
        return "The item you are trying to remove is not in your cart. Please check again."

    # Handle final order
    if "final order" in command or "submit" in command:
        if cart:
            items = ", ".join([f"{item[0]} (₹{item[1]})" for item in cart])
            total = sum(item[1] for item in cart)
            cart.clear()
            return f"Your final order is: {items}. Total price: ₹{total}. Thank you for ordering!"
        else:
            return "Your cart is empty. Please add items first."

    # Handle goodbye
    if "no" in command or "nothing" in command or "goodbye" in command:
        cart.clear()
        return "Goodbye! Thank you for using AI Dining Assistant."

    return "Sorry, I didn't understand that. Please try again."

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=7860)