74 lines
2.8 KiB
Python
74 lines
2.8 KiB
Python
import json
|
||
from pathlib import Path
|
||
from fpdf import FPDF
|
||
import unicodedata
|
||
|
||
def clean_text(text):
|
||
if not text:
|
||
return "N/A"
|
||
# Replace unicode quotes and dashes with ascii equivalents to avoid FPDF errors with Latin-1
|
||
text = str(text)
|
||
text = text.replace('"', '"').replace('"', '"').replace('"', "'").replace('"', "'")
|
||
text = text.replace('—', '-').replace('–', '-')
|
||
# Normalize to nearest ascii character
|
||
res = unicodedata.normalize('NFKD', text).encode('ascii', 'ignore').decode('ascii')
|
||
res = res.strip()
|
||
if not res:
|
||
return "N/A"
|
||
# Break up extremely long words that crash FPDF
|
||
res = " ".join([word[:50] for word in res.split()])
|
||
return res
|
||
|
||
def generate_political_pdf(selected_articles, job_dir):
|
||
job_dir = Path(job_dir)
|
||
images_dir = job_dir / "all_political_images"
|
||
|
||
if not images_dir.exists() or not selected_articles:
|
||
return
|
||
|
||
pdf = FPDF()
|
||
pdf.set_auto_page_break(auto=True, margin=15)
|
||
|
||
# Sort articles: high priority first
|
||
high = [a for a in selected_articles if a.get("priority") == "high"]
|
||
medium = [a for a in selected_articles if a.get("priority") == "medium"]
|
||
sorted_articles = high + medium
|
||
|
||
for i, art in enumerate(sorted_articles, 1):
|
||
pdf.add_page()
|
||
|
||
# Add Header
|
||
pdf.set_font("helvetica", "B", 16)
|
||
priority = str(art.get("priority", "N/A")).upper()
|
||
pdf.cell(0, 10, f"Article {i} - {priority} PRIORITY", new_x="LMARGIN", new_y="NEXT", align="C")
|
||
pdf.ln(5)
|
||
|
||
# Details
|
||
pdf.set_font("helvetica", "B", 12)
|
||
pdf.multi_cell(0, 8, f"Headline: {clean_text(art.get('headline_english'))}", new_x="LMARGIN", new_y="NEXT")
|
||
pdf.multi_cell(0, 8, f"Category: {clean_text(art.get('category')).upper()}", new_x="LMARGIN", new_y="NEXT")
|
||
|
||
pdf.set_font("helvetica", "", 12)
|
||
pdf.multi_cell(0, 8, f"Why: {clean_text(art.get('political_significance'))}", new_x="LMARGIN", new_y="NEXT")
|
||
pdf.multi_cell(0, 8, f"Attack Angle: {clean_text(art.get('attack_angle'))}", new_x="LMARGIN", new_y="NEXT")
|
||
pdf.ln(5)
|
||
|
||
# Image
|
||
art_id = art.get("id")
|
||
img_name = f"{art_id}.png" if art_id else None
|
||
if img_name:
|
||
img_path = images_dir / img_name
|
||
if img_path.exists():
|
||
# Get image dimensions to scale it properly if needed
|
||
try:
|
||
pdf.image(str(img_path), w=180)
|
||
except Exception as e:
|
||
print(f"Error adding image to PDF: {e}")
|
||
|
||
output_path = job_dir / "political_articles_insights.pdf"
|
||
try:
|
||
pdf.output(str(output_path))
|
||
print(f"Successfully generated PDF report at {output_path}")
|
||
except Exception as e:
|
||
print(f"Failed to generate PDF: {e}")
|