PrashanthB461 commited on
Commit
0737ecc
Β·
verified Β·
1 Parent(s): 3c44d40

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -53
app.py CHANGED
@@ -36,35 +36,21 @@ HF_API_TOKEN = os.getenv("HUGGINGFACE_API_TOKEN")
36
 
37
  # Salesforce configuration
38
  SF_CREDENTIALS = {
39
- "username": os.getenv("SF_USERNAME", "smartlabour@attendance.system"),
40
- "password": os.getenv("SF_PASSWORD", "#Prashanth@123"),
41
- "security_token": os.getenv("SF_SECURITY_TOKEN", "pasQDqmWApzD0skgbv76gVgIs"),
42
- "domain": "login" # Use "test" for sandbox
43
  }
44
 
45
-
46
  @retry(stop_max_attempt_number=3, wait_fixed=2000)
47
  def connect_to_salesforce():
48
  try:
49
- if SF_CREDENTIALS["instance"]:
50
- sf = Salesforce(
51
- username=SF_CREDENTIALS["username"],
52
- password=SF_CREDENTIALS["password"],
53
- security_token=SF_CREDENTIALS["security_token"],
54
- instance=SF_CREDENTIALS["instance"]
55
- )
56
- else:
57
- sf = Salesforce(
58
- username=SF_CREDENTIALS["username"],
59
- password=SF_CREDENTIALS["password"],
60
- security_token=SF_CREDENTIALS["security_token"],
61
- domain=SF_CREDENTIALS["domain"]
62
- )
63
- logger.info("Connected to Salesforce successfully")
64
  sf.describe()
65
  return sf
66
  except Exception as e:
67
- logger.error(f"Salesforce connection failed: {e}. Check SF_USERNAME, SF_PASSWORD, SF_SECURITY_TOKEN, and SF_DOMAIN in .env file.")
68
  raise
69
 
70
  class AttendanceSystem:
@@ -82,13 +68,12 @@ class AttendanceSystem:
82
  self.recognition_cooldown = 5 # seconds
83
  self.video_file_path = None
84
  self.video_processing = False
85
- self.min_face_size = (100, 100) # Minimum face size for registration/recognition
86
 
87
  # Initialize Salesforce
88
  try:
89
  self.sf = connect_to_salesforce()
90
  except Exception as e:
91
- logger.error(f"Failed to initialize Salesforce connection: {e}")
92
  self.sf = None
93
 
94
  # Create directories
@@ -110,6 +95,21 @@ class AttendanceSystem:
110
  if os.path.exists("data/attendance.json"):
111
  with open("data/attendance.json", "r") as f:
112
  self.attendance_records = json.load(f)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  except Exception as e:
114
  logger.error(f"Error loading data: {e}")
115
  self.known_face_embeddings = []
@@ -192,25 +192,24 @@ class AttendanceSystem:
192
  image_array = np.array(image)
193
 
194
  try:
195
- # Verify face and size
196
  face_analysis = DeepFace.analyze(img_path=image_array, actions=['emotion'], enforce_detection=True, detector_backend='opencv')
197
- faces = DeepFace.extract_faces(img_path=image_array, target_size=(160, 160), enforce_detection=False, detector_backend='opencv')
198
- if not faces or faces[0]['facial_area']['w'] < self.min_face_size[0] or faces[0]['facial_area']['h'] < self.min_face_size[1]:
199
- return "❌ Face too small or not clear enough (must be at least 100x100 pixels)!", self.get_registered_workers_info()
200
 
201
  embedding = DeepFace.represent(img_path=image_array, model_name='Facenet')[0]['embedding']
202
 
 
 
 
 
203
  # Check for duplicate face
204
  if len(self.known_face_embeddings) > 0:
205
  distances = [np.linalg.norm(np.array(embedding) - np.array(known_embedding))
206
  for known_embedding in self.known_face_embeddings]
207
- if min(distances) < 10:
208
- best_match_index = distances.index(min(distances))
209
- return f"❌ Face already registered as {self.known_face_names[best_match_index]} (ID: {self.known_face_ids[best_match_index]})!", self.get_registered_workers_info()
210
-
211
- name = name.strip().title()
212
- if name in self.known_face_names:
213
- return f"❌ {name} is already registered!", self.get_registered_workers_info()
214
 
215
  worker_id = f"W{self.next_worker_id:04d}"
216
 
@@ -241,7 +240,6 @@ class AttendanceSystem:
241
  logger.warning("Image URL not set due to upload failure")
242
  except Exception as e:
243
  logger.error(f"Error saving to Salesforce: {e}")
244
- return f"❌ Error saving to Salesforce: {e}. Check connection and permissions.", self.get_registered_workers_info()
245
 
246
  self.save_data()
247
 
@@ -254,23 +252,18 @@ class AttendanceSystem:
254
  except Exception as e:
255
  return f"❌ Error during registration: {str(e)}", self.get_registered_workers_info()
256
 
257
- def register_worker_auto(self, face_image: np.ndarray, face_area: dict) -> Tuple[Optional[str], Optional[str]]:
258
  """Automatic worker registration for unrecognized faces"""
259
  try:
260
- # Verify face size
261
- if face_area['w'] < self.min_face_size[0] or face_area['h'] < self.min_face_size[1]:
262
- logger.info("Face too small for registration (must be at least 100x100 pixels)")
263
- return None, None
264
-
265
  embedding = DeepFace.represent(img_path=face_image, model_name='Facenet')[0]['embedding']
266
 
267
  # Check for duplicate face
268
  if len(self.known_face_embeddings) > 0:
269
  distances = [np.linalg.norm(np.array(embedding) - np.array(known_embedding))
270
  for known_embedding in self.known_face_embeddings]
271
- if min(distances) < 10:
272
- best_match_index = distances.index(min(distances))
273
- logger.info(f"Face already registered as {self.known_face_names[best_match_index]} (ID: {self.known_face_ids[best_match_index]})")
274
  return self.known_face_ids[best_match_index], self.known_face_names[best_match_index]
275
 
276
  worker_id = f"W{self.next_worker_id:04d}"
@@ -367,10 +360,6 @@ class AttendanceSystem:
367
  face_area = face_obj['facial_area']
368
  x, y, w, h = face_area['x'], face_area['y'], face_area['w'], face_area['h']
369
 
370
- # Check face size
371
- if w < self.min_face_size[0] or h < self.min_face_size[1]:
372
- continue
373
-
374
  face_image = frame[y:y+h, x:x+w]
375
 
376
  try:
@@ -398,7 +387,7 @@ class AttendanceSystem:
398
  self.last_recognition_time[worker_id] = current_time
399
  else:
400
  if face_image.size > 0:
401
- new_id, new_name = self.register_worker_auto(face_image, face_area)
402
  if new_id:
403
  worker_id = new_id
404
  worker_name = new_name
@@ -527,7 +516,7 @@ class AttendanceSystem:
527
 
528
  def get_registered_workers_info(self) -> str:
529
  if not self.sf:
530
- return "❌ Salesforce connection not established. Check credentials in .env file and ensure user has access to Worker__c and ContentVersion objects."
531
 
532
  try:
533
  workers = self.sf.query_all("SELECT Name, Worker_ID__c, Image_Caption__c, Image_URL__c FROM Worker__c")['records']
@@ -555,7 +544,7 @@ class AttendanceSystem:
555
 
556
  def get_today_attendance(self) -> str:
557
  if not self.sf:
558
- return "❌ Salesforce connection not established. Check credentials in .env file and ensure user has access to Attendance__c object."
559
 
560
  today = date.today().isoformat()
561
  try:
@@ -599,7 +588,7 @@ class AttendanceSystem:
599
  return "Invalid date format. Please use YYYY-MM-DD."
600
 
601
  if not self.sf:
602
- return "❌ Salesforce connection not established. Check credentials in .env file and ensure user has access to Attendance__c object."
603
 
604
  try:
605
  records = self.sf.query_all(
@@ -705,7 +694,7 @@ def create_interface():
705
  ## πŸš€ **Key Features:**
706
  - **πŸŽ₯ Live Camera Recognition** - Real-time face detection from camera/CCTV
707
  - **πŸ“Ή Video File Processing** - Process pre-recorded videos for attendance
708
- - **πŸ€– Automatic Worker Registration** - Auto-register unknown faces with unique IDs in Salesforce
709
  - **πŸ‘€ Manual Registration** - Register workers manually with photos and AI-generated captions
710
  - **πŸ“… 24-Hour Attendance Rule** - One attendance mark per worker per day
711
  - **πŸ“Š Advanced Analytics** - Detailed reports and data export
 
36
 
37
  # Salesforce configuration
38
  SF_CREDENTIALS = {
39
+ "username": "smartlabour@attendance.system",
40
+ "password": "#Prashanth@123",
41
+ "security_token": "pasQDqmWApzD0skgbv76gVgIs",
42
+ "domain": "login"
43
  }
44
 
 
45
  @retry(stop_max_attempt_number=3, wait_fixed=2000)
46
  def connect_to_salesforce():
47
  try:
48
+ sf = Salesforce(**SF_CREDENTIALS)
49
+ logger.info("Connected to Salesforce")
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  sf.describe()
51
  return sf
52
  except Exception as e:
53
+ logger.error(f"Salesforce connection failed: {e}")
54
  raise
55
 
56
  class AttendanceSystem:
 
68
  self.recognition_cooldown = 5 # seconds
69
  self.video_file_path = None
70
  self.video_processing = False
 
71
 
72
  # Initialize Salesforce
73
  try:
74
  self.sf = connect_to_salesforce()
75
  except Exception as e:
76
+ logger.error(f"Error connecting to Salesforce: {e}")
77
  self.sf = None
78
 
79
  # Create directories
 
95
  if os.path.exists("data/attendance.json"):
96
  with open("data/attendance.json", "r") as f:
97
  self.attendance_records = json.load(f)
98
+
99
+ # Load embeddings from Salesforce for duplicate checks
100
+ if self.sf:
101
+ try:
102
+ workers = self.sf.query_all("SELECT Worker_ID__c, Name, Face_Embedding__c FROM Worker__c")['records']
103
+ for worker in workers:
104
+ if worker['Face_Embedding__c']:
105
+ embedding = json.loads(worker['Face_Embedding__c'])
106
+ if worker['Worker_ID__c'] not in self.known_face_ids:
107
+ self.known_face_embeddings.append(embedding)
108
+ self.known_face_names.append(worker['Name'])
109
+ self.known_face_ids.append(worker['Worker_ID__c'])
110
+ self.next_worker_id = max(self.next_worker_id, int(worker['Worker_ID__c'][1:]) + 1)
111
+ except Exception as e:
112
+ logger.error(f"Error loading embeddings from Salesforce: {e}")
113
  except Exception as e:
114
  logger.error(f"Error loading data: {e}")
115
  self.known_face_embeddings = []
 
192
  image_array = np.array(image)
193
 
194
  try:
 
195
  face_analysis = DeepFace.analyze(img_path=image_array, actions=['emotion'], enforce_detection=True, detector_backend='opencv')
 
 
 
196
 
197
  embedding = DeepFace.represent(img_path=image_array, model_name='Facenet')[0]['embedding']
198
 
199
+ name = name.strip().title()
200
+ if name in self.known_face_names:
201
+ return f"❌ {name} is already registered!", self.get_registered_workers_info()
202
+
203
  # Check for duplicate face
204
  if len(self.known_face_embeddings) > 0:
205
  distances = [np.linalg.norm(np.array(embedding) - np.array(known_embedding))
206
  for known_embedding in self.known_face_embeddings]
207
+ min_distance = min(distances)
208
+ if min_distance < 10:
209
+ best_match_index = distances.index(min_distance)
210
+ matched_name = self.known_face_names[best_match_index]
211
+ matched_id = self.known_face_ids[best_match_index]
212
+ return f"❌ Face matches existing worker: {matched_name} ({matched_id})!", self.get_registered_workers_info()
 
213
 
214
  worker_id = f"W{self.next_worker_id:04d}"
215
 
 
240
  logger.warning("Image URL not set due to upload failure")
241
  except Exception as e:
242
  logger.error(f"Error saving to Salesforce: {e}")
 
243
 
244
  self.save_data()
245
 
 
252
  except Exception as e:
253
  return f"❌ Error during registration: {str(e)}", self.get_registered_workers_info()
254
 
255
+ def register_worker_auto(self, face_image: np.ndarray) -> Tuple[Optional[str], Optional[str]]:
256
  """Automatic worker registration for unrecognized faces"""
257
  try:
 
 
 
 
 
258
  embedding = DeepFace.represent(img_path=face_image, model_name='Facenet')[0]['embedding']
259
 
260
  # Check for duplicate face
261
  if len(self.known_face_embeddings) > 0:
262
  distances = [np.linalg.norm(np.array(embedding) - np.array(known_embedding))
263
  for known_embedding in self.known_face_embeddings]
264
+ min_distance = min(distances)
265
+ if min_distance < 10:
266
+ best_match_index = distances.index(min_distance)
267
  return self.known_face_ids[best_match_index], self.known_face_names[best_match_index]
268
 
269
  worker_id = f"W{self.next_worker_id:04d}"
 
360
  face_area = face_obj['facial_area']
361
  x, y, w, h = face_area['x'], face_area['y'], face_area['w'], face_area['h']
362
 
 
 
 
 
363
  face_image = frame[y:y+h, x:x+w]
364
 
365
  try:
 
387
  self.last_recognition_time[worker_id] = current_time
388
  else:
389
  if face_image.size > 0:
390
+ new_id, new_name = self.register_worker_auto(face_image)
391
  if new_id:
392
  worker_id = new_id
393
  worker_name = new_name
 
516
 
517
  def get_registered_workers_info(self) -> str:
518
  if not self.sf:
519
+ return "❌ Salesforce connection not established."
520
 
521
  try:
522
  workers = self.sf.query_all("SELECT Name, Worker_ID__c, Image_Caption__c, Image_URL__c FROM Worker__c")['records']
 
544
 
545
  def get_today_attendance(self) -> str:
546
  if not self.sf:
547
+ return "❌ Salesforce connection not established."
548
 
549
  today = date.today().isoformat()
550
  try:
 
588
  return "Invalid date format. Please use YYYY-MM-DD."
589
 
590
  if not self.sf:
591
+ return "❌ Salesforce connection not established."
592
 
593
  try:
594
  records = self.sf.query_all(
 
694
  ## πŸš€ **Key Features:**
695
  - **πŸŽ₯ Live Camera Recognition** - Real-time face detection from camera/CCTV
696
  - **πŸ“Ή Video File Processing** - Process pre-recorded videos for attendance
697
+ - **πŸ€– Automatic Worker Registration** - Auto-register unknown faces with unique IDs
698
  - **πŸ‘€ Manual Registration** - Register workers manually with photos and AI-generated captions
699
  - **πŸ“… 24-Hour Attendance Rule** - One attendance mark per worker per day
700
  - **πŸ“Š Advanced Analytics** - Detailed reports and data export