File size: 4,694 Bytes
fd808de
 
 
 
4c680cd
fd808de
 
 
4c680cd
 
 
fd808de
 
 
 
4c680cd
fd808de
4c680cd
 
fd808de
4c680cd
 
 
 
 
 
fd808de
 
 
 
4c680cd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fd808de
 
4c680cd
fd808de
 
 
 
 
 
 
 
4c680cd
fd808de
4c680cd
 
 
fd808de
4c680cd
 
 
 
 
fd808de
4c680cd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fd808de
 
 
4c680cd
 
 
 
 
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
import io
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle
from reportlab.lib.units import mm
from reportlab.graphics.shapes import Drawing, Rect, String, Line

class SliderFlowable(Drawing):
    def __init__(self, name, value, min_val=1, max_val=10, width=400, height=50):
        Drawing.__init__(self, width, height)
        self.name = name
        self.value = value
        self.min_val = min_val
        self.max_val = max_val
        
        # Draw slider bar
        self.add(Rect(50, 15, 300, 20, fillColor=colors.lightgrey, strokeColor=colors.grey))
        
        # Draw slider value
        value_width = 50 + ((self.value - self.min_val) / (self.max_val - self.min_val) * 300)
        self.add(Rect(50, 15, value_width - 50, 20, fillColor=colors.blue, strokeColor=None))
        
        # Add slider name and value
        self.add(String(0, 40, self.name, fontSize=10))
        self.add(String(value_width - 10, 40, str(self.value), fontSize=10))

def create_styles():
    styles = getSampleStyleSheet()
    styles.add(ParagraphStyle(
        name='SectionTitle',
        parent=styles['Heading1'],
        fontSize=16,
        textColor=colors.HexColor("#3b0b75"),
        spaceAfter=10
    ))
    styles.add(ParagraphStyle(
        name='SubsectionTitle',
        parent=styles['Heading2'],
        fontSize=14,
        textColor=colors.HexColor("#52176a"),
        spaceAfter=8
    ))
    styles.add(ParagraphStyle(
        name='BodyText',
        parent=styles['Normal'],
        fontSize=10,
        textColor=colors.HexColor("#26004d"),
        spaceAfter=6
    ))
    styles.add(ParagraphStyle(
        name='AnswerText',
        parent=styles['BodyText'],
        backColor=colors.HexColor("#f0f2fd"),
        borderPadding=(4, 4, 4, 4),
        spaceAfter=10
    ))
    return styles

def generate_pdf(pages, answers):
    buffer = io.BytesIO()
    doc = SimpleDocTemplate(buffer, pagesize=A4, rightMargin=20*mm, leftMargin=20*mm, topMargin=20*mm, bottomMargin=20*mm)
    styles = create_styles()
    story = [Paragraph("Critical Infrastructure - LLM Considerations Report", styles['Title'])]

    for page in pages[:-1]:  # Skip the last page (report generation page)
        if page['type'] == 'description':
            story.append(Paragraph(page['title'], styles['SectionTitle']))
            story.append(Paragraph(page['content'], styles['BodyText']))
        
        elif page['type'] == 'quiz':
            story.append(Paragraph(page['title'], styles['SubsectionTitle']))
            story.append(Paragraph(page['description'], styles['BodyText']))
            
            answer = answers.get(page['input_key'], "")
            story.append(Paragraph(f"<b>Analysis:</b>", styles['BodyText']))
            story.append(Paragraph(answer, styles['AnswerText']))
            
            risk_level = answers.get(page['slider_key'], 1)
            story.append(SliderFlowable(f"Risk Level: {risk_level}", risk_level))
        
        elif page['type'] == 'inference':
            story.append(Paragraph(page['title'], styles['SubsectionTitle']))
            story.append(Paragraph(page['prompt_description'], styles['BodyText']))
            
            user_input = answers.get(page['input_key'], "")
            inference_output = answers.get(page['output_key'], "")
            
            story.append(Paragraph("<b>User Input:</b>", styles['BodyText']))
            story.append(Paragraph(user_input, styles['AnswerText']))
            story.append(Paragraph("<b>Inference Output:</b>", styles['BodyText']))
            story.append(Paragraph(inference_output, styles['AnswerText']))
        
        elif page['type'] == 'architecture':
            story.append(Paragraph(page['title'], styles['SubsectionTitle']))
            
            # We can't include the actual architecture diagram in the PDF,
            # so we'll just mention that it was reviewed
            story.append(Paragraph("Architecture diagram was reviewed.", styles['BodyText']))
            
            analysis = answers.get(page['input_key'], "")
            story.append(Paragraph("<b>Security Analysis:</b>", styles['BodyText']))
            story.append(Paragraph(analysis, styles['AnswerText']))
        
        story.append(Spacer(1, 12))

    doc.build(story)
    buffer.seek(0)
    return buffer

def create_page_template(canvas, doc):
    canvas.saveState()
    canvas.setFont('Helvetica', 9)
    canvas.drawString(20*mm, 10*mm, f"Page {doc.page}")
    canvas.restoreState()