MilanM commited on
Commit
f725ded
·
verified ·
1 Parent(s): 3770860

Update pdf_generator.py

Browse files
Files changed (1) hide show
  1. pdf_generator.py +31 -155
pdf_generator.py CHANGED
@@ -1,55 +1,9 @@
1
- import io
2
- import re
3
  from reportlab.lib import colors
4
  from reportlab.lib.pagesizes import A4
5
  from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
6
- from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Flowable
7
- from reportlab.lib.units import mm, inch
8
- from reportlab.graphics.shapes import Drawing, Rect, String, Line
9
-
10
- class SliderFlowable(Flowable):
11
- def __init__(self, name, value, min_val, max_val, is_percentage=False):
12
- Flowable.__init__(self)
13
- self.name = name
14
- self.value = value
15
- self.min_val = min_val
16
- self.max_val = max_val
17
- self.is_percentage = is_percentage
18
- self.width = 400
19
- self.height = 80
20
-
21
- def draw(self):
22
- drawing = Drawing(self.width, self.height)
23
-
24
- # Draw slider bar
25
- bar = Rect(50, 30, 300, 20, fillColor=colors.HexColor("#f7fbfd"), strokeColor=colors.HexColor("#9999ff"))
26
- drawing.add(bar)
27
-
28
- # Draw slider value
29
- if self.max_val == self.min_val:
30
- value_width = 50 # or some default width
31
- else:
32
- value_width = 50 + ((self.value - self.min_val) / (self.max_val - self.min_val) * 300)
33
- value_bar = Rect(50, 30, value_width - 50, 20, fillColor=colors.HexColor("#9999ff"), strokeColor=None)
34
- drawing.add(value_bar)
35
-
36
- # Add slider name
37
- drawing.add(String(0, 60, self.name, fontSize=12, fillColor=colors.HexColor("#26004d")))
38
-
39
- # Add range labels
40
- min_str = f"{self.min_val:.1f}%" if self.is_percentage else f"{self.min_val:.1f}"
41
- max_str = f"{self.max_val:.1f}%" if self.is_percentage else f"{self.max_val:.1f}"
42
- drawing.add(String(40, 10, min_str, fontSize=10, fillColor=colors.HexColor("#26004d")))
43
- drawing.add(String(340, 10, max_str, fontSize=10, fillColor=colors.HexColor("#26004d")))
44
-
45
- # Add value label
46
- value_str = f"{self.value:.1f}%" if self.is_percentage else f"{self.value:.1f}"
47
- drawing.add(String(value_width - 20, 55, value_str, fontSize=10, fillColor=colors.HexColor("#26004d")))
48
-
49
- # Add value marker
50
- drawing.add(Line(value_width, 25, value_width, 55, strokeColor=colors.HexColor("#26004d"), strokeWidth=2))
51
-
52
- drawing.drawOn(self.canv, 0, 0)
53
 
54
  def create_styles():
55
  styles = getSampleStyleSheet()
@@ -94,118 +48,40 @@ def create_page_template(canvas, doc):
94
  canvas.drawString(30, 20, f"Page {doc.page}")
95
  canvas.restoreState()
96
 
97
- def generate_pdf(session_state):
98
- buffer = io.BytesIO()
99
  doc = SimpleDocTemplate(buffer, pagesize=A4, rightMargin=20*mm, leftMargin=20*mm, topMargin=20*mm, bottomMargin=20*mm)
100
  styles = create_styles()
101
- story = [Paragraph("Pilot Drafting", styles['Title'])]
102
 
103
- for page in session_state.pages[:-1]: # Skip the last page
104
  if 'input_key' in page and page['input_key'] is not None:
105
  story.append(Paragraph(page['title'], styles['Heading1']))
106
-
107
- if page['input_key'] == 'workload_scope':
108
- story.extend(process_workload_scope(session_state, styles))
109
- elif page['input_key'] == 'useful_assets':
110
- story.extend(process_useful_assets(session_state, styles))
111
- elif page['input_key'] == 'pilot_evaluation':
112
- story.extend(process_pilot_evaluation(session_state, styles))
113
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  story.append(Spacer(1, 12))
115
 
116
  doc.build(story, onFirstPage=create_page_template, onLaterPages=create_page_template)
117
  buffer.seek(0)
118
- return buffer
119
-
120
- def process_workload_scope(session_state, styles):
121
- story = []
122
- answers = session_state.answers['workload_scope']
123
-
124
- story.append(Paragraph("Feature Prioritization", styles['Heading2']))
125
- for i, feature in enumerate(answers['feature_prioritization']):
126
- story.append(Paragraph(f"<b>Feature {i+1}</b>:", styles['Answer']))
127
- story.append(Paragraph(feature, styles['BodyText']))
128
-
129
- story.append(Paragraph("Preferred Start Period", styles['Heading2']))
130
- story.append(Paragraph(f"<b>{answers['preferred_start_period'][0]}</b> - <b>{answers['preferred_start_period'][1]}</b>", styles['Answer']))
131
-
132
- story.append(Paragraph("Team Composition", styles['Heading2']))
133
- for team_member in ['partner', 'ibm']:
134
- story.append(Paragraph(f"<b>{team_member.capitalize()}</b>:", styles['Answer']))
135
- story.append(Paragraph(answers['team_composition'][team_member], styles['BodyText']))
136
-
137
- return story
138
-
139
- def process_useful_assets(session_state, styles):
140
- story = []
141
- answers = session_state.answers['useful_assets']
142
-
143
- story.append(Paragraph("Solution Elements", styles['Heading2']))
144
- for element in answers['solution_elements']:
145
- story.append(Paragraph(element, styles['Answer']))
146
-
147
- story.append(Paragraph("IBM Software", styles['Heading2']))
148
- for software in answers['ibm_software']:
149
- story.append(Paragraph(software, styles['Answer']))
150
-
151
- story.append(Paragraph("Open Source Supports", styles['Heading2']))
152
- for support in answers['open_source_supports']:
153
- story.append(Paragraph(support, styles['Answer']))
154
-
155
- return story
156
-
157
- def process_pilot_evaluation(session_state, styles):
158
- story = []
159
- answers = session_state.answers['useful_assets']
160
-
161
- story.extend(process_validation_criteria(answers, styles))
162
-
163
- return story
164
-
165
- def process_validation_criteria(session_state, styles):
166
- story = []
167
-
168
- # Qualitative Criteria
169
- story.append(Paragraph("Qualitative Criteria:", styles['Heading2']))
170
- for i, criterion in enumerate(session_state.get('qualitative', [])):
171
- description = session_state.get(f'qual_desc_{i}', '')
172
- story.append(Paragraph(f"<b>{criterion}</b>:", styles['Answer']))
173
- story.append(Paragraph(description, styles['BodyText']))
174
-
175
- # Quantitative Criteria
176
- story.append(Paragraph("Quantitative Criteria:", styles['Heading2']))
177
- for i, criterion in enumerate(session_state.get('quantitative', [])):
178
- parsed = parse_quantitative_criteria(criterion)
179
- if parsed:
180
- name, min_val, max_val, is_percentage, is_integer = parsed
181
- value = session_state.get(f'quant_value_{i}', min_val)
182
-
183
- if is_percentage:
184
- slider = SliderFlowable(name, value*100, min_val*100, max_val*100, is_percentage=True)
185
- else:
186
- slider = SliderFlowable(name, value, min_val, max_val, is_percentage=False)
187
-
188
- story.append(slider)
189
- story.append(Paragraph(f"<b>{name}</b>: {value:.2f}", styles['Answer']))
190
-
191
- return story
192
-
193
- def parse_quantitative_criteria(input_string):
194
- match = re.match(r'(.+)\[([-+]?(?:\d*\.*\d+)(?:%)?)\s*-\s*([-+]?(?:\d*\.*\d+)(?:%)?)?\]', input_string)
195
- if match:
196
- name, min_val, max_val = match.groups()
197
- name = name.strip()
198
-
199
- # Handle percentage inputs
200
- is_percentage = '%' in min_val or '%' in max_val
201
- min_val = float(min_val.rstrip('%'))
202
- max_val = float(max_val.rstrip('%'))
203
-
204
- if is_percentage:
205
- min_val /= 100
206
- max_val /= 100
207
-
208
- is_integer = '.' not in input_string or (min_val.is_integer() and max_val.is_integer())
209
-
210
- return name, min_val, max_val, is_percentage, is_integer
211
- return None
 
1
+ from io import BytesIO
 
2
  from reportlab.lib import colors
3
  from reportlab.lib.pagesizes import A4
4
  from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
5
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
6
+ from reportlab.lib.units import mm
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
  def create_styles():
9
  styles = getSampleStyleSheet()
 
48
  canvas.drawString(30, 20, f"Page {doc.page}")
49
  canvas.restoreState()
50
 
51
+ def generate_pdf(pages, answers):
52
+ buffer = BytesIO()
53
  doc = SimpleDocTemplate(buffer, pagesize=A4, rightMargin=20*mm, leftMargin=20*mm, topMargin=20*mm, bottomMargin=20*mm)
54
  styles = create_styles()
55
+ story = [Paragraph("AI Trust and Opacity Evaluation", styles['Title'])]
56
 
57
+ for page in pages[:-1]: # Skip the last page
58
  if 'input_key' in page and page['input_key'] is not None:
59
  story.append(Paragraph(page['title'], styles['Heading1']))
60
+ story.append(Paragraph(page['content'], styles['BodyText']))
61
+
62
+ answer = answers.get(page['input_key'], "")
63
+ if isinstance(answer, list):
64
+ answer = ', '.join(answer)
65
+
66
+ if page.get('input_type') == 'combined':
67
+ option = answers.get(page['input_key'], "")
68
+ conclusion = answers.get(f"{page['input_key']}_conclusion", "")
69
+ answer = f"Option selected: {option}\n\nConclusion: {conclusion}"
70
+
71
+ # Create a table for the answer to allow multi-line text within a block
72
+ data = [[Paragraph(answer, styles['Answer'])]]
73
+ t = Table(data, colWidths=[450])
74
+ t.setStyle(TableStyle([
75
+ ('BACKGROUND', (0, 0), (-1, -1), colors.HexColor("#f0f2fd")),
76
+ ('TEXTCOLOR', (0, 0), (-1, -1), colors.HexColor("#26004d")),
77
+ ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
78
+ ('VALIGN', (0, 0), (-1, -1), 'TOP'),
79
+ ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.HexColor("#9999ff")),
80
+ ('BOX', (0, 0), (-1, -1), 0.25, colors.HexColor("#9999ff")),
81
+ ]))
82
+ story.append(t)
83
  story.append(Spacer(1, 12))
84
 
85
  doc.build(story, onFirstPage=create_page_template, onLaterPages=create_page_template)
86
  buffer.seek(0)
87
+ return buffer