From f857631011e4ef0642647b44623ffc8bc138d2cc Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Fri, 27 Jan 2017 15:46:51 +0200 Subject: Make ContentNotFoundError optional --- wkhtmltopdf/process.py | 88 +++++++++++++++++++++++++++++++++++++++++++++++ wkhtmltopdf/subprocess.py | 44 ------------------------ wkhtmltopdf/utils.py | 2 +- 3 files changed, 89 insertions(+), 45 deletions(-) create mode 100644 wkhtmltopdf/process.py delete mode 100644 wkhtmltopdf/subprocess.py diff --git a/wkhtmltopdf/process.py b/wkhtmltopdf/process.py new file mode 100644 index 0000000..d36aacb --- /dev/null +++ b/wkhtmltopdf/process.py @@ -0,0 +1,88 @@ +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(['wkhtmltopdf', + ... '--quiet', + ... '--encoding', 'utf8', + ... os.getenv('WKHTML_IN'), os.getenv('WKHTML_OUT')], + ... ignore_404=True) + '' + + Calling check_output WITH the ignore_404 keyword should still + raise a CalledProcessError if the error != ContentNotFoundError + + >>> check_output(['wkhtmltopdf', #doctest: +ELLIPSIS + ... '--blaa', + ... '--encoding', 'utf8', + ... os.getenv('WKHTML_IN'), os.getenv('WKHTML_OUT')], + ... ignore_404=True) + Traceback (most recent call last): + ... + CalledProcessError... + """ + if 'stdout' in kwargs: + raise ValueError('stdout argument not allowed, it will be overridden.') + + ignore_404 = kwargs.pop('ignore_404', False) + + if not kwargs.get('stderr'): + kwargs['stderr'] = PIPE + + process = Popen(stdout=PIPE, *popenargs, **kwargs) + output, error_message = process.communicate() + retcode = process.poll() + + if retcode: + if 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() diff --git a/wkhtmltopdf/subprocess.py b/wkhtmltopdf/subprocess.py deleted file mode 100644 index d0abacd..0000000 --- a/wkhtmltopdf/subprocess.py +++ /dev/null @@ -1,44 +0,0 @@ -from __future__ import absolute_import - -from subprocess import * - - -# Provide Python 2.7's check_output() function. -try: - check_output -except NameError: - 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"]) - 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' - - 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' - """ - if 'stdout' in kwargs: - raise ValueError('stdout argument not allowed, it will be overridden.') - process = Popen(stdout=PIPE, *popenargs, **kwargs) - output, unused_err = process.communicate() - retcode = process.poll() - if retcode: - 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 diff --git a/wkhtmltopdf/utils.py b/wkhtmltopdf/utils.py index c871bd0..079d165 100644 --- a/wkhtmltopdf/utils.py +++ b/wkhtmltopdf/utils.py @@ -22,7 +22,7 @@ from django.conf import settings 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): -- cgit v1.2.3