diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c7bd26b7e8e94374e84f1d9c3252832610f6c2c5..e1c561ca6408c49b5d3fa3b084ce4b0e9818ec5f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -23,6 +23,8 @@ Changed * Rewrite of frontend using Vuetify * [Dev] Provide function to generate PDF files from fully-rendered templates. * OIDC scope "profile" now exposes the avatar instead of the official photo +* [Dev] Accept pre-created file object for PDF generation to define + the redirect URL in advance. Fixed ~~~~~ diff --git a/aleksis/core/migrations/0042_pdffile_empty.py b/aleksis/core/migrations/0042_pdffile_empty.py new file mode 100644 index 0000000000000000000000000000000000000000..e8055132e11f2deba85ef4ecfa24840c51ce2081 --- /dev/null +++ b/aleksis/core/migrations/0042_pdffile_empty.py @@ -0,0 +1,21 @@ +# Generated by Django 3.2.16 on 2022-11-03 11:36 + +from django.db import migrations, models +import django.utils.timezone +import oauth2_provider.generators +import oauth2_provider.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0041_update_gender_choices'), + ] + + operations = [ + migrations.AlterField( + model_name='pdffile', + name='html_file', + field=models.FileField(blank=True, null=True, upload_to='pdfs/', verbose_name='Generated HTML file'), + ), + ] diff --git a/aleksis/core/models.py b/aleksis/core/models.py index 2f603ae0d2e2813b50f2024056cb460d71b4e484..0bf42033887664c79f71b0223deea994d69c21c5 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -1236,7 +1236,9 @@ class PDFFile(ExtensibleModel): expires_at = models.DateTimeField( verbose_name=_("File expires at"), default=_get_default_expiration ) - html_file = models.FileField(upload_to="pdfs/", verbose_name=_("Generated HTML file")) + html_file = models.FileField( + upload_to="pdfs/", verbose_name=_("Generated HTML file"), blank=True, null=True + ) file = models.FileField( upload_to="pdfs/", blank=True, null=True, verbose_name=_("Generated PDF file") ) diff --git a/aleksis/core/util/pdf.py b/aleksis/core/util/pdf.py index 8721d8c3167ba8a01fd250a0967f56af495bdf78..c840c620fd102dc01b3300f2205e19e399b00ed2 100644 --- a/aleksis/core/util/pdf.py +++ b/aleksis/core/util/pdf.py @@ -88,10 +88,16 @@ def process_context_for_pdf(context: Optional[dict] = None, request: Optional[Ht def generate_pdf_from_html( - html: str, request: Optional[HttpRequest] = None + html: str, request: Optional[HttpRequest] = None, file_object: Optional[PDFFile] = None ) -> Tuple[PDFFile, AsyncResult]: """Start a PDF generation task and return the matching file object and Celery result.""" - file_object = PDFFile.objects.create(html_file=ContentFile(html.encode(), name="source.html")) + html_file = ContentFile(html.encode(), name="source.html") + + # In some cases, the file object is already created (to get a redirect URL for the PDF) + if not file_object: + file_object = PDFFile.objects.create() + file_object.html_file = html_file + file_object.save() # As this method may be run in background and there is no request available, # we have to use a predefined URL from settings then @@ -110,6 +116,7 @@ def generate_pdf_from_template( context: Optional[dict] = None, request: Optional[HttpRequest] = None, render_method: Optional[Callable] = None, + file_object: Optional[PDFFile] = None, ) -> Tuple[PDFFile, AsyncResult]: """Start a PDF generation task and return the matching file object and Celery result.""" processed_context = process_context_for_pdf(context, request) @@ -119,7 +126,7 @@ def generate_pdf_from_template( else: html_template = render_to_string(template_name, processed_context, request) - return generate_pdf_from_html(html_template, request) + return generate_pdf_from_html(html_template, request, file_object=file_object) def render_pdf(