import subprocess import tempfile from io import BytesIO from pathlib import Path from pypdf import PdfWriter, PdfReader from django.utils.text import slugify from aemo.pdf import BasePDF, BilanPdf, EvaluationPdf, MessagePdf, RapportPdf, JournalPdf class ArchiveBase(BasePDF): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.merger = PdfWriter() def get_filename(self): return f"{slugify(self.instance.nom)}-{self.instance.pk}.pdf" def append_pdf(self, PDFClass, obj): temp = BytesIO() pdf = PDFClass(temp, obj) pdf.produce() self.merger.append(temp) def append_other_docs(self, documents): msg = [] for doc in documents: doc_path = Path(doc.fichier.path) if not doc_path.exists(): msg.append(f"Le fichier «{doc.titre}» n'existe pas!") continue if doc_path.suffix.lower() == '.pdf': self.merger.append(PdfReader(str(doc_path))) elif doc_path.suffix.lower() in ['.doc', '.docx']: with tempfile.TemporaryDirectory() as tmpdir: cmd = ['libreoffice', '--headless', '--convert-to', 'pdf', '--outdir', tmpdir, doc_path] subprocess.run(cmd, capture_output=True) converted_path = Path(tmpdir) / f'{doc_path.stem}.pdf' if converted_path.exists(): self.merger.append(PdfReader(str(converted_path))) else: msg.append(f"La conversion du fichier «{doc.titre}» a échoué") elif doc_path.suffix.lower() == '.msg': self.append_pdf(MessagePdf, doc) else: msg.append(f"Le format du fichier «{doc.titre}» ne peut pas être intégré.") return msg class ArchivePdf(ArchiveBase): title = "Archive" def produce(self): famille = self.instance self.append_pdf(EvaluationPdf, famille) self.append_pdf(JournalPdf, famille) for bilan in famille.bilans.all(): self.append_pdf(BilanPdf, bilan) for rapport in famille.rapports.all(): self.append_pdf(RapportPdf, rapport) msg = self.append_other_docs(famille.documents.all()) self.merger.write(self.doc.filename) return msg