Juan Esteban Agudelo Ortiz
Early errors failing to launch the app solved.
5eb924e
Raw
History Blame Contribute Delete
4.24 kB
import base64
import io
from pathlib import Path
from PIL import Image
from src.generation import ConsolidatedSummary, FlashCard
def image_to_base64(img: Image.Image) -> str:
buffer = io.BytesIO()
img.save(buffer, format="PNG")
encoded = base64.b64encode(buffer.getvalue()).decode("utf-8")
return f"data:image/png;base64,{encoded}"
def flashcard_to_html(card: FlashCard, reference_image: Image.Image = None) -> str:
key_points_html = "".join(f"<li>{p}</li>" for p in card.key_points)
examples_html = "".join(f"<li>{e}</li>" for e in card.examples)
if reference_image is not None:
img_src = image_to_base64(reference_image)
img_html = f'<img src="{img_src}" style="max-width:100%; border-radius:8px;">'
else:
img_html = f'<p style="color:#888; font-style:italic;">{card.suggested_image}</p>'
return f"""
<html>
<head>
<style>
body {{
font-family: Arial, sans-serif;
margin: 20px;
background: #ffffff;
}}
.card {{
display: flex;
border: 2px solid #2ecc71;
border-radius: 12px;
padding: 20px;
gap: 20px;
}}
.image-col {{
width: 35%;
display: flex;
align-items: center;
justify-content: center;
}}
.content-col {{
width: 65%;
}}
h1 {{
color: #2ecc71;
font-size: 22px;
margin-bottom: 8px;
}}
h3 {{
color: #555;
font-size: 14px;
margin: 12px 0 4px 0;
}}
ul {{
margin: 4px 0;
padding-left: 20px;
}}
li {{
font-size: 13px;
margin-bottom: 3px;
}}
p {{
font-size: 13px;
line-height: 1.5;
}}
</style>
</head>
<body>
<div class="card">
<div class="image-col">{img_html}</div>
<div class="content-col">
<h1>{card.concept}</h1>
<p>{card.definition}</p>
<h3>Key Points</h3>
<ul>{key_points_html}</ul>
<h3>Examples</h3>
<ul>{examples_html}</ul>
</div>
</div>
</body>
</html>
"""
def summary_to_html(summary: ConsolidatedSummary) -> str:
concepts_html = "".join(
f"<li><strong>{c['name']}:</strong> {c['description']}</li>"
for c in summary.concepts
)
return f"""
<html>
<head>
<style>
body {{
font-family: Arial, sans-serif;
margin: 20px;
background: #ffffff;
}}
.summary {{
border: 2px solid #3498db;
border-radius: 12px;
padding: 20px;
}}
h1 {{
color: #3498db;
font-size: 22px;
margin-bottom: 8px;
}}
h3 {{
color: #555;
font-size: 14px;
margin: 12px 0 4px 0;
}}
ul {{
margin: 4px 0;
padding-left: 20px;
}}
li {{
font-size: 13px;
margin-bottom: 6px;
}}
p {{
font-size: 13px;
line-height: 1.5;
}}
</style>
</head>
<body>
<div class="summary">
<h1>{summary.topic}</h1>
<p>{summary.overview}</p>
<h3>Concepts</h3>
<ul>{concepts_html}</ul>
</div>
</body>
</html>
"""
def export_to_pdf(
content: "FlashCard | ConsolidatedSummary",
output_path: Path,
reference_image: Image.Image = None,
) -> Path:
if isinstance(content, FlashCard):
html = flashcard_to_html(content, reference_image)
else:
html = summary_to_html(content)
try:
from weasyprint import HTML
except Exception as e:
raise RuntimeError(
"No se puede exportar PDF: faltan las librerias GTK en este sistema. "
"Ejecuta install.bat como administrador para instalarlas."
) from e
HTML(string=html).write_pdf(str(output_path))
return output_path