PrashanthB461 commited on
Commit
0f434be
·
verified ·
1 Parent(s): 08e92c3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +133 -81
app.py CHANGED
@@ -10,6 +10,7 @@ from reportlab.pdfgen import canvas
10
  from reportlab.lib.utils import ImageReader
11
  import base64
12
  from PIL import Image
 
13
 
14
  # ==========================
15
  # Configuration
@@ -44,6 +45,112 @@ except Exception as e:
44
  print(f"❌ Failed to load model: {e}")
45
  raise
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  # ==========================
48
  # Video Processing
49
  # ==========================
@@ -100,7 +207,7 @@ def process_video(video_data, frame_skip=5, max_frames=100):
100
  snapshots.append({
101
  "violation": label,
102
  "frame": frame_count,
103
- "snapshot_url": f"https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo1/output/{os.path.basename(snapshot_path)}"
104
  })
105
 
106
  frame_count += 1
@@ -117,13 +224,25 @@ def process_video(video_data, frame_skip=5, max_frames=100):
117
  os.remove(video_path)
118
 
119
  score = calculate_safety_score(violations)
120
- pdf_base64 = generate_pdf_report(violations, snapshots, score)
 
 
 
 
 
 
 
 
 
 
 
121
 
122
  return {
123
  "violations": violations,
124
  "snapshots": snapshots,
125
  "score": score,
126
- "pdf_base64": pdf_base64
 
127
  }
128
 
129
  except Exception as e:
@@ -133,100 +252,32 @@ def process_video(video_data, frame_skip=5, max_frames=100):
133
  "snapshots": [],
134
  "score": 0,
135
  "pdf_base64": "",
 
136
  "error": str(e)
137
  }
138
 
139
- # ==========================
140
- # Safety Score Calculation
141
- # ==========================
142
- def calculate_safety_score(violations):
143
- base_score = 100
144
- penalties = {
145
- "no_helmet": 25,
146
- "no_harness": 30,
147
- "unsafe_posture": 20,
148
- "unsafe_zone": 25
149
- }
150
- for v in violations:
151
- base_score -= penalties.get(v["violation"], 0)
152
- return max(base_score, 0)
153
-
154
- # ==========================
155
- # PDF Report Generation
156
- # ==========================
157
- def generate_pdf_report(violations, snapshots, score):
158
- try:
159
- pdf_path = os.path.join(OUTPUT_DIR, f"report_{int(time.time())}.pdf")
160
- c = canvas.Canvas(pdf_path, pagesize=letter)
161
- width, height = letter
162
-
163
- # Title
164
- c.setFont("Helvetica-Bold", 16)
165
- c.drawString(50, height - 50, "Worksite Safety Compliance Report")
166
-
167
- # Compliance Score
168
- c.setFont("Helvetica", 12)
169
- c.drawString(50, height - 80, f"Compliance Score: {score}%")
170
-
171
- # Violations Table
172
- y = height - 120
173
- c.setFont("Helvetica-Bold", 12)
174
- c.drawString(50, y, "Detected Violations:")
175
- y -= 20
176
-
177
- for v in violations:
178
- c.setFont("Helvetica", 10)
179
- text = f"Violation: {v['violation']}, Timestamp: {v['timestamp']:.2f}s, Confidence: {v['confidence']}"
180
- c.drawString(50, y, text)
181
- y -= 20
182
-
183
- # Add snapshot if available
184
- snapshot = next((s for s in snapshots if s["frame"] == v["frame"] and s["violation"] == v["violation"]), None)
185
- if snapshot and os.path.exists(snapshot["snapshot_url"].split('/')[-1]):
186
- img = ImageReader(snapshot["snapshot_url"].split('/')[-1])
187
- c.drawImage(img, 50, y - 100, width=200, height=150)
188
- y -= 170
189
-
190
- if y < 50:
191
- c.showPage()
192
- y = height - 50
193
-
194
- c.save()
195
- print(f"PDF generated at {pdf_path}")
196
-
197
- # Convert PDF to base64
198
- with open(pdf_path, "rb") as f:
199
- pdf_base64 = base64.b64encode(f.read()).decode('utf-8')
200
-
201
- # Clean up
202
- os.remove(pdf_path)
203
- print("PDF converted to base64 and file removed")
204
- return pdf_base64
205
- except Exception as e:
206
- print(f"❌ Error generating PDF: {e}")
207
- return ""
208
-
209
  # ==========================
210
  # Gradio Interface
211
  # ==========================
212
  def gradio_interface(video_file):
213
  try:
214
  if not video_file:
215
- return {"error": "Please upload a video file."}, "", "", []
216
 
217
  with open(video_file, "rb") as f:
218
  video_data = f.read()
219
 
220
  result = process_video(video_data)
221
  return (
222
- result["violations"],
223
- f"Safety Score: {result['score']}%",
224
- result["pdf_base64"],
225
- result["snapshots"]
 
226
  )
227
  except Exception as e:
228
  print(f"❌ Error in gradio_interface: {e}")
229
- return {"error": str(e)}, "", "", []
230
 
231
  interface = gr.Interface(
232
  fn=gradio_interface,
@@ -235,7 +286,8 @@ interface = gr.Interface(
235
  gr.JSON(label="Detected Safety Violations"),
236
  gr.Textbox(label="Compliance Score"),
237
  gr.Textbox(label="PDF Base64 (for API use)"),
238
- gr.JSON(label="Snapshots")
 
239
  ],
240
  title="Worksite Safety Violation Analyzer",
241
  description="Upload short site videos to detect safety violations (e.g., no helmet, no harness, unsafe posture)."
@@ -243,4 +295,4 @@ interface = gr.Interface(
243
 
244
  if __name__ == "__main__":
245
  print("🚀 Launching Safety Analyzer App...")
246
- 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
 
45
  print(f"❌ Failed to load model: {e}")
46
  raise
47
 
48
+ # ==========================
49
+ # Salesforce connection
50
+ # ==========================
51
+ def connect_to_salesforce():
52
+ sf = Salesforce(
53
+ username=os.getenv("prashanth1ai@safety.com"),
54
+ password=os.getenv("SaiPrash461"),
55
+ security_token=os.getenv("AP4AQnPoidIKPvSvNEfAHyoK"),
56
+ domain=os.getenv("SF_DOMAIN", "login")
57
+ )
58
+ return sf
59
+
60
+ def violations_to_text(violations):
61
+ lines = []
62
+ for v in violations:
63
+ line = f"{v['violation']} at {v['timestamp']:.2f}s (Confidence: {v['confidence']})"
64
+ lines.append(line)
65
+ return "\n".join(lines)
66
+
67
+ def push_report_to_salesforce(score, violations, pdf_filename):
68
+ sf = connect_to_salesforce()
69
+
70
+ violations_count = len(violations)
71
+ violations_details = violations_to_text(violations)
72
+
73
+ # Public URL base for your PDF reports on HuggingFace space or other hosting
74
+ PUBLIC_PDF_BASE_URL = "https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo1/resolve/main/output/"
75
+
76
+ pdf_url = f"{PUBLIC_PDF_BASE_URL}{os.path.basename(pdf_filename)}"
77
+
78
+ record = sf.Safety_Video_Report__c.create({
79
+ "Compliance_Score__c": score,
80
+ "Violations_Found__c": violations_count,
81
+ "Violations_Details__c": violations_details,
82
+ "Status__c": "Pending",
83
+ "PDF_Report_URL__c": pdf_url
84
+ })
85
+
86
+ return record.get("id")
87
+
88
+ # ==========================
89
+ # Safety Score Calculation
90
+ # ==========================
91
+ def calculate_safety_score(violations):
92
+ base_score = 100
93
+ penalties = {
94
+ "no_helmet": 25,
95
+ "no_harness": 30,
96
+ "unsafe_posture": 20,
97
+ "unsafe_zone": 25
98
+ }
99
+ for v in violations:
100
+ base_score -= penalties.get(v["violation"], 0)
101
+ return max(base_score, 0)
102
+
103
+ # ==========================
104
+ # PDF Report Generation
105
+ # ==========================
106
+ def generate_pdf_report(violations, snapshots, score):
107
+ try:
108
+ pdf_path = os.path.join(OUTPUT_DIR, f"report_{int(time.time())}.pdf")
109
+ c = canvas.Canvas(pdf_path, pagesize=letter)
110
+ width, height = letter
111
+
112
+ # Title
113
+ c.setFont("Helvetica-Bold", 16)
114
+ c.drawString(50, height - 50, "Worksite Safety Compliance Report")
115
+
116
+ # Compliance Score
117
+ c.setFont("Helvetica", 12)
118
+ c.drawString(50, height - 80, f"Compliance Score: {score}%")
119
+
120
+ # Violations Table
121
+ y = height - 120
122
+ c.setFont("Helvetica-Bold", 12)
123
+ c.drawString(50, y, "Detected Violations:")
124
+ y -= 20
125
+
126
+ for v in violations:
127
+ c.setFont("Helvetica", 10)
128
+ text = f"Violation: {v['violation']}, Timestamp: {v['timestamp']:.2f}s, Confidence: {v['confidence']}"
129
+ c.drawString(50, y, text)
130
+ y -= 20
131
+
132
+ # Add snapshot if available and exists locally
133
+ snapshot = next((s for s in snapshots if s["frame"] == v["frame"] and s["violation"] == v["violation"]), None)
134
+ if snapshot:
135
+ local_img_path = os.path.join(OUTPUT_DIR, os.path.basename(snapshot["snapshot_url"]))
136
+ if os.path.exists(local_img_path):
137
+ img = ImageReader(local_img_path)
138
+ c.drawImage(img, 50, y - 100, width=200, height=150)
139
+ y -= 170
140
+
141
+ if y < 50:
142
+ c.showPage()
143
+ y = height - 50
144
+
145
+ c.save()
146
+ print(f"PDF generated at {pdf_path}")
147
+
148
+ return pdf_path
149
+
150
+ except Exception as e:
151
+ print(f"❌ Error generating PDF: {e}")
152
+ return ""
153
+
154
  # ==========================
155
  # Video Processing
156
  # ==========================
 
207
  snapshots.append({
208
  "violation": label,
209
  "frame": frame_count,
210
+ "snapshot_url": f"https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo1/resolve/main/output/{os.path.basename(snapshot_path)}"
211
  })
212
 
213
  frame_count += 1
 
224
  os.remove(video_path)
225
 
226
  score = calculate_safety_score(violations)
227
+ pdf_path = generate_pdf_report(violations, snapshots, score)
228
+
229
+ # Push report to Salesforce with public PDF URL
230
+ if pdf_path:
231
+ report_id = push_report_to_salesforce(score, violations, pdf_path)
232
+ print(f"Salesforce record created with Id: {report_id}")
233
+ else:
234
+ report_id = None
235
+
236
+ # Convert PDF to base64 for UI display (optional)
237
+ with open(pdf_path, "rb") as f:
238
+ pdf_base64 = base64.b64encode(f.read()).decode('utf-8')
239
 
240
  return {
241
  "violations": violations,
242
  "snapshots": snapshots,
243
  "score": score,
244
+ "pdf_base64": pdf_base64,
245
+ "salesforce_record_id": report_id
246
  }
247
 
248
  except Exception as e:
 
252
  "snapshots": [],
253
  "score": 0,
254
  "pdf_base64": "",
255
+ "salesforce_record_id": None,
256
  "error": str(e)
257
  }
258
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  # ==========================
260
  # Gradio Interface
261
  # ==========================
262
  def gradio_interface(video_file):
263
  try:
264
  if not video_file:
265
+ return {"error": "Please upload a video file."}, "", "", [], ""
266
 
267
  with open(video_file, "rb") as f:
268
  video_data = f.read()
269
 
270
  result = process_video(video_data)
271
  return (
272
+ result.get("violations", []),
273
+ f"Safety Score: {result.get('score', 0)}%",
274
+ result.get("pdf_base64", ""),
275
+ result.get("snapshots", []),
276
+ f"Salesforce Record ID: {result.get('salesforce_record_id', '')}"
277
  )
278
  except Exception as e:
279
  print(f"❌ Error in gradio_interface: {e}")
280
+ return {"error": str(e)}, "", "", [], ""
281
 
282
  interface = gr.Interface(
283
  fn=gradio_interface,
 
286
  gr.JSON(label="Detected Safety Violations"),
287
  gr.Textbox(label="Compliance Score"),
288
  gr.Textbox(label="PDF Base64 (for API use)"),
289
+ gr.JSON(label="Snapshots"),
290
+ gr.Textbox(label="Salesforce Record ID")
291
  ],
292
  title="Worksite Safety Violation Analyzer",
293
  description="Upload short site videos to detect safety violations (e.g., no helmet, no harness, unsafe posture)."
 
295
 
296
  if __name__ == "__main__":
297
  print("🚀 Launching Safety Analyzer App...")
298
+ interface.launch()