From bd8903e7787a7bc0738432d9b75f9d1eac446061 Mon Sep 17 00:00:00 2001 From: Simon Law Date: Fri, 20 Jul 2012 16:32:58 -0400 Subject: Use warnings.warn instead of raising PendingDeprecationWarnings. --- wkhtmltopdf/views.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'wkhtmltopdf/views.py') diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py index 164f94f..8da86f5 100644 --- a/wkhtmltopdf/views.py +++ b/wkhtmltopdf/views.py @@ -1,5 +1,6 @@ import os from re import compile +import warnings from django.conf import settings from django.contrib.sites.models import Site @@ -21,8 +22,8 @@ class PDFResponse(HttpResponse): class PdfResponse(PDFResponse): def __init__(self, content, filename): - warning = '''PdfResponse is deprecated in favour of PDFResponse. It will be removed in version 1.''' - raise PendingDeprecationWarning(warning) + warnings.warn('PdfResponse is deprecated in favour of PDFResponse. It will be removed in version 1.', + PendingDeprecationWarning, 2) super(PdfResponse, self).__init__(content, filename) @@ -90,7 +91,7 @@ class PDFTemplateView(TemplateView): class PdfTemplateView(PDFTemplateView): #TODO: Remove this in v1.0 - def as_view(cls, **initkwargs): - warning = '''PdfTemplateView is deprecated in favour of PDFTemplateView. It will be removed in version 1.''' - raise PendingDeprecationWarning(warning) - return super(PdfTemplateView, cls).as_view(**initkwargs) + def __init__(self, *args, **kwargs): + warnings.warn('PdfTemplateView is deprecated in favour of PDFTemplateView. It will be removed in version 1.', + PendingDeprecationWarning, 2) + super(PdfTemplateView, self).__init__(*args, **kwargs) -- cgit v1.2.3 From 4a27fe9f16ecd4bc6f94ad89046767450316490c Mon Sep 17 00:00:00 2001 From: Simon Law Date: Mon, 23 Jul 2012 15:29:39 -0400 Subject: PDFResponse is more robust: * Now matches HttpResponse in function signature. * Modern Django content_type/mimetype handling. * Sanitizes and quotes filenames in Content-Disposition header. * Tests. --- wkhtmltopdf/views.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'wkhtmltopdf/views.py') diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py index 8da86f5..539a669 100644 --- a/wkhtmltopdf/views.py +++ b/wkhtmltopdf/views.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + import os from re import compile import warnings @@ -8,23 +10,27 @@ from django.template.context import RequestContext from django.template.response import HttpResponse from django.views.generic import TemplateView -from wkhtmltopdf.utils import template_to_temp_file, wkhtmltopdf +from .utils import (content_disposition_filename, + template_to_temp_file, wkhtmltopdf) class PDFResponse(HttpResponse): - def __init__(self, content, *args, **kwargs): + def __init__(self, content, mimetype=None, status=200, + content_type='application/pdf', *args, **kwargs): filename = kwargs.pop('filename', None) - super(PDFResponse, self).__init__(content, 'application/pdf', *args, **kwargs) + super(PDFResponse, self).__init__(content, mimetype, status, + content_type, *args, **kwargs) if filename: + filename = content_disposition_filename(filename) header_content = 'attachment; filename={0}'.format(filename) - self.__setitem__('Content-Disposition', header_content) + self['Content-Disposition'] = header_content class PdfResponse(PDFResponse): def __init__(self, content, filename): warnings.warn('PdfResponse is deprecated in favour of PDFResponse. It will be removed in version 1.', PendingDeprecationWarning, 2) - super(PdfResponse, self).__init__(content, filename) + super(PdfResponse, self).__init__(content, filename=filename) class PDFTemplateView(TemplateView): -- cgit v1.2.3 From 8e53c5bc5db462f6e39404c73ac96ec0cbb6a6c7 Mon Sep 17 00:00:00 2001 From: Simon Law Date: Tue, 24 Jul 2012 14:57:06 -0400 Subject: PDFTemplateResponse and PDFTemplateView now match Django's implementations PDFTemplateResponse is like TemplateResponse in that it does dynamic rendering of a template on the fly. PDFTemplateView has a much smaller implementation, relying on PDFTemplateResponse to do the rendering for it. It also knows about the standard TemplateResponse when it needs to render the HTML version. --- wkhtmltopdf/views.py | 174 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 139 insertions(+), 35 deletions(-) (limited to 'wkhtmltopdf/views.py') diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py index 539a669..0e91b2a 100644 --- a/wkhtmltopdf/views.py +++ b/wkhtmltopdf/views.py @@ -2,28 +2,40 @@ from __future__ import absolute_import import os from re import compile +from tempfile import NamedTemporaryFile import warnings from django.conf import settings from django.contrib.sites.models import Site +from django.http import HttpResponse from django.template.context import RequestContext -from django.template.response import HttpResponse +from django.template.response import TemplateResponse from django.views.generic import TemplateView -from .utils import (content_disposition_filename, - template_to_temp_file, wkhtmltopdf) +from .utils import (content_disposition_filename, wkhtmltopdf) class PDFResponse(HttpResponse): def __init__(self, content, mimetype=None, status=200, - content_type='application/pdf', *args, **kwargs): - filename = kwargs.pop('filename', None) - super(PDFResponse, self).__init__(content, mimetype, status, - content_type, *args, **kwargs) + content_type=None, filename=None, *args, **kwargs): + + if content_type is None: + content_type = 'application/pdf' + + super(PDFResponse, self).__init__(content=content, + mimetype=mimetype, + status=status, + content_type=content_type) + self.set_filename(filename) + + def set_filename(self, filename): + self.filename = filename if filename: filename = content_disposition_filename(filename) header_content = 'attachment; filename={0}'.format(filename) self['Content-Disposition'] = header_content + else: + del self['Content-Disposition'] class PdfResponse(PDFResponse): @@ -33,6 +45,94 @@ class PdfResponse(PDFResponse): super(PdfResponse, self).__init__(content, filename=filename) +class PDFTemplateResponse(TemplateResponse, PDFResponse): + """Renders a Template into a PDF using wkhtmltopdf""" + + def __init__(self, request, template, context=None, mimetype=None, + status=None, content_type=None, current_app=None, + filename=None, header_template=None, footer_template=None, + cmd_options=None, *args, **kwargs): + + super(PDFTemplateResponse, self).__init__(request=request, + template=template, + context=context, + mimetype=mimetype, + status=status, + content_type=content_type, + current_app=None, + *args, **kwargs) + self.set_filename(filename) + + self.header_template = header_template + self.footer_template = footer_template + + if cmd_options is None: + cmd_options = {} + self.cmd_options = cmd_options + + def render_to_temporary_file(self, template_name, mode='w+b', bufsize=-1, + suffix='', prefix='tmp', dir=None, + delete=True): + template = self.resolve_template(template_name) + context = self.resolve_context(self.context_data) + content = template.render(context) + tempfile = NamedTemporaryFile(mode=mode, bufsize=bufsize, + suffix=suffix, prefix=prefix, + dir=dir, delete=delete) + try: + tempfile.write(content) + tempfile.flush() + return tempfile + except: + # Clean-up tempfile if an Exception is raised. + tempfile.close() + raise + + @property + def rendered_content(self): + """Returns the freshly rendered content for the template and context + described by the PDFResponse. + + This *does not* set the final content of the response. To set the + response content, you must either call render(), or set the + content explicitly using the value of this property. + """ + debug = getattr(settings, 'WKHTMLTOPDF_DEBUG', False) + + cmd_options = self.cmd_options.copy() + + input_file = header_file = footer_file = None + + try: + input_file = self.render_to_temporary_file( + template_name=self.template_name, + prefix='wkhtmltopdf', suffix='.html', + delete=(not debug) + ) + + if self.header_template: + header_file = self.render_to_temporary_file( + template_name=self.header_template, + prefix='wkhtmltopdf', suffix='.html', + delete=(not debug) + ) + cmd_options.setdefault('header_html', header_file.name) + + if self.footer_template: + footer_file = self.render_to_temporary_file( + template_name=self.footer_template, + prefix='wkhtmltopdf', suffix='.html', + delete=(not debug) + ) + cmd_options.setdefault('footer_html', footer_file.name) + + return wkhtmltopdf(pages=[input_file.name], **cmd_options) + finally: + # Clean up temporary files + for f in filter(None, (input_file, header_file, footer_file)): + f.close() + + class PDFTemplateView(TemplateView): filename = 'rendered_pdf.pdf' footer_template = None @@ -42,28 +142,20 @@ class PDFTemplateView(TemplateView): margin_left = 0 margin_right = 0 margin_top = 0 - response = PDFResponse - _tmp_files = None - - def __init__(self, *args, **kwargs): - self._tmp_files = [] - super(PDFTemplateView, self).__init__(*args, **kwargs) - - def get(self, request, context_instance=None, *args, **kwargs): - if request.GET.get('as', '') == 'html': - return super(PDFTemplateView, self).get(request, *args, **kwargs) - - if context_instance: - self.context_instance = context_instance - else: - self.context_instance = RequestContext(request, self.get_context_data(**kwargs)) - - page_path = template_to_temp_file(self.get_template_names(), self.get_context_data(), self.context_instance) - pdf_kwargs = self.get_pdf_kwargs() - output = wkhtmltopdf(page_path, **pdf_kwargs) - if self._tmp_files: - map(os.remove, self._tmp_files) - return self.response(output, filename=self.get_filename()) + response_class = PDFTemplateResponse + html_response_class = TemplateResponse + + def get(self, request, *args, **kwargs): + response_class = self.response_class + try: + if request.GET.get('as', '') == 'html': + # Use the html_response_class if HTML was requested. + self.response_class = self.html_response_class + return super(PDFTemplateView, self).get(request, + *args, **kwargs) + finally: + # Remove self.response_class + self.response_class = response_class def get_filename(self): return self.filename @@ -76,12 +168,6 @@ class PDFTemplateView(TemplateView): 'margin_top': self.margin_top, 'orientation': self.orientation, } - if self.header_template: - kwargs['header_html'] = template_to_temp_file(self.header_template, self.get_context_data(), self.context_instance) - self._tmp_files.append(kwargs['header_html']) - if self.footer_template: - kwargs['footer_html'] = template_to_temp_file(self.footer_template, self.get_context_data(), self.context_instance) - self._tmp_files.append(kwargs['footer_html']) return kwargs def get_context_data(self, **kwargs): @@ -95,6 +181,24 @@ class PDFTemplateView(TemplateView): return context + def render_to_response(self, context, **response_kwargs): + """ + Returns a PDF response with a template rendered with the given context. + """ + filename = response_kwargs.pop('filename', self.get_filename()) + cmd_options = response_kwargs.pop('cmd_options', self.get_pdf_kwargs()) + + if issubclass(self.response_class, PDFTemplateResponse): + return super(PDFTemplateView, self).render_to_response( + context=context, filename=filename, cmd_options=cmd_options, + **response_kwargs + ) + else: + return super(PDFTemplateView, self).render_to_response( + context=context, + **response_kwargs + ) + class PdfTemplateView(PDFTemplateView): #TODO: Remove this in v1.0 def __init__(self, *args, **kwargs): -- cgit v1.2.3 From a0da923c093f79e2205529c5f12fad620f3159a7 Mon Sep 17 00:00:00 2001 From: Simon Law Date: Tue, 24 Jul 2012 16:18:39 -0400 Subject: PDFTemplateView.cmd_options contains all the options to pass to wkhtmltopdf Before, command-line arguments were class-based. Unfortunately, this means that you cannot add new command-line arguments without subclassing. Instead, PDFTemplateView.cmd_options is a dictionary of all command-line arguments. PDFTemplateView.as_view(cmd_options={...}) now works as expected. !!!! WARNING !!!! cmd_options is now empty, leaving wkhtmltopdf with its default behaviour. Explicitly add the options you want. Existing subclasses of PDFTemplateView will now break, but a PendingDeprecationWarning will be issued. Margins will now be wkhtmltopdf's default of 10mm. PdfTemplateView contains a compatibility shim with the old default values for margins and orientation. --- wkhtmltopdf/views.py | 60 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 15 deletions(-) (limited to 'wkhtmltopdf/views.py') diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py index 0e91b2a..bbb6e7d 100644 --- a/wkhtmltopdf/views.py +++ b/wkhtmltopdf/views.py @@ -137,14 +137,23 @@ class PDFTemplateView(TemplateView): filename = 'rendered_pdf.pdf' footer_template = None header_template = None - orientation = 'portrait' - margin_bottom = 0 - margin_left = 0 - margin_right = 0 - margin_top = 0 + response_class = PDFTemplateResponse html_response_class = TemplateResponse + # Command-line options to pass to wkhtmltopdf + cmd_options = { + # 'orientation': 'portrait', + # 'collate': True, + # 'quiet': None, + } + + def __init__(self, *args, **kwargs): + super(PDFTemplateView, self).__init__(*args, **kwargs) + + # Copy self.cmd_options to prevent clobbering the class-level object. + self.cmd_options = self.cmd_options.copy() + def get(self, request, *args, **kwargs): response_class = self.response_class try: @@ -160,15 +169,13 @@ class PDFTemplateView(TemplateView): def get_filename(self): return self.filename + def get_cmd_options(self): + return self.cmd_options + def get_pdf_kwargs(self): - kwargs = { - 'margin_bottom': self.margin_bottom, - 'margin_left': self.margin_left, - 'margin_right': self.margin_right, - 'margin_top': self.margin_top, - 'orientation': self.orientation, - } - return kwargs + warnings.warn('PDFTemplateView.get_pdf_kwargs() is deprecated in favour of get_cmd_options(). It will be removed in version 1.', + PendingDeprecationWarning, 2) + return self.get_cmd_options() def get_context_data(self, **kwargs): context = super(PDFTemplateView, self).get_context_data(**kwargs) @@ -185,10 +192,14 @@ class PDFTemplateView(TemplateView): """ Returns a PDF response with a template rendered with the given context. """ - filename = response_kwargs.pop('filename', self.get_filename()) - cmd_options = response_kwargs.pop('cmd_options', self.get_pdf_kwargs()) + filename = response_kwargs.pop('filename', None) + cmd_options = response_kwargs.pop('cmd_options', None) if issubclass(self.response_class, PDFTemplateResponse): + if filename is None: + filename = self.get_filename() + if cmd_options is None: + cmd_options = self.get_cmd_options() return super(PDFTemplateView, self).render_to_response( context=context, filename=filename, cmd_options=cmd_options, **response_kwargs @@ -201,7 +212,26 @@ class PDFTemplateView(TemplateView): class PdfTemplateView(PDFTemplateView): #TODO: Remove this in v1.0 + orientation = 'portrait' + margin_bottom = 0 + margin_left = 0 + margin_right = 0 + margin_top = 0 + def __init__(self, *args, **kwargs): warnings.warn('PdfTemplateView is deprecated in favour of PDFTemplateView. It will be removed in version 1.', PendingDeprecationWarning, 2) super(PdfTemplateView, self).__init__(*args, **kwargs) + + def get_cmd_options(self): + return self.get_pdf_kwargs() + + def get_pdf_kwargs(self): + kwargs = { + 'margin_bottom': self.margin_bottom, + 'margin_left': self.margin_left, + 'margin_right': self.margin_right, + 'margin_top': self.margin_top, + 'orientation': self.orientation, + } + return kwargs -- cgit v1.2.3 From 566738a2f151918c00c522b3f2c742f2faf185dc Mon Sep 17 00:00:00 2001 From: Simon Law Date: Tue, 24 Jul 2012 16:28:06 -0400 Subject: PDFTemplateView actually renders headers and footers now. --- wkhtmltopdf/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'wkhtmltopdf/views.py') diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py index bbb6e7d..bd1da13 100644 --- a/wkhtmltopdf/views.py +++ b/wkhtmltopdf/views.py @@ -201,7 +201,10 @@ class PDFTemplateView(TemplateView): if cmd_options is None: cmd_options = self.get_cmd_options() return super(PDFTemplateView, self).render_to_response( - context=context, filename=filename, cmd_options=cmd_options, + context=context, filename=filename, + header_template=self.header_template, + footer_template=self.footer_template, + cmd_options=cmd_options, **response_kwargs ) else: -- cgit v1.2.3 From a6f0a53702a940bf055dadb3bf558aea49c6d862 Mon Sep 17 00:00:00 2001 From: Simon Law Date: Tue, 24 Jul 2012 16:29:30 -0400 Subject: Cleanups and documentation. --- wkhtmltopdf/views.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'wkhtmltopdf/views.py') diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py index bd1da13..c337b6c 100644 --- a/wkhtmltopdf/views.py +++ b/wkhtmltopdf/views.py @@ -1,6 +1,5 @@ from __future__ import absolute_import -import os from re import compile from tempfile import NamedTemporaryFile import warnings @@ -8,7 +7,6 @@ import warnings from django.conf import settings from django.contrib.sites.models import Site from django.http import HttpResponse -from django.template.context import RequestContext from django.template.response import TemplateResponse from django.views.generic import TemplateView @@ -16,6 +14,8 @@ from .utils import (content_disposition_filename, wkhtmltopdf) class PDFResponse(HttpResponse): + """HttpResponse that sets the headers for PDF output.""" + def __init__(self, content, mimetype=None, status=200, content_type=None, filename=None, *args, **kwargs): @@ -134,10 +134,17 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): class PDFTemplateView(TemplateView): + """Class-based view for HTML templates rendered to PDF.""" + + # Filename for downloaded PDF. If None, the response is inline. filename = 'rendered_pdf.pdf' - footer_template = None + + # Filenames for the content, header, and footer templates. + template_name = None header_template = None + footer_template = None + # TemplateResponse classes for PDF and HTML response_class = PDFTemplateResponse html_response_class = TemplateResponse -- cgit v1.2.3 From 5a1847309e7fa431c98565805d88a21a40d01406 Mon Sep 17 00:00:00 2001 From: Simon Law Date: Wed, 25 Jul 2012 12:51:26 -0400 Subject: MEDIA_URL and STATIC_URL overrides PDFTemplateResponse.get_override_settings() MEDIA_URL and STATIC_URL used to be set only in get_context_data(), but there are apps such as staticfiles and Django Compressor where this won't work well. Instead, they need to be overridden at the settings level, not at the context level. This allows template context processors to populate a RequestContext with the right values. In addition, MEDIA_URL and STATIC_URL are now overridden as file:// URLs, based on MEDIA_ROOT and STATIC_ROOT. This allows developers to access these views in runserver, against their current codebase. It also means faster access for wkhtmltopdf, since the files are stored locally. --- wkhtmltopdf/views.py | 63 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 17 deletions(-) (limited to 'wkhtmltopdf/views.py') diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py index c337b6c..4bceb27 100644 --- a/wkhtmltopdf/views.py +++ b/wkhtmltopdf/views.py @@ -5,12 +5,12 @@ from tempfile import NamedTemporaryFile import warnings from django.conf import settings -from django.contrib.sites.models import Site from django.http import HttpResponse from django.template.response import TemplateResponse from django.views.generic import TemplateView -from .utils import (content_disposition_filename, wkhtmltopdf) +from .utils import (content_disposition_filename, override_settings, + pathname2fileurl, wkhtmltopdf) class PDFResponse(HttpResponse): @@ -51,7 +51,8 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): def __init__(self, request, template, context=None, mimetype=None, status=None, content_type=None, current_app=None, filename=None, header_template=None, footer_template=None, - cmd_options=None, *args, **kwargs): + cmd_options=None, override_settings=None, + *args, **kwargs): super(PDFTemplateResponse, self).__init__(request=request, template=template, @@ -70,12 +71,23 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): cmd_options = {} self.cmd_options = cmd_options + self.override_settings = override_settings + def render_to_temporary_file(self, template_name, mode='w+b', bufsize=-1, suffix='', prefix='tmp', dir=None, delete=True): template = self.resolve_template(template_name) - context = self.resolve_context(self.context_data) - content = template.render(context) + + # Since many things require a sensible settings.MEDIA_URL and + # settings.STATIC_URL, including TEMPLATE_CONTEXT_PROCESSORS; + # the settings themselves need to be overridden when rendering. + # + # This allows django-wkhtmltopdf to play nicely with the + # staticfiles app, for instance. + with override_settings(**self.get_override_settings()): + context = self.resolve_context(self.context_data) + content = template.render(context) + tempfile = NamedTemporaryFile(mode=mode, bufsize=bufsize, suffix=suffix, prefix=prefix, dir=dir, delete=delete) @@ -132,6 +144,31 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): for f in filter(None, (input_file, header_file, footer_file)): f.close() + def get_override_settings(self): + """Returns a dictionary of settings to override for response_class""" + overrides = { + 'MEDIA_ROOT': settings.MEDIA_ROOT, + 'MEDIA_URL': settings.MEDIA_URL, + 'STATIC_ROOT': settings.STATIC_ROOT, + 'STATIC_URL': settings.STATIC_URL, + } + if self.override_settings is not None: + overrides.update(self.override_settings) + + has_scheme = compile(r'^[^:/]+://') + + # If MEDIA_URL doesn't have a scheme, we transform it into a + # file:// URL based on MEDIA_ROOT. + urls = [('MEDIA_URL', 'MEDIA_ROOT'), + ('STATIC_URL', 'STATIC_ROOT')] + for url, root in urls: + if not has_scheme.match(overrides[url]): + overrides[url] = pathname2fileurl(overrides[root]) + if not overrides[url].endswith('/'): + overrides[url] += '/' + + return overrides + class PDFTemplateView(TemplateView): """Class-based view for HTML templates rendered to PDF.""" @@ -184,34 +221,26 @@ class PDFTemplateView(TemplateView): PendingDeprecationWarning, 2) return self.get_cmd_options() - def get_context_data(self, **kwargs): - context = super(PDFTemplateView, self).get_context_data(**kwargs) - - match_full_url = compile(r'^https?://') - if not match_full_url.match(settings.STATIC_URL): - context['STATIC_URL'] = 'http://' + Site.objects.get_current().domain + settings.STATIC_URL - if not match_full_url.match(settings.MEDIA_URL): - context['MEDIA_URL'] = 'http://' + Site.objects.get_current().domain + settings.MEDIA_URL - - return context - def render_to_response(self, context, **response_kwargs): """ Returns a PDF response with a template rendered with the given context. """ filename = response_kwargs.pop('filename', None) cmd_options = response_kwargs.pop('cmd_options', None) + override_settings = response_kwargs.pop('override_settings', None) if issubclass(self.response_class, PDFTemplateResponse): if filename is None: filename = self.get_filename() + if cmd_options is None: cmd_options = self.get_cmd_options() + return super(PDFTemplateView, self).render_to_response( context=context, filename=filename, header_template=self.header_template, footer_template=self.footer_template, - cmd_options=cmd_options, + cmd_options=cmd_options, override_settings=override_settings, **response_kwargs ) else: -- cgit v1.2.3 From 22d2721030ccc81dff23093321290b6ffda6d5fd Mon Sep 17 00:00:00 2001 From: Simon Law Date: Wed, 25 Jul 2012 13:17:35 -0400 Subject: PDFTemplateResponse.convert_to_pdf() calls wkhtmltopdf. Method to make it easier to override spawning of the wkhtmltopdf subprocess. --- wkhtmltopdf/views.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'wkhtmltopdf/views.py') diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py index 4bceb27..ad69874 100644 --- a/wkhtmltopdf/views.py +++ b/wkhtmltopdf/views.py @@ -100,6 +100,18 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): tempfile.close() raise + def convert_to_pdf(self, filename, + header_filename=None, footer_filename=None): + cmd_options = self.cmd_options.copy() + # Clobber header_html and footer_html only if filenames are + # provided. These keys may be in self.cmd_options as hardcoded + # static files. + if header_filename is not None: + cmd_options['header_html'] = header_filename + if footer_filename is not None: + cmd_options['footer_html'] = footer_filename + return wkhtmltopdf(pages=[filename], **cmd_options) + @property def rendered_content(self): """Returns the freshly rendered content for the template and context @@ -111,9 +123,8 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): """ debug = getattr(settings, 'WKHTMLTOPDF_DEBUG', False) - cmd_options = self.cmd_options.copy() - input_file = header_file = footer_file = None + header_filename = footer_filename = None try: input_file = self.render_to_temporary_file( @@ -128,7 +139,7 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): prefix='wkhtmltopdf', suffix='.html', delete=(not debug) ) - cmd_options.setdefault('header_html', header_file.name) + header_filename = header_file.name if self.footer_template: footer_file = self.render_to_temporary_file( @@ -136,9 +147,11 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): prefix='wkhtmltopdf', suffix='.html', delete=(not debug) ) - cmd_options.setdefault('footer_html', footer_file.name) + footer_filename = footer_file.name - return wkhtmltopdf(pages=[input_file.name], **cmd_options) + return self.convert_to_pdf(filename=input_file.name, + header_filename=header_filename, + footer_filename=footer_filename) finally: # Clean up temporary files for f in filter(None, (input_file, header_file, footer_file)): -- cgit v1.2.3 From 18132dc19a5bbfe094269d4d0152f3586115306f Mon Sep 17 00:00:00 2001 From: Simon Law Date: Wed, 25 Jul 2012 13:33:03 -0400 Subject: settings.WKHTMLTOPDF_DEBUG defaults to settings.DEBUG. --- wkhtmltopdf/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wkhtmltopdf/views.py') diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py index ad69874..fff98c8 100644 --- a/wkhtmltopdf/views.py +++ b/wkhtmltopdf/views.py @@ -121,7 +121,7 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): response content, you must either call render(), or set the content explicitly using the value of this property. """ - debug = getattr(settings, 'WKHTMLTOPDF_DEBUG', False) + debug = getattr(settings, 'WKHTMLTOPDF_DEBUG', settings.DEBUG) input_file = header_file = footer_file = None header_filename = footer_filename = None -- cgit v1.2.3