aboutsummaryrefslogtreecommitdiffstats
path: root/wkhtmltopdf
diff options
context:
space:
mode:
authorCharlie Denton <charlie@meshy.co.uk>2014-06-19 11:46:18 +0100
committerCharlie Denton <charlie@meshy.co.uk>2014-06-19 11:46:18 +0100
commit8e615cf00343d61e2bf3716c66888758aeb878ed (patch)
tree9f6f4ada901749eaeddb32ac75c0955a5327c2b5 /wkhtmltopdf
parent0de693a16fa35525d3adb115bf8bf21c76581d0b (diff)
parent301bef0d6931582583a156b3195b8b13f54d2875 (diff)
downloaddjango-wkhtmltopdf-8e615cf00343d61e2bf3716c66888758aeb878ed.tar.gz
django-wkhtmltopdf-8e615cf00343d61e2bf3716c66888758aeb878ed.tar.bz2
django-wkhtmltopdf-8e615cf00343d61e2bf3716c66888758aeb878ed.zip
Merge pull request #48 from incuna/python3
Add Python3 support
Diffstat (limited to 'wkhtmltopdf')
-rw-r--r--wkhtmltopdf/__init__.py2
-rw-r--r--wkhtmltopdf/test_settings.py30
-rw-r--r--wkhtmltopdf/tests/run.py38
-rw-r--r--wkhtmltopdf/tests/test_requirements.txt1
-rw-r--r--wkhtmltopdf/tests/tests.py36
-rw-r--r--wkhtmltopdf/utils.py21
-rw-r--r--wkhtmltopdf/views.py14
7 files changed, 82 insertions, 60 deletions
diff --git a/wkhtmltopdf/__init__.py b/wkhtmltopdf/__init__.py
index a1663c7..537dafc 100644
--- a/wkhtmltopdf/__init__.py
+++ b/wkhtmltopdf/__init__.py
@@ -3,4 +3,4 @@ if 'DJANGO_SETTINGS_MODULE' in os.environ:
from .utils import *
__author__ = 'Incuna Ltd'
-__version__ = '1.2.3'
+__version__ = '2.0.0'
diff --git a/wkhtmltopdf/test_settings.py b/wkhtmltopdf/test_settings.py
deleted file mode 100644
index 16fb734..0000000
--- a/wkhtmltopdf/test_settings.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import os
-
-DEBUG = True
-
-DIRNAME = os.path.abspath(os.path.dirname(__file__))
-
-SECRET_KEY = 'fooooooo'
-
-DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': ':memory:',
- }
-}
-
-MEDIA_ROOT = os.path.join(DIRNAME, 'media')
-MEDIA_URL = '/media/'
-STATIC_ROOT = os.path.join(DIRNAME, 'static')
-STATIC_URL = '/static/'
-
-INSTALLED_APPS = (
- 'wkhtmltopdf.tests',
- 'wkhtmltopdf',
-)
-
-TEMPLATE_DIRS = [
- os.path.join(DIRNAME, 'testproject', 'tests', 'templates'),
-]
-
-WKHTMLTOPDF_DEBUG = DEBUG
diff --git a/wkhtmltopdf/tests/run.py b/wkhtmltopdf/tests/run.py
new file mode 100644
index 0000000..a840e68
--- /dev/null
+++ b/wkhtmltopdf/tests/run.py
@@ -0,0 +1,38 @@
+#! /usr/bin/env python
+import os
+import sys
+
+from django.conf import settings
+
+DIRNAME = os.path.abspath(os.path.dirname(__file__))
+
+
+settings.configure(
+ DEBUG=True,
+ DATABASES={
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': ':memory:',
+ }
+ },
+ INSTALLED_APPS=(
+ 'wkhtmltopdf.tests',
+ 'wkhtmltopdf',
+ ),
+ MEDIA_ROOT=os.path.join(DIRNAME, 'media'),
+ MEDIA_URL='/media/',
+ STATIC_ROOT=os.path.join(DIRNAME, 'static'),
+ STATIC_URL='/static/',
+ WKHTMLTOPDF_DEBUG=True,
+)
+
+try:
+ from django.test.runner import DiscoverRunner
+except ImportError:
+ from discover_runner.runner import DiscoverRunner
+
+
+test_runner = DiscoverRunner(verbosity=1)
+failures = test_runner.run_tests(['wkhtmltopdf'])
+if failures:
+ sys.exit(1)
diff --git a/wkhtmltopdf/tests/test_requirements.txt b/wkhtmltopdf/tests/test_requirements.txt
deleted file mode 100644
index 3999bef..0000000
--- a/wkhtmltopdf/tests/test_requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-Django==1.4.2
diff --git a/wkhtmltopdf/tests/tests.py b/wkhtmltopdf/tests/tests.py
index b007687..7365d05 100644
--- a/wkhtmltopdf/tests/tests.py
+++ b/wkhtmltopdf/tests/tests.py
@@ -8,6 +8,8 @@ import sys
from django.conf import settings
from django.test import TestCase
from django.test.client import RequestFactory
+from django.utils import six
+from django.utils.encoding import smart_str
from wkhtmltopdf.subprocess import CalledProcessError
from wkhtmltopdf.utils import (_options_to_args, make_absolute_paths,
@@ -41,15 +43,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 +65,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 +82,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 +155,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 +181,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 +191,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)
+ title = '\0'.join(cmd_options['title'])
+ self.assertIn(six.b(title), pdf_content)
def test_pdf_template_response_to_browser(self):
self.test_pdf_template_response(show_content=True)
@@ -214,8 +216,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 +225,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 +256,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..e34085d 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.request import pathname2url
+ from urllib.parse import urljoin
+except ImportError: # Python2
+ from urllib import pathname2url
+ from urlparse 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..2f1945d 100644
--- a/wkhtmltopdf/views.py
+++ b/wkhtmltopdf/views.py
@@ -77,12 +77,18 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse):
content = smart_str(template.render(context))
content = make_absolute_paths(content)
- tempfile = NamedTemporaryFile(mode=mode, bufsize=bufsize,
- suffix=suffix, prefix=prefix,
- dir=dir, delete=delete)
+ try:
+ # Python3 has 'buffering' arg instead of 'bufsize'
+ tempfile = NamedTemporaryFile(mode=mode, buffering=bufsize,
+ suffix=suffix, prefix=prefix,
+ dir=dir, delete=delete)
+ except TypeError:
+ tempfile = NamedTemporaryFile(mode=mode, bufsize=bufsize,
+ suffix=suffix, prefix=prefix,
+ dir=dir, delete=delete)
try:
- tempfile.write(content)
+ tempfile.write(content.encode('utf-8'))
tempfile.flush()
return tempfile
except: