geethareddy commited on
Commit
6927368
·
verified ·
1 Parent(s): bd8aaca

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +249 -35
app.py CHANGED
@@ -1,8 +1,16 @@
1
- from flask import Flask, render_template, request, redirect, url_for, jsonify
2
  from simple_salesforce import Salesforce
 
 
 
 
3
  import os
 
 
 
 
4
 
5
  app = Flask(__name__)
 
6
 
7
  # Salesforce connection setup
8
  sf = Salesforce(
@@ -17,74 +25,280 @@ sf = Salesforce(
17
  cart = [] # To store items, quantities, and prices
18
  MENU = {}
19
 
 
 
 
 
20
  # Fetching menu items dynamically from Salesforce
21
  def get_menu_items():
22
  menu_items = {}
 
23
  query = "SELECT Name, Category__c, Price__c, Ingredients__c FROM Menu_Item__c"
24
  results = sf.query_all(query)
 
 
25
  for record in results['records']:
26
  category = record['Category__c']
27
  item_name = record['Name']
28
  price = record['Price__c']
 
29
  if category not in menu_items:
30
  menu_items[category] = {}
31
  menu_items[category][item_name] = price
 
32
  return menu_items
33
 
34
- # Fetch menu on app load
35
  MENU = get_menu_items()
36
 
37
- # Welcome page for registration/login
38
- @app.route("/", methods=["GET", "POST"])
39
- def welcome():
40
- if request.method == "POST":
41
- customer_type = request.form["customer_type"]
42
- if customer_type == 'new':
43
- return redirect(url_for('register')) # Redirect to registration
44
- elif customer_type == 'existing':
45
- return redirect(url_for('login')) # Redirect to login
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
- return render_template("welcome.html") # Render Welcome page
 
 
 
48
 
49
- # Register new customer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  @app.route("/register", methods=["GET", "POST"])
51
  def register():
52
  if request.method == "POST":
53
- name = request.form["name"]
54
- email = request.form["email"]
55
- phone = request.form["phone"]
56
-
57
  if not name or not email or not phone:
58
- return jsonify({"error": "All fields are required"}), 400
59
-
60
- # Create Salesforce record for new customer
61
  try:
62
  customer_login = sf.Customer_Login__c.create({
63
  'Name': name,
64
  'Email__c': email,
65
  'Phone_Number__c': phone
66
  })
67
- return redirect(url_for('ai_dining_assistant')) # Redirect to AI Dining Assistant page
68
  except Exception as e:
69
- return jsonify({"error": f"Failed to create record: {str(e)}"}), 500
70
- return render_template("register.html") # Render registration page
 
71
 
72
- # Login existing customer
73
  @app.route("/login", methods=["GET", "POST"])
74
  def login():
75
  if request.method == "POST":
76
- email = request.form["email"]
77
- phone = request.form["phone"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
- # You can implement logic to check the email and phone number with Salesforce records
80
- return redirect(url_for('ai_dining_assistant')) # Redirect to AI Dining Assistant page
81
- return render_template("login.html") # Render login page
 
82
 
83
- # AI Dining Assistant page for menu interaction
84
- @app.route("/ai_dining_assistant", methods=["GET"])
85
- def ai_dining_assistant():
86
- return render_template("ai_dining_assistant.html", menu=MENU)
87
 
88
- # Run the Flask app
89
  if __name__ == "__main__":
90
- app.run(host="0.0.0.0", port=7860, debug=True) # Enable debug mode
 
 
1
  from simple_salesforce import Salesforce
2
+ import logging
3
+ from flask import Flask, render_template_string, request, jsonify, redirect, url_for
4
+ import speech_recognition as sr
5
+ from tempfile import NamedTemporaryFile
6
  import os
7
+ import ffmpeg
8
+ from werkzeug.exceptions import BadRequest
9
+ from gtts import gTTS
10
+ import time
11
 
12
  app = Flask(__name__)
13
+ logging.basicConfig(level=logging.INFO)
14
 
15
  # Salesforce connection setup
16
  sf = Salesforce(
 
25
  cart = [] # To store items, quantities, and prices
26
  MENU = {}
27
 
28
+ current_category = None
29
+ current_item = None
30
+ awaiting_quantity = False
31
+
32
  # Fetching menu items dynamically from Salesforce
33
  def get_menu_items():
34
  menu_items = {}
35
+ # Querying the Menu_Item__c object to fetch details
36
  query = "SELECT Name, Category__c, Price__c, Ingredients__c FROM Menu_Item__c"
37
  results = sf.query_all(query)
38
+
39
+ # Organizing the menu items by category
40
  for record in results['records']:
41
  category = record['Category__c']
42
  item_name = record['Name']
43
  price = record['Price__c']
44
+
45
  if category not in menu_items:
46
  menu_items[category] = {}
47
  menu_items[category][item_name] = price
48
+
49
  return menu_items
50
 
51
+ # Update global MENU variable
52
  MENU = get_menu_items()
53
 
54
+ # HTML Template for Frontend (for register, login, and menu pages)
55
+ html_code = """
56
+ <!DOCTYPE html>
57
+ <html lang="en">
58
+ <head>
59
+ <meta charset="UTF-8">
60
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
61
+ <title>Register / Login</title>
62
+ <style>
63
+ body {
64
+ font-family: Arial, sans-serif;
65
+ text-align: center;
66
+ background-color: #f4f4f9;
67
+ }
68
+ h1 {
69
+ color: #333;
70
+ }
71
+ .status, .response {
72
+ margin-top: 20px;
73
+ }
74
+ </style>
75
+ </head>
76
+ <body>
77
+ <h1>Welcome to Biryani Hub</h1>
78
+ <div id="welcomePage">
79
+ <button onclick="startRegistration()">New Customer</button>
80
+ <button onclick="startLogin()">Existing Customer</button>
81
+ </div>
82
+
83
+ <div id="registrationPage" style="display: none;">
84
+ <h2>Register</h2>
85
+ <form action="/register" method="POST">
86
+ <label for="name">Name</label><br>
87
+ <input type="text" id="name" name="name" required><br>
88
+ <label for="email">Email</label><br>
89
+ <input type="email" id="email" name="email" required><br>
90
+ <label for="phone">Phone</label><br>
91
+ <input type="text" id="phone" name="phone" required><br>
92
+ <button type="submit">Register</button>
93
+ </form>
94
+ </div>
95
+
96
+ <div id="loginPage" style="display: none;">
97
+ <h2>Login</h2>
98
+ <form action="/login" method="POST">
99
+ <label for="email">Email</label><br>
100
+ <input type="email" id="email" name="email" required><br>
101
+ <label for="phone">Phone</label><br>
102
+ <input type="text" id="phone" name="phone" required><br>
103
+ <button type="submit">Login</button>
104
+ </form>
105
+ </div>
106
+
107
+ <div id="menuPage" style="display: none;">
108
+ <h1>AI Dining Assistant</h1>
109
+ <div class="status" id="status">Starting interaction...</div>
110
+ <div class="response" id="response" style="display: none;">Response will appear here...</div>
111
+ <button onclick="showMenu()">Show Menu</button>
112
+ </div>
113
+
114
+ <script>
115
+ function startRegistration() {
116
+ document.getElementById('welcomePage').style.display = 'none';
117
+ document.getElementById('registrationPage').style.display = 'block';
118
+ }
119
 
120
+ function startLogin() {
121
+ document.getElementById('welcomePage').style.display = 'none';
122
+ document.getElementById('loginPage').style.display = 'block';
123
+ }
124
 
125
+ function showMenu() {
126
+ document.getElementById('menuPage').style.display = 'block';
127
+ const categories = {{ MENU | tojson }};
128
+ let menuText = "We have the following categories: ";
129
+ for (let category in categories) {
130
+ menuText += category + " ";
131
+ }
132
+ document.getElementById('status').innerText = menuText;
133
+ }
134
+ </script>
135
+ </body>
136
+ </html>
137
+ """
138
+
139
+ @app.route("/")
140
+ def index():
141
+ return render_template_string(html_code)
142
+
143
+ # Register Page
144
  @app.route("/register", methods=["GET", "POST"])
145
  def register():
146
  if request.method == "POST":
147
+ name = request.form.get('name')
148
+ email = request.form.get('email')
149
+ phone = request.form.get('phone')
 
150
  if not name or not email or not phone:
151
+ return jsonify({"error": "All fields are required."}), 400
152
+
153
+ # Create a record in Salesforce
154
  try:
155
  customer_login = sf.Customer_Login__c.create({
156
  'Name': name,
157
  'Email__c': email,
158
  'Phone_Number__c': phone
159
  })
160
+ return redirect(url_for('menu')) # Redirect to menu after successful registration
161
  except Exception as e:
162
+ return jsonify({'error': f'Failed to create record in Salesforce: {str(e)}'}), 500
163
+
164
+ return render_template_string(html_code)
165
 
166
+ # Login Page
167
  @app.route("/login", methods=["GET", "POST"])
168
  def login():
169
  if request.method == "POST":
170
+ email = request.form.get('email')
171
+ phone = request.form.get('phone')
172
+
173
+ if not email or not phone:
174
+ return jsonify({"error": "Email and phone are required."}), 400
175
+
176
+ # Check if the customer exists in Salesforce
177
+ try:
178
+ customer_query = sf.query(f"SELECT Id, Name FROM Customer_Login__c WHERE Email__c = '{email}' AND Phone_Number__c = '{phone}'")
179
+ if customer_query['totalSize'] == 0:
180
+ return jsonify({"error": "Customer not found."}), 404
181
+ return redirect(url_for('menu')) # Redirect to menu after successful login
182
+ except Exception as e:
183
+ return jsonify({'error': f'Failed to query Salesforce: {str(e)}'}), 500
184
+
185
+ return render_template_string(html_code)
186
+
187
+ # Menu Page
188
+ @app.route("/menu")
189
+ def menu():
190
+ return render_template_string(html_code)
191
+
192
+ @app.route("/process-audio", methods=["POST"])
193
+ def process_audio():
194
+ global current_category, current_item, awaiting_quantity
195
+ try:
196
+ audio_file = request.files.get("audio")
197
+ if not audio_file:
198
+ raise BadRequest("No audio file provided.")
199
+
200
+ temp_file = NamedTemporaryFile(delete=False, suffix=".webm")
201
+ audio_file.save(temp_file.name)
202
+
203
+ if os.path.getsize(temp_file.name) == 0:
204
+ raise BadRequest("Uploaded audio file is empty.")
205
+
206
+ converted_file = NamedTemporaryFile(delete=False, suffix=".wav")
207
+ ffmpeg.input(temp_file.name).output(
208
+ converted_file.name, acodec="pcm_s16le", ac=1, ar="16000"
209
+ ).run(overwrite_output=True)
210
+
211
+ recognizer = sr.Recognizer()
212
+ with sr.AudioFile(converted_file.name) as source:
213
+ audio_data = recognizer.record(source)
214
+ try:
215
+ command = recognizer.recognize_google(audio_data)
216
+ logging.info(f"Recognized command: {command}")
217
+ response = process_command(command)
218
+ except sr.UnknownValueError:
219
+ response = "Sorry, I couldn't understand your command. Could you please repeat?"
220
+ except sr.RequestError as e:
221
+ response = f"Error with the speech recognition service: {e}"
222
+
223
+ return jsonify({"response": response})
224
+
225
+ except BadRequest as br:
226
+ return jsonify({"response": f"Bad Request: {str(br)}"}), 400
227
+ except Exception as e:
228
+ return jsonify({"response": f"An error occurred: {str(e)}"}), 500
229
+ finally:
230
+ os.unlink(temp_file.name)
231
+ os.unlink(converted_file.name)
232
+
233
+ def process_command(command):
234
+ global cart, MENU, current_category, current_item, awaiting_quantity
235
+ command = command.lower()
236
+
237
+ # Handle quantity input
238
+ if awaiting_quantity:
239
+ quantity = extract_quantity(command)
240
+ if quantity:
241
+ cart.append((current_item, MENU[current_category][current_item], quantity))
242
+ awaiting_quantity = False
243
+ item = current_item
244
+ current_item = None
245
+ total = sum(i[1] * i[2] for i in cart)
246
+ cart_summary = ", ".join([f"{i[0]} x{i[2]} (₹{i[1] * i[2]})" for i in cart])
247
+ return f"Added {quantity} x {item} to your cart. Your current cart: {cart_summary}. Total: ₹{total}. Would you like to add more items?"
248
+ else:
249
+ return "Sorry, I couldn't understand the quantity. Please provide a valid quantity."
250
+
251
+ # Handle category selection
252
+ for category, items in MENU.items():
253
+ if category.lower() in command:
254
+ current_category = category
255
+ item_list = ", ".join([f"{item} (₹{price})" for item, price in items.items()])
256
+ return f"{category} menu: {item_list}. What would you like to order?"
257
+
258
+ # Handle item selection with dynamic matching
259
+ if current_category:
260
+ for item in MENU[current_category].keys():
261
+ if item.lower().startswith(command) or command in item.lower():
262
+ current_item = item
263
+ awaiting_quantity = True
264
+ return f"How many quantities of {current_item} would you like?"
265
+
266
+ # Handle item removal
267
+ if "remove" in command:
268
+ for item in cart:
269
+ if item[0].lower() in command:
270
+ cart.remove(item)
271
+ total = sum(i[1] * i[2] for i in cart)
272
+ cart_summary = ", ".join([f"{i[0]} x{i[2]} (₹{i[1] * i[2]})" for i in cart])
273
+ return f"Removed {item[0]} from your cart. Updated cart: {cart_summary}. Total: ₹{total}."
274
+ return "The item you are trying to remove is not in your cart."
275
+
276
+ # Handle final order
277
+ if "final order" in command or "submit" in command or "Proceed" in command or "place the order" in command:
278
+ if cart:
279
+ order_details = ", ".join([f"{item[0]} x{item[2]} (₹{item[1] * item[2]})" for item in cart])
280
+ total = sum(item[1] * item[2] for item in cart)
281
+ cart.clear()
282
+ return f"Your final order is: {order_details}. Total price: ₹{total}. Your order will arrive soon, Thank you for visiting Biryani Hub!"
283
+ else:
284
+ return "Your cart is empty. Please add items before placing the final order."
285
+
286
+ # Handle cart details
287
+ if "cart details" in command:
288
+ if cart:
289
+ cart_summary = "\n".join([f"{i[0]} x{i[2]} (₹{i[1] * i[2]})" for i in cart])
290
+ total = sum(i[1] * i[2] for i in cart)
291
+ return f"Your cart contains:\n{cart_summary}\nTotal: ₹{total}."
292
+ else:
293
+ return "Your cart is empty."
294
 
295
+ # Handle menu request
296
+ if "menu" in command or "yes" in command or "yeah" in command:
297
+ categories = ", ".join(MENU.keys())
298
+ return f"We have the following categories: {categories}. Please select a category to proceed."
299
 
300
+ # Default response
301
+ return "Sorry, I didn't understand that. Please try again."
 
 
302
 
 
303
  if __name__ == "__main__":
304
+ app.run(host="0.0.0.0", port=7860)