1 # -*- coding: utf-8 -*-
2 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
7 from django.conf import settings
9 from django.http import HttpResponse
11 logger = logging.getLogger(__name__)
14 def render_to_pdf(output_path, template, context=None, add_files=None):
15 """Renders a TeXML document into a PDF file.
17 :param str output_path: is where the PDF file should go
18 :param str template: is a TeXML template path
19 :param context: is context for rendering the template
20 :param dict add_files: a dictionary of additional files XeTeX will need
23 from StringIO import StringIO
25 from tempfile import mkdtemp
27 import Texml.processor
28 from django.template.loader import render_to_string
30 rendered = render_to_string(template, context)
31 texml = StringIO(rendered.encode('utf-8'))
32 tempdir = mkdtemp(prefix = "render_to_pdf-")
33 tex_path = os.path.join(tempdir, "doc.tex")
34 with open(tex_path, 'w') as tex_file:
35 Texml.processor.process(texml, tex_file, encoding="utf-8")
38 for add_name, src_file in add_files.items():
39 add_path = os.path.join(tempdir, add_name)
40 if hasattr(src_file, "read"):
41 with open(add_path, 'w') as add_file:
42 add_file.write(add_file.read())
44 shutil.copy(src_file, add_path)
49 subprocess.check_call(['xelatex', '-interaction=batchmode', tex_path],
50 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
52 os.makedirs(os.path.dirname(output_path))
55 shutil.move(os.path.join(tempdir, "doc.pdf"), output_path)
58 shutil.rmtree(tempdir)
61 def read_chunks(f, size=8192):
68 def generated_file_view(file_name, mime_type, send_name=None, signals=None):
69 file_path = os.path.join(settings.MEDIA_ROOT, file_name)
70 file_url = os.path.join(settings.MEDIA_URL, file_name)
72 send_name = os.path.basename(file_name)
74 def signal_handler(*args, **kwargs):
78 for signal in signals:
79 signal.connect(signal_handler, weak=False)
82 def view(request, *args, **kwargs):
83 if not os.path.exists(file_path):
84 func(file_path, *args, **kwargs)
86 if hasattr(send_name, "__call__"):
91 response = HttpResponse(mimetype=mime_type)
92 response['Content-Disposition'] = 'attachment; filename=%s' % name
93 with open(file_path) as f:
94 for chunk in read_chunks(f):