♻️(backend) automatic delete temporary files

To leverage the automatic deletion of temporary
files, we do the conversion inside the with context.
Even if the conversion fails, the temporary file
will be deleted.
This commit is contained in:
Anthony LC
2024-08-21 14:50:00 +02:00
committed by Anthony LC
parent 67625dff7a
commit f0e2a2b710
2 changed files with 44 additions and 15 deletions

View File

@@ -3,7 +3,6 @@ Declare and configure the models for the impress core application
"""
import hashlib
import os
import tempfile
import textwrap
import uuid
@@ -609,26 +608,25 @@ class Template(BaseModel):
"""
reference_docx = "core/static/reference.docx"
output = BytesIO()
# Convert the HTML to a temporary docx file
with tempfile.NamedTemporaryFile(delete=False, suffix=".docx") as tmp_file:
with tempfile.NamedTemporaryFile(suffix=".docx", prefix="docx_") as tmp_file:
output_path = tmp_file.name
pypandoc.convert_text(
html_string,
"docx",
format="html",
outputfile=output_path,
extra_args=["--reference-doc", reference_docx],
)
pypandoc.convert_text(
html_string,
"docx",
format="html",
outputfile=output_path,
extra_args=["--reference-doc", reference_docx],
)
# Create a BytesIO object to store the output of the temporary docx file
with open(output_path, "rb") as f:
output = BytesIO(f.read())
# Remove the temporary docx file
os.remove(output_path)
# Create a BytesIO object to store the output of the temporary docx file
with open(output_path, "rb") as f:
output = BytesIO(f.read())
# Ensure the pointer is at the beginning
output.seek(0)
response = FileResponse(
@@ -636,6 +634,7 @@ class Template(BaseModel):
content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
)
response["Content-Disposition"] = f"attachment; filename={self.title}.docx"
return response
def generate_document(self, body, body_type, export_format):

View File

@@ -2,6 +2,9 @@
Unit tests for the Template model
"""
import os
from unittest import mock
from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ValidationError
@@ -185,3 +188,30 @@ def test_models_templates_get_abilities_preset_role(django_assert_num_queries):
"partial_update": False,
"generate_document": True,
}
def test_models_templates__generate_word():
"""Generate word document and assert no tmp files are left in /tmp folder."""
template = factories.TemplateFactory()
response = template.generate_word("<p>Test body</p>", {})
assert response.status_code == 200
assert len([f for f in os.listdir("/tmp") if f.startswith("docx_")]) == 0
@mock.patch(
"pypandoc.convert_text",
side_effect=RuntimeError("Conversion failed"),
)
def test_models_templates__generate_word__raise_error(_mock_send_mail):
"""
Generate word document and assert no tmp files are left in /tmp folder
even when the conversion fails.
"""
template = factories.TemplateFactory()
try:
template.generate_word("<p>Test body</p>", {})
except RuntimeError as e:
assert str(e) == "Conversion failed"
assert len([f for f in os.listdir("/tmp") if f.startswith("docx_")]) == 0