RajaThor commited on
Commit
f165c69
·
verified ·
1 Parent(s): 3b3b006

Create 24-03

Browse files
Files changed (1) hide show
  1. backup1/24-03 +570 -0
backup1/24-03 ADDED
@@ -0,0 +1,570 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ import firebase_admin
4
+ from firebase_admin import credentials, db, auth, firestore
5
+ import face_recognition
6
+ from PIL import Image
7
+ import numpy as np
8
+ import cv2
9
+ import dlib
10
+ from io import BytesIO
11
+
12
+ # Get the current working directory
13
+ current_directory = os.path.dirname(os.path.abspath(__file__))
14
+ skp_path = os.path.join(current_directory, "projectinsta-s-firebase-adminsdk-y6vlu-9a1345f468.json")
15
+
16
+ # Check if the app is already initialized
17
+ if not firebase_admin._apps:
18
+ # Initialize Firebase Admin SDK
19
+ cred = credentials.Certificate(skp_path)
20
+ firebase_admin.initialize_app(cred, {
21
+ 'databaseURL': 'https://projectinsta-s-default-rtdb.firebaseio.com/',
22
+ 'projectId': 'projectinsta-s'
23
+ })
24
+
25
+ # Reference to the root of your Firebase Realtime Database
26
+ ref = db.reference('/')
27
+
28
+ # Initialize Firestore client
29
+ db_firestore = firestore.client()
30
+
31
+ # Streamlit session state
32
+ if "auth_state" not in st.session_state:
33
+ st.session_state.auth_state = {
34
+ "user": None,
35
+ "signed_in": False,
36
+ }
37
+
38
+ # Add the shape predictor model for face alignment
39
+ shape_predictor_path = "shape_predictor_68_face_landmarks.dat"
40
+ detector = dlib.get_frontal_face_detector()
41
+ shape_predictor = dlib.shape_predictor(shape_predictor_path)
42
+
43
+ # Firebase Authentication
44
+ def authenticate_user(email, password):
45
+ try:
46
+ user = auth.get_user_by_email(email)
47
+ # The user is successfully fetched, meaning the email and password are valid.
48
+ return True, user
49
+ except auth.AuthError as e:
50
+ print(f"Authentication error: {str(e)}")
51
+ return False, None
52
+
53
+ # Sign-up Functionality
54
+ def create_user(email, password):
55
+ try:
56
+ user = auth.create_user(
57
+ email=email,
58
+ password=password
59
+ )
60
+ return True, user.uid
61
+ except Exception as e:
62
+ print(f"User creation error: {str(e)}")
63
+ return False, None
64
+
65
+ # Update load_and_encode function to return encodings for all detected faces
66
+ def load_and_encode(image_file):
67
+ try:
68
+ # Read the uploaded file as bytes
69
+ image_bytes = image_file.read()
70
+
71
+ # Convert the bytes to a NumPy array
72
+ nparr = np.frombuffer(image_bytes, np.uint8)
73
+
74
+ # Decode the NumPy array as an image
75
+ image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
76
+
77
+ aligned_faces = detect_and_align_faces(image)
78
+
79
+ if aligned_faces is not None:
80
+ encodings = []
81
+ for aligned_face in aligned_faces:
82
+ encoding = face_recognition.face_encodings(aligned_face)
83
+ if encoding:
84
+ encodings.append(encoding[0])
85
+
86
+ if encodings:
87
+ return encodings
88
+ else:
89
+ return None
90
+ else:
91
+ return None
92
+ except Exception as e:
93
+ print(f"Error loading and encoding image: {str(e)}")
94
+ return None
95
+
96
+ # Modify detect_and_align_faces function to detect and align multiple faces
97
+ def detect_and_align_faces(image):
98
+ # Resize the image to a fixed width (you can adjust the width as needed)
99
+ target_width = 800
100
+ aspect_ratio = image.shape[1] / image.shape[0]
101
+ target_height = int(target_width / aspect_ratio)
102
+ resized_image = cv2.resize(image, (target_width, target_height))
103
+
104
+ gray = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY)
105
+
106
+ # Detect faces using dlib
107
+ faces = detector(gray)
108
+
109
+ if not faces:
110
+ return None
111
+
112
+ aligned_faces = []
113
+ for face in faces:
114
+ # Use dlib for face alignment
115
+ landmarks = shape_predictor(gray, face)
116
+ aligned_face = dlib.get_face_chip(resized_image, landmarks, size=256) # Adjust the size as needed
117
+ aligned_faces.append(aligned_face)
118
+
119
+ return aligned_faces
120
+
121
+ # Add person to database
122
+ def add_person(name, image_path, instagram_handle, email=None):
123
+ try:
124
+ encoding = load_and_encode(image_path)
125
+ if not encoding:
126
+ return "No face found in the provided image."
127
+
128
+ # Convert NumPy arrays to lists for JSON serialization
129
+ encoding = encoding[0].tolist()
130
+
131
+ # Save data to Firebase Realtime Database
132
+ person_data = {
133
+ "encoding": encoding,
134
+ "info": {
135
+ "instagram_handle": instagram_handle,
136
+ "instagram_link": f"https://www.instagram.com/{instagram_handle}/"
137
+ }
138
+ }
139
+ if email:
140
+ person_data["info"]["email"] = email
141
+
142
+ ref.child(name).set(person_data)
143
+
144
+ log_action(st.session_state.auth_state["user"].email, "Added person")
145
+ return f"Success: {name} added to the database!"
146
+ except Exception as e:
147
+ return f"Failed to add person: {str(e)}"
148
+
149
+ # Update recognize_face function to handle multiple face encodings
150
+ def recognize_face(image_path):
151
+ if not image_path:
152
+ return "Please upload an image."
153
+
154
+ try:
155
+ unknown_encodings = load_and_encode(image_path)
156
+ if not unknown_encodings:
157
+ return "No face found in the provided image."
158
+
159
+ matches = []
160
+ for unknown_encoding in unknown_encodings:
161
+ face_matches = []
162
+ for name, data in ref.get().items():
163
+ known_encoding = np.array(data["encoding"])
164
+ if face_recognition.compare_faces([known_encoding], unknown_encoding)[0]:
165
+ info = data["info"]
166
+ email = info.get("email", "Email not provided")
167
+ face_matches.append((name, info["instagram_handle"], email))
168
+
169
+ if face_matches:
170
+ matches.extend(face_matches)
171
+ else:
172
+ matches.append(("Unknown", "Unknown", "Unknown"))
173
+
174
+ if matches:
175
+ results = []
176
+ for name, insta_handle, email in matches:
177
+ insta_link = f"https://www.instagram.com/{insta_handle}/"
178
+ insta_link_html = f'<a href="{insta_link}" target="_blank"><font color="red">{insta_handle}</font></a>'
179
+ results.append(f"- It's a picture of {name}! Insta handle: {insta_link_html}, Email: {email}")
180
+ log_action(st.session_state.auth_state["user"].email, "Recognized face")
181
+ return "\n".join(results)
182
+ else:
183
+ return "Face not found in the database."
184
+ except Exception as e:
185
+ return f"Failed to recognize face: {str(e)}"
186
+
187
+ # Update recognize_face_optimal function to handle multiple face encodings
188
+ def recognize_face_optimal(image_path):
189
+ if not image_path:
190
+ return "Please upload an image."
191
+
192
+ try:
193
+ unknown_encodings = load_and_encode(image_path)
194
+ if not unknown_encodings:
195
+ return "No face found in the provided image."
196
+
197
+ matches = []
198
+ for unknown_encoding in unknown_encodings:
199
+ face_matches = []
200
+ for name, data in ref.get().items():
201
+ known_encoding = np.array(data["encoding"])
202
+ similarity_score = face_recognition.face_distance([known_encoding], unknown_encoding)[0]
203
+ if similarity_score > 0.50: # Only consider matches above 50.00% similarity
204
+ continue
205
+ face_matches.append((name, similarity_score))
206
+
207
+ if face_matches:
208
+ best_match = min(face_matches, key=lambda x: x[1])
209
+ best_name, best_score = best_match
210
+ info = ref.child(best_name).child("info").get()
211
+ insta_handle = info["instagram_handle"]
212
+ insta_link = info["instagram_link"]
213
+ insta_link_html = f'<a href="{insta_link}" target="_blank"><font color="red">{insta_handle}</font></a>'
214
+ matches.append(f"Best match: {best_name} with a similarity score of {1 - best_score:.2%}. Insta handle: {insta_link_html}")
215
+ else:
216
+ matches.append("Face not found in the database.")
217
+
218
+ return "\n".join(matches)
219
+ except Exception as e:
220
+ return f"Failed to recognize face: {str(e)}"
221
+
222
+ # Delete person from database
223
+ def delete_person(name):
224
+ try:
225
+ ref.child(name).delete()
226
+ log_action(st.session_state.auth_state["user"].email, "Deleted person")
227
+ return f"{name} deleted from the database!"
228
+ except Exception as e:
229
+ return f"Failed to delete person: {str(e)}"
230
+
231
+ # Delete user from Firebase Authentication
232
+ def delete_user(email):
233
+ try:
234
+ user = auth.get_user_by_email(email)
235
+ auth.delete_user(user.uid)
236
+ return "User deleted successfully!"
237
+ except Exception as e:
238
+ return f"Failed to delete user: {str(e)}"
239
+
240
+ # Send feedback to Firebase
241
+ def send_feedback(feedback_data):
242
+ try:
243
+ db_firestore.collection('feedback').add(feedback_data)
244
+ except Exception as e:
245
+ st.error(f"Failed to submit feedback: {str(e)}")
246
+
247
+ # Streamlit interface for adding a person
248
+ def add_person_ui():
249
+ st.title("😎 Add Person")
250
+ name = st.text_input("Enter Name", help="Enter the name of the person")
251
+ image_path = st.file_uploader("Upload Image", help="Upload an image containing the person's face")
252
+ email = st.text_input("Enter Email (Optional)", help="Enter the person's email address (optional)")
253
+ instagram_handle = st.text_input("Enter Instagram Handle", help="Enter the person's Instagram handle")
254
+ if st.button("Add Person"):
255
+ if not name or not image_path or not instagram_handle:
256
+ st.error("Please fill all the required fields.")
257
+ else:
258
+ result = add_person(name, image_path, instagram_handle, email)
259
+ st.success(result)
260
+
261
+ # Streamlit interface for recognizing face
262
+ def recognize_face_ui():
263
+ st.title("🔍 Recognize Face")
264
+ image_path = st.file_uploader("Upload Image", help="Upload an image for face recognition")
265
+ if st.button("Recognize Face"):
266
+ result = recognize_face(image_path)
267
+ st.write(result, unsafe_allow_html=True)
268
+
269
+ def recognize_face_optimal_ui():
270
+ st.title("🔍 Recognize Face (Optimal)")
271
+ image_path = st.file_uploader("Upload Image", help="Upload an image for optimal face recognition")
272
+ if st.button("Recognize Face (Optimal)"):
273
+ result = recognize_face_optimal(image_path)
274
+ st.write(result, unsafe_allow_html=True)
275
+
276
+ # Streamlit interface for deleting a person
277
+ def delete_person_ui():
278
+ st.title("🗑️ Delete Person")
279
+ name = st.text_input("Enter Name", help="Enter the name of the person to delete")
280
+ if st.button("Delete Person"):
281
+ if not name:
282
+ st.error("Please enter a name.")
283
+ else:
284
+ # Check if the person exists in the database
285
+ if name not in ref.get().keys():
286
+ st.error("Person not found in the database.")
287
+ return
288
+
289
+ # Check if the person was added by the currently signed-in user
290
+ person_data = ref.child(name).get()
291
+ if person_data["added_by"] != st.session_state.auth_state["user"].email:
292
+ st.error("You can only delete the person added by you.")
293
+ return
294
+
295
+ result = delete_person(name)
296
+ st.success(result)
297
+
298
+ # Streamlit interface for feedback
299
+ def feedback_ui():
300
+ st.title("✍️ Feedback")
301
+ st.write("Your feedback is important to us! Please fill out the form below:")
302
+
303
+ name = st.text_input("Name (optional)")
304
+ email = st.text_input("Email (optional)")
305
+ category = st.selectbox("Category", ["Bug Report", "Feature Request", "General Feedback"])
306
+ message = st.text_area("Feedback Message")
307
+
308
+ if st.button("Submit Feedback"):
309
+ if not message:
310
+ st.error("Please enter your feedback message.")
311
+ else:
312
+ feedback_data = {
313
+ "name": name,
314
+ "email": email,
315
+ "category": category,
316
+ "message": message,
317
+ }
318
+ send_feedback(feedback_data)
319
+ st.success("Feedback submitted successfully! Thank you for your feedback.")
320
+
321
+ #section for messaging
322
+
323
+ # Function to send a message
324
+ def send_message(sender_email, receiver_email, message_content):
325
+ try:
326
+ # Add message to Firestore
327
+ db_firestore.collection('messages').add({
328
+ 'sender_email': sender_email,
329
+ 'receiver_email': receiver_email,
330
+ 'message_content': message_content,
331
+ 'timestamp': firestore.SERVER_TIMESTAMP
332
+ })
333
+ return "Message sent successfully!"
334
+ except Exception as e:
335
+ return f"Failed to send message: {str(e)}"
336
+
337
+ # Function to retrieve messages for a user
338
+ def get_messages(user_email):
339
+ try:
340
+ messages = db_firestore.collection('messages').where('receiver_email', '==', user_email).order_by('timestamp', direction=firestore.Query.DESCENDING).stream()
341
+ return messages
342
+ except Exception as e:
343
+ return None
344
+
345
+ # Streamlit interface for messaging
346
+ def messaging_ui():
347
+ st.title("💬 Messaging")
348
+
349
+ if st.session_state.auth_state["signed_in"]:
350
+ sender_email = st.session_state.auth_state["user"].email
351
+ receiver_email = st.text_input("Receiver's Email", help="Enter the receiver's email address")
352
+ message_content = st.text_area("Message Content")
353
+
354
+ if st.button("Send Message"):
355
+ result = send_message(sender_email, receiver_email, message_content)
356
+ st.write(result)
357
+
358
+ messages = get_messages(sender_email)
359
+ if messages:
360
+ st.write("Your messages:")
361
+ for message in messages:
362
+ message_data = message.to_dict()
363
+ st.write(f"From: {message_data['sender_email']}")
364
+ st.write(f"Message: {message_data['message_content']}")
365
+ st.write("---")
366
+ else:
367
+ st.write("Please sign in to send and view messages.")
368
+
369
+ #end of messaging section
370
+
371
+ # History section
372
+ def log_action(user_email, action):
373
+ try:
374
+ db_firestore.collection('history').add({
375
+ 'user_email': user_email,
376
+ 'action': action,
377
+ 'timestamp': firestore.SERVER_TIMESTAMP
378
+ })
379
+ except Exception as e:
380
+ st.error(f"Failed to log action: {str(e)}")
381
+
382
+ # Display history of actions taken by the user
383
+ def display_history(user_email):
384
+ st.title("📜 History")
385
+ st.write("Here is the history of actions taken by you:")
386
+
387
+ try:
388
+ history = db_firestore.collection('history').where('user_email', '==', user_email).order_by('timestamp', direction=firestore.Query.DESCENDING).stream()
389
+ for entry in history:
390
+ entry_data = entry.to_dict()
391
+ action = entry_data['action']
392
+ timestamp = entry_data['timestamp']
393
+ st.write(f"- {action} at {timestamp}")
394
+ except Exception as e:
395
+ st.error(f"Failed to retrieve history: {str(e)}")
396
+ #End of history section
397
+
398
+ # Streamlit interface for Deleting user
399
+ def delete_user_ui():
400
+ st.title("Delete User")
401
+ email = st.text_input("Enter User's Email", help="Enter the email of the user to delete")
402
+ if st.button("Delete User"):
403
+ if not email:
404
+ st.error("Please enter a user's email.")
405
+ else:
406
+ result = delete_user(email)
407
+ st.success(result)
408
+
409
+ def tour_guide_ui():
410
+ st.title("🗺️ Tour Guide")
411
+ st.markdown("This tour will guide you through the application.")
412
+
413
+ with st.expander("Welcome"):
414
+ st.write("This is a tour guide to help you navigate through the application.")
415
+
416
+ with st.expander("Options Sidebar"):
417
+ st.write("Here you can select different options such as adding a person, recognizing a face, deleting a person, or recognizing a face with optimal identification.")
418
+
419
+ with st.expander("Main Interface"):
420
+ st.write("This is where the main functionality of the application is displayed.")
421
+
422
+ with st.expander("Upload Image"):
423
+ st.write("You can upload an image here for face recognition or adding a person.")
424
+
425
+ with st.expander("Text Input"):
426
+ st.write("Enter text here such as the person's name or Instagram handle.")
427
+
428
+ with st.expander("Buttons"):
429
+ st.write("Click on these buttons to perform actions like adding a person or recognizing a face.")
430
+
431
+ def authenticate_user_ui():
432
+ # Display logo and title
433
+ c30, c31, c32 = st.columns([0.2, 0.1, 3])
434
+ with c30:
435
+ st.caption("")
436
+ # Display the logo
437
+ logo_path = os.path.join(current_directory, "Explore+.png")
438
+ logo = Image.open(logo_path)
439
+ st.image(logo, width=60)
440
+
441
+ with c32:
442
+ st.title("Insta's EYE")
443
+ st.sidebar.title("Options")
444
+
445
+ if st.session_state.auth_state["signed_in"]:
446
+ st.sidebar.button("Sign Out", on_click=logout)
447
+ st.title("Welcome!")
448
+ main()
449
+ else:
450
+ option = st.sidebar.radio("Select Option", ["Login", "Sign-Up"])
451
+
452
+ email = st.text_input("Enter Email", help="Enter your email address")
453
+ password = st.text_input("Enter Password", type="password", help="Enter your password")
454
+
455
+ if option == "Login":
456
+ if st.button("Login"):
457
+ if not email or not password:
458
+ st.error("Please enter both email and password.")
459
+ else:
460
+ success, user = authenticate_user(email, password)
461
+ if success:
462
+ st.session_state.auth_state["user"] = user
463
+ st.session_state.auth_state["signed_in"] = True
464
+ st.success("Authentication successful! You can now manage your set of images and profiles.")
465
+ main()
466
+ else:
467
+ st.error("Authentication failed. Please check your email and password.")
468
+
469
+ elif option == "Sign-Up":
470
+ confirm_password = st.text_input("Confirm Password", type="password", help="Re-enter your password for confirmation")
471
+ if st.button("Sign-Up"):
472
+ if not email or not password or not confirm_password:
473
+ st.error("Please fill all the fields.")
474
+ elif password != confirm_password:
475
+ st.error("Passwords do not match.")
476
+ else:
477
+ success, uid = create_user(email, password)
478
+ if success:
479
+ st.success(f"User with UID: {uid} created successfully! You can now log in.")
480
+ else:
481
+ st.error("User creation failed. Please try again.")
482
+
483
+ # Log out user
484
+ def logout():
485
+ st.session_state.auth_state["user"] = None
486
+ st.session_state.auth_state["signed_in"] = False
487
+
488
+ # Define tour steps
489
+ steps = [
490
+ {
491
+ "title": "Welcome to Insta's EYE",
492
+ "content": "This is a tour guide to help you navigate through the application.",
493
+ },
494
+ {
495
+ "title": "Options Sidebar",
496
+ "content": "Here you can select different options such as adding a person, recognizing a face, deleting a person, or recognizing a face with optimal identification.",
497
+ },
498
+ {
499
+ "title": "Recognize face",
500
+ "content": "This function will return you Id's for your provided face.",
501
+ },
502
+ {
503
+ "title": "Recognize face(optimal)",
504
+ "content": "This function will return you Id's of provided face with more accuracy",
505
+ },
506
+ {
507
+ "title": "Add person",
508
+ "content": "Here you can add yourself or someone else too",
509
+ },
510
+ {
511
+ "title": "Delete person",
512
+ "content": "Here you can delete the person by entering their name",
513
+ },
514
+ {
515
+ "title": "History",
516
+ "content": "Here you can track history of your activities",
517
+ },
518
+ {
519
+ "title": "Upload Image",
520
+ "content": "You can upload an image here for face recognition or adding a person.",
521
+ },
522
+ {
523
+ "title": "Text Input",
524
+ "content": "Enter text here such as the person's name or Instagram handle.",
525
+ },
526
+ {
527
+ "title": "Buttons",
528
+ "content": "Click on these buttons to perform actions like adding a person or recognizing a face.",
529
+ },
530
+ ]
531
+
532
+ # Function to display tour steps
533
+ def display_tour_steps(steps):
534
+ st.markdown("# Tour Guide")
535
+ st.markdown("This tour will guide you through the application.")
536
+ st.markdown("---")
537
+
538
+ for step in steps:
539
+ st.markdown(f"## {step['title']}")
540
+ st.write(step['content'])
541
+ st.markdown("---")
542
+
543
+ # Update the main function to include the feedback option
544
+ def main():
545
+ st.sidebar.title("Options")
546
+ option = st.sidebar.radio("Select Option", ["Recognize Face", "Add Person", "Recognize Face (Optimal)", "Delete Person", "Tour Guide", "Feedback", "Messaging", "History", "Delete User"])
547
+
548
+ if option == "Recognize Face":
549
+ recognize_face_ui()
550
+ elif option == "Recognize Face (Optimal)":
551
+ recognize_face_optimal_ui()
552
+ elif option == "Add Person":
553
+ add_person_ui()
554
+ elif option == "Delete Person":
555
+ delete_person_ui()
556
+ elif option == "Tour Guide":
557
+ tour_guide_ui()
558
+ elif option == "Feedback":
559
+ feedback_ui()
560
+ elif option == "Messaging":
561
+ messaging_ui()
562
+ elif option == "History":
563
+ display_history(st.session_state.auth_state["user"].email)
564
+ elif option == "Delete User":
565
+ delete_user_ui()
566
+
567
+ # Run the tour guide
568
+ if __name__ == "__main__":
569
+ authenticate_user_ui()
570
+