ChAbhishek28 commited on
Commit
f547301
·
1 Parent(s): fde5743

New change

Browse files
Files changed (1) hide show
  1. evidence_pack_export.py +33 -16
evidence_pack_export.py CHANGED
@@ -3,6 +3,22 @@ from fpdf import FPDF
3
  import tempfile
4
  import os
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  def export_evidence_pack_pdf(data, filename=None):
7
  """
8
  Export evidence pack as PDF. Data should include clause, summary, checklist, scenario, metadata.
@@ -19,7 +35,7 @@ def export_evidence_pack_pdf(data, filename=None):
19
  pdf.cell(0, 8, txt="Clause:", ln=True)
20
  pdf.set_font("Arial", size=10)
21
  clause_text = data.get('clause_text', 'No clause information available')
22
- pdf.multi_cell(0, 6, clause_text)
23
  pdf.ln(3)
24
 
25
  # Summary section
@@ -27,7 +43,7 @@ def export_evidence_pack_pdf(data, filename=None):
27
  pdf.cell(0, 8, txt="Summary:", ln=True)
28
  pdf.set_font("Arial", size=10)
29
  summary_text = data.get('summary', 'No summary available')
30
- pdf.multi_cell(0, 6, summary_text)
31
  pdf.ln(3)
32
 
33
  # Checklist section
@@ -37,7 +53,8 @@ def export_evidence_pack_pdf(data, filename=None):
37
  checklist = data.get('role_checklist', [])
38
  if checklist:
39
  for item in checklist:
40
- pdf.multi_cell(0, 6, f"• {item}")
 
41
  else:
42
  pdf.multi_cell(0, 6, "No checklist items available")
43
  pdf.ln(3)
@@ -46,27 +63,27 @@ def export_evidence_pack_pdf(data, filename=None):
46
  pdf.set_font("Arial", "B", size=12)
47
  pdf.cell(0, 8, txt="Source Information:", ln=True)
48
  pdf.set_font("Arial", size=10)
49
- pdf.multi_cell(0, 6, f"Source: {data.get('source_title', 'Not specified')}")
50
- pdf.multi_cell(0, 6, f"Clause ID: {data.get('clause_id', 'Not assigned')}")
51
- pdf.multi_cell(0, 6, f"Date: {data.get('date', 'Not specified')}")
52
- pdf.multi_cell(0, 6, f"URL: {data.get('url', 'Not available')}")
53
 
54
  # User role and context information
55
  if data.get('user_role'):
56
- pdf.multi_cell(0, 6, f"User Role: {data.get('user_role', '').title()}")
57
  if data.get('language_preference'):
58
- pdf.multi_cell(0, 6, f"Language: {data.get('language_preference', '').title()}")
59
 
60
  pdf.ln(5)
61
  scenario = data.get('scenario_analysis',{})
62
  if scenario:
63
- pdf.multi_cell(0, 8, f"Scenario Analysis:")
64
- pdf.multi_cell(0, 8, f"Yearly Results: {scenario.get('yearly_results','')}")
65
- pdf.multi_cell(0, 8, f"Cumulative Base: {scenario.get('cumulative_base','')}")
66
- pdf.multi_cell(0, 8, f"Cumulative Scenario: {scenario.get('cumulative_scenario','')}")
67
- pdf.multi_cell(0, 8, f"Optimistic: {scenario.get('optimistic','')}")
68
- pdf.multi_cell(0, 8, f"Pessimistic: {scenario.get('pessimistic','')}")
69
- pdf.multi_cell(0, 8, f"Driver Breakdown: {scenario.get('driver_breakdown','')}")
70
  if not filename:
71
  filename = os.path.join(tempfile.gettempdir(), f"evidence_pack_{os.getpid()}.pdf")
72
  pdf.output(filename)
 
3
  import tempfile
4
  import os
5
 
6
+ def _safe_text_for_pdf(s: object) -> str:
7
+ """
8
+ Ensure text passed to FPDF only contains characters encodable in latin-1.
9
+ FPDF (classic) writes using latin-1 encoding by default and will raise
10
+ an error when encountering characters outside that range (e.g. •).
11
+ This helper replaces unsupported characters with a best-effort replacement
12
+ so PDF generation doesn't fail.
13
+ """
14
+ if s is None:
15
+ return ""
16
+ try:
17
+ text = str(s)
18
+ except Exception:
19
+ text = ""
20
+ # encode -> decode using latin-1 with replacement to avoid exceptions
21
+ return text.encode('latin-1', 'replace').decode('latin-1')
22
  def export_evidence_pack_pdf(data, filename=None):
23
  """
24
  Export evidence pack as PDF. Data should include clause, summary, checklist, scenario, metadata.
 
35
  pdf.cell(0, 8, txt="Clause:", ln=True)
36
  pdf.set_font("Arial", size=10)
37
  clause_text = data.get('clause_text', 'No clause information available')
38
+ pdf.multi_cell(0, 6, _safe_text_for_pdf(clause_text))
39
  pdf.ln(3)
40
 
41
  # Summary section
 
43
  pdf.cell(0, 8, txt="Summary:", ln=True)
44
  pdf.set_font("Arial", size=10)
45
  summary_text = data.get('summary', 'No summary available')
46
+ pdf.multi_cell(0, 6, _safe_text_for_pdf(summary_text))
47
  pdf.ln(3)
48
 
49
  # Checklist section
 
53
  checklist = data.get('role_checklist', [])
54
  if checklist:
55
  for item in checklist:
56
+ # use a simple hyphen bullet and sanitize text
57
+ pdf.multi_cell(0, 6, _safe_text_for_pdf(f"- {item}"))
58
  else:
59
  pdf.multi_cell(0, 6, "No checklist items available")
60
  pdf.ln(3)
 
63
  pdf.set_font("Arial", "B", size=12)
64
  pdf.cell(0, 8, txt="Source Information:", ln=True)
65
  pdf.set_font("Arial", size=10)
66
+ pdf.multi_cell(0, 6, _safe_text_for_pdf(f"Source: {data.get('source_title', 'Not specified')}"))
67
+ pdf.multi_cell(0, 6, _safe_text_for_pdf(f"Clause ID: {data.get('clause_id', 'Not assigned')}"))
68
+ pdf.multi_cell(0, 6, _safe_text_for_pdf(f"Date: {data.get('date', 'Not specified')}"))
69
+ pdf.multi_cell(0, 6, _safe_text_for_pdf(f"URL: {data.get('url', 'Not available')}"))
70
 
71
  # User role and context information
72
  if data.get('user_role'):
73
+ pdf.multi_cell(0, 6, _safe_text_for_pdf(f"User Role: {data.get('user_role', '').title()}"))
74
  if data.get('language_preference'):
75
+ pdf.multi_cell(0, 6, _safe_text_for_pdf(f"Language: {data.get('language_preference', '').title()}"))
76
 
77
  pdf.ln(5)
78
  scenario = data.get('scenario_analysis',{})
79
  if scenario:
80
+ pdf.multi_cell(0, 8, _safe_text_for_pdf(f"Scenario Analysis:"))
81
+ pdf.multi_cell(0, 8, _safe_text_for_pdf(f"Yearly Results: {scenario.get('yearly_results','')}"))
82
+ pdf.multi_cell(0, 8, _safe_text_for_pdf(f"Cumulative Base: {scenario.get('cumulative_base','')}"))
83
+ pdf.multi_cell(0, 8, _safe_text_for_pdf(f"Cumulative Scenario: {scenario.get('cumulative_scenario','')}"))
84
+ pdf.multi_cell(0, 8, _safe_text_for_pdf(f"Optimistic: {scenario.get('optimistic','')}"))
85
+ pdf.multi_cell(0, 8, _safe_text_for_pdf(f"Pessimistic: {scenario.get('pessimistic','')}"))
86
+ pdf.multi_cell(0, 8, _safe_text_for_pdf(f"Driver Breakdown: {scenario.get('driver_breakdown','')}"))
87
  if not filename:
88
  filename = os.path.join(tempfile.gettempdir(), f"evidence_pack_{os.getpid()}.pdf")
89
  pdf.output(filename)