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, quantities, and prices MENU = { "Biryanis": {"Chicken Biryani": 250, "Veg Biryani": 200, "Mutton Biryani": 300}, "Starters": {"Chicken Wings": 220, "Paneer Tikka": 180, "Fish Fingers": 250, "Spring Rolls": 160}, "Rotis": {"Butter Naan": 50, "Garlic Naan": 60, "Roti": 40, "Lachha Paratha": 70}, "Main Course": {"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}, } current_category = None current_item = None awaiting_quantity = False # Extract quantity from command (e.g., "two" -> 2, "three" -> 3, etc.) def extract_quantity(command): number_words = { "one": 1, "two": 2, "three": 3, "four": 4, "five": 5, "six": 6, "seven": 7, "eight": 8, "nine": 9, "ten": 10, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10 } command_words = command.split() for word in command_words: if word in number_words: return number_words[word] return None # HTML Template for Frontend html_code = """ AI Dining Assistant

AI Dining Assistant

Press the mic button to start...
""" @app.route("/") def index(): return render_template_string(html_code) @app.route("/process-audio", methods=["POST"]) def process_audio(): global current_category, current_item, awaiting_quantity 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) logging.info(f"Recognized command: {command}") response = process_command(command) except sr.UnknownValueError: response = "Sorry, I couldn't understand your command. Could you please repeat?" except sr.RequestError as e: response = f"Error with the speech recognition service: {e}" 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, current_category, current_item, awaiting_quantity command = command.lower() # Handle quantity input if awaiting_quantity: quantity = extract_quantity(command) if quantity: cart.append((current_item, MENU[current_category][current_item], quantity)) awaiting_quantity = False item = current_item current_item = None total = sum(i[1] * i[2] for i in cart) cart_summary = ", ".join([f"{i[0]} x{i[2]} (₹{i[1] * i[2]})" for i in cart]) return f"Added {quantity} x {item} to your cart. Your current cart: {cart_summary}. Total: ₹{total}. Would you like to add more items?" else: return "Sorry, I couldn't understand the quantity. Please provide a valid quantity." # Handle category selection for category, items in MENU.items(): if category.lower() in command: current_category = 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 item selection with dynamic matching if current_category: for item in MENU[current_category].keys(): if item.lower().startswith(command) or command in item.lower(): current_item = item awaiting_quantity = True return f"How many quantities of {current_item} would you like?" # Handle item removal if "remove" in command: for item in cart: if item[0].lower() in command: cart.remove(item) total = sum(i[1] * i[2] for i in cart) cart_summary = ", ".join([f"{i[0]} x{i[2]} (₹{i[1] * i[2]})" for i in cart]) return f"Removed {item[0]} from your cart. Updated cart: {cart_summary}. Total: ₹{total}." return "The item you are trying to remove is not in your cart." # Handle final order if "final order" in command or "submit" in command or "Proceed" in command or "place the order" in command: if cart: order_details = ", ".join([f"{item[0]} x{item[2]} (₹{item[1] * item[2]})" for item in cart]) total = sum(item[1] * item[2] for item in cart) cart.clear() return f"Your final order is: {order_details}. Total price: ₹{total}. Your order will arrive soon, Thank you for visiting Biryani Hub!" else: return "Your cart is empty. Please add items before placing the final order." # Handle cart details if "cart details" in command: if cart: cart_summary = "\n".join([f"{i[0]} x{i[2]} (₹{i[1] * i[2]})" for i in cart]) total = sum(i[1] * i[2] for i in cart) return f"Your cart contains:\n{cart_summary}\nTotal: ₹{total}." else: return "Your cart is empty." # Handle menu request if "menu" in command or "yes" in command or "yeah" in command: categories = ", ".join(MENU.keys()) return f"We have the following categories: {categories}. Please select a category to proceed." # Default response return "Sorry, I didn't understand that. Please try again." if __name__ == "__main__": app.run(host="0.0.0.0", port=7860)