File size: 2,769 Bytes
b2b6341
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from fastapi import APIRouter, HTTPException
from fastapi.responses import FileResponse
from pydantic import BaseModel
from fpdf import FPDF
import os
import tempfile
import uuid

router = APIRouter()

class ExportRequest(BaseModel):
    title: str
    content: str
    citations: list[dict] = []

class PDFGenerator(FPDF):
    def header(self):
        self.set_font('helvetica', 'B', 12)
        self.cell(0, 10, 'InteleX Research Memorandum', 0, 1, 'C')
        self.ln(5)

    def footer(self):
        self.set_y(-15)
        self.set_font('helvetica', 'I', 8)
        self.cell(0, 10, f'Page {self.page_no()}', 0, 0, 'C')

import re

def _clean_text(text: str) -> str:
    """Strip emojis and non-latin characters that crash FPDF."""
    if not text:
        return " "
    # Remove markdown headers
    text = text.replace('#', '').replace('*', '')
    # Keep only common latin characters and punctuation for standard fonts
    cleaned = re.sub(r'[^\x00-\x7F]+', '', text)
    return cleaned if cleaned.strip() else "[Non-supported characters]"

@router.post("/pdf")
async def export_pdf(req: ExportRequest):
    try:
        pdf = PDFGenerator()
        pdf.add_page()
        
        # Ensure we are at the left margin to avoid "horizontal space" errors
        pdf.set_x(pdf.l_margin)
        
        # Title
        pdf.set_font("helvetica", 'B', 16)
        title = _clean_text(req.title)
        pdf.multi_cell(0, 10, title)
        pdf.ln(10)
        
        # Content
        pdf.set_font("helvetica", '', 11)
        content = _clean_text(req.content)
        pdf.set_x(pdf.l_margin) # Reset X before body
        pdf.multi_cell(0, 7, content)
        
        # Citations
        if req.citations:
            pdf.ln(10)
            pdf.set_font("helvetica", 'B', 12)
            pdf.set_x(pdf.l_margin)
            pdf.cell(0, 10, 'Sources & Citations', 0, 1)
            pdf.set_font("helvetica", '', 9)
            for i, cite in enumerate(req.citations):
                source_title = cite.get('source_title') or cite.get('sourceTitle') or "Source"
                ref = cite.get('reference') or ""
                text = f"[{i+1}] {source_title} - {ref}"
                pdf.set_x(pdf.l_margin)
                pdf.multi_cell(0, 5, _clean_text(text))
        
        # Save to temp file
        tmp_dir = tempfile.gettempdir()
        filename = f"research_{uuid.uuid4().hex[:8]}.pdf"
        filepath = os.path.join(tmp_dir, filename)
        pdf.output(filepath)
        
        return FileResponse(
            path=filepath, 
            filename=filename,
            media_type='application/pdf'
        )
    except Exception as e:
        print(f"[Export] PDF Error: {e}")
        raise HTTPException(status_code=500, detail=str(e))