diff options
Diffstat (limited to 'wkhtmltopdf')
-rw-r--r-- | wkhtmltopdf/__init__.py | 3 | ||||
-rw-r--r-- | wkhtmltopdf/_testproject/manage.py | 14 | ||||
-rw-r--r-- | wkhtmltopdf/_testproject/requirements.txt | 1 | ||||
-rw-r--r-- | wkhtmltopdf/_testproject/settings.py | 152 | ||||
-rw-r--r-- | wkhtmltopdf/_testproject/urls.py | 17 | ||||
-rw-r--r-- | wkhtmltopdf/test_settings.py | 16 | ||||
-rw-r--r-- | wkhtmltopdf/tests/__init__.py (renamed from wkhtmltopdf/_testproject/__init__.py) | 0 | ||||
-rw-r--r-- | wkhtmltopdf/tests/models.py | 0 | ||||
-rw-r--r-- | wkhtmltopdf/tests/templates/footer.html (renamed from wkhtmltopdf/_testproject/templates/footer.html) | 0 | ||||
-rw-r--r-- | wkhtmltopdf/tests/templates/sample.html (renamed from wkhtmltopdf/_testproject/templates/sample.html) | 0 | ||||
-rw-r--r-- | wkhtmltopdf/tests/tests.py (renamed from wkhtmltopdf/tests.py) | 66 | ||||
-rw-r--r-- | wkhtmltopdf/utils.py | 20 | ||||
-rw-r--r-- | wkhtmltopdf/views.py | 45 |
13 files changed, 39 insertions, 295 deletions
diff --git a/wkhtmltopdf/__init__.py b/wkhtmltopdf/__init__.py index 39b1413..7411417 100644 --- a/wkhtmltopdf/__init__.py +++ b/wkhtmltopdf/__init__.py @@ -3,5 +3,4 @@ if 'DJANGO_SETTINGS_MODULE' in os.environ: from .utils import * __author__ = 'Incuna Ltd' -__version__ = '0.3' - +__version__ = '1.0' diff --git a/wkhtmltopdf/_testproject/manage.py b/wkhtmltopdf/_testproject/manage.py deleted file mode 100644 index 3e4eedc..0000000 --- a/wkhtmltopdf/_testproject/manage.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python -from django.core.management import execute_manager -import imp -try: - imp.find_module('settings') # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__) - sys.exit(1) - -import settings - -if __name__ == "__main__": - execute_manager(settings) diff --git a/wkhtmltopdf/_testproject/requirements.txt b/wkhtmltopdf/_testproject/requirements.txt deleted file mode 100644 index 74c18fb..0000000 --- a/wkhtmltopdf/_testproject/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -Django==1.3.1 diff --git a/wkhtmltopdf/_testproject/settings.py b/wkhtmltopdf/_testproject/settings.py deleted file mode 100644 index 0454766..0000000 --- a/wkhtmltopdf/_testproject/settings.py +++ /dev/null @@ -1,152 +0,0 @@ -import os - -PROJECT_PATH = os.path.abspath(os.path.dirname(__file__)) - -# Django settings for testproject project. - -DEBUG = True -TEMPLATE_DEBUG = DEBUG - -ADMINS = ( - # ('Your Name', 'your_email@example.com'), -) - -MANAGERS = ADMINS - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': 'test.db', # Or path to database file if using sqlite3. - 'USER': '', # Not used with sqlite3. - 'PASSWORD': '', # Not used with sqlite3. - 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. - 'PORT': '', # Set to empty string for default. Not used with sqlite3. - } -} - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -# although not all choices may be available on all operating systems. -# On Unix systems, a value of None will cause Django to use the same -# timezone as the operating system. -# If running in a Windows environment this must be set to the same as your -# system time zone. -TIME_ZONE = 'America/Chicago' - -# Language code for this installation. All choices can be found here: -# http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = 'en-us' - -SITE_ID = 1 - -# If you set this to False, Django will make some optimizations so as not -# to load the internationalization machinery. -USE_I18N = True - -# If you set this to False, Django will not format dates, numbers and -# calendars according to the current locale -USE_L10N = True - -# Absolute filesystem path to the directory that will hold user-uploaded files. -# Example: "/home/media/media.lawrence.com/media/" -MEDIA_ROOT = '' - -# URL that handles the media served from MEDIA_ROOT. Make sure to use a -# trailing slash. -# Examples: "http://media.lawrence.com/media/", "http://example.com/media/" -MEDIA_URL = '' - -# Absolute path to the directory static files should be collected to. -# Don't put anything in this directory yourself; store your static files -# in apps' "static/" subdirectories and in STATICFILES_DIRS. -# Example: "/home/media/media.lawrence.com/static/" -STATIC_ROOT = '' - -# URL prefix for static files. -# Example: "http://media.lawrence.com/static/" -STATIC_URL = '/static/' - -# URL prefix for admin static files -- CSS, JavaScript and images. -# Make sure to use a trailing slash. -# Examples: "http://foo.com/static/admin/", "/static/admin/". -ADMIN_MEDIA_PREFIX = '/static/admin/' - -# Additional locations of static files -STATICFILES_DIRS = ( - # Put strings here, like "/home/html/static" or "C:/www/django/static". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. -) - -# List of finder classes that know how to find static files in -# various locations. -STATICFILES_FINDERS = ( - 'django.contrib.staticfiles.finders.FileSystemFinder', - 'django.contrib.staticfiles.finders.AppDirectoriesFinder', -# 'django.contrib.staticfiles.finders.DefaultStorageFinder', -) - -# Make this unique, and don't share it with anybody. -SECRET_KEY = '$)v)0$h)^c5!h2wms8*wn1c!7)7dp@qb87h7q)zecp2@$pnv=g' - -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', -# 'django.template.loaders.eggs.Loader', -) - -MIDDLEWARE_CLASSES = ( - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', -) - -ROOT_URLCONF = 'testproject.urls' - -TEMPLATE_DIRS = ( - os.path.join(PROJECT_PATH, 'templates') - # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. -) - -INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'django.contrib.messages', - 'django.contrib.staticfiles', - # Uncomment the next line to enable the admin: - # 'django.contrib.admin', - # Uncomment the next line to enable admin documentation: - # 'django.contrib.admindocs', - - 'wkhtmltopdf', -) - -# A sample logging configuration. The only tangible logging -# performed by this configuration is to send an email to -# the site admins on every HTTP 500 error. -# See http://docs.djangoproject.com/en/dev/topics/logging for -# more details on how to customize your logging configuration. -LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'handlers': { - 'mail_admins': { - 'level': 'ERROR', - 'class': 'django.utils.log.AdminEmailHandler' - } - }, - 'loggers': { - 'django.request': { - 'handlers': ['mail_admins'], - 'level': 'ERROR', - 'propagate': True, - }, - } -} diff --git a/wkhtmltopdf/_testproject/urls.py b/wkhtmltopdf/_testproject/urls.py deleted file mode 100644 index 039e61a..0000000 --- a/wkhtmltopdf/_testproject/urls.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.conf.urls.defaults import patterns, include, url - -# Uncomment the next two lines to enable the admin: -# from django.contrib import admin -# admin.autodiscover() - -urlpatterns = patterns('', - # Examples: - # url(r'^$', 'testproject.views.home', name='home'), - # url(r'^testproject/', include('testproject.foo.urls')), - - # Uncomment the admin/doc line below to enable admin documentation: - # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), - - # Uncomment the next line to enable the admin: - # url(r'^admin/', include(admin.site.urls)), -) diff --git a/wkhtmltopdf/test_settings.py b/wkhtmltopdf/test_settings.py new file mode 100644 index 0000000..37d086f --- /dev/null +++ b/wkhtmltopdf/test_settings.py @@ -0,0 +1,16 @@ +DEBUG = True + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': ':memory:', + } +} + +MEDIA_URL = '' +STATIC_URL = '' + +INSTALLED_APPS = ( + 'wkhtmltopdf.tests', + 'wkhtmltopdf', +) diff --git a/wkhtmltopdf/_testproject/__init__.py b/wkhtmltopdf/tests/__init__.py index e69de29..e69de29 100644 --- a/wkhtmltopdf/_testproject/__init__.py +++ b/wkhtmltopdf/tests/__init__.py diff --git a/wkhtmltopdf/tests/models.py b/wkhtmltopdf/tests/models.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/wkhtmltopdf/tests/models.py diff --git a/wkhtmltopdf/_testproject/templates/footer.html b/wkhtmltopdf/tests/templates/footer.html index 3ae09cb..3ae09cb 100644 --- a/wkhtmltopdf/_testproject/templates/footer.html +++ b/wkhtmltopdf/tests/templates/footer.html diff --git a/wkhtmltopdf/_testproject/templates/sample.html b/wkhtmltopdf/tests/templates/sample.html index 3dfbdbb..3dfbdbb 100644 --- a/wkhtmltopdf/_testproject/templates/sample.html +++ b/wkhtmltopdf/tests/templates/sample.html diff --git a/wkhtmltopdf/tests.py b/wkhtmltopdf/tests/tests.py index 3bdc481..6d8f3ac 100644 --- a/wkhtmltopdf/tests.py +++ b/wkhtmltopdf/tests/tests.py @@ -4,16 +4,13 @@ from __future__ import absolute_import import os import sys -import warnings from django.test import TestCase from django.test.client import RequestFactory -from .subprocess import CalledProcessError -from .utils import (override_settings, - _options_to_args, template_to_temp_file, wkhtmltopdf) -from .views import (PDFResponse, PdfResponse, PDFTemplateResponse, - PDFTemplateView, PdfTemplateView) +from wkhtmltopdf.subprocess import CalledProcessError +from wkhtmltopdf.utils import override_settings, _options_to_args, wkhtmltopdf +from wkhtmltopdf.views import PDFResponse, PDFTemplateView, PDFTemplateResponse class TestUtils(TestCase): @@ -21,6 +18,7 @@ class TestUtils(TestCase): # Clear standard error self._stderr = sys.stderr sys.stderr = open(os.devnull, 'w') + self.factory = RequestFactory() def tearDown(self): sys.stderr = self._stderr @@ -36,39 +34,36 @@ class TestUtils(TestCase): def test_wkhtmltopdf(self): """Should run wkhtmltopdf to generate a PDF""" title = 'A test template.' - temp_file = template_to_temp_file('sample.html', {'title': title}) - pdf_output = None + response = PDFTemplateResponse(self.factory.get('/'), None, context={'title': title}) + temp_file = response.render_to_temporary_file('sample.html') try: # Standard call - pdf_output = wkhtmltopdf(pages=[temp_file]) + pdf_output = wkhtmltopdf(pages=[temp_file.name]) self.assertTrue(pdf_output.startswith('%PDF'), pdf_output) # Single page - pdf_output = wkhtmltopdf(pages=temp_file) + pdf_output = wkhtmltopdf(pages=temp_file.name) self.assertTrue(pdf_output.startswith('%PDF'), pdf_output) # Unicode - pdf_output = wkhtmltopdf(pages=[temp_file], title=u'♥') + pdf_output = wkhtmltopdf(pages=[temp_file.name], title=u'♥') self.assertTrue(pdf_output.startswith('%PDF'), pdf_output) # Invalid arguments self.assertRaises(CalledProcessError, wkhtmltopdf, pages=[]) finally: - if os.path.exists(temp_file): - os.remove(temp_file) + temp_file.close() - def test_template_to_temp_file(self): + def test_PDFTemplateResponse_render_to_temporary_file(self): """Should render a template to a temporary file.""" title = 'A test template.' - temp_file = template_to_temp_file('sample.html', {'title': title}) - try: - with open(temp_file, 'r') as f: - saved_content = f.read() - self.assertTrue(title in saved_content) - finally: - if os.path.exists(temp_file): - os.remove(temp_file) + 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() + self.assertTrue(title in saved_content) + temp_file.close() class TestViews(TestCase): @@ -275,30 +270,3 @@ class TestViews(TestCase): 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: - warnings.simplefilter('always') - PdfTemplateView() - self.assertEqual(len(w), 1) - self.assertEqual(w[0].category, PendingDeprecationWarning) - self.assertTrue( - 'PDFTemplateView' in str(w[0].message), - "'PDFTemplateView' not in {0!r}".format(w[0].message)) - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - PdfResponse(None, None) - self.assertEqual(len(w), 1) - self.assertEqual(w[0].category, PendingDeprecationWarning) - self.assertTrue( - 'PDFResponse' in str(w[0].message), - "'PDFResponse' not in {0!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 {0!r}".format(w[0].message)) diff --git a/wkhtmltopdf/utils.py b/wkhtmltopdf/utils.py index 29e4ef6..99998a2 100644 --- a/wkhtmltopdf/utils.py +++ b/wkhtmltopdf/utils.py @@ -1,23 +1,19 @@ from __future__ import absolute_import from copy import copy +from functools import wraps from itertools import chain -from os import fdopen import os import sys -from tempfile import mkstemp import urllib -import warnings from django.conf import settings -from django.template import loader -from django.utils.encoding import smart_str from .subprocess import check_output def _options_to_args(**options): - """Converts ``options`` into a string of command-line arguments.""" + """Converts ``options`` into a list of command-line arguments.""" flags = [] for name in sorted(options): value = options[name] @@ -87,18 +83,6 @@ def wkhtmltopdf(pages, output=None, **kwargs): return check_output(args, stderr=sys.stderr, env=env) -def template_to_temp_file(template_name, dictionary=None, context_instance=None): - """ - Renders a template to a temp file, and returns the path of the file. - """ - warnings.warn('template_to_temp_file is deprecated in favour of PDFResponse. It will be removed in version 1.', - PendingDeprecationWarning, 2) - file_descriptor, tempfile_path = mkstemp(suffix='.html') - with fdopen(file_descriptor, 'wt') as f: - f.write(smart_str(loader.render_to_string(template_name, dictionary=dictionary, context_instance=context_instance))) - return tempfile_path - - def content_disposition_filename(filename): """ Sanitize a file name to be used in the Content-Disposition HTTP diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py index 741742f..210ff0a 100644 --- a/wkhtmltopdf/views.py +++ b/wkhtmltopdf/views.py @@ -1,8 +1,7 @@ from __future__ import absolute_import -from re import compile from tempfile import NamedTemporaryFile -import warnings +import re from django.conf import settings from django.http import HttpResponse @@ -39,13 +38,6 @@ class PDFResponse(HttpResponse): del self['Content-Disposition'] -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=filename) - - class PDFTemplateResponse(TemplateResponse, PDFResponse): """Renders a Template into a PDF using wkhtmltopdf""" @@ -75,7 +67,7 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): self.override_settings = override_settings def render_to_temporary_file(self, template_name, mode='w+b', bufsize=-1, - suffix='', prefix='tmp', dir=None, + suffix='.html', prefix='tmp', dir=None, delete=True): template = self.resolve_template(template_name) @@ -169,7 +161,7 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): if self.override_settings is not None: overrides.update(self.override_settings) - has_scheme = compile(r'^[^:/]+://') + has_scheme = re.compile(r'^[^:/]+://') # If MEDIA_URL doesn't have a scheme, we transform it into a # file:// URL based on MEDIA_ROOT. @@ -230,11 +222,6 @@ class PDFTemplateView(TemplateView): def get_cmd_options(self): return self.cmd_options - def get_pdf_kwargs(self): - 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 render_to_response(self, context, **response_kwargs): """ Returns a PDF response with a template rendered with the given context. @@ -262,29 +249,3 @@ class PDFTemplateView(TemplateView): context=context, **response_kwargs ) - - -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 |