banao-tech commited on
Commit
00647b0
·
verified ·
1 Parent(s): c4daea8

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +74 -146
main.py CHANGED
@@ -313,174 +313,102 @@ Root Causes:\n{root_causes}""",
313
 
314
  # ── PDF Generator ─────────────────────────────────────────────────────────────
315
 
316
- def strip_markdown(text: str) -> str:
317
- """Remove markdown bold/italic markers for plain PDF text."""
318
  text = re.sub(r"\*\*(.*?)\*\*", r"\1", text)
319
  text = re.sub(r"\*(.*?)\*", r"\1", text)
320
  return text
321
 
322
 
323
  def build_pdf(analysis: FullAnalysis, name: str, role: str) -> bytes:
324
- """Generate a professional PDF report from the analysis."""
325
  buf = io.BytesIO()
 
 
 
 
 
326
 
327
- # ── Page setup
328
  doc = SimpleDocTemplate(
329
- buf,
330
- pagesize=A4,
331
- rightMargin=20 * mm,
332
- leftMargin=20 * mm,
333
- topMargin=22 * mm,
334
- bottomMargin=22 * mm,
335
  )
336
-
337
  styles = getSampleStyleSheet()
338
- W = A4[0] - 40 * mm # usable width
339
-
340
- # ── Custom styles
341
- s_title = ParagraphStyle(
342
- "title",
343
- parent=styles["Normal"],
344
- fontSize=22,
345
- fontName="Helvetica-Bold",
346
- textColor=colors.HexColor("#1a1a2e"),
347
- spaceAfter=4,
348
- )
349
- s_sub = ParagraphStyle(
350
- "sub",
351
- parent=styles["Normal"],
352
- fontSize=11,
353
- fontName="Helvetica",
354
- textColor=colors.HexColor("#6b7280"),
355
- spaceAfter=12,
356
- )
357
- s_section = ParagraphStyle(
358
- "section",
359
- parent=styles["Normal"],
360
- fontSize=13,
361
- fontName="Helvetica-Bold",
362
- textColor=colors.HexColor("#2563eb"),
363
- spaceBefore=16,
364
- spaceAfter=6,
365
- )
366
- s_h3 = ParagraphStyle(
367
- "h3",
368
- parent=styles["Normal"],
369
- fontSize=11,
370
- fontName="Helvetica-Bold",
371
- textColor=colors.HexColor("#374151"),
372
- spaceBefore=8,
373
- spaceAfter=3,
374
- )
375
- s_body = ParagraphStyle(
376
- "body",
377
- parent=styles["Normal"],
378
- fontSize=10,
379
- fontName="Helvetica",
380
- textColor=colors.HexColor("#374151"),
381
- leading=15,
382
- spaceAfter=4,
383
- )
384
- s_label = ParagraphStyle(
385
- "label",
386
- parent=styles["Normal"],
387
- fontSize=8,
388
- fontName="Helvetica-Bold",
389
- textColor=colors.white,
390
- )
391
 
392
- def agent_badge(label: str, color: str) -> Table:
393
- """Small colored badge showing which agent produced this section."""
394
- data = [[Paragraph(f"◉ {label}", s_label)]]
395
- t = Table(data, colWidths=[W])
396
- t.setStyle(
397
- TableStyle(
398
- [
399
- ("BACKGROUND", (0, 0), (-1, -1), colors.HexColor(color)),
400
- ("TOPPADDING", (0, 0), (-1, -1), 5),
401
- ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
402
- ("LEFTPADDING", (0, 0), (-1, -1), 10),
403
- ("ROUNDEDCORNERS", [4, 4, 4, 4]),
404
- ]
405
- )
406
- )
407
- return t
408
-
409
- def render_markdown_block(md_text: str) -> list:
410
- """Convert basic markdown to ReportLab flowables."""
411
- flowables = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
412
  for line in md_text.splitlines():
413
  line = line.strip()
414
  if not line:
415
- flowables.append(Spacer(1, 4))
416
- continue
417
- if line.startswith("## "):
418
- flowables.append(Paragraph(line[3:], s_section))
419
  elif line.startswith("### "):
420
- flowables.append(Paragraph(line[4:], s_h3))
421
  elif line.startswith("- ") or line.startswith("* "):
422
- clean = strip_markdown(line[2:])
423
- flowables.append(Paragraph(f"• {clean}", s_body))
424
  elif re.match(r"^\d+\.", line):
425
- clean = strip_markdown(line)
426
- flowables.append(Paragraph(clean, s_body))
427
- elif line.startswith("**") and line.endswith("**"):
428
- flowables.append(Paragraph(line[2:-2], s_h3))
429
  else:
430
- clean = strip_markdown(line)
431
- flowables.append(Paragraph(clean, s_body))
432
- return flowables
433
 
434
  story = []
435
 
436
- # ── Header
437
- story.append(Paragraph("Problem Analysis Report", s_title))
438
- story.append(
439
- Paragraph(
440
- f"{name} · {role} · {datetime.now().strftime('%d %B %Y')}",
441
- s_sub,
442
- )
443
- )
444
- story.append(HRFlowable(width=W, thickness=1.5, color=colors.HexColor("#2563eb"), spaceAfter=10))
445
-
446
- # ── Section 1: Problem Statement
447
- story.append(agent_badge("AGENT 1 — Problem Analyst", "#1e3a5f"))
448
- story.append(Spacer(1, 6))
449
- story += render_markdown_block(analysis.problem_statement)
450
-
451
- # ── Section 2: Root Cause
452
- story.append(Spacer(1, 8))
453
- story.append(agent_badge("AGENT 2 — Root Cause Analyst", "#1a4731"))
454
- story.append(Spacer(1, 6))
455
- story += render_markdown_block(analysis.root_causes)
456
-
457
- # ── Section 3: Solutions
458
- story.append(Spacer(1, 8))
459
- story.append(agent_badge("AGENT 3 — Solution Brainstorm", "#4a1942"))
460
- story.append(Spacer(1, 6))
461
- story += render_markdown_block(analysis.solutions)
462
-
463
- # ── Section 4: Action Plan
464
- story.append(Spacer(1, 8))
465
- story.append(agent_badge("AGENT 4 — Action Planner", "#7c2d12"))
466
- story.append(Spacer(1, 6))
467
- story += render_markdown_block(analysis.action_plan)
468
-
469
- # ── Section 5: Thinking Coach
470
- story.append(Spacer(1, 8))
471
- story.append(agent_badge("AGENT 5 — Thinking Coach", "#312e81"))
472
- story.append(Spacer(1, 6))
473
- story += render_markdown_block(analysis.thinking_feedback)
474
-
475
- # ── Footer note
476
- story.append(Spacer(1, 16))
477
- story.append(HRFlowable(width=W, thickness=0.5, color=colors.HexColor("#e5e7eb"), spaceAfter=6))
478
- story.append(
479
- Paragraph(
480
- "Generated by the AI Intern Problem-Solving System · Confidential",
481
- ParagraphStyle("footer", parent=styles["Normal"], fontSize=8, textColor=colors.HexColor("#9ca3af"), alignment=1),
482
- )
483
- )
484
 
485
  doc.build(story)
486
  buf.seek(0)
 
313
 
314
  # ── PDF Generator ─────────────────────────────────────────────────────────────
315
 
316
+ def strip_md(text: str) -> str:
 
317
  text = re.sub(r"\*\*(.*?)\*\*", r"\1", text)
318
  text = re.sub(r"\*(.*?)\*", r"\1", text)
319
  return text
320
 
321
 
322
  def build_pdf(analysis: FullAnalysis, name: str, role: str) -> bytes:
323
+ """Clean black-and-white PDF report."""
324
  buf = io.BytesIO()
325
+ INK = colors.HexColor("#111827")
326
+ INK2 = colors.HexColor("#374151")
327
+ GRAY = colors.HexColor("#6b7280")
328
+ LGRAY = colors.HexColor("#d1d5db")
329
+ W = A4[0] - 48 * mm
330
 
 
331
  doc = SimpleDocTemplate(
332
+ buf, pagesize=A4,
333
+ rightMargin=24 * mm, leftMargin=24 * mm,
334
+ topMargin=24 * mm, bottomMargin=24 * mm,
 
 
 
335
  )
 
336
  styles = getSampleStyleSheet()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
 
338
+ s_title = ParagraphStyle("t", parent=styles["Normal"],
339
+ fontSize=20, fontName="Helvetica-Bold", textColor=INK, spaceAfter=3)
340
+ s_meta = ParagraphStyle("m", parent=styles["Normal"],
341
+ fontSize=10, fontName="Helvetica", textColor=GRAY, spaceAfter=14)
342
+ s_section_head = ParagraphStyle("sh", parent=styles["Normal"],
343
+ fontSize=11, fontName="Helvetica-Bold", textColor=INK,
344
+ spaceBefore=20, spaceAfter=2)
345
+ s_section_num = ParagraphStyle("sn", parent=styles["Normal"],
346
+ fontSize=10, fontName="Helvetica", textColor=GRAY, spaceAfter=8)
347
+ s_h2 = ParagraphStyle("h2", parent=styles["Normal"],
348
+ fontSize=10, fontName="Helvetica-Bold", textColor=INK,
349
+ spaceBefore=10, spaceAfter=3)
350
+ s_h3 = ParagraphStyle("h3", parent=styles["Normal"],
351
+ fontSize=10, fontName="Helvetica-Bold", textColor=INK2,
352
+ spaceBefore=7, spaceAfter=2)
353
+ s_body = ParagraphStyle("b", parent=styles["Normal"],
354
+ fontSize=10, fontName="Helvetica", textColor=INK2,
355
+ leading=15, spaceAfter=3)
356
+ s_bullet = ParagraphStyle("bl", parent=styles["Normal"],
357
+ fontSize=10, fontName="Helvetica", textColor=INK2,
358
+ leading=15, spaceAfter=2, leftIndent=12, firstLineIndent=-12)
359
+ s_footer = ParagraphStyle("f", parent=styles["Normal"],
360
+ fontSize=8, fontName="Helvetica", textColor=GRAY, alignment=1)
361
+
362
+ SECTIONS = [
363
+ ("Problem Analyst", analysis.problem_statement),
364
+ ("Root Cause Analyst", analysis.root_causes),
365
+ ("Solutions", analysis.solutions),
366
+ ("Action Plan", analysis.action_plan),
367
+ ("Thinking Coach", analysis.thinking_feedback),
368
+ ]
369
+
370
+ def render_block(md_text: str) -> list:
371
+ out = []
372
  for line in md_text.splitlines():
373
  line = line.strip()
374
  if not line:
375
+ out.append(Spacer(1, 3))
376
+ elif line.startswith("## "):
377
+ out.append(Paragraph(strip_md(line[3:]), s_h2))
 
378
  elif line.startswith("### "):
379
+ out.append(Paragraph(strip_md(line[4:]), s_h3))
380
  elif line.startswith("- ") or line.startswith("* "):
381
+ out.append(Paragraph(f"– {strip_md(line[2:])}", s_bullet))
 
382
  elif re.match(r"^\d+\.", line):
383
+ out.append(Paragraph(strip_md(line), s_body))
 
 
 
384
  else:
385
+ out.append(Paragraph(strip_md(line), s_body))
386
+ return out
 
387
 
388
  story = []
389
 
390
+ # Header
391
+ story.append(Paragraph("Problem Analysis", s_title))
392
+ story.append(Paragraph(
393
+ f"{name} · {datetime.now().strftime('%d %B %Y')}",
394
+ s_meta,
395
+ ))
396
+ story.append(HRFlowable(width=W, thickness=0.5, color=LGRAY, spaceAfter=4))
397
+
398
+ # Sections
399
+ for i, (title, text) in enumerate(SECTIONS, 1):
400
+ story.append(Spacer(1, 4))
401
+ story.append(Paragraph(title, s_section_head))
402
+ story.append(HRFlowable(width=W, thickness=0.5, color=LGRAY, spaceAfter=6))
403
+ story += render_block(text)
404
+
405
+ # Footer
406
+ story.append(Spacer(1, 20))
407
+ story.append(HRFlowable(width=W, thickness=0.5, color=LGRAY, spaceAfter=6))
408
+ story.append(Paragraph(
409
+ f"Problem Solver · {datetime.now().strftime('%d %B %Y')}",
410
+ s_footer,
411
+ ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
412
 
413
  doc.build(story)
414
  buf.seek(0)