sivfastapi / utils /pdf_generator.py
hello674's picture
Upload 54 files
e7f02ca verified
Raw History Blame Contribute Delete
5.27 kB
# utils/pdf_generator.py pdf generator module
from fpdf import FPDF
from datetime import datetime
import os
import json
import re
class PDFGenerator:
def __init__(self):
# No initialization needed for this class
pass
def clean_text(self, text: str) -> str:
replacements = {
"→": "->",
"–": "-",
"—": "-",
"…": "...",
}
for old, new in replacements.items():
text = text.replace(old, new)
return re.sub(r'[^\x00-\x7F]+', '', str(text))
# At the top of utils/pdf_generator.py
def safe_load(self, data):
"""Convert JSON string to dict if needed."""
if isinstance(data, str):
try:
return json.loads(data)
except json.JSONDecodeError:
return {}
return data
def generate_pdf(self,idea: str, structured: dict, scores: dict, suggestions: dict, feedback: dict,chats: list, user_id: str) -> str:
# Convert inputs
structured = self.safe_load(structured)
scores = self.safe_load(scores)
suggestions = self.safe_load(suggestions)
feedback = self.safe_load(feedback)
pdf = FPDF()
pdf.set_auto_page_break(auto=True, margin=15)
pdf.add_page()
pdf.set_font("Arial", 'B', 20)
pdf.cell(0, 100, "Startup Idea Evaluation Report", ln=True, align='C')
pdf.set_font("Arial", '', 14)
pdf.cell(0, 10, f"Idea Name: {idea}", ln=True, align='C')
pdf.ln(10)
pdf.set_font("Arial", 'I', 12)
pdf.cell(0, 10, f"Generated on {datetime.now().strftime('%Y-%m-%d')}", ln=True, align='C')
pdf.add_page() # then continue with details
# Structured Format
pdf.set_font("Arial", 'B', 12)
pdf.cell(0, 10, "Structured Format:", ln=True)
pdf.set_font("Arial", '', 11)
for key, value in structured.items():
pdf.multi_cell(0, 8, f"- {key.capitalize()}: {self.clean_text(value)}")
pdf.ln(5)
# Scores
pdf.set_font("Arial", 'B', 12)
pdf.cell(0, 10, "Scores:", ln=True)
pdf.set_font("Arial", '', 11)
for key, value in scores.items():
pdf.multi_cell(0, 8, f"- {key}: {value}")
pdf.ln(5)
# Suggestions
pdf.set_font("Arial", 'B', 12)
pdf.cell(0, 10, "Suggestions:", ln=True)
pdf.set_font("Arial", '', 11)
for i, suggestion in enumerate(suggestions.get("improvements", []), start=1):
pdf.multi_cell(0, 8, f"{i}. {self.clean_text(suggestion)}")
pdf.ln(2)
pdf.set_font("Arial", 'I', 10)
for i, rationale in enumerate(suggestions.get("rationale", []), start=1):
pdf.multi_cell(0, 7, f" Rationale {i}: {self.clean_text(rationale)}")
pdf.ln(5)
# Feedback
pdf.set_font("Arial", 'B', 12)
pdf.cell(0, 10, "Feedback:", ln=True)
pdf.set_font("Arial", '', 11)
for i, fb in enumerate(feedback.get("feedbacks", []), start=1):
pdf.multi_cell(0, 8, f"{i}. {self.clean_text(fb)}")
pdf.ln(2)
pdf.add_page()
pdf.set_font("Arial", 'B', 16)
pdf.cell(0, 10, "Expert Chats", ln=True, align='C')
pdf.ln(5)
if chats and len(chats) > 0:
for expert in chats:
pdf.set_font("Arial", 'B', 13)
pdf.cell(0, 8, f"Expert: {expert.get('name', '')} ({expert.get('expertise', '')})", ln=True)
pdf.set_font("Arial", 'I', 11)
pdf.multi_cell(0, 6, f"Bio: {self.clean_text(expert.get('bio', ''))}")
pdf.multi_cell(0, 6, f"Email: {expert.get('email', '')}")
pdf.ln(3)
chat = expert.get("chat", {})
chathistory = chat.get("chathistory", [])
if chathistory:
pdf.set_font("Arial", '', 11)
for msg in chathistory:
timestamp = datetime.fromisoformat(msg["timestamp"].replace("Z", "+00:00")).strftime("%Y-%m-%d %H:%M")
sender = msg.get("sender", "unknown").capitalize()
message = self.clean_text(msg.get("message", ""))
pdf.multi_cell(0, 8, f"[{timestamp}] {sender}: {message}")
pdf.ln(6)
else:
pdf.set_font("Arial", 'I', 11)
pdf.cell(0, 8, "No messages found.", ln=True)
pdf.ln(5)
else:
pdf.set_font("Arial", 'I', 12)
pdf.cell(0, 10, "No expert chats available.", ln=True, align='C')
# Footer
pdf.set_y(-30)
pdf.set_font("Arial", 'I', 8)
pdf.cell(0, 10, f"Generated by SIV | Version: {4.0} | Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", align='C')
# Save file
output_dir = "/mnt/data"
os.makedirs(output_dir, exist_ok=True)
output_path = os.path.join(output_dir, f"{user_id}_startup_report.pdf")
pdf.output(output_path)
return output_path