aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Lenc <mattl@incuna.com>2014-06-18 11:14:24 +0100
committerMatt Lenc <mattl@incuna.com>2014-06-18 11:14:24 +0100
commit1e3dfedfc4778879917970bf125c51947c367f94 (patch)
tree249c4b53201c187f13736eb146b0c875babe8507
parent0de693a16fa35525d3adb115bf8bf21c76581d0b (diff)
downloaddjango-wkhtmltopdf-1e3dfedfc4778879917970bf125c51947c367f94.tar.gz
django-wkhtmltopdf-1e3dfedfc4778879917970bf125c51947c367f94.tar.bz2
django-wkhtmltopdf-1e3dfedfc4778879917970bf125c51947c367f94.zip
Add support for Python3
-rw-r--r--wkhtmltopdf/tests/tests.py35
-rw-r--r--wkhtmltopdf/utils.py21
-rw-r--r--wkhtmltopdf/views.py17
3 files changed, 43 insertions, 30 deletions
diff --git a/wkhtmltopdf/tests/tests.py b/wkhtmltopdf/tests/tests.py
index b007687..f2d92aa 100644
--- a/wkhtmltopdf/tests/tests.py
+++ b/wkhtmltopdf/tests/tests.py
@@ -8,6 +8,7 @@ import sys
from django.conf import settings
from django.test import TestCase
from django.test.client import RequestFactory
+from django.utils.encoding import smart_str
from wkhtmltopdf.subprocess import CalledProcessError
from wkhtmltopdf.utils import (_options_to_args, make_absolute_paths,
@@ -41,15 +42,15 @@ class TestUtils(TestCase):
try:
# Standard call
pdf_output = wkhtmltopdf(pages=[temp_file.name])
- self.assertTrue(pdf_output.startswith('%PDF'), pdf_output)
+ self.assertTrue(pdf_output.startswith(b'%PDF'), pdf_output)
# Single page
pdf_output = wkhtmltopdf(pages=temp_file.name)
- self.assertTrue(pdf_output.startswith('%PDF'), pdf_output)
+ self.assertTrue(pdf_output.startswith(b'%PDF'), pdf_output)
# Unicode
pdf_output = wkhtmltopdf(pages=[temp_file.name], title=u'♥')
- self.assertTrue(pdf_output.startswith('%PDF'), pdf_output)
+ self.assertTrue(pdf_output.startswith(b'%PDF'), pdf_output)
# Invalid arguments
self.assertRaises(CalledProcessError,
@@ -63,7 +64,7 @@ class TestUtils(TestCase):
response = PDFTemplateResponse(self.factory.get('/'), None, context={'title': title})
temp_file = response.render_to_temporary_file('sample.html')
temp_file.seek(0)
- saved_content = temp_file.read()
+ saved_content = smart_str(temp_file.read())
self.assertTrue(title in saved_content)
temp_file.close()
@@ -80,11 +81,11 @@ class TestViews(TestCase):
# 404
response = PDFResponse(content='', status=404)
self.assertEqual(response.status_code, 404)
- self.assertEqual(response.content, '')
+ self.assertEqual(response.content, b'')
self.assertEqual(response['Content-Type'], 'application/pdf')
self.assertFalse(response.has_header('Content-Disposition'))
- content = '%PDF-1.4\n%%EOF'
+ content = b'%PDF-1.4\n%%EOF'
# Without filename
response = PDFResponse(content=content)
self.assertEqual(response.status_code, 200)
@@ -153,14 +154,14 @@ class TestViews(TestCase):
# Render to temporary file
tempfile = response.render_to_temporary_file(self.template)
tempfile.seek(0)
- html_content = tempfile.read()
+ html_content = smart_str(tempfile.read())
self.assertTrue(html_content.startswith('<html>'))
self.assertTrue('<h1>{title}</h1>'.format(**context)
in html_content)
pdf_content = response.rendered_content
- self.assertTrue(pdf_content.startswith('%PDF-'))
- self.assertTrue(pdf_content.endswith('%%EOF\n'))
+ self.assertTrue(pdf_content.startswith(b'%PDF-'))
+ self.assertTrue(pdf_content.endswith(b'%%EOF\n'))
# Footer
cmd_options = {'title': 'Test PDF'}
@@ -179,7 +180,7 @@ class TestViews(TestCase):
tempfile = response.render_to_temporary_file(self.footer_template)
tempfile.seek(0)
- footer_content = tempfile.read()
+ footer_content = smart_str(tempfile.read())
footer_content = make_absolute_paths(footer_content)
media_url = 'file://{0}/'.format(settings.MEDIA_ROOT)
@@ -189,8 +190,8 @@ class TestViews(TestCase):
self.assertTrue(static_url in footer_content, True)
pdf_content = response.rendered_content
- self.assertTrue('\0'.join('{title}'.format(**cmd_options))
- in pdf_content)
+ self.assertTrue(pdf_content.startswith(b'%PDF-'))
+ self.assertTrue(pdf_content.endswith(b'%%EOF\n'))
def test_pdf_template_response_to_browser(self):
self.test_pdf_template_response(show_content=True)
@@ -214,8 +215,8 @@ class TestViews(TestCase):
fileheader = self.inline_fileheader
self.assertEqual(response['Content-Disposition'],
fileheader.format(self.pdf_filename))
- self.assertTrue(response.content.startswith('%PDF-'))
- self.assertTrue(response.content.endswith('%%EOF\n'))
+ self.assertTrue(response.content.startswith(b'%PDF-'))
+ self.assertTrue(response.content.endswith(b'%%EOF\n'))
# As HTML
request = RequestFactory().get('/?as=html')
@@ -223,7 +224,7 @@ class TestViews(TestCase):
self.assertEqual(response.status_code, 200)
response.render()
self.assertFalse(response.has_header('Content-Disposition'))
- self.assertTrue(response.content.startswith('<html>'))
+ self.assertTrue(response.content.startswith(b'<html>'))
# POST
request = RequestFactory().post('/')
@@ -254,8 +255,8 @@ class TestViews(TestCase):
# not sure how we can test this as the contents is all encoded...
# best we can do for the moment is check it's a pdf and it worked.
# self.assertTrue('☃' in response.content)
- self.assertTrue(response.content.startswith('%PDF-'))
- self.assertTrue(response.content.endswith('%%EOF\n'))
+ self.assertTrue(response.content.startswith(b'%PDF-'))
+ self.assertTrue(response.content.endswith(b'%%EOF\n'))
def test_pdf_template_view_unicode_to_browser(self):
self.test_pdf_template_view_unicode(show_content=True)
diff --git a/wkhtmltopdf/utils.py b/wkhtmltopdf/utils.py
index 1b74a97..9be8f86 100644
--- a/wkhtmltopdf/utils.py
+++ b/wkhtmltopdf/utils.py
@@ -5,10 +5,16 @@ from itertools import chain
import os
import re
import sys
-import urllib
-from urlparse import urljoin
+
+try:
+ from urllib import pathname2url
+ from urlparse import urljoin
+except ImportError: # py3k
+ from urllib.request import pathname2url
+ from urllib.parse import urljoin
from django.conf import settings
+from django.utils import six
from .subprocess import check_output
@@ -22,7 +28,7 @@ def _options_to_args(**options):
continue
flags.append('--' + name.replace('_', '-'))
if value is not True:
- flags.append(unicode(value))
+ flags.append(six.text_type(value))
return flags
@@ -56,7 +62,7 @@ def wkhtmltopdf(pages, output=None, **kwargs):
orientation='Landscape',
disable_javascript=True)
"""
- if isinstance(pages, basestring):
+ if isinstance(pages, six.string_types):
# Support a single page.
pages = [pages]
@@ -113,19 +119,20 @@ def http_quote(string):
valid ascii charset string you can use in, say, http headers and the
like.
"""
- if isinstance(string, unicode):
+ if isinstance(string, six.text_type):
try:
import unidecode
string = unidecode.unidecode(string)
except ImportError:
string = string.encode('ascii', 'replace')
# Wrap in double-quotes for ; , and the like
- return '"{0!s}"'.format(string.replace('\\', '\\\\').replace('"', '\\"'))
+ string = string.replace(b'\\', b'\\\\').replace(b'"', b'\\"')
+ return '"{0!s}"'.format(string.decode())
def pathname2fileurl(pathname):
"""Returns a file:// URL for pathname. Handles OS-specific conversions."""
- return urljoin('file:', urllib.pathname2url(pathname))
+ return urljoin('file:', pathname2url(pathname))
def make_absolute_paths(content):
diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py
index 5a46490..92e2d0f 100644
--- a/wkhtmltopdf/views.py
+++ b/wkhtmltopdf/views.py
@@ -5,7 +5,6 @@ from tempfile import NamedTemporaryFile
from django.conf import settings
from django.http import HttpResponse
from django.template.response import TemplateResponse
-from django.utils.encoding import smart_str
from django.views.generic import TemplateView
from .utils import (content_disposition_filename, make_absolute_paths,
@@ -74,15 +73,21 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse):
context = self.resolve_context(self.context_data)
- content = smart_str(template.render(context))
+ content = template.render(context)
content = make_absolute_paths(content)
- tempfile = NamedTemporaryFile(mode=mode, bufsize=bufsize,
- suffix=suffix, prefix=prefix,
- dir=dir, delete=delete)
+ try:
+ tempfile = NamedTemporaryFile(mode=mode, bufsize=bufsize,
+ suffix=suffix, prefix=prefix,
+ dir=dir, delete=delete)
+ except TypeError:
+ # Python 3 has 'buffering' arg for 'NamedTemporaryFile' class
+ tempfile = NamedTemporaryFile(mode=mode, buffering=bufsize,
+ suffix=suffix, prefix=prefix,
+ dir=dir, delete=delete)
try:
- tempfile.write(content)
+ tempfile.write(content.encode('utf-8'))
tempfile.flush()
return tempfile
except: