Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added option to ignore ContentNotFoundError #128

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions wkhtmltopdf/process.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import os
from subprocess import Popen, PIPE, STDOUT, CalledProcessError


def check_output(*popenargs, **kwargs):
r"""Run command with arguments and return its output as a byte string.

If the exit code was non-zero it raises a CalledProcessError. The
CalledProcessError object will have the return code in the returncode
attribute and output in the output attribute.

The arguments are the same as for the Popen constructor. Example:

>>> check_output(["ls", "-l", "/dev/null"]) #doctest: +ELLIPSIS
'crw-rw-rw- 1 root wheel 3...

The stdout argument is not allowed as it is used internally.
To capture standard error in the result, use stderr=STDOUT.

>>> check_output(["/bin/sh", "-c",
... "ls -l non_existent_file ; exit 0"],
... stderr=STDOUT)
'ls: non_existent_file: No such file or directory\n'

Calling check_output without the ignore_404 keyword argument
will raise a CalledProcessError if wkhtmltopdf exits with a non-zero code

>>> check_output(['wkhtmltopdf', #doctest: +ELLIPSIS
... '--quiet',
... '--encoding', 'utf8',
... os.getenv('WKHTML_IN'), os.getenv('WKHTML_OUT')])
Traceback (most recent call last):
...
CalledProcessError...

Calling check_output WITH the ignore_404 keyword will not raise
the CalledProcessError, but only if the error == ContentNotFoundError

>>> check_output(['/usr/local/bin/wkhtmltopdf',
... '--quiet',
... '--encoding', 'utf8',
... os.getenv('WKHTML_IN'), os.getenv('WKHTML_OUT')],
... env={'ignore_404': True})
''

Calling check_output WITH the ignore_404 keyword should still
raise a CalledProcessError if the error != ContentNotFoundError

>>> check_output(['/usr/local/bin/wkhtmltopdf', #doctest: +ELLIPSIS
... '--blaa',
... '--encoding', 'utf8',
... os.getenv('WKHTML_IN'), os.getenv('WKHTML_OUT')],
... env={'ignore_404': True})
Traceback (most recent call last):
...
CalledProcessError...
"""
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')

if kwargs.get('env'):
ignore_404 = kwargs['env'].pop('ignore_404', False)
else:
ignore_404 = False

kwargs.setdefault('stderr', PIPE)
process = Popen(stdout=PIPE, *popenargs, **kwargs)
output, error_message = process.communicate()
retcode = process.poll()

if retcode:
if error_message and ignore_404:
if 'ContentNotFoundError' in error_message:
return output
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
error = CalledProcessError(retcode, cmd)
# Add the output attribute to CalledProcessError, which
# doesn't exist until Python 2.7.
error.output = output
raise error

return output


if __name__ == "__main__":
import doctest
doctest.testmod()
44 changes: 0 additions & 44 deletions wkhtmltopdf/subprocess.py

This file was deleted.

2 changes: 1 addition & 1 deletion wkhtmltopdf/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from django.utils import six
from django.utils.encoding import smart_str

from wkhtmltopdf.subprocess import CalledProcessError
from wkhtmltopdf.process import CalledProcessError
from wkhtmltopdf.utils import (_options_to_args, make_absolute_paths,
wkhtmltopdf, render_to_temporary_file,
RenderedFile)
Expand Down
9 changes: 1 addition & 8 deletions wkhtmltopdf/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from django.template.context import Context, RequestContext
from django.utils import six

from .subprocess import check_output
from .process import check_output


def _options_to_args(**options):
Expand Down Expand Up @@ -99,13 +99,6 @@ def wkhtmltopdf(pages, output=None, **kwargs):
list(pages),
[output]))
ck_kwargs = {'env': env}
# Handling of fileno() attr. based on https://github.com/GrahamDumpleton/mod_wsgi/issues/85
try:
i = sys.stderr.fileno()
ck_kwargs['stderr'] = sys.stderr
except (AttributeError, IOError):
# can't call fileno() on mod_wsgi stderr object
pass

return check_output(ck_args, **ck_kwargs)

Expand Down