Spaces:
Sleeping
Sleeping
from transformers import BlipProcessor, BlipForConditionalGeneration | |
from PIL import Image | |
import gradio as gr | |
import torch | |
from datetime import datetime | |
from fpdf import FPDF | |
from simple_salesforce import Salesforce | |
import requests | |
import json | |
import os | |
from dotenv import load_dotenv | |
# Load environment variables from .env file | |
load_dotenv() | |
# Salesforce credentials | |
SF_USERNAME = os.getenv('SF_USERNAME') | |
SF_PASSWORD = os.getenv('SF_PASSWORD') | |
SF_SECURITY_TOKEN = os.getenv('SF_SECURITY_TOKEN') | |
# Initialize Salesforce connection | |
sf = Salesforce(username=SF_USERNAME, password=SF_PASSWORD, security_token=SF_SECURITY_TOKEN) | |
# Load BLIP model and processor | |
processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base") | |
model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base") | |
model.eval() | |
device = "cuda" if torch.cuda.is_available() else "cpu" | |
model.to(device) | |
# Inference function to generate captions dynamically based on image content | |
def generate_captions_from_image(image): | |
if image.mode != "RGB": | |
image = image.convert("RGB") | |
# Preprocess the image and generate a caption | |
inputs = processor(image, return_tensors="pt").to(device, torch.float16) | |
output = model.generate(**inputs, max_new_tokens=50) | |
caption = processor.decode(output[0], skip_special_tokens=True) | |
return caption | |
# Function to create PDF and upload to Salesforce | |
def create_and_upload_pdf(dpr_content): | |
# Create PDF instance using FPDF | |
pdf = FPDF() | |
pdf.set_auto_page_break(auto=True, margin=15) | |
pdf.add_page() | |
# Set title and content for the PDF | |
pdf.set_font("Arial", size=12) | |
pdf.cell(200, 10, txt="Daily Progress Report", ln=True, align='C') | |
pdf.ln(10) # Add space between lines | |
# Add the content of the DPR text to the PDF | |
pdf.multi_cell(0, 10, dpr_content) | |
# Save PDF to a file (temporary storage) | |
pdf_output_path = "/tmp/dpr_report.pdf" | |
pdf.output(pdf_output_path) | |
# Upload PDF to Salesforce as ContentVersion | |
with open(pdf_output_path, 'rb') as pdf_file: | |
pdf_data = pdf_file.read() | |
# Prepare request to Salesforce | |
content_version_payload = { | |
"Title": "Daily Progress Report", | |
"PathOnClient": "DPR_Report.pdf", | |
"VersionData": pdf_data | |
} | |
content_version_url = f"{sf.base_url}/services/data/v50.0/sobjects/ContentVersion/" | |
headers = { | |
"Authorization": f"Bearer {sf.session_id}", | |
"Content-Type": "application/json" | |
} | |
response = requests.post(content_version_url, headers=headers, files={"VersionData": pdf_data}, data=json.dumps(content_version_payload)) | |
if response.status_code == 201: | |
content_version = response.json() | |
pdf_url = f"/sfc/servlet.shepherd/version/download/{content_version['Id']}" | |
return pdf_url | |
else: | |
raise Exception("Error uploading PDF to Salesforce: " + response.text) | |
# Function to generate the daily progress report (DPR) text | |
def generate_dpr(files): | |
dpr_text = [] | |
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
# Add header to the DPR | |
dpr_text.append(f"Daily Progress Report\nGenerated on: {current_time}\n") | |
# Process each uploaded file (image) | |
for file in files: | |
# Open the image from file path | |
image = Image.open(file.name) # Using file.name for filepath | |
if image.mode != "RGB": | |
image = image.convert("RGB") | |
# Dynamically generate a caption based on the image | |
caption = generate_captions_from_image(image) | |
# Generate DPR section for this image with dynamic caption | |
dpr_section = f"\nImage: {file.name}\nDescription: {caption}\n" | |
dpr_text.append(dpr_section) | |
# Join the DPR sections to form the complete report | |
dpr_content = "\n".join(dpr_text) | |
# Create and upload the PDF for this report in Salesforce | |
pdf_url = create_and_upload_pdf(dpr_content) | |
# Create a new Salesforce record for this report | |
new_report_data = { | |
"Report_Date__c": current_time, # Set Report Date to current time | |
"Detected_Activities__c": dpr_content, # Set the activities field to the generated text | |
"Photo_Uploads__c": ", ".join([file.name for file in files]), # Upload file names as Photo Uploads | |
"PDF_URL__c": pdf_url # Set the PDF URL field with the generated PDF link | |
} | |
# Insert new Daily Progress Report record into Salesforce | |
new_report = sf.Daily_Progress_Reports__c.create(new_report_data) | |
return f"New report created in Salesforce with PDF URL: {pdf_url}" | |
# Gradio interface for uploading multiple files and displaying the text-based DPR | |
iface = gr.Interface( | |
fn=generate_dpr, | |
inputs=gr.Files(type="filepath", label="Upload Site Photos"), # Handle batch upload of images | |
outputs="text", # Display the DPR as text in the output section | |
title="Daily Progress Report Generator", | |
description="Upload up to 10 site photos. The AI model will dynamically detect construction activities, materials, and progress and generate a text-based Daily Progress Report (DPR).", | |
allow_flagging="never" # Optional: Disable flagging | |
) | |
iface.launch() | |