8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-04 18:42:25 +00:00
re2o/cotisations/tex.py

152 lines
5 KiB
Python
Raw Permalink Normal View History

2018-08-22 21:18:12 +00:00
# -*- mode: python; coding: utf-8 -*-
2020-11-23 16:06:37 +00:00
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
2017-01-15 23:01:18 +00:00
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Lara Kermarec
2017-01-15 23:01:18 +00:00
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""tex.py
Module in charge of rendering some LaTex templates.
Used to generated PDF invoice.
"""
2017-01-15 23:01:18 +00:00
2018-04-14 13:39:51 +00:00
import os
2021-02-10 10:06:09 +00:00
import tempfile
2018-04-14 13:39:51 +00:00
from datetime import datetime
2021-02-10 10:06:09 +00:00
from subprocess import PIPE, Popen
2018-04-14 13:39:51 +00:00
2021-02-10 10:06:09 +00:00
from django.conf import settings
2019-01-03 18:52:06 +00:00
from django.db import models
2017-11-14 19:00:24 +00:00
from django.http import HttpResponse
2021-02-10 10:06:09 +00:00
from django.template.loader import get_template
2017-11-14 19:00:24 +00:00
from django.utils.text import slugify
2019-01-03 18:52:06 +00:00
from preferences.models import CotisationsOption
2021-02-10 10:06:09 +00:00
from re2o.mixins import AclMixin, RevMixin
2016-07-09 15:16:44 +00:00
TEMP_PREFIX = getattr(settings, "TEX_TEMP_PREFIX", "render_tex-")
CACHE_PREFIX = getattr(settings, "TEX_CACHE_PREFIX", "render-tex")
CACHE_TIMEOUT = getattr(settings, "TEX_CACHE_TIMEOUT", 86400) # 1 day
2016-07-09 15:16:44 +00:00
2018-04-14 13:39:51 +00:00
def render_invoice(_request, ctx={}):
"""
Render an invoice using some available information such as the current
date, the user, the articles, the prices, ...
"""
options, _ = CotisationsOption.objects.get_or_create()
is_estimate = ctx.get("is_estimate", False)
filename = "_".join(
[
"cost_estimate" if is_estimate else "invoice",
slugify(ctx.get("asso_name", "")),
slugify(ctx.get("recipient_name", "")),
str(ctx.get("DATE", datetime.now()).year),
str(ctx.get("DATE", datetime.now()).month),
str(ctx.get("DATE", datetime.now()).day),
]
2018-04-13 18:58:29 +00:00
)
templatename = options.invoice_template.template.name.split("/")[-1]
r = render_tex(_request, templatename, ctx)
r["Content-Disposition"] = 'attachment; filename="{name}.pdf"'.format(name=filename)
2017-11-14 19:00:24 +00:00
return r
2018-04-13 18:58:29 +00:00
2019-01-05 18:45:21 +00:00
def render_voucher(_request, ctx={}):
"""
Render a subscribtion voucher.
"""
options, _ = CotisationsOption.objects.get_or_create()
filename = "_".join(
[
"voucher",
slugify(ctx.get("asso_name", "")),
slugify(ctx.get("firstname", "")),
slugify(ctx.get("lastname", "")),
str(ctx.get("date_begin", datetime.now()).year),
str(ctx.get("date_begin", datetime.now()).month),
str(ctx.get("date_begin", datetime.now()).day),
]
2019-01-05 18:45:21 +00:00
)
templatename = options.voucher_template.template.name.split("/")[-1]
r = render_tex(_request, templatename, ctx)
r["Content-Disposition"] = 'attachment; filename="{name}.pdf"'.format(name=filename)
2019-01-05 18:45:21 +00:00
return r
2018-07-18 00:08:03 +00:00
def create_pdf(template, ctx={}):
"""Creates and returns a PDF from a LaTeX template using pdflatex.
It create a temporary file for the PDF then read it to return its content.
Args:
template: Path to the LaTeX template.
ctx: Dict with the context for rendering the template.
Returns:
The content of the temporary PDF file generated.
"""
context = ctx
2017-11-14 19:00:24 +00:00
template = get_template(template)
rendered_tpl = template.render(context).encode("utf-8")
2018-04-13 18:58:29 +00:00
2016-07-09 21:26:17 +00:00
with tempfile.TemporaryDirectory() as tempdir:
for _ in range(2):
2019-11-17 11:58:23 +00:00
process = Popen(
["pdflatex", "-output-directory", tempdir],
stdin=PIPE,
stdout=PIPE,
)
process.communicate(rendered_tpl)
with open(os.path.join(tempdir, "texput.pdf"), "rb") as f:
2016-07-09 21:26:17 +00:00
pdf = f.read()
2018-07-18 00:08:03 +00:00
return pdf
2018-12-29 13:01:22 +00:00
def escape_chars(string):
"""Escape the '%' and the '' signs to avoid messing with LaTeX"""
if not isinstance(string, str):
return string
mapping = (("", r"\euro"), ("%", r"\%"))
2018-12-29 13:01:22 +00:00
r = str(string)
for k, v in mapping:
r = r.replace(k, v)
return r
2018-07-18 00:08:03 +00:00
def render_tex(_request, template, ctx={}):
"""Creates a PDF from a LaTex templates using pdflatex.
Calls `create_pdf` and send back an HTTP response for
2018-07-18 00:08:03 +00:00
accessing this file.
Args:
_request: Unused, but allow using this function as a Django view.
template: Path to the LaTeX template.
ctx: Dict with the context for rendering the template.
Returns:
An HttpResponse with type `application/pdf` containing the PDF file.
2018-07-18 00:08:03 +00:00
"""
2018-08-15 22:22:07 +00:00
pdf = create_pdf(template, ctx)
r = HttpResponse(content_type="application/pdf")
2016-07-09 21:26:17 +00:00
r.write(pdf)
return r