From 545e8b2a3c98d7e3c73ba08630ea9aa35adf9519 Mon Sep 17 00:00:00 2001
From: Anthony LC
Date: Mon, 6 Jan 2025 16:20:57 +0100
Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A5(backend)=20remove=20code=20related?=
=?UTF-8?q?=20to=20export=20pdf=20docx?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The export is managed by the frontend, so we
don't need the code related to the export
in the backend side anymore.
---
Dockerfile | 1 -
src/backend/core/api/viewsets.py | 34 ---
src/backend/core/models.py | 113 +---------
src/backend/core/static/reference.docx | Bin 7227 -> 0 bytes
.../test_api_templates_generate_document.py | 208 ------------------
.../core/tests/test_models_templates.py | 32 ---
src/backend/demo/data/template/code.txt | 12 +-
src/backend/demo/data/template/css.txt | 20 --
src/backend/pyproject.toml | 3 -
9 files changed, 3 insertions(+), 420 deletions(-)
delete mode 100644 src/backend/core/static/reference.docx
delete mode 100644 src/backend/core/tests/templates/test_api_templates_generate_document.py
diff --git a/Dockerfile b/Dockerfile
index 6547f0b6..60f464ee 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -72,7 +72,6 @@ RUN apk add \
gettext \
gdk-pixbuf \
libffi-dev \
- pandoc \
pango \
shared-mime-info
diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py
index 10adee35..5f2be8d8 100644
--- a/src/backend/core/api/viewsets.py
+++ b/src/backend/core/api/viewsets.py
@@ -939,40 +939,6 @@ class TemplateViewSet(
role=models.RoleChoices.OWNER,
)
- @drf.decorators.action(
- detail=True,
- methods=["post"],
- url_path="generate-document",
- permission_classes=[permissions.AccessPermission],
- )
- # pylint: disable=unused-argument
- def generate_document(self, request, pk=None):
- """
- Generate and return a document for this template around the
- body passed as argument.
-
- 2 types of body are accepted:
- - HTML: body_type = "html"
- - Markdown: body_type = "markdown"
-
- 2 types of documents can be generated:
- - PDF: format = "pdf"
- - Docx: format = "docx"
- """
- serializer = serializers.DocumentGenerationSerializer(data=request.data)
-
- if not serializer.is_valid():
- return drf.response.Response(
- serializer.errors, status=drf.status.HTTP_400_BAD_REQUEST
- )
-
- body = serializer.validated_data["body"]
- body_type = serializer.validated_data["body_type"]
- export_format = serializer.validated_data["format"]
-
- template = self.get_object()
- return template.generate_document(body, body_type, export_format)
-
class TemplateAccessViewSet(
ResourceAccessViewsetMixin,
diff --git a/src/backend/core/models.py b/src/backend/core/models.py
index 52e66aab..1dc85739 100644
--- a/src/backend/core/models.py
+++ b/src/backend/core/models.py
@@ -5,11 +5,8 @@ Declare and configure the models for the impress core application
import hashlib
import smtplib
-import tempfile
-import textwrap
import uuid
from datetime import timedelta
-from io import BytesIO
from logging import getLogger
from django.conf import settings
@@ -21,19 +18,12 @@ from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
from django.core.mail import send_mail
from django.db import models
-from django.http import FileResponse
-from django.template.base import Template as DjangoTemplate
-from django.template.context import Context
from django.template.loader import render_to_string
-from django.utils import html, timezone
+from django.utils import timezone
from django.utils.functional import cached_property, lazy
from django.utils.translation import get_language, override
from django.utils.translation import gettext_lazy as _
-import frontmatter
-import markdown
-import pypandoc
-import weasyprint
from botocore.exceptions import ClientError
from timezone_field import TimeZoneField
@@ -794,107 +784,6 @@ class Template(BaseModel):
"retrieve": can_get,
}
- def generate_pdf(self, body_html, metadata):
- """
- Generate and return a pdf document wrapped around the current template
- """
- document_html = weasyprint.HTML(
- string=DjangoTemplate(self.code).render(
- Context({"body": html.format_html(body_html), **metadata})
- )
- )
- css = weasyprint.CSS(
- string=self.css,
- font_config=weasyprint.text.fonts.FontConfiguration(),
- )
-
- pdf_content = document_html.write_pdf(stylesheets=[css], zoom=1)
- response = FileResponse(BytesIO(pdf_content), content_type="application/pdf")
- response["Content-Disposition"] = f"attachment; filename={self.title}.pdf"
-
- return response
-
- def generate_word(self, body_html, metadata):
- """
- Generate and return a docx document wrapped around the current template
- """
- template_string = DjangoTemplate(self.code).render(
- Context({"body": html.format_html(body_html), **metadata})
- )
-
- html_string = f"""
-
-
-
-
-
-
- {template_string}
-
-
- """
-
- reference_docx = "core/static/reference.docx"
- output = BytesIO()
-
- # Convert the HTML to a temporary docx 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],
- )
-
- # 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(
- output,
- 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):
- """
- Generate and return a document for this template around the
- body passed as argument.
-
- 2 types of body are accepted:
- - HTML: body_type = "html"
- - Markdown: body_type = "markdown"
-
- 2 types of documents can be generated:
- - PDF: export_format = "pdf"
- - Docx: export_format = "docx"
- """
- document = frontmatter.loads(body)
- metadata = document.metadata
- strip_body = document.content.strip()
-
- if body_type == "html":
- body_html = strip_body
- else:
- body_html = (
- markdown.markdown(textwrap.dedent(strip_body)) if strip_body else ""
- )
-
- if export_format == "pdf":
- return self.generate_pdf(body_html, metadata)
-
- return self.generate_word(body_html, metadata)
-
class TemplateAccess(BaseAccess):
"""Relation model to give access to a template for a user or a team with a role."""
diff --git a/src/backend/core/static/reference.docx b/src/backend/core/static/reference.docx
deleted file mode 100644
index 2192455df1a394ac05c4739b93f04abd2a6d6bc8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 7227
zcmaJ`1yo$ivPFWsyL)g5?(Q(SJA=CicM=HhHUWZ5g1ZL~4k5S&3mM#kg+JW)-%D=(
zf463xv(BuU>eF4js=8`7KneC4E)*gnBGiKtsy@_jf&zIqbq6|nu(Lhgt7m!@VL373
zH~imPWcm9vX-iwxcfOj+kq-<>96N%~QI;<;SYHDmw*ho|$+>U#_GpS$NgulWN>j-Y
z;40ffW5Ue8_vLSRT{m<@t2Eo1+I}dOKHIl=KdL&6ESvNrBy(KeWG|a0(tXzB%wUug
zjj-|MEbL~R-4VwFIK+8I->EvRp^>@F`)$(CFL5AgLsnum27^JZrWF3sVx!Vf=}_Rg
z(cn#LnG*K~aO(D$^2pz2KWV&IGf|065E)L%8&qVOi?eE^X@#!8@OUO&I!5~KD!a&T
zYx%r)q);SbGFv7#Qvv%OVVp~2=bM9h9w+mY<3nCvz{`_EkiY8W
zgFV-JMr1RrlQf+sE*#aFcwG!iR_Q*l@uYN^J6%yVR#7qr-E2y@T``loYUZSj8Ey%g
z1H_#i#gSGR*BE2wxB#zc4^x^LZ=~B+G%t~7DYHm04n1V<8>dv0s;T5=xnJ3fMaC*X
z!tz;%pc>kS5SdZJAp9L=A44^qads?*!LG7CvOmC8eJLf}&!wNT>bqc>T=m=~#b)!)
zM-QP2cB}g5@Qh0FahN5c1{)x5O5;}0OS09~5BQ9+AAP~mnqtVhZu0b4uWgQzeqMHQ
zg0~cH(EMT8cFi*JN83oew-X{h!lm8JvkDtJ1fR|+MrnDBh7q@W%9)~UG$ZV}QGM~z
zBKLSCWui|ZB3jRlnamrP(
zOkGHKQoQqD(UHcI3s}k`o2=^e^a8hUgbX6nWtd|Rn1>`+8Vo;h1+c%RKj)}Hw?fNH
zZb4PE{fO6I;PCDRF~b!6n#2-tL9mn{LT}9igZIqon@}8=2tUR+sH_BwlmhSZKwU6-
z@bt~bbU{@uXup@ELy!&qsJo#g&&94gICW2>&5zXX{ZU-Amj%53GB4Pc;7qmV#}AscNo9
zpou5zz7z_4%lR3%faJRgot7&V*deiOtYZ&UFxviAArTcuR9-E`6A-)21N%x4AQb))
z2%O)6u=MiqbaDC%i-}rfNVr69u9hM$E^8qq%{0XF3u#>^t~Eh>xD2br2Kv*49mPje
zh^o$tJV;exE@IiYvNJP5v7(_fu(~`H^DFd@Y?zTpcu5>m~J@*=IkNtGA(W8{yK?PL)fcmavNSDZe?C$6<}YXa!tY
zscPlveZ?Np^*01Hqq5)74HY(De<1m;zc6hgu40vu>#uFe5NO46z`+#vofdBYxpT4L
zDDn+${NBnX59QsI)v{#BGCoqxz5OYLlV*BcU!!^{I!|Ej2IxKOZ9b!MB<)7%yL{OD
z_6IBZyBXWjoq_?MFoH|we$OfNM85;z%4F6;u
zZ>tKYImp^G{t@-36#18Rez!}p)^dCf2WH^0E@d}^cxp9ugOzEaGjn65{9;fDC#>H0
z97i19hg)~G>my_yTO}NQGMJk
zI$g7JBTb%P3X!au(a}gSG#s)VrJ9T3Q#j*nqAZi^e7`xU;<(rSSxkv@z^hs7uz@x1
zGit6BO%dUD#nI2oDfE0VR?f$WcGE|Ti&wQrOe0BUUClka)hD>-8EIPhYA8*!J2r)Q
z=6d>cx)Tnk59XB}lUHY|i>``!IxXSV8aBf2K280ge!kkJ_StaqXTtHp&mx~k*_tdQ
z+D~0`iiQS=xwKl?mxnUL@>l$TNH+Ed`>40?$kJ1~5nr`|m1R^#VGj|w>D&@Jp)whK
zFL4f>P*Bd&m|Z_k5RG!6d_)#Muf6b℘@?oP|hbzENoUK*;U@Fnf%Md=*NTNkQ{4
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 body
", "body_type": "html"}
-
- response = client.post(
- f"/api/v1.0/templates/{template.id!s}/generate-document/",
- data,
- format="json",
- )
-
- assert response.status_code == 200
- assert response.headers["content-type"] == "application/pdf"
-
-
-def test_api_templates_generate_document_type_markdown():
- """Generate pdf document with the body type markdown."""
- user = factories.UserFactory()
-
- client = APIClient()
- client.force_login(user)
-
- template = factories.TemplateFactory(is_public=True)
- data = {"body": "# Test markdown body", "body_type": "markdown"}
-
- response = client.post(
- f"/api/v1.0/templates/{template.id!s}/generate-document/",
- data,
- format="json",
- )
-
- assert response.status_code == 200
- assert response.headers["content-type"] == "application/pdf"
-
-
-def test_api_templates_generate_document_type_unknown():
- """Generate pdf document with the body type unknown."""
- user = factories.UserFactory()
-
- client = APIClient()
- client.force_login(user)
-
- template = factories.TemplateFactory(is_public=True)
- data = {"body": "# Test markdown body", "body_type": "unknown"}
-
- response = client.post(
- f"/api/v1.0/templates/{template.id!s}/generate-document/",
- data,
- format="json",
- )
-
- assert response.status_code == 400
- assert response.json() == {
- "body_type": [
- '"unknown" is not a valid choice.',
- ]
- }
-
-
-def test_api_templates_generate_document_export_docx():
- """Generate pdf document with the body type html."""
- user = factories.UserFactory()
-
- client = APIClient()
- client.force_login(user)
-
- template = factories.TemplateFactory(is_public=True)
- data = {"body": "Test body
", "body_type": "html", "format": "docx"}
-
- response = client.post(
- f"/api/v1.0/templates/{template.id!s}/generate-document/",
- data,
- format="json",
- )
-
- assert response.status_code == 200
- assert (
- response.headers["content-type"]
- == "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
- )
diff --git a/src/backend/core/tests/test_models_templates.py b/src/backend/core/tests/test_models_templates.py
index 6e7cba2c..95f8fbde 100644
--- a/src/backend/core/tests/test_models_templates.py
+++ b/src/backend/core/tests/test_models_templates.py
@@ -2,10 +2,6 @@
Unit tests for the Template model
"""
-import os
-import time
-from unittest import mock
-
from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ValidationError
@@ -189,31 +185,3 @@ 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("Test body
", {})
-
- 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_pypandoc):
- """
- 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("Test body
", {})
- except RuntimeError as e:
- assert str(e) == "Conversion failed"
- time.sleep(0.5)
- assert len([f for f in os.listdir("/tmp") if f.startswith("docx_")]) == 0
diff --git a/src/backend/demo/data/template/code.txt b/src/backend/demo/data/template/code.txt
index 0ab83f60..56f6736b 100644
--- a/src/backend/demo/data/template/code.txt
+++ b/src/backend/demo/data/template/code.txt
@@ -1,10 +1,2 @@
-
-
-
-
+
+
\ No newline at end of file
diff --git a/src/backend/demo/data/template/css.txt b/src/backend/demo/data/template/css.txt
index 79a440ab..e69de29b 100644
--- a/src/backend/demo/data/template/css.txt
+++ b/src/backend/demo/data/template/css.txt
@@ -1,20 +0,0 @@
-body {
- background: white;
- font-family: arial;
-}
-.header img {
- width: 5cm;
- margin-left: -0.4cm;
-}
-.body{
- margin-top: 1.5rem;
-}
-img {
- max-width: 100%;
-}
-[custom-style="center"] {
- text-align: center;
-}
-[custom-style="right"] {
- text-align: right;
-}
diff --git a/src/backend/pyproject.toml b/src/backend/pyproject.toml
index 4ce29fa6..286f07b7 100644
--- a/src/backend/pyproject.toml
+++ b/src/backend/pyproject.toml
@@ -50,13 +50,10 @@ dependencies = [
"openai==1.58.1",
"psycopg[binary]==3.2.3",
"PyJWT==2.10.1",
- "pypandoc==1.14",
- "python-frontmatter==1.1.0",
"python-magic==0.4.27",
"requests==2.32.3",
"sentry-sdk==2.19.2",
"url-normalize==1.4.3",
- "WeasyPrint>=60.2",
"whitenoise==6.8.2",
"mozilla-django-oidc==4.0.1",
]