Spaces:
Runtime error
Runtime error
File size: 8,111 Bytes
c2fa27a 8614e2f 58f1841 8614e2f 58f1841 a5fe846 8614e2f 58f1841 8614e2f 58f1841 a5fe846 8614e2f a5fe846 8614e2f a5fe846 8614e2f a5fe846 8614e2f a5fe846 8614e2f a5fe846 8614e2f c2fa27a 8614e2f f3b82b8 8614e2f f3b82b8 8614e2f 58f1841 8614e2f 58f1841 8614e2f c2fa27a 8614e2f c2fa27a 8614e2f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
import gradio as gr
import requests
import os
from PIL import Image
import numpy as np
from transformers import pipeline
from simple_salesforce import Salesforce
import io
import time
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Function to validate photo size (< 20MB)
def validate_photo_size(image_file):
max_size_mb = 20
if isinstance(image_file, Image.Image):
# Convert PIL Image to bytes for size check
img_byte_arr = io.BytesIO()
image_file.save(img_byte_arr, format='JPEG')
file_size_mb = img_byte_arr.tell() / (1024 * 1024) # Convert bytes to MB
return file_size_mb <= max_size_mb, None
return False, "Invalid image format"
# Function to process image with AI and predict milestone
def predict_milestone(image):
try:
# Simulate AI processing time (ensure < 5 seconds)
start_time = time.time()
# Process image with Hugging Face model
model = pipeline("image-classification", model="microsoft/resnet-50")
predictions = model(image)
# Placeholder logic: Map model output to construction milestones
milestone = predictions[0]["label"] # Example: "positive" -> "Walls Erected"
confidence = predictions[0]["score"]
# Map model output to construction milestones (customize this)
milestone_map = {
"positive": "Walls Erected",
"negative": "Foundation Completed",
# Add more mappings based on your model
}
completion_map = {
"positive": 60.00, # Example: Walls = 60% complete
"negative": 20.00, # Example: Foundation = 20% complete
}
predicted_milestone = milestone_map.get(milestone, "Unknown Milestone")
completion_percentage = completion_map.get(milestone, 0.00)
processing_time = time.time() - start_time
if processing_time > 5:
return None, None, "AI took too long to process (> 5 seconds)."
return predicted_milestone, completion_percentage, None
except Exception as e:
return None, None, f"AI failed to process the image: {str(e)}"
# Function to upload image to Salesforce and get a URL
def upload_image_to_salesforce(image, project_name):
try:
# Placeholder: Simulate uploading image to Salesforce ContentVersion
image_url = f"https://your-salesforce-instance.com/file/{project_name}.jpg" # Simulated URL
return image_url, None
except Exception as e:
return None, f"Failed to upload image to Salesforce: {str(e)}"
# Function to update Salesforce Construction_Project__c object and fetch fields
def update_salesforce_record(sf, project_name, milestone, percentage, image_url, status, comments):
try:
# Query to check if the project exists
query = f"SELECT Id FROM Construction_Project__c WHERE Name = '{project_name}'"
result = sf.query(query)
if result['totalSize'] == 0:
return None, f"No project found with Name: {project_name}"
record_id = result['records'][0]['Id']
# Update the record
sf.Construction_Project__c.update(record_id, {
'Current_Milestone__c': milestone,
'Completion_Percentage__c': percentage,
'Last_Updated_Image__c': image_url,
'Last_Updated_On__c': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),
'Upload_Status__c': status,
'Comments__c': comments
})
# Fetch the updated record to get the specified fields
updated_query = f"SELECT Current_Milestone__c, Last_Updated_Image__c, Last_Updated_On__c, Upload_Status__c FROM Construction_Project__c WHERE Id = '{record_id}'"
updated_result = sf.query(updated_query)
if updated_result['totalSize'] == 0:
return None, "Failed to retrieve updated record."
record = updated_result['records'][0]
fields_output = {
'Current_Milestone__c': record.get('Current_Milestone__c', 'N/A'),
'Last_Updated_Image__c': record.get('Last_Updated_Image__c', 'N/A'),
'Last_Updated_On__c': record.get('Last_Updated_On__c', 'N/A'),
'Upload_Status__c': record.get('Upload_Status__c', 'N/A')
}
return fields_output, None
except Exception as e:
return None, f"Failed to update Salesforce: {str(e)}"
# Main Gradio function
def process_construction_photo(project_name, image):
if not project_name or not image:
return None, "Please provide a project name and upload a photo."
# Connect to Salesforce
try:
sf = Salesforce(
username=os.getenv('SALESFORCE_USERNAME'),
password=os.getenv('SALESFORCE_PASSWORD'),
security_token=os.getenv('SALESFORCE_SECURITY_TOKEN'),
domain=os.getenv('SALESFORCE_DOMAIN')
)
except Exception as e:
return None, f"Failed to connect to Salesforce: {str(e)}"
# Validate photo size
is_valid, error = validate_photo_size(image)
if not is_valid:
return None, error or "Photo is too large! Please upload a photo smaller than 20MB."
# Process the image with AI
milestone, percentage, error = predict_milestone(image)
if error:
fields, error_message = update_salesforce_record(
sf=sf,
project_name=project_name,
milestone=None,
percentage=0.00,
image_url=None,
status="Failure",
comments=error
)
error_text = f"AI Error: {error}"
if error_message:
error_text += f"\nSalesforce Error: {error_message}"
if fields:
error_text += "\nUpdated Salesforce Fields:\n"
for field, value in fields.items():
error_text += f"{field}: {value}\n"
return None, error_text
# Upload image to Salesforce
image_url, upload_error = upload_image_to_salesforce(image, project_name)
if upload_error:
fields, error_message = update_salesforce_record(
sf=sf,
project_name=project_name,
milestone=milestone,
percentage=percentage,
image_url=None,
status="Failure",
comments=upload_error
)
error_text = f"Upload Error: {upload_error}"
if error_message:
error_text += f"\nSalesforce Error: {error_message}"
if fields:
error_text += "\nUpdated Salesforce Fields:\n"
for field, value in fields.items():
error_text += f"{field}: {value}\n"
return None, error_text
# Update Salesforce with success
fields, error_message = update_salesforce_record(
sf=sf,
project_name=project_name,
milestone=milestone,
percentage=percentage,
image_url=image_url,
status="Success",
comments="Photo processed successfully"
)
if error_message:
return None, f"Salesforce Error: {error_message}"
# Prepare output with AI results and Salesforce fields
result_text = f"Success! Milestone: {milestone}, Completion: {percentage}%\nProgress saved to Salesforce!\n\nSalesforce Fields:\n"
for field, value in fields.items():
result_text += f"{field}: {value}\n"
return image, result_text
# Gradio interface
iface = gr.Interface(
fn=process_construction_photo,
inputs=[
gr.Textbox(label="Project Name (e.g., Sunshine Apartments)", placeholder="Sunshine Apartments"),
gr.Image(type="pil", label="Upload a Construction Photo")
],
outputs=[
gr.Image(label="Uploaded Photo"),
gr.Textbox(label="Result")
],
title="Construction Project Progress Tracker",
description="Upload a photo of your construction site, and the AI will tell you the progress!"
)
# Launch the Gradio app
if __name__ == "__main__":
iface.launch() |