lokesh341 commited on
Commit
787bd32
·
verified ·
1 Parent(s): 7d5309b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +357 -158
app.py CHANGED
@@ -1,163 +1,362 @@
1
- import torch
2
- from flask import Flask, render_template, request, jsonify
3
- import json
4
- import os
5
- from transformers import pipeline
6
- from gtts import gTTS
7
- from pydub import AudioSegment
8
- from pydub.silence import detect_nonsilent
9
- from transformers import AutoConfig
10
- import time
11
- from waitress import serve
12
- from simple_salesforce import Salesforce
13
- import requests
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
- app = Flask(__name__)
 
 
 
16
 
17
- # Use whisper-small for faster processing and better speed
18
- device = "cuda" if torch.cuda.is_available() else "cpu"
 
 
 
 
 
 
 
 
19
 
20
- # Create config object to set timeout and other parameters
21
- config = AutoConfig.from_pretrained("openai/whisper-small")
22
- config.update({"timeout": 60})
 
 
23
 
24
- # Generate required voice prompts
25
- prompts = {
26
- "welcome": "Welcome to Biryani Hub.",
27
- "ask_name": "Tell me your name.",
28
- "ask_email": "Please provide your email address.",
29
- "thank_you": "Thank you for registration."
30
- }
 
31
 
32
- # Function to generate and save audio prompts
33
- def generate_audio_prompt(text, filename):
34
- try:
35
- tts = gTTS(text)
36
- tts.save(os.path.join("static", filename))
37
- except gtts.tts.gTTSError as e:
38
- print(f"Error: {e}")
39
- print("Retrying after 5 seconds...")
40
- time.sleep(5)
41
- generate_audio_prompt(text, filename)
42
-
43
- for key, text in prompts.items():
44
- generate_audio_prompt(text, f"{key}.mp3")
45
-
46
- # Function to convert audio to WAV format
47
- def convert_to_wav(input_path, output_path):
48
- try:
49
- audio = AudioSegment.from_file(input_path)
50
- audio = audio.set_frame_rate(16000).set_channels(1)
51
- audio.export(output_path, format="wav")
52
- except Exception as e:
53
- raise Exception(f"Audio conversion failed: {str(e)}")
54
-
55
- # Function to check if audio contains actual speech
56
- def is_silent_audio(audio_path):
57
- audio = AudioSegment.from_wav(audio_path)
58
- nonsilent_parts = detect_nonsilent(audio, min_silence_len=500, silence_thresh=audio.dBFS-16)
59
- return len(nonsilent_parts) == 0
60
-
61
- # Connect to Salesforce
62
- try:
63
- print("Attempting to connect to Salesforce...")
64
- sf = Salesforce(username='[email protected]', password='Sati@1020', security_token='sSSjyhInIsUohKpG8sHzty2q')
65
- print("Connected to Salesforce successfully!")
66
- except Exception as e:
67
- print(f"Failed to connect to Salesforce: {str(e)}")
68
-
69
- # LOGIN ENDPOINT (Validates User)
70
- @app.route('/login', methods=['POST'])
71
- def login():
72
- data = request.json
73
- email = data.get('email').strip().lower()
74
- phone_number = data.get('phone_number').strip()
75
-
76
- if not email or not phone_number:
77
- return jsonify({'error': 'Missing email or phone number'}), 400
78
-
79
- try:
80
- # Check if user exists in Salesforce
81
- query = f"SELECT Id, Name FROM Customer_Login__c WHERE LOWER(Email__c) = '{email}' AND Phone_Number__c = '{phone_number}' LIMIT 1"
82
- result = sf.query(query)
83
-
84
- if result['totalSize'] == 0:
85
- return jsonify({'error': 'Invalid email or phone number. User not found'}), 401
86
-
87
- user_data = result['records'][0]
88
- return jsonify({'success': True, 'message': 'Login successful', 'user_id': user_data['Id'], 'name': user_data['Name']}), 200
89
-
90
- except requests.exceptions.RequestException as req_error:
91
- return jsonify({'error': f'Salesforce connection error: {str(req_error)}'}), 500
92
- except Exception as e:
93
- return jsonify({'error': f'Unexpected error: {str(e)}'}), 500
94
-
95
- # REGISTRATION ENDPOINT (Creates New User)
96
- @app.route("/submit", methods=["POST"])
97
- def submit():
98
- data = request.json
99
- name = data.get('name')
100
- email = data.get('email').strip().lower()
101
- phone = data.get('phone').strip()
102
-
103
- if not name or not email or not phone:
104
- return jsonify({'error': 'Missing data'}), 400
105
-
106
- try:
107
- # Check if user already exists
108
- query = f"SELECT Id FROM Customer_Login__c WHERE LOWER(Email__c) = '{email}' AND Phone_Number__c = '{phone}' LIMIT 1"
109
- existing_user = sf.query(query)
110
-
111
- if existing_user['totalSize'] > 0:
112
- return jsonify({'error': 'User already exists'}), 409 # Conflict
113
-
114
- # Create new user
115
- customer_login = sf.Customer_Login__c.create({
116
- 'Name': name,
117
- 'Email__c': email,
118
- 'Phone_Number__c': phone
119
- })
120
-
121
- if customer_login.get('id'):
122
- return jsonify({'success': True, 'user_id': customer_login['id']}), 200
123
- else:
124
- return jsonify({'error': 'Failed to create record'}), 500
125
-
126
- except Exception as e:
127
- return jsonify({'error': str(e)}), 500
128
-
129
- @app.route("/")
130
- def index():
131
- return render_template("index.html")
132
-
133
- # TRANSCRIPTION ENDPOINT (Converts Speech to Text)
134
- @app.route("/transcribe", methods=["POST"])
135
- def transcribe():
136
- if "audio" not in request.files:
137
- return jsonify({"error": "No audio file provided"}), 400
138
-
139
- audio_file = request.files["audio"]
140
- input_audio_path = os.path.join("static", "temp_input.wav")
141
- output_audio_path = os.path.join("static", "temp.wav")
142
- audio_file.save(input_audio_path)
143
-
144
- try:
145
- # Convert to WAV
146
- convert_to_wav(input_audio_path, output_audio_path)
147
-
148
- # Check for silence
149
- if is_silent_audio(output_audio_path):
150
- return jsonify({"error": "No speech detected. Please try again."}), 400
151
-
152
- # Use Whisper ASR model for transcription
153
- result = pipeline("automatic-speech-recognition", model="openai/whisper-small", device=0 if torch.cuda.is_available() else -1, config=config)
154
- transcribed_text = result(output_audio_path)["text"].strip().capitalize()
155
-
156
- return jsonify({"text": transcribed_text})
157
-
158
- except Exception as e:
159
- return jsonify({"error": f"Speech recognition error: {str(e)}"}), 500
160
-
161
- # Start Production Server
162
- if __name__ == "__main__":
163
- serve(app, host="0.0.0.0", port=7860)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Biryani Hub - Register & Login</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap" rel="stylesheet">
8
+ <style>
9
+ body {
10
+ font-family: 'Roboto', sans-serif;
11
+ background: linear-gradient(135deg, #f4c542, #ff8f6a);
12
+ margin: 0;
13
+ display: flex;
14
+ justify-content: center;
15
+ align-items: center;
16
+ height: 100vh;
17
+ text-align: center;
18
+ }
19
+ .container {
20
+ background-color: #fff;
21
+ padding: 40px 50px;
22
+ border-radius: 10px;
23
+ width: 500px;
24
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
25
+ display: flex;
26
+ justify-content: space-between;
27
+ }
28
+ .form-container {
29
+ width: 48%;
30
+ }
31
+ h1 {
32
+ font-size: 30px;
33
+ font-weight: bold;
34
+ color: #ff6a00;
35
+ }
36
+ label {
37
+ font-size: 16px;
38
+ margin-top: 20px;
39
+ display: block;
40
+ text-align: left;
41
+ font-weight: bold;
42
+ color: #333;
43
+ }
44
+ input[type="text"] {
45
+ width: 100%;
46
+ padding: 12px;
47
+ font-size: 16px;
48
+ border: 2px solid #ccc;
49
+ border-radius: 8px;
50
+ margin-top: 8px;
51
+ box-sizing: border-box;
52
+ background-color: #f9f9f9;
53
+ }
54
+ input[type="text"]:focus {
55
+ border-color: #ff6a00;
56
+ outline: none;
57
+ }
58
+ .info {
59
+ margin-top: 20px;
60
+ font-size: 16px;
61
+ color: #ff6a00;
62
+ font-weight: bold;
63
+ }
64
+ .status {
65
+ font-size: 14px;
66
+ color: gray;
67
+ margin-top: 20px;
68
+ }
69
+ .header {
70
+ font-size: 24px;
71
+ font-weight: bold;
72
+ color: #ff6a00;
73
+ margin-bottom: 20px;
74
+ }
75
+ .form-section {
76
+ padding: 20px;
77
+ background-color: #f9f9f9;
78
+ border-radius: 10px;
79
+ }
80
+ #confirmation {
81
+ display: none;
82
+ margin-top: 20px;
83
+ background-color: #f9f9f9;
84
+ padding: 20px;
85
+ border-radius: 10px;
86
+ }
87
+ #confirmation h2 {
88
+ font-size: 20px;
89
+ font-weight: bold;
90
+ }
91
+ .confirm-details {
92
+ margin: 10px 0;
93
+ }
94
+ .confirm-button {
95
+ padding: 10px 20px;
96
+ background-color: #ff6a00;
97
+ color: white;
98
+ border: none;
99
+ border-radius: 5px;
100
+ cursor: pointer;
101
+ }
102
+ .confirm-button:hover {
103
+ background-color: #e65e00;
104
+ }
105
+ </style>
106
+ </head>
107
+ <body>
108
+ <div class="container">
109
+ <!-- Register Section -->
110
+ <div class="form-container" id="registrationForm" style="display: none;">
111
+ <h1>Welcome to Biryani Hub 🍽 🍗</h1>
112
+ <div class="form-section">
113
+ <h2 class="header">Register</h2>
114
+ <label for="name">Your Name</label>
115
+ <input type="text" id="name" placeholder="Your name will appear here..." readonly>
116
+
117
+ <label for="email">Your Email</label>
118
+ <input type="text" id="email" placeholder="Your email will appear here..." readonly>
119
+
120
+ <label for="mobile">Your Mobile Number</label>
121
+ <input type="text" id="mobile" placeholder="Your mobile number will appear here..." readonly>
122
 
123
+ <p class="info" id="infoMessage">Listening 🗣🎙️...</p>
124
+ <p class="status" id="status">🔊...</p>
125
+ </div>
126
+ </div>
127
 
128
+ <!-- Login Section -->
129
+ <div class="form-container" id="loginForm" style="display: none;">
130
+ <h1>Welcome to Biryani Hub 🍽 🍗</h1>
131
+ <div class="form-section">
132
+ <h2 class="header">Login</h2>
133
+ <label for="loginEmail">Your Email</label>
134
+ <input type="text" id="loginEmail" placeholder="Your email will appear here..." readonly>
135
+
136
+ <label for="loginMobile">Your Mobile Number</label>
137
+ <input type="text" id="loginMobile" placeholder="Your mobile number will appear here..." readonly>
138
 
139
+ <p class="info" id="infoMessageLogin">Listening 🗣🎙️...</p>
140
+ <p class="status" id="statusLogin">🔊...</p>
141
+ </div>
142
+ </div>
143
+ </div>
144
 
145
+ <!-- Confirmation Section -->
146
+ <div id="confirmation">
147
+ <h2>Confirm Your Details:</h2>
148
+ <p class="confirm-details"><strong>Name:</strong> <span id="confirmName"></span></p>
149
+ <p class="confirm-details"><strong>Email:</strong> <span id="confirmEmail"></span></p>
150
+ <p class="confirm-details"><strong>Phone:</strong> <span id="confirmPhone"></span></p>
151
+ <button class="confirm-button" onclick="autoSubmit()">Confirm</button>
152
+ </div>
153
 
154
+ <script>
155
+ let recognition;
156
+ let nameCaptured = "";
157
+ let emailCaptured = "";
158
+ let mobileCaptured = "";
159
+ if ('webkitSpeechRecognition' in window) {
160
+ recognition = new webkitSpeechRecognition();
161
+ recognition.continuous = false;
162
+ recognition.interimResults = false;
163
+ recognition.lang = 'en-US';
164
+ } else {
165
+ alert("Speech Recognition API is not supported in this browser.");
166
+ }
167
+ function speak(text, callback) {
168
+ const speech = new SpeechSynthesisUtterance(text);
169
+ speech.onend = callback;
170
+ window.speechSynthesis.speak(speech);
171
+ }
172
+ // Ask the user if they want to register or login
173
+ function askLoginOrRegister() {
174
+ speak("Are you a new customer or an existing customer? Say 'new' for registration or 'existing' for login.", function() {
175
+ recognition.start();
176
+ recognition.onresult = function(event) {
177
+ let response = event.results[0][0].transcript.trim().toLowerCase();
178
+ recognition.stop();
179
+ if (response.includes("new")) {
180
+ showRegistrationForm();
181
+ } else if (response.includes("existing")) {
182
+ showLoginForm();
183
+ } else {
184
+ speak("Sorry, I didn't understand. Please say 'new' for registration or 'existing' for login.", askLoginOrRegister);
185
+ }
186
+ };
187
+ });
188
+ }
189
+ function showRegistrationForm() {
190
+ document.getElementById('registrationForm').style.display = 'block';
191
+ document.getElementById('loginForm').style.display = 'none';
192
+ speak("Please tell me your name to begin the registration.", startListeningForName);
193
+ }
194
+ function showLoginForm() {
195
+ document.getElementById('loginForm').style.display = 'block';
196
+ document.getElementById('registrationForm').style.display = 'none';
197
+ speak("Please tell me your email to begin the login process.", startListeningForLoginEmail);
198
+ }
199
+ // Capture the name for registration
200
+ function startListeningForName() {
201
+ recognition.start();
202
+ recognition.onresult = function(event) {
203
+ nameCaptured = event.results[0][0].transcript.trim();
204
+ document.getElementById('name').value = nameCaptured;
205
+ recognition.stop();
206
+ speak("You said " + nameCaptured + ". Is it correct?", confirmName);
207
+ };
208
+ }
209
+ function confirmName() {
210
+ recognition.start();
211
+ recognition.onresult = function(event) {
212
+ let confirmation = event.results[0][0].transcript.trim().toLowerCase();
213
+ recognition.stop();
214
+ if (confirmation.includes("ok")) {
215
+ speak("Great! Now, tell me your email.", startListeningForEmail);
216
+ } else {
217
+ speak("Let's try again. Tell me your name.", startListeningForName);
218
+ }
219
+ };
220
+ }
221
+ // Capture email for registration
222
+ function startListeningForEmail() {
223
+ recognition.start();
224
+ recognition.onresult = function(event) {
225
+ emailCaptured = event.results[0][0].transcript.trim().replace(/\bat\b/g, '@').replace(/\s+/g, '');
226
+ document.getElementById('email').value = emailCaptured;
227
+ recognition.stop();
228
+ speak("You said " + emailCaptured + ". Is it correct?", confirmEmail);
229
+ };
230
+ }
231
+ function confirmEmail() {
232
+ recognition.start();
233
+ recognition.onresult = function(event) {
234
+ let confirmation = event.results[0][0].transcript.trim().toLowerCase();
235
+ recognition.stop();
236
+ if (confirmation.includes("ok")) {
237
+ speak("Great! Now, tell me your mobile number.", startListeningForMobile);
238
+ } else {
239
+ speak("Let's try again. Tell me your email.", startListeningForEmail);
240
+ }
241
+ };
242
+ }
243
+ // Capture mobile number for registration
244
+ function startListeningForMobile() {
245
+ recognition.start();
246
+ recognition.onresult = function(event) {
247
+ mobileCaptured = event.results[0][0].transcript.trim().replace(/\s+/g, '');
248
+ document.getElementById('mobile').value = mobileCaptured;
249
+ recognition.stop();
250
+ speak("You said " + mobileCaptured + ". Is it correct?", confirmMobile);
251
+ };
252
+ }
253
+ function confirmMobile() {
254
+ recognition.start();
255
+ recognition.onresult = function(event) {
256
+ let confirmation = event.results[0][0].transcript.trim().toLowerCase();
257
+ recognition.stop();
258
+ if (confirmation.includes("ok")) {
259
+ autoConfirm();
260
+ } else {
261
+ speak("Let's try again. Tell me your mobile number.", startListeningForMobile);
262
+ }
263
+ };
264
+ }
265
+ // Confirm details and submit automatically
266
+ function autoConfirm() {
267
+ document.getElementById('confirmName').textContent = document.getElementById('name').value;
268
+ document.getElementById('confirmEmail').textContent = document.getElementById('email').value;
269
+ document.getElementById('confirmPhone').textContent = document.getElementById('mobile').value;
270
+ document.getElementById('confirmation').style.display = 'block';
271
+ setTimeout(autoSubmit, 3000);
272
+ }
273
+ // Submit details to backend
274
+ function autoSubmit() {
275
+ var name = document.getElementById('name').value;
276
+ var email = document.getElementById('email').value;
277
+ var phone = document.getElementById('mobile').value;
278
+ fetch('/submit', {
279
+ method: 'POST',
280
+ headers: { 'Content-Type': 'application/json' },
281
+ body: JSON.stringify({ name: name, email: email, phone: phone })
282
+ })
283
+ .then(response => response.json())
284
+ .then(data => {
285
+ if (data.success) {
286
+ document.getElementById('status').textContent = 'Your details were submitted successfully!';
287
+ document.getElementById('confirmation').style.display = 'none';
288
+ speak("Your registration is complete. Thank you for registering.");
289
+ setTimeout(() => location.reload(), 5000);
290
+ } else {
291
+ document.getElementById('status').textContent = 'There was an error submitting your details.';
292
+ speak("There was an error submitting your details. Please try again.");
293
+ }
294
+ });
295
+ }
296
+ // Start login process
297
+ function startListeningForLoginEmail() {
298
+ recognition.start();
299
+ recognition.onresult = function(event) {
300
+ emailCaptured = event.results[0][0].transcript.trim().replace(/\bat\b/g, '@').replace(/\s+/g, '');
301
+ document.getElementById('loginEmail').value = emailCaptured;
302
+ recognition.stop();
303
+ speak("You said " + emailCaptured + ". Is it correct?", confirmLoginEmail);
304
+ };
305
+ }
306
+ function confirmLoginEmail() {
307
+ recognition.start();
308
+ recognition.onresult = function(event) {
309
+ let confirmation = event.results[0][0].transcript.trim().toLowerCase();
310
+ recognition.stop();
311
+ if (confirmation.includes("ok")) {
312
+ speak("Great! Now, tell me your mobile number.", startListeningForLoginMobile);
313
+ } else {
314
+ speak("Let's try again. Tell me your email.", startListeningForLoginEmail);
315
+ }
316
+ };
317
+ }
318
+ function startListeningForLoginMobile() {
319
+ recognition.start();
320
+ recognition.onresult = function(event) {
321
+ mobileCaptured = event.results[0][0].transcript.trim().replace(/\s+/g, '');
322
+ document.getElementById('loginMobile').value = mobileCaptured;
323
+ recognition.stop();
324
+ speak("You said " + mobileCaptured + ". Is it correct?", confirmLoginMobile);
325
+ };
326
+ }
327
+ function confirmLoginMobile() {
328
+ recognition.start();
329
+ recognition.onresult = function(event) {
330
+ let confirmation = event.results[0][0].transcript.trim().toLowerCase();
331
+ recognition.stop();
332
+ if (confirmation.includes("ok")) {
333
+ submitLogin();
334
+ } else {
335
+ speak("Let's try again. Tell me your mobile number.", startListeningForLoginMobile);
336
+ }
337
+ };
338
+ }
339
+ // Submit login details to backend
340
+ function submitLogin() {
341
+ let email = document.getElementById('loginEmail').value;
342
+ let mobile = document.getElementById('loginMobile').value;
343
+ fetch('/submit_login', {
344
+ method: 'POST',
345
+ headers: { 'Content-Type': 'application/json' },
346
+ body: JSON.stringify({ email: email, mobile: mobile })
347
+ })
348
+ .then(response => response.json())
349
+ .then(data => {
350
+ speak("Login successful. Welcome back!");
351
+ // Redirect or perform other actions
352
+ })
353
+ .catch(error => {
354
+ speak("There was an error with your login. Please try again.");
355
+ });
356
+ }
357
+ window.onload = function () {
358
+ askLoginOrRegister();
359
+ };
360
+ </script>
361
+ </body>
362
+ </html>