From c51068cd1864d995e81ee5fd248b8a2027e56c35 Mon Sep 17 00:00:00 2001 From: Padraic Harley Date: Fri, 18 Dec 2015 19:33:32 +0000 Subject: Fix unidecode bytes error on python2 `bytes` takes no additional args in python2 unlike it's taking an encoding in python3. Unidecode returns a unicode string in python3 and a bytestring in python2 which, I believe, was the main cause of error #71. Now, regardless of whether unidecode is included, all strings passing through http_quote will be encoded to ascii which should fix both issues. Also included is a fix for a failing test when unidecode is used. Unidecode's `_unidecode` function ignores characters greater than 0xefff, which '\xe2\x99\xa5' (the heart symbol) is. This caused users with unidecode to fail '.pdf' was produced rather than the expected '?.pdf'. --- wkhtmltopdf/tests/tests.py | 20 ++++++++++++++++---- wkhtmltopdf/utils.py | 6 ++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/wkhtmltopdf/tests/tests.py b/wkhtmltopdf/tests/tests.py index c15d88f..fc1545d 100644 --- a/wkhtmltopdf/tests/tests.py +++ b/wkhtmltopdf/tests/tests.py @@ -130,8 +130,14 @@ class TestViews(TestCase): self.assertEqual(response['Content-Disposition'], 'attachment; filename="4\'5.pdf"') response = PDFResponse(content=content, filename=u"♥.pdf") - self.assertEqual(response['Content-Disposition'], - 'attachment; filename="?.pdf"') + try: + import unidecode + except ImportError: + self.assertEqual(response['Content-Disposition'], + 'attachment; filename="?.pdf"') + else: + self.assertEqual(response['Content-Disposition'], + 'attachment; filename=".pdf"') # Content as a direct output response = PDFResponse(content=content, filename="nospace.pdf", @@ -148,8 +154,14 @@ class TestViews(TestCase): 'inline; filename="4\'5.pdf"') response = PDFResponse(content=content, filename=u"♥.pdf", show_content_in_browser=True) - self.assertEqual(response['Content-Disposition'], - 'inline; filename="?.pdf"') + try: + import unidecode + except ImportError: + self.assertEqual(response['Content-Disposition'], + 'inline; filename="?.pdf"') + else: + self.assertEqual(response['Content-Disposition'], + 'inline; filename=".pdf"') # Content-Type response = PDFResponse(content=content, diff --git a/wkhtmltopdf/utils.py b/wkhtmltopdf/utils.py index 3d125bb..f002066 100644 --- a/wkhtmltopdf/utils.py +++ b/wkhtmltopdf/utils.py @@ -186,9 +186,11 @@ def http_quote(string): if isinstance(string, six.text_type): try: import unidecode - string = bytes(unidecode.unidecode(string), 'ascii') except ImportError: - string = string.encode('ascii', 'replace') + pass + else: + string = unidecode.unidecode(string) + string = string.encode('ascii', 'replace') # Wrap in double-quotes for ; , and the like string = string.replace(b'\\', b'\\\\').replace(b'"', b'\\"') return '"{0!s}"'.format(string.decode()) -- cgit v1.2.3 From e4f9b2fc20d61642663db5cae419609b0f06a228 Mon Sep 17 00:00:00 2001 From: Padraic Harley Date: Fri, 29 Jan 2016 12:05:25 +0000 Subject: Assert once but get the filename from the ImportError It was pointed out that instead setting the filename from the ``except/else`` makes what's being tested much clearer. --- wkhtmltopdf/tests/tests.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/wkhtmltopdf/tests/tests.py b/wkhtmltopdf/tests/tests.py index fc1545d..5344e09 100644 --- a/wkhtmltopdf/tests/tests.py +++ b/wkhtmltopdf/tests/tests.py @@ -133,11 +133,11 @@ class TestViews(TestCase): try: import unidecode except ImportError: - self.assertEqual(response['Content-Disposition'], - 'attachment; filename="?.pdf"') + filename = '?.pdf' else: - self.assertEqual(response['Content-Disposition'], - 'attachment; filename=".pdf"') + filename = '.pdf' + self.assertEqual(response['Content-Disposition'], + 'attachment; filename="{}"'.format(filename)) # Content as a direct output response = PDFResponse(content=content, filename="nospace.pdf", @@ -157,11 +157,11 @@ class TestViews(TestCase): try: import unidecode except ImportError: - self.assertEqual(response['Content-Disposition'], - 'inline; filename="?.pdf"') + filename = '?.pdf' else: - self.assertEqual(response['Content-Disposition'], - 'inline; filename=".pdf"') + filename = '.pdf' + self.assertEqual(response['Content-Disposition'], + 'attachment; filename="{}"'.format(filename)) # Content-Type response = PDFResponse(content=content, -- cgit v1.2.3 From 61bec5852aed5399bc251dfd06118c584792f0d1 Mon Sep 17 00:00:00 2001 From: Padraic Harley Date: Fri, 29 Jan 2016 12:45:30 +0000 Subject: Fix py26 bug and copypasta error Python 2.6 doesn't allow empty format arguments: ``{}`` must be ``{0}``. Also second test is ``inline`` rather than ``attachment``. --- wkhtmltopdf/tests/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wkhtmltopdf/tests/tests.py b/wkhtmltopdf/tests/tests.py index 5344e09..983e10a 100644 --- a/wkhtmltopdf/tests/tests.py +++ b/wkhtmltopdf/tests/tests.py @@ -137,7 +137,7 @@ class TestViews(TestCase): else: filename = '.pdf' self.assertEqual(response['Content-Disposition'], - 'attachment; filename="{}"'.format(filename)) + 'attachment; filename="{0}"'.format(filename)) # Content as a direct output response = PDFResponse(content=content, filename="nospace.pdf", @@ -161,7 +161,7 @@ class TestViews(TestCase): else: filename = '.pdf' self.assertEqual(response['Content-Disposition'], - 'attachment; filename="{}"'.format(filename)) + 'inline; filename="{0}"'.format(filename)) # Content-Type response = PDFResponse(content=content, -- cgit v1.2.3