File size: 6,895 Bytes
df97270
7d8ec5e
4bdf8dd
 
49702ec
7f9cc39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c4e3ea5
e6e1a6f
 
 
df97270
 
 
 
 
 
3dfd15f
e6e1a6f
df97270
 
 
e6e1a6f
 
df97270
 
 
e6e1a6f
df97270
c4e3ea5
7f9cc39
 
e6e1a6f
7f9cc39
 
 
e6e1a6f
 
7f9cc39
 
e6e1a6f
 
 
7f9cc39
 
e6e1a6f
7f9cc39
 
 
1f8a64a
7f9cc39
 
 
e6e1a6f
7f9cc39
 
e6e1a6f
7f9cc39
e6e1a6f
 
7f9cc39
e6e1a6f
 
7f9cc39
 
4739337
 
 
e6e1a6f
a44a0fc
e6e1a6f
a44a0fc
e6e1a6f
 
 
 
f565f61
296134c
 
 
 
e6e1a6f
 
 
 
 
7f9cc39
296134c
 
e6e1a6f
7f9cc39
e6e1a6f
49702ec
e6e1a6f
9349e75
e6e1a6f
 
 
 
 
 
 
 
 
 
 
4677555
 
e6e1a6f
4677555
 
 
e6e1a6f
c4fefad
e6e1a6f
 
 
df97270
 
e6e1a6f
 
df97270
e6e1a6f
 
df97270
49702ec
df97270
e6e1a6f
7f9cc39
e6e1a6f
 
7f9cc39
 
e6e1a6f
7f9cc39
e6e1a6f
 
 
 
 
7f9cc39
 
e6e1a6f
 
 
7f9cc39
49702ec
e6e1a6f
4bdf8dd
49702ec
e6e1a6f
 
49702ec
e6e1a6f
 
c4e3ea5
 
e6e1a6f
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
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)

print(f"SF_USERNAME: {SF_USERNAME}, SF_PASSWORD: {SF_PASSWORD}, SF_SECURITY_TOKEN: {SF_SECURITY_TOKEN}")
print("Salesforce Base URL:", sf.base_url)

# 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)

    # Read the generated PDF as binary data
    with open(pdf_output_path, 'rb') as pdf_file:
        pdf_data = pdf_file.read()

    # Prepare request to Salesforce ContentVersion API
    content_version_payload = {
        "Title": "Daily Progress Report",
        "PathOnClient": "DPR_Report.pdf",
    }

    content_version_url = f"https://sathkruthatechsolutionspvt6-dev-ed.develop.my.salesforce.com/services/data/v59.0/sobjects/ContentVersion/"
    headers = {
        "Authorization": f"Bearer {sf.session_id}",
        "Content-Type": "application/json"  # For metadata
    }

    # Debugging step: Log the payload being sent to Salesforce
    print("Content Version Payload:", json.dumps(content_version_payload, indent=4))

    # Pass the binary data in the files parameter (do not include it in the JSON payload)
    files = {
        "VersionData": ("DPR_Report.pdf", pdf_data)  # Tuple (filename, binary data)
    }

    # Make the POST request to upload the file
    response = requests.post(content_version_url, headers=headers, files=files)

    # Log the full response from Salesforce
    print("Response Status Code:", response.status_code)
    print("Response Headers:", response.headers)
    print("Response Body:", response.text)

    # Check the response status
    if response.status_code == 201:
        content_version = response.json()
        pdf_url = f"/sfc/servlet.shepherd/version/download/{content_version['Id']}"
        return pdf_url
    else:
        # If response is not 201, log the response text for further debugging
        print("Error details from Salesforce response:", response.text)
        raise Exception("Error uploading PDF to Salesforce: " + response.text)

# Function to generate the daily progress report (DPR) text
def generate_dpr(files):
    # Query the latest Daily Progress Report records to get the highest number
    last_report = sf.query("SELECT Name FROM Daily_Progress_Reports__c ORDER BY CreatedDate DESC LIMIT 1")
    
    # Generate the new report name
    if last_report['totalSize'] > 0:
        last_name = last_report['records'][0]['Name']
        # Extract the number from the last report name, assuming format "Daily Progress Report X"
        report_number = int(last_name.split()[-1]) + 1  # Increment the number
    else:
        # If no records exist, start with "1"
        report_number = 1
    
    # Generate the new report name dynamically
    new_report_name = f"Daily Progress Report {report_number}"

    # Prepare the current time and start the DPR text
    current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    dpr_text = [f"Daily Progress Report\nGenerated on: {current_time}\n"]

    # Process each uploaded file (image)
    for file in files:
        # Open the image from the file path
        image = Image.open(file.name)  # Using file.name for filepath
        
        if image.mode != "RGB":
            image = image.convert("RGB")
        
        # Generate a caption for the image
        caption = generate_captions_from_image(image)
        
        # Generate a section of the DPR for this image
        dpr_section = f"\nImage: {file.name}\nDescription: {caption}\n"
        dpr_text.append(dpr_section)

    # Join the DPR sections into one complete string
    dpr_content = "\n".join(dpr_text)

    # Create and upload the PDF for this report to Salesforce
    pdf_url = create_and_upload_pdf(dpr_content)

    # Create the new Daily Progress Report record in Salesforce
    new_report_data = {
        "Name": new_report_name,  # Set the dynamic name
        "Report_Date__c": current_time,  # Set the report date to the 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 the image names as Photo Uploads
        "PDF_URL__c": pdf_url  # Set the PDF URL field with the generated PDF link
    }

    # Insert the new report 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()