Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -21,9 +21,6 @@ SF_SECURITY_TOKEN = os.getenv('SF_SECURITY_TOKEN')
|
|
| 21 |
# Initialize Salesforce connection
|
| 22 |
sf = Salesforce(username=SF_USERNAME, password=SF_PASSWORD, security_token=SF_SECURITY_TOKEN)
|
| 23 |
|
| 24 |
-
print(f"SF_USERNAME: {SF_USERNAME}, SF_PASSWORD: {SF_PASSWORD}, SF_SECURITY_TOKEN: {SF_SECURITY_TOKEN}")
|
| 25 |
-
print("Salesforce Base URL:", sf.base_url)
|
| 26 |
-
|
| 27 |
# Load BLIP model and processor
|
| 28 |
processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 29 |
model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
|
|
@@ -31,35 +28,28 @@ model.eval()
|
|
| 31 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 32 |
model.to(device)
|
| 33 |
|
| 34 |
-
#
|
| 35 |
def generate_captions_from_image(image):
|
| 36 |
if image.mode != "RGB":
|
| 37 |
image = image.convert("RGB")
|
| 38 |
-
|
| 39 |
-
# Preprocess the image and generate a caption
|
| 40 |
inputs = processor(image, return_tensors="pt").to(device, torch.float16)
|
| 41 |
output = model.generate(**inputs, max_new_tokens=50)
|
| 42 |
caption = processor.decode(output[0], skip_special_tokens=True)
|
| 43 |
-
|
| 44 |
return caption
|
| 45 |
-
|
| 46 |
|
| 47 |
# Function to create PDF and upload to Salesforce
|
| 48 |
def create_and_upload_pdf(dpr_content):
|
| 49 |
-
# Create PDF instance using FPDF
|
| 50 |
pdf = FPDF()
|
| 51 |
pdf.set_auto_page_break(auto=True, margin=15)
|
| 52 |
pdf.add_page()
|
| 53 |
-
|
| 54 |
-
# Set title and content for the PDF
|
| 55 |
pdf.set_font("Arial", size=12)
|
| 56 |
pdf.cell(200, 10, txt="Daily Progress Report", ln=True, align='C')
|
| 57 |
-
pdf.ln(10)
|
| 58 |
-
|
| 59 |
-
# Add the content of the DPR text to the PDF
|
| 60 |
pdf.multi_cell(0, 10, dpr_content)
|
| 61 |
|
| 62 |
-
# Save PDF to
|
| 63 |
pdf_output_path = "/tmp/dpr_report.pdf"
|
| 64 |
pdf.output(pdf_output_path)
|
| 65 |
|
|
@@ -67,99 +57,74 @@ def create_and_upload_pdf(dpr_content):
|
|
| 67 |
with open(pdf_output_path, 'rb') as pdf_file:
|
| 68 |
pdf_data = pdf_file.read()
|
| 69 |
|
| 70 |
-
#
|
| 71 |
content_version_payload = {
|
| 72 |
"Title": "Daily Progress Report",
|
| 73 |
-
"PathOnClient": "DPR_Report.pdf"
|
| 74 |
}
|
| 75 |
-
|
| 76 |
-
content_version_url = f"https://
|
| 77 |
headers = {
|
| 78 |
-
"Authorization": f"Bearer {sf.session_id}"
|
| 79 |
-
"Content-Type": "application/json" # For metadata
|
| 80 |
}
|
| 81 |
|
| 82 |
-
#
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
# Make the POST request to upload the file
|
| 89 |
-
response = requests.post(content_version_url, headers=headers, files=files)
|
| 90 |
|
| 91 |
-
#
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
| 96 |
else:
|
| 97 |
-
raise Exception("Error uploading PDF
|
| 98 |
|
| 99 |
-
# Function to generate the daily progress report
|
| 100 |
def generate_dpr(files):
|
| 101 |
-
# Query the latest Daily Progress Report records to get the highest number
|
| 102 |
last_report = sf.query("SELECT Name FROM Daily_Progress_Reports__c ORDER BY CreatedDate DESC LIMIT 1")
|
| 103 |
-
|
| 104 |
-
# Generate the new report name
|
| 105 |
-
if last_report['totalSize'] > 0:
|
| 106 |
-
last_name = last_report['records'][0]['Name']
|
| 107 |
-
# Extract the number from the last report name, assuming format "Daily Progress Report X"
|
| 108 |
-
report_number = int(last_name.split()[-1]) + 1 # Increment the number
|
| 109 |
-
else:
|
| 110 |
-
# If no records exist, start with "1"
|
| 111 |
-
report_number = 1
|
| 112 |
-
|
| 113 |
-
# Generate the new report name dynamically
|
| 114 |
new_report_name = f"Daily Progress Report {report_number}"
|
| 115 |
|
| 116 |
-
# Prepare the current time and start the DPR text
|
| 117 |
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
| 118 |
dpr_text = [f"Daily Progress Report\nGenerated on: {current_time}\n"]
|
| 119 |
|
| 120 |
-
# Process each uploaded file (image)
|
| 121 |
for file in files:
|
| 122 |
-
|
| 123 |
-
image = Image.open(file.name) # Using file.name for filepath
|
| 124 |
-
|
| 125 |
if image.mode != "RGB":
|
| 126 |
image = image.convert("RGB")
|
| 127 |
-
|
| 128 |
-
# Generate a caption for the image
|
| 129 |
caption = generate_captions_from_image(image)
|
| 130 |
-
|
| 131 |
-
# Generate a section of the DPR for this image
|
| 132 |
dpr_section = f"\nImage: {file.name}\nDescription: {caption}\n"
|
| 133 |
dpr_text.append(dpr_section)
|
| 134 |
|
| 135 |
-
# Join the DPR sections into one complete string
|
| 136 |
dpr_content = "\n".join(dpr_text)
|
| 137 |
-
|
| 138 |
-
# Create and upload the PDF for this report to Salesforce
|
| 139 |
pdf_url = create_and_upload_pdf(dpr_content)
|
| 140 |
|
| 141 |
-
# Create the new Daily Progress Report record in Salesforce
|
| 142 |
new_report_data = {
|
| 143 |
-
"Name": new_report_name,
|
| 144 |
-
"Report_Date__c": current_time,
|
| 145 |
-
"Detected_Activities__c": dpr_content,
|
| 146 |
-
"Photo_Uploads__c": ", ".join([file.name for file in files]),
|
| 147 |
-
"PDF_URL__c": pdf_url
|
| 148 |
}
|
| 149 |
|
| 150 |
-
|
| 151 |
-
new_report = sf.Daily_Progress_Reports__c.create(new_report_data)
|
| 152 |
-
|
| 153 |
return f"New report created in Salesforce with PDF URL: {pdf_url}"
|
| 154 |
|
| 155 |
-
# Gradio interface for uploading
|
| 156 |
iface = gr.Interface(
|
| 157 |
fn=generate_dpr,
|
| 158 |
-
inputs=gr.Files(type="filepath", label="Upload Site Photos"),
|
| 159 |
-
outputs="text",
|
| 160 |
title="Daily Progress Report Generator",
|
| 161 |
-
description="Upload up to 10 site photos. The AI model
|
| 162 |
-
allow_flagging="never"
|
| 163 |
)
|
| 164 |
|
| 165 |
-
iface.launch()
|
|
|
|
| 21 |
# Initialize Salesforce connection
|
| 22 |
sf = Salesforce(username=SF_USERNAME, password=SF_PASSWORD, security_token=SF_SECURITY_TOKEN)
|
| 23 |
|
|
|
|
|
|
|
|
|
|
| 24 |
# Load BLIP model and processor
|
| 25 |
processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
|
| 26 |
model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
|
|
|
|
| 28 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 29 |
model.to(device)
|
| 30 |
|
| 31 |
+
# Function to generate image captions
|
| 32 |
def generate_captions_from_image(image):
|
| 33 |
if image.mode != "RGB":
|
| 34 |
image = image.convert("RGB")
|
| 35 |
+
|
|
|
|
| 36 |
inputs = processor(image, return_tensors="pt").to(device, torch.float16)
|
| 37 |
output = model.generate(**inputs, max_new_tokens=50)
|
| 38 |
caption = processor.decode(output[0], skip_special_tokens=True)
|
| 39 |
+
|
| 40 |
return caption
|
|
|
|
| 41 |
|
| 42 |
# Function to create PDF and upload to Salesforce
|
| 43 |
def create_and_upload_pdf(dpr_content):
|
|
|
|
| 44 |
pdf = FPDF()
|
| 45 |
pdf.set_auto_page_break(auto=True, margin=15)
|
| 46 |
pdf.add_page()
|
|
|
|
|
|
|
| 47 |
pdf.set_font("Arial", size=12)
|
| 48 |
pdf.cell(200, 10, txt="Daily Progress Report", ln=True, align='C')
|
| 49 |
+
pdf.ln(10)
|
|
|
|
|
|
|
| 50 |
pdf.multi_cell(0, 10, dpr_content)
|
| 51 |
|
| 52 |
+
# Save PDF to file
|
| 53 |
pdf_output_path = "/tmp/dpr_report.pdf"
|
| 54 |
pdf.output(pdf_output_path)
|
| 55 |
|
|
|
|
| 57 |
with open(pdf_output_path, 'rb') as pdf_file:
|
| 58 |
pdf_data = pdf_file.read()
|
| 59 |
|
| 60 |
+
# First, create metadata record
|
| 61 |
content_version_payload = {
|
| 62 |
"Title": "Daily Progress Report",
|
| 63 |
+
"PathOnClient": "DPR_Report.pdf"
|
| 64 |
}
|
| 65 |
+
|
| 66 |
+
content_version_url = f"https://{sf.sf_instance}/services/data/v59.0/sobjects/ContentVersion/"
|
| 67 |
headers = {
|
| 68 |
+
"Authorization": f"Bearer {sf.session_id}"
|
|
|
|
| 69 |
}
|
| 70 |
|
| 71 |
+
# Create ContentVersion record metadata
|
| 72 |
+
metadata_response = requests.post(content_version_url, headers=headers, json=content_version_payload)
|
| 73 |
+
if metadata_response.status_code != 201:
|
| 74 |
+
raise Exception("Metadata creation error: " + metadata_response.text)
|
| 75 |
+
|
| 76 |
+
content_version_id = metadata_response.json()["Id"]
|
|
|
|
|
|
|
| 77 |
|
| 78 |
+
# Upload file separately
|
| 79 |
+
files = {
|
| 80 |
+
"VersionData": ("DPR_Report.pdf", pdf_data, "application/pdf")
|
| 81 |
+
}
|
| 82 |
+
upload_response = requests.post(content_version_url, headers=headers, files=files)
|
| 83 |
+
|
| 84 |
+
if upload_response.status_code == 201:
|
| 85 |
+
return f"/sfc/servlet.shepherd/version/download/{content_version_id}"
|
| 86 |
else:
|
| 87 |
+
raise Exception("Error uploading PDF: " + upload_response.text)
|
| 88 |
|
| 89 |
+
# Function to generate the daily progress report
|
| 90 |
def generate_dpr(files):
|
|
|
|
| 91 |
last_report = sf.query("SELECT Name FROM Daily_Progress_Reports__c ORDER BY CreatedDate DESC LIMIT 1")
|
| 92 |
+
report_number = int(last_report['records'][0]['Name'].split()[-1]) + 1 if last_report['totalSize'] > 0 else 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
new_report_name = f"Daily Progress Report {report_number}"
|
| 94 |
|
|
|
|
| 95 |
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
| 96 |
dpr_text = [f"Daily Progress Report\nGenerated on: {current_time}\n"]
|
| 97 |
|
|
|
|
| 98 |
for file in files:
|
| 99 |
+
image = Image.open(file.name)
|
|
|
|
|
|
|
| 100 |
if image.mode != "RGB":
|
| 101 |
image = image.convert("RGB")
|
|
|
|
|
|
|
| 102 |
caption = generate_captions_from_image(image)
|
|
|
|
|
|
|
| 103 |
dpr_section = f"\nImage: {file.name}\nDescription: {caption}\n"
|
| 104 |
dpr_text.append(dpr_section)
|
| 105 |
|
|
|
|
| 106 |
dpr_content = "\n".join(dpr_text)
|
|
|
|
|
|
|
| 107 |
pdf_url = create_and_upload_pdf(dpr_content)
|
| 108 |
|
|
|
|
| 109 |
new_report_data = {
|
| 110 |
+
"Name": new_report_name,
|
| 111 |
+
"Report_Date__c": current_time,
|
| 112 |
+
"Detected_Activities__c": dpr_content,
|
| 113 |
+
"Photo_Uploads__c": ", ".join([file.name for file in files]),
|
| 114 |
+
"PDF_URL__c": pdf_url
|
| 115 |
}
|
| 116 |
|
| 117 |
+
sf.Daily_Progress_Reports__c.create(new_report_data)
|
|
|
|
|
|
|
| 118 |
return f"New report created in Salesforce with PDF URL: {pdf_url}"
|
| 119 |
|
| 120 |
+
# Gradio interface for uploading site images
|
| 121 |
iface = gr.Interface(
|
| 122 |
fn=generate_dpr,
|
| 123 |
+
inputs=gr.Files(type="filepath", label="Upload Site Photos"),
|
| 124 |
+
outputs="text",
|
| 125 |
title="Daily Progress Report Generator",
|
| 126 |
+
description="Upload up to 10 site photos. The AI model detects construction activities and generates a report.",
|
| 127 |
+
allow_flagging="never"
|
| 128 |
)
|
| 129 |
|
| 130 |
+
iface.launch()
|