Update app.py
Browse files
app.py
CHANGED
|
@@ -40,6 +40,10 @@ SF_INSTANCE_URL = os.getenv("SF_INSTANCE_URL")
|
|
| 40 |
# Validate Salesforce environment variables
|
| 41 |
if not all([SF_USERNAME, SF_PASSWORD, SF_SECURITY_TOKEN, SF_INSTANCE_URL]):
|
| 42 |
logging.error("One or more Salesforce environment variables are missing. Salesforce functionality will be disabled.")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
SALESFORCE_AVAILABLE = False
|
| 44 |
|
| 45 |
# Hugging Face configuration
|
|
@@ -143,7 +147,7 @@ def create_salesforce_record(score, checklist_summary, missing_summary, status,
|
|
| 143 |
"QA_Report__c": qa_report
|
| 144 |
}
|
| 145 |
|
| 146 |
-
logging.debug(f"Attempting to create Salesforce record: {record}")
|
| 147 |
result = sf.Project_Closure_Handover__c.create(record)
|
| 148 |
logging.info(f"Successfully created Salesforce record: {result}")
|
| 149 |
return "Record created successfully"
|
|
@@ -249,19 +253,11 @@ def generate_pdf(score, checklist_summary, missing_summary, status, logs, qa_rep
|
|
| 249 |
logging.info("Sanitizing inputs for PDF generation")
|
| 250 |
score = str(float(score)) if score is not None else "0"
|
| 251 |
checklist_summary = str(checklist_summary) if checklist_summary is not None else ""
|
| 252 |
-
missing_summary = str(missing_summary) if missing_summary is not None else ""
|
| 253 |
status = str(status) if status is not None else ""
|
| 254 |
-
logs = str(logs) if logs else ""
|
| 255 |
-
qa_report = str(qa_report) if qa_report else ""
|
| 256 |
-
punch_list_text = str(punch_list_text) if punch_list_text else ""
|
| 257 |
|
| 258 |
# Remove non-ASCII characters to prevent rendering issues
|
| 259 |
checklist_summary = checklist_summary.encode('ascii', 'ignore').decode('ascii')
|
| 260 |
-
missing_summary = missing_summary.encode('ascii', 'ignore').decode('ascii')
|
| 261 |
status = status.encode('ascii', 'ignore').decode('ascii')
|
| 262 |
-
logs = logs.encode('ascii', 'ignore').decode('ascii')
|
| 263 |
-
qa_report = qa_report.encode('ascii', 'ignore').decode('ascii')
|
| 264 |
-
punch_list_text = punch_list_text.encode('ascii', 'ignore').decode('ascii')
|
| 265 |
|
| 266 |
# Define the temporary file path
|
| 267 |
pdf_path = "readiness_report.pdf"
|
|
@@ -295,77 +291,20 @@ def generate_pdf(score, checklist_summary, missing_summary, status, logs, qa_rep
|
|
| 295 |
c.drawString(50, y, line)
|
| 296 |
y -= 20
|
| 297 |
|
| 298 |
-
# Draw
|
| 299 |
-
logging.info("Drawing remaining fields")
|
| 300 |
-
if y < BOTTOM_MARGIN:
|
| 301 |
-
logging.info("Y position below margin, creating new page")
|
| 302 |
-
c.showPage()
|
| 303 |
-
c.setFont("Times-Roman", 12)
|
| 304 |
-
y = 750
|
| 305 |
-
c.drawString(50, y - 20, "Missing Items:")
|
| 306 |
-
|
| 307 |
if y - 40 < BOTTOM_MARGIN:
|
| 308 |
logging.info("Y position below margin, creating new page")
|
| 309 |
c.showPage()
|
| 310 |
c.setFont("Times-Roman", 12)
|
| 311 |
y = 750
|
| 312 |
-
c.drawString(50, y - 40,
|
| 313 |
|
| 314 |
if y - 60 < BOTTOM_MARGIN:
|
| 315 |
logging.info("Y position below margin, creating new page")
|
| 316 |
c.showPage()
|
| 317 |
c.setFont("Times-Roman", 12)
|
| 318 |
y = 750
|
| 319 |
-
c.drawString(50, y - 60, "
|
| 320 |
-
|
| 321 |
-
if y - 80 < BOTTOM_MARGIN:
|
| 322 |
-
logging.info("Y position below margin, creating new page")
|
| 323 |
-
c.showPage()
|
| 324 |
-
c.setFont("Times-Roman", 12)
|
| 325 |
-
y = 750
|
| 326 |
-
c.drawString(50, y - 80, logs[:100] + "..." if len(logs) > 100 else logs)
|
| 327 |
-
|
| 328 |
-
if y - 100 < BOTTOM_MARGIN:
|
| 329 |
-
logging.info("Y position below margin, creating new page")
|
| 330 |
-
c.showPage()
|
| 331 |
-
c.setFont("Times-Roman", 12)
|
| 332 |
-
y = 750
|
| 333 |
-
c.drawString(50, y - 100, "QA Report:")
|
| 334 |
-
|
| 335 |
-
if y - 120 < BOTTOM_MARGIN:
|
| 336 |
-
logging.info("Y position below margin, creating new page")
|
| 337 |
-
c.showPage()
|
| 338 |
-
c.setFont("Times-Roman", 12)
|
| 339 |
-
y = 750
|
| 340 |
-
c.drawString(50, y - 120, qa_report[:100] + "..." if len(qa_report) > 100 else qa_report)
|
| 341 |
-
|
| 342 |
-
if y - 140 < BOTTOM_MARGIN:
|
| 343 |
-
logging.info("Y position below margin, creating new page")
|
| 344 |
-
c.showPage()
|
| 345 |
-
c.setFont("Times-Roman", 12)
|
| 346 |
-
y = 750
|
| 347 |
-
c.drawString(50, y - 140, "Punch List:")
|
| 348 |
-
|
| 349 |
-
if y - 160 < BOTTOM_MARGIN:
|
| 350 |
-
logging.info("Y position below margin, creating new page")
|
| 351 |
-
c.showPage()
|
| 352 |
-
c.setFont("Times-Roman", 12)
|
| 353 |
-
y = 750
|
| 354 |
-
c.drawString(50, y - 160, punch_list_text[:100] + "..." if len(punch_list_text) > 100 else punch_list_text)
|
| 355 |
-
|
| 356 |
-
if y - 180 < BOTTOM_MARGIN:
|
| 357 |
-
logging.info("Y position below margin, creating new page")
|
| 358 |
-
c.showPage()
|
| 359 |
-
c.setFont("Times-Roman", 12)
|
| 360 |
-
y = 750
|
| 361 |
-
c.drawString(50, y - 180, "Stakeholder Signature: ____________________")
|
| 362 |
-
|
| 363 |
-
if y - 200 < BOTTOM_MARGIN:
|
| 364 |
-
logging.info("Y position below margin, creating new page")
|
| 365 |
-
c.showPage()
|
| 366 |
-
c.setFont("Times-Roman", 12)
|
| 367 |
-
y = 750
|
| 368 |
-
c.drawString(50, y - 200, "Date: ____________________")
|
| 369 |
|
| 370 |
# Finalize the PDF
|
| 371 |
logging.info("Finalizing PDF")
|
|
@@ -377,7 +316,7 @@ def generate_pdf(score, checklist_summary, missing_summary, status, logs, qa_rep
|
|
| 377 |
raise FileNotFoundError(f"PDF file {pdf_path} was not created")
|
| 378 |
|
| 379 |
logging.info(f"PDF generated successfully at {pdf_path}")
|
| 380 |
-
return pdf_path, "PDF generation
|
| 381 |
except Exception as e:
|
| 382 |
logging.error(f"Error in generate_pdf: {str(e)}")
|
| 383 |
raise
|
|
@@ -401,7 +340,7 @@ with gr.Blocks(css="""
|
|
| 401 |
logs_input = gr.Textbox(label="Project Logs", lines=5, placeholder="Enter project logs (e.g., 'Project complete, handover done')")
|
| 402 |
qa_input = gr.Textbox(label="QA Report", placeholder="Enter QA status (e.g., 'Approved')")
|
| 403 |
punch_input = gr.Textbox(label="Punch List (Plain Text)", placeholder="Enter punch list status (e.g., 'None' or 'Resolved')")
|
| 404 |
-
submit_btn = gr.Button("Evaluate and
|
| 405 |
with gr.Column(scale=3):
|
| 406 |
score_output = gr.Number(label="Readiness Score (%)")
|
| 407 |
progress_output = gr.HTML(label="Alert Indicator: Progress")
|
|
@@ -411,7 +350,7 @@ with gr.Blocks(css="""
|
|
| 411 |
gr.Markdown("### Handover Summary")
|
| 412 |
checklist_output = gr.Textbox(label="Checklist Summary")
|
| 413 |
missing_output = gr.Textbox(label="Missing Items")
|
| 414 |
-
pdf_output = gr.File(label="PDF Report
|
| 415 |
pdf_debug = gr.Textbox(label="PDF Debug Output") # Temporary debug output
|
| 416 |
|
| 417 |
# Chain the evaluation, PDF generation, and Salesforce record creation
|
|
|
|
| 40 |
# Validate Salesforce environment variables
|
| 41 |
if not all([SF_USERNAME, SF_PASSWORD, SF_SECURITY_TOKEN, SF_INSTANCE_URL]):
|
| 42 |
logging.error("One or more Salesforce environment variables are missing. Salesforce functionality will be disabled.")
|
| 43 |
+
logging.error(f"SF_USERNAME: {SF_USERNAME}")
|
| 44 |
+
logging.error(f"SF_PASSWORD: {'Set' if SF_PASSWORD else 'Not Set'}")
|
| 45 |
+
logging.error(f"SF_SECURITY_TOKEN: {'Set' if SF_SECURITY_TOKEN else 'Not Set'}")
|
| 46 |
+
logging.error(f"SF_INSTANCE_URL: {SF_INSTANCE_URL}")
|
| 47 |
SALESFORCE_AVAILABLE = False
|
| 48 |
|
| 49 |
# Hugging Face configuration
|
|
|
|
| 147 |
"QA_Report__c": qa_report
|
| 148 |
}
|
| 149 |
|
| 150 |
+
logging.debug(f"Attempting to create Salesforce record with data: {record}")
|
| 151 |
result = sf.Project_Closure_Handover__c.create(record)
|
| 152 |
logging.info(f"Successfully created Salesforce record: {result}")
|
| 153 |
return "Record created successfully"
|
|
|
|
| 253 |
logging.info("Sanitizing inputs for PDF generation")
|
| 254 |
score = str(float(score)) if score is not None else "0"
|
| 255 |
checklist_summary = str(checklist_summary) if checklist_summary is not None else ""
|
|
|
|
| 256 |
status = str(status) if status is not None else ""
|
|
|
|
|
|
|
|
|
|
| 257 |
|
| 258 |
# Remove non-ASCII characters to prevent rendering issues
|
| 259 |
checklist_summary = checklist_summary.encode('ascii', 'ignore').decode('ascii')
|
|
|
|
| 260 |
status = status.encode('ascii', 'ignore').decode('ascii')
|
|
|
|
|
|
|
|
|
|
| 261 |
|
| 262 |
# Define the temporary file path
|
| 263 |
pdf_path = "readiness_report.pdf"
|
|
|
|
| 291 |
c.drawString(50, y, line)
|
| 292 |
y -= 20
|
| 293 |
|
| 294 |
+
# Draw signature slots
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
if y - 40 < BOTTOM_MARGIN:
|
| 296 |
logging.info("Y position below margin, creating new page")
|
| 297 |
c.showPage()
|
| 298 |
c.setFont("Times-Roman", 12)
|
| 299 |
y = 750
|
| 300 |
+
c.drawString(50, y - 40, "Stakeholder Signature: ____________________")
|
| 301 |
|
| 302 |
if y - 60 < BOTTOM_MARGIN:
|
| 303 |
logging.info("Y position below margin, creating new page")
|
| 304 |
c.showPage()
|
| 305 |
c.setFont("Times-Roman", 12)
|
| 306 |
y = 750
|
| 307 |
+
c.drawString(50, y - 60, "Date: ____________________")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
|
| 309 |
# Finalize the PDF
|
| 310 |
logging.info("Finalizing PDF")
|
|
|
|
| 316 |
raise FileNotFoundError(f"PDF file {pdf_path} was not created")
|
| 317 |
|
| 318 |
logging.info(f"PDF generated successfully at {pdf_path}")
|
| 319 |
+
return pdf_path, "PDF generation completed. Click the link to download."
|
| 320 |
except Exception as e:
|
| 321 |
logging.error(f"Error in generate_pdf: {str(e)}")
|
| 322 |
raise
|
|
|
|
| 340 |
logs_input = gr.Textbox(label="Project Logs", lines=5, placeholder="Enter project logs (e.g., 'Project complete, handover done')")
|
| 341 |
qa_input = gr.Textbox(label="QA Report", placeholder="Enter QA status (e.g., 'Approved')")
|
| 342 |
punch_input = gr.Textbox(label="Punch List (Plain Text)", placeholder="Enter punch list status (e.g., 'None' or 'Resolved')")
|
| 343 |
+
submit_btn = gr.Button("Evaluate and Generate PDF")
|
| 344 |
with gr.Column(scale=3):
|
| 345 |
score_output = gr.Number(label="Readiness Score (%)")
|
| 346 |
progress_output = gr.HTML(label="Alert Indicator: Progress")
|
|
|
|
| 350 |
gr.Markdown("### Handover Summary")
|
| 351 |
checklist_output = gr.Textbox(label="Checklist Summary")
|
| 352 |
missing_output = gr.Textbox(label="Missing Items")
|
| 353 |
+
pdf_output = gr.File(label="Download PDF Report", type="filepath", interactive=False) # Output only, no auto-download
|
| 354 |
pdf_debug = gr.Textbox(label="PDF Debug Output") # Temporary debug output
|
| 355 |
|
| 356 |
# Chain the evaluation, PDF generation, and Salesforce record creation
|