PrashanthB461 commited on
Commit
d6b1114
·
verified ·
1 Parent(s): 4ef3fa4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -91
app.py CHANGED
@@ -10,7 +10,7 @@ from reportlab.pdfgen import canvas
10
  from reportlab.lib.utils import ImageReader
11
  import base64
12
  from PIL import Image
13
- from simple_salesforce import Salesforce, SalesforceMalformedRequest
14
 
15
  # ==========================
16
  # Configuration
@@ -19,12 +19,10 @@ DEFAULT_MODEL_PATH = "models/yolov8_safety.pt"
19
  FALLBACK_MODEL = "yolov8n.pt"
20
  MODEL_PATH = os.getenv("SAFETY_MODEL_PATH", DEFAULT_MODEL_PATH)
21
 
 
22
  STATIC_OUTPUT_DIR = "static/output"
23
  os.makedirs(STATIC_OUTPUT_DIR, exist_ok=True)
24
 
25
- # Base URL for publicly accessible files (Hugging Face Spaces)
26
- BASE_PUBLIC_URL = "https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo1/raw/main/static/output/"
27
-
28
  VIOLATION_LABELS = {
29
  0: "no_helmet",
30
  1: "no_harness",
@@ -50,59 +48,44 @@ except Exception as e:
50
  raise
51
 
52
  # ==========================
53
- # Salesforce Connection
54
  # ==========================
55
  def connect_to_salesforce():
56
- try:
57
- sf = Salesforce(
58
- username="prashanth1ai@safety.com",
59
- password="SaiPrash461",
60
- security_token="AP4AQnPoidIKPvSvNEfAHyoK",
61
- domain="login"
62
- )
63
- print("✅ Salesforce connection successful.")
64
- return sf
65
- except Exception as e:
66
- print(f"❌ Salesforce connection failed: {e}")
67
- raise
68
 
69
- # ==========================
70
- # Violation Format Update
71
- # ==========================
72
  def violations_to_text(violations):
73
  lines = []
74
  for v in violations:
75
- line = f"Violation: {v['violation']} | Timestamp: {v['timestamp']:.2f}s | Confidence: {v['confidence']}"
76
  lines.append(line)
77
  return "\n".join(lines)
78
 
79
- # ==========================
80
- # Salesforce Record Creation
81
- # ==========================
82
- def push_report_to_salesforce(score, violations, pdf_url):
83
- try:
84
- sf = connect_to_salesforce()
85
- violations_count = len(violations)
86
- violations_details = violations_to_text(violations)
 
87
 
88
- # Create the record in the custom object Safety_Video_Report__c
89
- print(f"Creating Salesforce record with compliance score: {score} and violations found: {violations_count}")
90
  record = sf.Safety_Video_Report__c.create({
91
  "Compliance_Score__c": score,
92
  "Violations_Found__c": violations_count,
93
- "Violfilepath: app.py
94
  "Violations_Details__c": violations_details,
95
  "Status__c": "Pending",
96
  "PDF_Report_URL__c": pdf_url
97
  })
98
- record_id = record.get('id')
99
- print(f"✅ Salesforce record created with Id: {record_id}")
100
- return record_id
101
-
102
- except SalesforceMalformedRequest as e:
103
- print(f"❌ Salesforce malformed request: {e}")
104
- print(f"Error details: {e.content}")
105
- return None
106
  except Exception as e:
107
  print(f"❌ Salesforce record creation failed: {e}")
108
  return None
@@ -127,8 +110,7 @@ def calculate_safety_score(violations):
127
  # ==========================
128
  def generate_pdf_report(violations, snapshots, score):
129
  try:
130
- pdf_filename = f"report_{int(time.time())}.pdf"
131
- pdf_path = os.path.join(STATIC_OUTPUT_DIR, pdf_filename)
132
  c = canvas.Canvas(pdf_path, pagesize=letter)
133
  width, height = letter
134
 
@@ -145,7 +127,7 @@ def generate_pdf_report(violations, snapshots, score):
145
 
146
  for v in violations:
147
  c.setFont("Helvetica", 10)
148
- text = f"Violation: {v['violation']} | Timestamp: {v['timestamp']:.2f}s | Confidence: {v['confidence']}"
149
  c.drawString(50, y, text)
150
  y -= 20
151
 
@@ -162,36 +144,24 @@ def generate_pdf_report(violations, snapshots, score):
162
  y = height - 50
163
 
164
  c.save()
165
- print(f"PDF generated at {pdf_path}")
166
-
167
- # Verify the file exists with retry
168
- for _ in range(3):
169
- if os.path.exists(pdf_path):
170
- break
171
- time.sleep(1)
172
- else:
173
- raise Exception(f"PDF file not found at {pdf_path} after retries")
174
 
175
- # Generate public URL for the PDF
176
- pdf_url = f"{BASE_PUBLIC_URL}{pdf_filename}"
177
- print(f"📎 Public PDF URL: {pdf_url}")
178
-
179
- return pdf_path, pdf_url
180
 
181
  except Exception as e:
182
  print(f"❌ Error generating PDF: {e}")
183
- return "", ""
184
 
185
  # ==========================
186
  # Video Processing
187
  # ==========================
188
  def process_video(video_data, frame_skip=5, max_frames=100):
189
  try:
190
- print("📹 Processing video data...")
191
  video_path = os.path.join(STATIC_OUTPUT_DIR, f"temp_{int(time.time())}.mp4")
192
  with open(video_path, "wb") as f:
193
  f.write(video_data)
194
- print(f"💾 Video saved to {video_path}")
195
 
196
  video = cv2.VideoCapture(video_path)
197
  if not video.isOpened():
@@ -230,17 +200,13 @@ def process_video(video_data, frame_skip=5, max_frames=100):
230
  }
231
  violations.append(violation)
232
 
233
- snapshot_filename = f"snapshot_{frame_count}_{label}.jpg"
234
- snapshot_path = os.path.join(STATIC_OUTPUT_DIR, snapshot_filename)
235
  cv2.imwrite(snapshot_path, frame)
236
- if os.path.exists(snapshot_path):
237
- snapshots.append({
238
- "violation": label,
239
- "frame": frame_count,
240
- "snapshot_url": f"{BASE_PUBLIC_URL}{snapshot_filename}"
241
- })
242
- else:
243
- print(f"⚠️ Snapshot not saved at {snapshot_path}")
244
 
245
  frame_count += 1
246
  processed_frame_count += 1
@@ -254,18 +220,15 @@ def process_video(video_data, frame_skip=5, max_frames=100):
254
 
255
  video.release()
256
  os.remove(video_path)
257
- print(f"🗑️ Temporary video file removed: {video_path}")
258
 
259
  score = calculate_safety_score(violations)
260
- pdf_path, pdf_url = generate_pdf_report(violations, snapshots, score)
261
 
262
- if not pdf_path:
263
- raise Exception("Failed to generate PDF report")
264
-
265
- # Create Salesforce record with the PDF URL
266
- record_id = push_report_to_salesforce(score, violations, pdf_url)
267
- if not record_id:
268
- print("⚠️ Salesforce record creation failed, but PDF URL is available")
269
 
270
  with open(pdf_path, "rb") as f:
271
  pdf_base64 = base64.b64encode(f.read()).decode('utf-8')
@@ -275,8 +238,7 @@ def process_video(video_data, frame_skip=5, max_frames=100):
275
  "snapshots": snapshots,
276
  "score": score,
277
  "pdf_base64": pdf_base64,
278
- "pdf_url": pdf_url,
279
- "salesforce_record_id": record_id
280
  }
281
 
282
  except Exception as e:
@@ -286,7 +248,6 @@ def process_video(video_data, frame_skip=5, max_frames=100):
286
  "snapshots": [],
287
  "score": 0,
288
  "pdf_base64": "",
289
- "pdf_url": "",
290
  "salesforce_record_id": None,
291
  "error": str(e)
292
  }
@@ -297,40 +258,37 @@ def process_video(video_data, frame_skip=5, max_frames=100):
297
  def gradio_interface(video_file):
298
  try:
299
  if not video_file:
300
- return "Error: Please upload a video file.", "", "", [], "", ""
301
 
302
  with open(video_file, "rb") as f:
303
  video_data = f.read()
304
 
305
  result = process_video(video_data)
306
- violation_text = violations_to_text(result.get("violations", []))
307
  return (
308
- violation_text,
309
  f"Safety Score: {result.get('score', 0)}%",
310
- f"PDF URL: {result.get('pdf_url', '')}",
311
  result.get("pdf_base64", ""),
312
  result.get("snapshots", []),
313
  f"Salesforce Record ID: {result.get('salesforce_record_id', '')}"
314
  )
315
  except Exception as e:
316
  print(f"❌ Error in gradio_interface: {e}")
317
- return f"Error: {e}", "", "", [], "", ""
318
 
319
  interface = gr.Interface(
320
  fn=gradio_interface,
321
  inputs=gr.Video(label="Upload Site Video"),
322
  outputs=[
323
- gr.Textbox(label="Detected Safety Violations"),
324
  gr.Textbox(label="Compliance Score"),
325
  gr.Textbox(label="PDF Base64 (for API use)"),
326
  gr.JSON(label="Snapshots"),
327
- gr.Textbox(label="PDF URL"),
328
  gr.Textbox(label="Salesforce Record ID")
329
  ],
330
  title="Worksite Safety Violation Analyzer",
331
- description="Upload short site videos to detect safety violations (e.g., no helmet, no harness, unsafe posture). The PDF URL is saved in a Salesforce custom object."
332
  )
333
 
334
  if __name__ == "__main__":
335
  print("🚀 Launching Safety Analyzer App...")
336
- interface.launch()
 
10
  from reportlab.lib.utils import ImageReader
11
  import base64
12
  from PIL import Image
13
+ from simple_salesforce import Salesforce
14
 
15
  # ==========================
16
  # Configuration
 
19
  FALLBACK_MODEL = "yolov8n.pt"
20
  MODEL_PATH = os.getenv("SAFETY_MODEL_PATH", DEFAULT_MODEL_PATH)
21
 
22
+ # Use static/output for publicly accessible files
23
  STATIC_OUTPUT_DIR = "static/output"
24
  os.makedirs(STATIC_OUTPUT_DIR, exist_ok=True)
25
 
 
 
 
26
  VIOLATION_LABELS = {
27
  0: "no_helmet",
28
  1: "no_harness",
 
48
  raise
49
 
50
  # ==========================
51
+ # Salesforce connection (hardcoded creds for testing)
52
  # ==========================
53
  def connect_to_salesforce():
54
+ sf = Salesforce(
55
+ username="prashanth1ai@safety.com",
56
+ password="SaiPrash461",
57
+ security_token="AP4AQnPoidIKPvSvNEfAHyoK",
58
+ domain="login"
59
+ )
60
+ return sf
 
 
 
 
 
61
 
 
 
 
62
  def violations_to_text(violations):
63
  lines = []
64
  for v in violations:
65
+ line = f"{v['violation']} at {v['timestamp']:.2f}s (Confidence: {v['confidence']})"
66
  lines.append(line)
67
  return "\n".join(lines)
68
 
69
+ def push_report_to_salesforce(score, violations, pdf_filename):
70
+ sf = connect_to_salesforce()
71
+
72
+ violations_count = len(violations)
73
+ violations_details = violations_to_text(violations)
74
+
75
+ # Updated public URL base with static/output path
76
+ PUBLIC_PDF_BASE_URL = "https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo1/resolve/main/static/output/"
77
+ pdf_url = f"{PUBLIC_PDF_BASE_URL}{os.path.basename(pdf_filename)}"
78
 
79
+ try:
 
80
  record = sf.Safety_Video_Report__c.create({
81
  "Compliance_Score__c": score,
82
  "Violations_Found__c": violations_count,
 
83
  "Violations_Details__c": violations_details,
84
  "Status__c": "Pending",
85
  "PDF_Report_URL__c": pdf_url
86
  })
87
+ print(f"✅ Salesforce record created with Id: {record.get('id')}")
88
+ return record.get("id")
 
 
 
 
 
 
89
  except Exception as e:
90
  print(f"❌ Salesforce record creation failed: {e}")
91
  return None
 
110
  # ==========================
111
  def generate_pdf_report(violations, snapshots, score):
112
  try:
113
+ pdf_path = os.path.join(STATIC_OUTPUT_DIR, f"report_{int(time.time())}.pdf")
 
114
  c = canvas.Canvas(pdf_path, pagesize=letter)
115
  width, height = letter
116
 
 
127
 
128
  for v in violations:
129
  c.setFont("Helvetica", 10)
130
+ text = f"Violation: {v['violation']}, Timestamp: {v['timestamp']:.2f}s, Confidence: {v['confidence']}"
131
  c.drawString(50, y, text)
132
  y -= 20
133
 
 
144
  y = height - 50
145
 
146
  c.save()
147
+ print(f"PDF generated at {pdf_path}")
 
 
 
 
 
 
 
 
148
 
149
+ return pdf_path
 
 
 
 
150
 
151
  except Exception as e:
152
  print(f"❌ Error generating PDF: {e}")
153
+ return ""
154
 
155
  # ==========================
156
  # Video Processing
157
  # ==========================
158
  def process_video(video_data, frame_skip=5, max_frames=100):
159
  try:
160
+ print("Processing video data...")
161
  video_path = os.path.join(STATIC_OUTPUT_DIR, f"temp_{int(time.time())}.mp4")
162
  with open(video_path, "wb") as f:
163
  f.write(video_data)
164
+ print(f"Video saved to {video_path}")
165
 
166
  video = cv2.VideoCapture(video_path)
167
  if not video.isOpened():
 
200
  }
201
  violations.append(violation)
202
 
203
+ snapshot_path = os.path.join(STATIC_OUTPUT_DIR, f"snapshot_{frame_count}_{label}.jpg")
 
204
  cv2.imwrite(snapshot_path, frame)
205
+ snapshots.append({
206
+ "violation": label,
207
+ "frame": frame_count,
208
+ "snapshot_url": f"https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo1/resolve/main/static/output/{os.path.basename(snapshot_path)}"
209
+ })
 
 
 
210
 
211
  frame_count += 1
212
  processed_frame_count += 1
 
220
 
221
  video.release()
222
  os.remove(video_path)
 
223
 
224
  score = calculate_safety_score(violations)
225
+ pdf_path = generate_pdf_report(violations, snapshots, score)
226
 
227
+ if pdf_path:
228
+ report_id = push_report_to_salesforce(score, violations, pdf_path)
229
+ print(f"Salesforce record created with Id: {report_id}")
230
+ else:
231
+ report_id = None
 
 
232
 
233
  with open(pdf_path, "rb") as f:
234
  pdf_base64 = base64.b64encode(f.read()).decode('utf-8')
 
238
  "snapshots": snapshots,
239
  "score": score,
240
  "pdf_base64": pdf_base64,
241
+ "salesforce_record_id": report_id
 
242
  }
243
 
244
  except Exception as e:
 
248
  "snapshots": [],
249
  "score": 0,
250
  "pdf_base64": "",
 
251
  "salesforce_record_id": None,
252
  "error": str(e)
253
  }
 
258
  def gradio_interface(video_file):
259
  try:
260
  if not video_file:
261
+ return {"error": "Please upload a video file."}, "", "", [], ""
262
 
263
  with open(video_file, "rb") as f:
264
  video_data = f.read()
265
 
266
  result = process_video(video_data)
 
267
  return (
268
+ result.get("violations", []),
269
  f"Safety Score: {result.get('score', 0)}%",
 
270
  result.get("pdf_base64", ""),
271
  result.get("snapshots", []),
272
  f"Salesforce Record ID: {result.get('salesforce_record_id', '')}"
273
  )
274
  except Exception as e:
275
  print(f"❌ Error in gradio_interface: {e}")
276
+ return {"error": str(e)}, "", "", [], ""
277
 
278
  interface = gr.Interface(
279
  fn=gradio_interface,
280
  inputs=gr.Video(label="Upload Site Video"),
281
  outputs=[
282
+ gr.JSON(label="Detected Safety Violations"),
283
  gr.Textbox(label="Compliance Score"),
284
  gr.Textbox(label="PDF Base64 (for API use)"),
285
  gr.JSON(label="Snapshots"),
 
286
  gr.Textbox(label="Salesforce Record ID")
287
  ],
288
  title="Worksite Safety Violation Analyzer",
289
+ description="Upload short site videos to detect safety violations (e.g., no helmet, no harness, unsafe posture)."
290
  )
291
 
292
  if __name__ == "__main__":
293
  print("🚀 Launching Safety Analyzer App...")
294
+ interface.launch()