Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -6,6 +6,11 @@ import numpy as np
|
|
| 6 |
from ultralytics import YOLO
|
| 7 |
import time
|
| 8 |
from simple_salesforce import Salesforce
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
# ==========================
|
| 11 |
# Configuration
|
|
@@ -66,58 +71,131 @@ def violations_to_text(violations):
|
|
| 66 |
lines.append(line)
|
| 67 |
return "\n".join(lines)
|
| 68 |
|
| 69 |
-
def
|
| 70 |
try:
|
| 71 |
# Ensure the directory is writable
|
| 72 |
if not os.access(STATIC_OUTPUT_DIR, os.W_OK):
|
| 73 |
raise PermissionError(f"Cannot write to directory: {STATIC_OUTPUT_DIR}")
|
| 74 |
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
# Generate
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
except Exception as e:
|
| 94 |
-
print(f"β Error
|
| 95 |
-
return ""
|
| 96 |
|
| 97 |
-
def push_report_to_salesforce(score, violations,
|
| 98 |
try:
|
| 99 |
sf = connect_to_salesforce()
|
| 100 |
violations_count = len(violations)
|
| 101 |
violations_details = violations_to_text(violations)
|
| 102 |
|
| 103 |
PUBLIC_BASE_URL = "https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo1/resolve/main/static/output/"
|
| 104 |
-
|
| 105 |
|
| 106 |
record_data = {
|
| 107 |
"Compliance_Score__c": score,
|
| 108 |
"Violations_Found__c": violations_count,
|
| 109 |
"Violations_Details__c": violations_details,
|
| 110 |
"Status__c": "Pending",
|
| 111 |
-
"PDF_Report_URL__c":
|
| 112 |
}
|
| 113 |
|
| 114 |
print(f"Attempting to create Salesforce record with data: {record_data}")
|
| 115 |
record = sf.Safety_Video_Report__c.create(record_data)
|
| 116 |
-
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
except Exception as e:
|
| 119 |
print(f"β Salesforce record creation failed: {e}")
|
| 120 |
-
return None
|
| 121 |
|
| 122 |
# ==========================
|
| 123 |
# Safety Score Calculation
|
|
@@ -204,22 +282,22 @@ def process_video(video_data, frame_skip=5, max_frames=100):
|
|
| 204 |
os.remove(video_path)
|
| 205 |
|
| 206 |
score = calculate_safety_score(violations)
|
| 207 |
-
|
| 208 |
|
| 209 |
-
if
|
| 210 |
-
report_id = push_report_to_salesforce(score, violations,
|
| 211 |
print(f"β
Salesforce record created with Id: {report_id}")
|
| 212 |
else:
|
| 213 |
-
report_id = None
|
| 214 |
-
print("β No
|
| 215 |
|
| 216 |
return {
|
| 217 |
"violations": violations,
|
| 218 |
"snapshots": snapshots,
|
| 219 |
"score": score,
|
| 220 |
"salesforce_record_id": report_id,
|
| 221 |
-
"violation_details_url":
|
| 222 |
-
"violation_details_content":
|
| 223 |
}
|
| 224 |
|
| 225 |
except Exception as e:
|
|
|
|
| 6 |
from ultralytics import YOLO
|
| 7 |
import time
|
| 8 |
from simple_salesforce import Salesforce
|
| 9 |
+
from reportlab.lib.pagesizes import letter
|
| 10 |
+
from reportlab.pdfgen import canvas
|
| 11 |
+
from reportlab.lib.units import inch
|
| 12 |
+
from io import BytesIO
|
| 13 |
+
import base64
|
| 14 |
|
| 15 |
# ==========================
|
| 16 |
# Configuration
|
|
|
|
| 71 |
lines.append(line)
|
| 72 |
return "\n".join(lines)
|
| 73 |
|
| 74 |
+
def generate_violation_pdf(violations, score):
|
| 75 |
try:
|
| 76 |
# Ensure the directory is writable
|
| 77 |
if not os.access(STATIC_OUTPUT_DIR, os.W_OK):
|
| 78 |
raise PermissionError(f"Cannot write to directory: {STATIC_OUTPUT_DIR}")
|
| 79 |
|
| 80 |
+
pdf_filename = f"violations_{int(time.time())}.pdf"
|
| 81 |
+
pdf_path = os.path.join(STATIC_OUTPUT_DIR, pdf_filename)
|
| 82 |
+
|
| 83 |
+
# Generate PDF
|
| 84 |
+
pdf_file = BytesIO()
|
| 85 |
+
c = canvas.Canvas(pdf_file, pagesize=letter)
|
| 86 |
+
c.setFont("Helvetica", 12)
|
| 87 |
+
c.drawString(1 * inch, 10 * inch, "Worksite Safety Violation Report")
|
| 88 |
+
c.setFont("Helvetica", 10)
|
| 89 |
+
y_position = 9.5 * inch
|
| 90 |
+
|
| 91 |
+
# Add report details
|
| 92 |
+
report_data = {
|
| 93 |
+
"Compliance Score": f"{score}%",
|
| 94 |
+
"Violations Found": len(violations),
|
| 95 |
+
"Timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
|
| 96 |
+
}
|
| 97 |
+
for key, value in report_data.items():
|
| 98 |
+
c.drawString(1 * inch, y_position, f"{key}: {value}")
|
| 99 |
+
y_position -= 0.3 * inch
|
| 100 |
+
|
| 101 |
+
# Add violation details
|
| 102 |
+
y_position -= 0.3 * inch
|
| 103 |
+
c.drawString(1 * inch, y_position, "Violation Details:")
|
| 104 |
+
y_position -= 0.3 * inch
|
| 105 |
+
for v in violations:
|
| 106 |
+
violation_text = f"{v['violation']} at {v['timestamp']:.2f}s (Confidence: {v['confidence']})"
|
| 107 |
+
c.drawString(1 * inch, y_position, violation_text)
|
| 108 |
+
y_position -= 0.3 * inch
|
| 109 |
+
if y_position < 1 * inch: # Handle page overflow
|
| 110 |
+
c.showPage()
|
| 111 |
+
c.setFont("Helvetica", 10)
|
| 112 |
+
y_position = 10 * inch
|
| 113 |
+
|
| 114 |
+
c.showPage()
|
| 115 |
+
c.save()
|
| 116 |
+
pdf_file.seek(0)
|
| 117 |
+
|
| 118 |
+
# Save PDF to disk
|
| 119 |
+
with open(pdf_path, "wb") as f:
|
| 120 |
+
f.write(pdf_file.getvalue())
|
| 121 |
+
|
| 122 |
+
print(f"β
PDF generated at {pdf_path}")
|
| 123 |
+
if not os.path.exists(pdf_path):
|
| 124 |
+
raise FileNotFoundError(f"PDF was not created at {pdf_path}")
|
| 125 |
+
|
| 126 |
+
public_url = f"https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo1/resolve/main/static/output/{pdf_filename}"
|
| 127 |
+
print(f"β
PDF URL: {public_url}")
|
| 128 |
+
return pdf_path, public_url, pdf_file
|
| 129 |
+
except Exception as e:
|
| 130 |
+
print(f"β Error generating PDF: {e}")
|
| 131 |
+
return "", "", None
|
| 132 |
+
|
| 133 |
+
def upload_pdf_to_salesforce(pdf_file: BytesIO, report_id: str):
|
| 134 |
+
try:
|
| 135 |
+
sf = connect_to_salesforce()
|
| 136 |
+
if not pdf_file:
|
| 137 |
+
print("β No PDF file provided for upload")
|
| 138 |
+
return ""
|
| 139 |
+
|
| 140 |
+
encoded_pdf_data = base64.b64encode(pdf_file.getvalue()).decode('utf-8')
|
| 141 |
+
content_version_data = {
|
| 142 |
+
"Title": f"Safety_Violation_Report_{int(time.time())}",
|
| 143 |
+
"PathOnClient": f"safety_violation_{int(time.time())}.pdf",
|
| 144 |
+
"VersionData": encoded_pdf_data,
|
| 145 |
+
"FirstPublishLocationId": report_id
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
content_version = sf.ContentVersion.create(content_version_data)
|
| 149 |
+
content_version_id = content_version["id"]
|
| 150 |
+
|
| 151 |
+
result = sf.query(f"SELECT Id, ContentDocumentId FROM ContentVersion WHERE Id = '{content_version_id}'")
|
| 152 |
+
if not result['records']:
|
| 153 |
+
print("β Failed to retrieve ContentVersion")
|
| 154 |
+
return ""
|
| 155 |
+
|
| 156 |
+
file_url = f"https://{sf.sf_instance}/sfc/servlet.shepherd/version/download/{content_version_id}"
|
| 157 |
+
print(f"β
PDF uploaded to Salesforce, URL: {file_url}")
|
| 158 |
+
return file_url
|
| 159 |
except Exception as e:
|
| 160 |
+
print(f"β Error uploading PDF to Salesforce: {e}")
|
| 161 |
+
return ""
|
| 162 |
|
| 163 |
+
def push_report_to_salesforce(score, violations, pdf_path, pdf_file):
|
| 164 |
try:
|
| 165 |
sf = connect_to_salesforce()
|
| 166 |
violations_count = len(violations)
|
| 167 |
violations_details = violations_to_text(violations)
|
| 168 |
|
| 169 |
PUBLIC_BASE_URL = "https://huggingface.co/spaces/PrashanthB461/AI_Safety_Demo1/resolve/main/static/output/"
|
| 170 |
+
pdf_url = f"{PUBLIC_BASE_URL}{os.path.basename(pdf_path)}"
|
| 171 |
|
| 172 |
record_data = {
|
| 173 |
"Compliance_Score__c": score,
|
| 174 |
"Violations_Found__c": violations_count,
|
| 175 |
"Violations_Details__c": violations_details,
|
| 176 |
"Status__c": "Pending",
|
| 177 |
+
"PDF_Report_URL__c": pdf_url
|
| 178 |
}
|
| 179 |
|
| 180 |
print(f"Attempting to create Salesforce record with data: {record_data}")
|
| 181 |
record = sf.Safety_Video_Report__c.create(record_data)
|
| 182 |
+
record_id = record.get('id')
|
| 183 |
+
print(f"β
Salesforce record created with Id: {record_id}")
|
| 184 |
+
|
| 185 |
+
# Upload PDF to Salesforce
|
| 186 |
+
if pdf_file:
|
| 187 |
+
uploaded_url = upload_pdf_to_salesforce(pdf_file, record_id)
|
| 188 |
+
if uploaded_url:
|
| 189 |
+
sf.Safety_Video_Report__c.update(
|
| 190 |
+
record_id,
|
| 191 |
+
{"PDF_Report_URL__c": uploaded_url}
|
| 192 |
+
)
|
| 193 |
+
pdf_url = uploaded_url
|
| 194 |
+
|
| 195 |
+
return record_id, pdf_url
|
| 196 |
except Exception as e:
|
| 197 |
print(f"β Salesforce record creation failed: {e}")
|
| 198 |
+
return None, ""
|
| 199 |
|
| 200 |
# ==========================
|
| 201 |
# Safety Score Calculation
|
|
|
|
| 282 |
os.remove(video_path)
|
| 283 |
|
| 284 |
score = calculate_safety_score(violations)
|
| 285 |
+
pdf_path, pdf_url, pdf_file = generate_violation_pdf(violations, score)
|
| 286 |
|
| 287 |
+
if pdf_path:
|
| 288 |
+
report_id, final_pdf_url = push_report_to_salesforce(score, violations, pdf_path, pdf_file)
|
| 289 |
print(f"β
Salesforce record created with Id: {report_id}")
|
| 290 |
else:
|
| 291 |
+
report_id, final_pdf_url = None, ""
|
| 292 |
+
print("β No PDF generated, skipping Salesforce record creation")
|
| 293 |
|
| 294 |
return {
|
| 295 |
"violations": violations,
|
| 296 |
"snapshots": snapshots,
|
| 297 |
"score": score,
|
| 298 |
"salesforce_record_id": report_id,
|
| 299 |
+
"violation_details_url": final_pdf_url,
|
| 300 |
+
"violation_details_content": violations_to_text(violations) if violations else "No violations detected."
|
| 301 |
}
|
| 302 |
|
| 303 |
except Exception as e:
|