from fpdf import FPDF import os from app.services.hf_storage_service import HuggingFaceStorageService import unicodedata import markdown2 storage_service = HuggingFaceStorageService() def normalize_text(text: str) -> str: replacements = { "’": "'", "‘": "'", "“": '"', "”": '"', "—": "-", "–": "-", "…": "...", "→": "->", "•": "-", } for old, new in replacements.items(): text = text.replace(old, new) # Convert accented letters to closest ASCII equivalent text = unicodedata.normalize('NFKD', text).encode('ascii', 'ignore').decode('ascii') return text def save_pdf(text: str, filename: str) -> str: text = normalize_text(text) if filename is None: filename = f"coverletter_{uuid.uuid4().hex}.pdf" # Generate PDF in memory pdf = FPDF() pdf.add_page() pdf.set_font("Arial", size=11) pdf.set_auto_page_break(auto=True, margin=15) sections = text.split('\n\n') for section in sections: if section.strip(): if any(word in section.lower() for word in ["best regards", "yours sincerely", "sincerely"]): pdf.ln(5) lines = section.strip().split('\n') for line in lines: pdf.cell(0, 6, line.strip(), ln=True, align='L') else: pdf.multi_cell(0, 6, section.strip(), align='L') pdf.ln(8) pdf_data = pdf.output(dest='S').encode('latin-1', errors='replace') # Upload PDF bytes to Hugging Face using your class method url = storage_service.upload_file_to_hf(file_content=pdf_data, folder="cover-letters", filename=filename) return url def build_cover_letter_md( your_name, postal_code, city, email, phone, job_title, company_name, generated_paragraphs ): template = f""" {your_name} {postal_code}, {city} {email} | {phone} Dear {company_name}, {generated_paragraphs} Warm Regards, {your_name} """ return template def convert_md_to_text(md_text: str) -> str: """Convert markdown to plain text for PDF saving.""" # markdown2 converts to HTML, then strip tags html = markdown2.markdown(md_text) plain_text = "".join(html.split("<")[0] if "<" in html else html for html in html.split(">")) return plain_text