import gradio as gr import pandas as pd import asyncio import tempfile from edge_tts import Communicate # Global cart to store ordered items cart = [] # Load Menu Data def load_menu(): menu_file = "menu.xlsx" # Ensure this file exists in the same directory try: return pd.read_excel(menu_file) except Exception as e: raise ValueError(f"Error loading menu file: {e}") # Generate Text-to-Speech Response async def generate_tts_response(text): communicate = Communicate(text, "en-US-JennyNeural") with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file: await communicate.save(tmp_file.name) return tmp_file.name # Search for Dish def search_dish(dish_name): menu_data = load_menu() dish = menu_data[menu_data["Dish Name"].str.contains(dish_name, case=False, na=False)] return dish # Handle Voice Commands async def handle_voice_command(audio_path, preference): transcription = transcribe_audio(audio_path) transcription = transcription.lower() if "menu items" in transcription: menu_text = list_menu_items(preference) audio_response = await generate_tts_response(menu_text) return audio_response, preference, f"Menu: {menu_text}" if transcription.startswith("order"): dish_name = transcription.replace("order", "").strip() dish = search_dish(dish_name) if not dish.empty: # Add to cart item_name = dish.iloc[0]["Dish Name"] item_price = dish.iloc[0]["Price ($)"] cart.append({"name": item_name, "price": item_price}) confirmation_text = f"{item_name} is available for ${item_price}. Order confirmed and added to cart." audio_response = await generate_tts_response(confirmation_text) return audio_response, preference, confirmation_text else: unavailable_text = f"Sorry, {dish_name} is not available in the menu." audio_response = await generate_tts_response(unavailable_text) return audio_response, preference, unavailable_text # Out-of-Topic Response out_of_topic_response = "Sorry, I didn't understand that. Please respond according to the menu." audio_response = await generate_tts_response(out_of_topic_response) return audio_response, preference, out_of_topic_response # List Menu Items def list_menu_items(preference): menu_data = load_menu() if preference == "Halal/Non-Veg": filtered_data = menu_data[menu_data["Ingredients"].str.contains("Chicken|Mutton|Fish|Prawns|Goat", case=False, na=False)] elif preference == "Vegetarian": filtered_data = menu_data[~menu_data["Ingredients"].str.contains("Chicken|Mutton|Fish|Prawns|Goat", case=False, na=False)] elif preference == "Guilt-Free": filtered_data = menu_data[menu_data["Description"].str.contains(r"Fat: ([0-9]|10)g", case=False, na=False)] else: filtered_data = menu_data # Create a textual summary for speech text_summary = "" for _, item in filtered_data.iterrows(): text_summary += f"{item['Dish Name']} for ${item['Price ($)']}. " if not text_summary: text_summary = "No items available in this category." return text_summary # Transcribe Audio Placeholder def transcribe_audio(audio_path): # Replace with actual transcription logic (e.g., Whisper API or Google Speech-to-Text) return "menu items" # Example transcription for testing # Gradio App def app(): with gr.Blocks() as demo: with gr.Row(): gr.Markdown("## Welcome to the Menu") with gr.Row(): audio_input = gr.Audio(label="Speak your preference or order", type="filepath") tts_output = gr.Audio(label="Assistant Response", autoplay=True) preference = gr.Textbox(label="Preference", value="All", interactive=False) menu_output = gr.Textbox(label="Transcript", value="") cart_output = gr.Textbox(label="Cart", value="Your cart is empty.", interactive=False) # Update outputs dynamically audio_input.change( handle_voice_command, inputs=[audio_input, preference], outputs=[tts_output, preference, menu_output], ) # Update cart content dynamically def update_cart(): if cart: cart_content = "\n".join([f"{item['name']} - ${item['price']}" for item in cart]) else: cart_content = "Your cart is empty." return cart_content gr.Button("Update Cart").click( update_cart, inputs=[], outputs=cart_output ) return demo if __name__ == "__main__": demo = app() demo.launch()