diff options
Diffstat (limited to 'wkhtmltopdf')
-rw-r--r-- | wkhtmltopdf/utils.py | 52 | ||||
-rw-r--r-- | wkhtmltopdf/views.py | 67 |
2 files changed, 32 insertions, 87 deletions
diff --git a/wkhtmltopdf/utils.py b/wkhtmltopdf/utils.py index 8e0caef..0111736 100644 --- a/wkhtmltopdf/utils.py +++ b/wkhtmltopdf/utils.py @@ -120,55 +120,3 @@ def http_quote(string): def pathname2fileurl(pathname): """Returns a file:// URL for pathname. Handles OS-specific conversions.""" return 'file://' + urllib.pathname2url(pathname) - - -try: - # From Django 1.4 - from django.conf import override_settings -except ImportError: - class override_settings(object): - """ - Acts as either a decorator, or a context manager. If it's a decorator it - takes a function and returns a wrapped function. If it's a contextmanager - it's used with the ``with`` statement. In either event entering/exiting - are called before and after, respectively, the function/block is executed. - """ - def __init__(self, **kwargs): - self.options = kwargs - self.wrapped = settings._wrapped - - def __enter__(self): - self.enable() - - def __exit__(self, exc_type, exc_value, traceback): - self.disable() - - def __call__(self, test_func): - from django.test import TransactionTestCase - if isinstance(test_func, type) and issubclass(test_func, TransactionTestCase): - original_pre_setup = test_func._pre_setup - original_post_teardown = test_func._post_teardown - def _pre_setup(innerself): - self.enable() - original_pre_setup(innerself) - def _post_teardown(innerself): - original_post_teardown(innerself) - self.disable() - test_func._pre_setup = _pre_setup - test_func._post_teardown = _post_teardown - return test_func - else: - @wraps(test_func) - def inner(*args, **kwargs): - with self: - return test_func(*args, **kwargs) - return inner - - def enable(self): - override = copy(settings._wrapped) - for key, new_value in self.options.items(): - setattr(override, key, new_value) - settings._wrapped = override - - def disable(self): - settings._wrapped = self.wrapped diff --git a/wkhtmltopdf/views.py b/wkhtmltopdf/views.py index 210ff0a..4d0ccca 100644 --- a/wkhtmltopdf/views.py +++ b/wkhtmltopdf/views.py @@ -9,8 +9,7 @@ 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, override_settings, - pathname2fileurl, wkhtmltopdf) +from .utils import content_disposition_filename, pathname2fileurl, wkhtmltopdf class PDFResponse(HttpResponse): @@ -64,26 +63,20 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): cmd_options = {} self.cmd_options = cmd_options - self.override_settings = override_settings - def render_to_temporary_file(self, template_name, mode='w+b', bufsize=-1, suffix='.html', prefix='tmp', dir=None, delete=True): template = self.resolve_template(template_name) - # Since many things require a sensible settings.MEDIA_URL and - # settings.STATIC_URL, including TEMPLATE_CONTEXT_PROCESSORS; - # the settings themselves need to be overridden when rendering. - # - # This allows django-wkhtmltopdf to play nicely with the - # staticfiles app, for instance. - with override_settings(**self.get_override_settings()): - context = self.resolve_context(self.context_data) - content = smart_str(template.render(context)) + context = self.resolve_context(self.context_data) + content = smart_str(template.render(context)) + + content = self.make_absolute_paths(content) tempfile = NamedTemporaryFile(mode=mode, bufsize=bufsize, suffix=suffix, prefix=prefix, dir=dir, delete=delete) + try: tempfile.write(content) tempfile.flush() @@ -150,30 +143,35 @@ class PDFTemplateResponse(TemplateResponse, PDFResponse): for f in filter(None, (input_file, header_file, footer_file)): f.close() - def get_override_settings(self): - """Returns a dictionary of settings to override for response_class""" - overrides = { - 'MEDIA_ROOT': settings.MEDIA_ROOT, - 'MEDIA_URL': settings.MEDIA_URL, - 'STATIC_ROOT': settings.STATIC_ROOT, - 'STATIC_URL': settings.STATIC_URL, - } - if self.override_settings is not None: - overrides.update(self.override_settings) + def make_absolute_paths(self, content): + """Convert all MEDIA files into a file://URL paths in order to correctly get it displayed in PDFs + mattl's disclaimer: I know it sucks, but it works and I haz no time for better solution now + """ + + overrides = [ + { + 'root': settings.MEDIA_ROOT, + 'url': settings.MEDIA_URL, + }, + { + 'root': settings.STATIC_ROOT, + 'url': settings.STATIC_URL, + } + ] has_scheme = re.compile(r'^[^:/]+://') - # If MEDIA_URL doesn't have a scheme, we transform it into a - # file:// URL based on MEDIA_ROOT. - urls = [('MEDIA_URL', 'MEDIA_ROOT'), - ('STATIC_URL', 'STATIC_ROOT')] - for url, root in urls: - if not has_scheme.match(overrides[url]): - overrides[url] = pathname2fileurl(overrides[root]) - if not overrides[url].endswith('/'): - overrides[url] += '/' + for x in overrides: + if has_scheme.match(x['url']): + continue + + if not x['root'].endswith('/'): + x['root'] += '/' + + for occur in re.findall('''["|']({0}.*?)["|']'''.format(x['url']), content): + content = content.replace(occur, pathname2fileurl(x['root']) + occur[len(x['url']):]) - return overrides + return content class PDFTemplateView(TemplateView): @@ -228,7 +226,6 @@ class PDFTemplateView(TemplateView): """ filename = response_kwargs.pop('filename', None) cmd_options = response_kwargs.pop('cmd_options', None) - override_settings = response_kwargs.pop('override_settings', None) if issubclass(self.response_class, PDFTemplateResponse): if filename is None: @@ -241,7 +238,7 @@ class PDFTemplateView(TemplateView): context=context, filename=filename, header_template=self.header_template, footer_template=self.footer_template, - cmd_options=cmd_options, override_settings=override_settings, + cmd_options=cmd_options, **response_kwargs ) else: |