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/tests.py | 26 +++++++++++++++++++++++ wkhtmltopdf/utils.py | 8 +++++++ wkhtmltopdf/views.py | 60 +++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 79 insertions(+), 15 deletions(-) (limited to 'wkhtmltopdf') diff --git a/wkhtmltopdf/tests.py b/wkhtmltopdf/tests.py index 19fde76..1802440 100644 --- a/wkhtmltopdf/tests.py +++ b/wkhtmltopdf/tests.py @@ -218,6 +218,24 @@ class TestViews(TestCase): response = view(request) self.assertEqual(response.status_code, 405) + def test_get_cmd_options(self): + # Default cmd_options + view = PDFTemplateView() + self.assertEqual(view.cmd_options, PDFTemplateView.cmd_options) + self.assertEqual(PDFTemplateView.cmd_options, {}) + + # Instantiate with new cmd_options + cmd_options = {'orientation': 'landscape'} + view = PDFTemplateView(cmd_options=cmd_options) + self.assertEqual(view.cmd_options, cmd_options) + self.assertEqual(PDFTemplateView.cmd_options, {}) + + # Update local instance of cmd_options + view = PDFTemplateView() + view.cmd_options.update(cmd_options) + self.assertEqual(view.cmd_options, cmd_options) + self.assertEqual(PDFTemplateView.cmd_options, {}) + def test_deprecated(self): """Should warn when using deprecated views.""" with warnings.catch_warnings(record=True) as w: @@ -236,3 +254,11 @@ class TestViews(TestCase): self.assertTrue( 'PDFResponse' in str(w[0].message), "'PDFResponse' not in {!r}".format(w[0].message)) + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + PDFTemplateView().get_pdf_kwargs() + self.assertEqual(len(w), 1) + self.assertEqual(w[0].category, PendingDeprecationWarning) + self.assertTrue( + 'get_pdf_kwargs()' in str(w[0].message), + "'get_pdf_kwargs()' not in {!r}".format(w[0].message)) diff --git a/wkhtmltopdf/utils.py b/wkhtmltopdf/utils.py index d0475c4..03a5f82 100644 --- a/wkhtmltopdf/utils.py +++ b/wkhtmltopdf/utils.py @@ -19,6 +19,8 @@ def _options_to_args(**options): flags = [] for name in sorted(options): value = options[name] + if value is None: + continue flags.append('--' + name.replace('_', '-')) if value is not True: flags.append(unicode(value)) @@ -38,11 +40,17 @@ def wkhtmltopdf(pages, output=None, **kwargs): {'footer_html': 'http://example.com/foot.html'} becomes '--footer-html http://example.com/foot.html' + Where there is no value passed, use True. e.g.: {'disable_javascript': True} becomes: '--disable-javascript' + To disable a default option, use None. e.g: + {'quiet': None'} + becomes: + '' + example usage: wkhtmltopdf(pages=['/tmp/example.html'], dpi=300, 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