From bac0816fa90b8eab949453a5abf34db2e6d4883c Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Thu, 4 May 2017 00:06:00 -0700 Subject: [PATCH 01/68] only treat stderr as text after getting non-zero exit code, otherwise it should be pdf binary data --- pdfkit/pdfkit.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index dc56174..65c457f 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -140,23 +140,25 @@ def to_pdf(self, path=None): input = None stdout, stderr = result.communicate(input=input) stderr = stderr or stdout - try: - stderr = stderr.decode('utf-8') - except UnicodeDecodeError: - stderr = '' + exit_code = result.returncode + if exit_code != 0: + try: + stderr = stderr.decode('utf-8') + except UnicodeDecodeError: + stderr = '' - if 'cannot connect to X server' in stderr: - raise IOError('%s\n' - 'You will need to run wkhtmltopdf within a "virtual" X server.\n' - 'Go to the link below for more information\n' - 'https://github.com/JazzCore/python-pdfkit/wiki/Using-wkhtmltopdf-without-X-server' % stderr) + if 'cannot connect to X server' in stderr: + raise IOError('%s\n' + 'You will need to run wkhtmltopdf within a "virtual" X server.\n' + 'Go to the link below for more information\n' + 'https://github.com/JazzCore/python-pdfkit/wiki/Using-wkhtmltopdf-without-X-server' % stderr) - if 'Error' in stderr: - raise IOError('wkhtmltopdf reported an error:\n' + stderr) + if 'Error' in stderr: + raise IOError('wkhtmltopdf reported an error:\n' + stderr) - if exit_code != 0: - raise IOError("wkhtmltopdf exited with non-zero code {0}. error:\n{1}".format(exit_code, stderr)) + error_msg = stderr or 'Unknown Error' + raise IOError("wkhtmltopdf exited with non-zero code {0}. error:\n{1}".format(exit_code, error_msg)) # Since wkhtmltopdf sends its output to stderr we will capture it # and properly send to stdout From d667a337428c61144bd85cfdf92926d717c3b6c8 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Thu, 4 May 2017 00:08:27 -0700 Subject: [PATCH 02/68] decode stderr before writing to stdout --- pdfkit/pdfkit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 65c457f..1d0aada 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -163,7 +163,7 @@ def to_pdf(self, path=None): # Since wkhtmltopdf sends its output to stderr we will capture it # and properly send to stdout if '--quiet' not in args: - sys.stdout.write(stderr) + sys.stdout.write(stderr.decode('utf-8')) if not path: return stdout From 438b9b7abcb2045df2b5dc71e6e0a9f5601c7253 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Thu, 4 May 2017 00:19:08 -0700 Subject: [PATCH 03/68] catch OSError in case output file does not exist --- pdfkit/pdfkit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 1d0aada..9aec4f4 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -177,7 +177,7 @@ def to_pdf(self, path=None): 'Check whhtmltopdf output without \'quiet\' ' 'option' % ' '.join(args)) return True - except IOError as e: + except (IOError, OSError) as e: raise IOError('Command failed: %s\n' 'Check whhtmltopdf output without \'quiet\' option\n' '%s ' %(' '.join(args)),e) From 736b697a77b03a971b367855302aaef617fa3a6c Mon Sep 17 00:00:00 2001 From: NestorTejero Date: Mon, 19 Jun 2017 14:57:39 +0200 Subject: [PATCH 04/68] Correct placing of arguments for IOError message --- pdfkit/pdfkit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 9aec4f4..a4cf7e7 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -180,7 +180,7 @@ def to_pdf(self, path=None): except (IOError, OSError) as e: raise IOError('Command failed: %s\n' 'Check whhtmltopdf output without \'quiet\' option\n' - '%s ' %(' '.join(args)),e) + '%s ' % (' '.join(args), e)) def _normalize_options(self, options): """ Generator of 2-tuples (option-key, option-value). From 810d3d86e954215e963ec5304be36032542dda65 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Fri, 1 Sep 2017 10:18:09 +0100 Subject: [PATCH 05/68] correct spelling mistake --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 65cb8b5..cc0e28e 100644 --- a/README.rst +++ b/README.rst @@ -90,7 +90,7 @@ You can specify all wkhtmltopdf `options Date: Fri, 15 Sep 2017 19:00:39 +0200 Subject: [PATCH 06/68] assertRegexpMatches deprecated ../tests/pdfkit-tests.py:408: DeprecationWarning: Please use assertRegex instead. --- tests/pdfkit-tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pdfkit-tests.py b/tests/pdfkit-tests.py index 66e9f8e..fe6e30f 100644 --- a/tests/pdfkit-tests.py +++ b/tests/pdfkit-tests.py @@ -402,7 +402,7 @@ def test_raise_error_if_bad_wkhtmltopdf_option(self): r.to_pdf() raised_exception = cm.exception - self.assertRegexpMatches(str(raised_exception), '^wkhtmltopdf exited with non-zero code 1. error:\nUnknown long argument --bad-option\r?\n') + self.assertRegex(str(raised_exception), '^wkhtmltopdf exited with non-zero code 1. error:\nUnknown long argument --bad-option\r?\n') if __name__ == "__main__": unittest.main() From 397ed72ef540a38be55dc431ede6f0c9b130c7d0 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Fri, 29 Dec 2017 10:35:50 -0800 Subject: [PATCH 07/68] fix wkhtml2pdf install on travis --- travis/before-script.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/travis/before-script.sh b/travis/before-script.sh index 026db37..984d40a 100755 --- a/travis/before-script.sh +++ b/travis/before-script.sh @@ -1,8 +1,10 @@ -#!/bin/sh +#!/usr/bin/env sh + +WKHTML2PDF_VERSION='0.12.4' sudo apt-get install -y openssl build-essential xorg libssl-dev -wget http://download.gna.org/wkhtmltopdf/0.12/0.12.3/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz -tar -xJf wkhtmltox-0.12.3_linux-generic-amd64.tar.xz +wget "https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/${WKHTML2PDF_VERSION}/wkhtmltox-${WKHTML2PDF_VERSION}_linux-generic-amd64.tar.xz" +tar -xJf "wkhtmltox-${WKHTML2PDF_VERSION}_linux-generic-amd64.tar.xz" cd wkhtmltox sudo chown root:root bin/wkhtmltopdf sudo cp -r * /usr/ From 6f1077dbae22863390915b6f69c8ec77f7c4a83f Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Fri, 29 Dec 2017 10:43:23 -0800 Subject: [PATCH 08/68] patch unittest.TestCase.assertRegex for py27 --- tests/pdfkit-tests.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/pdfkit-tests.py b/tests/pdfkit-tests.py index fe6e30f..78fc329 100644 --- a/tests/pdfkit-tests.py +++ b/tests/pdfkit-tests.py @@ -6,6 +6,10 @@ import unittest +if sys.version_info[0] == 2 and sys.version_info[1] == 7: + unittest.TestCase.assertRegex = unittest.TestCase.assertRegexpMatches + + #Prepend ../ to PYTHONPATH so that we can import PDFKIT form there. TESTS_ROOT = os.path.abspath(os.path.dirname(__file__)) sys.path.insert(0, os.path.realpath(os.path.join(TESTS_ROOT, '..'))) @@ -80,9 +84,9 @@ def test_options_parsing_with_tuple_no_dashes(self): def test_repeatable_options(self): roptions = { '--page-size': 'Letter', - 'cookies': [ + 'cookies': [ ('test_cookie1','cookie_value1'), - ('test_cookie2','cookie_value2'), + ('test_cookie2','cookie_value2'), ] } From de4c38f4f2457afe72956fc8dcfe1321143c5c3d Mon Sep 17 00:00:00 2001 From: fbataill Date: Thu, 11 Jan 2018 22:51:00 +0100 Subject: [PATCH 09/68] Update Readme for python3 I had to search on internet to understand why I was not able to import pdfkit in python3. I just did not know that I had to use pip3 instead of pip. Indicating this here could same hours of search or premature abandon :) --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index cc0e28e..da7fbe6 100644 --- a/README.rst +++ b/README.rst @@ -19,7 +19,7 @@ Installation .. code-block:: bash - $ pip install pdfkit + $ pip install pdfkit (or pip3 for python3) 2. Install wkhtmltopdf: From 5b81171fd4e84ce6de56fdb2066fbfeb99e5ce58 Mon Sep 17 00:00:00 2001 From: Mathieu Zonzon Date: Tue, 6 Feb 2018 14:20:48 +0100 Subject: [PATCH 10/68] pdfkit/pdfkit: Keeping the options order for python < 3.6 Options mixup may result in wkhtmltopdf failing example: OSError: wkhtmltopdf exited with non-zero code 1. error: --margin-bottom specified in incorrect location --- pdfkit/pdfkit.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index a4cf7e7..fc01793 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -2,6 +2,7 @@ import re import subprocess import sys +from collections import OrderedDict from .source import Source from .configuration import Configuration import io @@ -46,7 +47,7 @@ def __init__(self, url_or_file, type_, options=None, toc=None, cover=None, except AttributeError: self.wkhtmltopdf = self.configuration.wkhtmltopdf - self.options = dict() + self.options = OrderedDict() if self.source.isString(): self.options.update(self._find_options_in_meta(url_or_file)) From 5f2d3714bc49959102e06bc474602ce5532dff29 Mon Sep 17 00:00:00 2001 From: Mathieu Zonzon Date: Wed, 7 Feb 2018 17:59:20 +0100 Subject: [PATCH 11/68] pdfkit/pdfkit: Improved stdout/stderr decoding (errors handling) --- pdfkit/pdfkit.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index fc01793..7e59373 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -144,10 +144,7 @@ def to_pdf(self, path=None): exit_code = result.returncode if exit_code != 0: - try: - stderr = stderr.decode('utf-8') - except UnicodeDecodeError: - stderr = '' + stderr = stderr.decode('utf-8', errors='replace') if 'cannot connect to X server' in stderr: raise IOError('%s\n' @@ -164,7 +161,7 @@ def to_pdf(self, path=None): # Since wkhtmltopdf sends its output to stderr we will capture it # and properly send to stdout if '--quiet' not in args: - sys.stdout.write(stderr.decode('utf-8')) + sys.stdout.write(stderr.decode('utf-8', errors='replace')) if not path: return stdout From 1b58db090885b8269cc68f45597aab49ba89b043 Mon Sep 17 00:00:00 2001 From: Martin Rehr Date: Thu, 22 Mar 2018 08:28:50 +0100 Subject: [PATCH 12/68] Support for passing custom OS environment to Popen --- pdfkit/configuration.py | 12 +++++++++++- pdfkit/pdfkit.py | 6 ++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/pdfkit/configuration.py b/pdfkit/configuration.py index 95228f3..b086995 100644 --- a/pdfkit/configuration.py +++ b/pdfkit/configuration.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- +import os import subprocess import sys class Configuration(object): - def __init__(self, wkhtmltopdf='', meta_tag_prefix='pdfkit-'): + def __init__(self, wkhtmltopdf='', meta_tag_prefix='pdfkit-', environ=''): self.meta_tag_prefix = meta_tag_prefix self.wkhtmltopdf = wkhtmltopdf @@ -25,3 +26,12 @@ def __init__(self, wkhtmltopdf='', meta_tag_prefix='pdfkit-'): 'If this file exists please check that this process can ' 'read it. Otherwise please install wkhtmltopdf - ' 'https://github.com/JazzCore/python-pdfkit/wiki/Installing-wkhtmltopdf' % self.wkhtmltopdf) + + self.environ = environ + + if not self.environ: + self.environ = os.environ + + for key in self.environ.keys(): + if not isinstance(self.environ[key], str): + self.environ[key] = str(self.environ[key]) \ No newline at end of file diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 7e59373..6de7f5e 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -51,6 +51,8 @@ def __init__(self, url_or_file, type_, options=None, toc=None, cover=None, if self.source.isString(): self.options.update(self._find_options_in_meta(url_or_file)) + self.environ = self.configuration.environ + if options is not None: self.options.update(options) self.toc = {} if toc is None else toc @@ -125,9 +127,9 @@ def command(self, path=None): def to_pdf(self, path=None): args = self.command(path) - + result = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stderr=subprocess.PIPE, env=self.environ) # If the source is a string then we will pipe it into wkhtmltopdf. # If we want to add custom CSS to file then we read input file to From 86fd2e88ccc517f65da924cfc35e9ea1e00a8f3c Mon Sep 17 00:00:00 2001 From: Martin Joly Date: Fri, 30 Mar 2018 10:06:19 +0200 Subject: [PATCH 13/68] Added wkhtmltopdf installation command for macOS --- README.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.rst b/README.rst index cc0e28e..db0d19a 100644 --- a/README.rst +++ b/README.rst @@ -28,6 +28,12 @@ Installation .. code-block:: bash $ sudo apt-get install wkhtmltopdf + +* macOS: + +.. code-block:: bash + + $ brew install caskroom/cask/wkhtmltopdf **Warning!** Version in debian/ubuntu repos have reduced functionality (because it compiled without the wkhtmltopdf QT patches), such as adding outlines, headers, footers, TOC etc. To use this options you should install static binary from `wkhtmltopdf `_ site or you can use `this script `_. From 479d65646ab422bc095ed1c72d05f46dc834c83b Mon Sep 17 00:00:00 2001 From: Michael Kim Date: Sat, 4 Aug 2018 16:09:28 -0700 Subject: [PATCH 14/68] [CLEANUP] reformat code --- pdfkit/pdfkit.py | 54 ++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 6de7f5e..8153b3d 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -127,9 +127,14 @@ def command(self, path=None): def to_pdf(self, path=None): args = self.command(path) - - result = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, env=self.environ) + + result = subprocess.Popen( + args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=self.environ + ) # If the source is a string then we will pipe it into wkhtmltopdf. # If we want to add custom CSS to file then we read input file to @@ -141,18 +146,18 @@ def to_pdf(self, path=None): input = self.source.source.read().encode('utf-8') else: input = None + stdout, stderr = result.communicate(input=input) stderr = stderr or stdout - + stderr = stderr.decode('utf-8', errors='replace') exit_code = result.returncode - if exit_code != 0: - stderr = stderr.decode('utf-8', errors='replace') + if exit_code != 0: if 'cannot connect to X server' in stderr: raise IOError('%s\n' - 'You will need to run wkhtmltopdf within a "virtual" X server.\n' - 'Go to the link below for more information\n' - 'https://github.com/JazzCore/python-pdfkit/wiki/Using-wkhtmltopdf-without-X-server' % stderr) + 'You will need to run wkhtmltopdf within a "virtual" X server.\n' + 'Go to the link below for more information\n' + 'https://github.com/JazzCore/python-pdfkit/wiki/Using-wkhtmltopdf-without-X-server' % stderr) if 'Error' in stderr: raise IOError('wkhtmltopdf reported an error:\n' + stderr) @@ -163,24 +168,24 @@ def to_pdf(self, path=None): # Since wkhtmltopdf sends its output to stderr we will capture it # and properly send to stdout if '--quiet' not in args: - sys.stdout.write(stderr.decode('utf-8', errors='replace')) + sys.stdout.write(stderr) if not path: return stdout - else: - try: - with codecs.open(path, encoding='utf-8') as f: - # read 4 bytes to get PDF signature '%PDF' - text = f.read(4) - if text == '': - raise IOError('Command failed: %s\n' - 'Check whhtmltopdf output without \'quiet\' ' - 'option' % ' '.join(args)) - return True - except (IOError, OSError) as e: - raise IOError('Command failed: %s\n' - 'Check whhtmltopdf output without \'quiet\' option\n' - '%s ' % (' '.join(args), e)) + + try: + with codecs.open(path, encoding='utf-8') as f: + # read 4 bytes to get PDF signature '%PDF' + text = f.read(4) + if text == '': + raise IOError('Command failed: %s\n' + 'Check whhtmltopdf output without \'quiet\' ' + 'option' % ' '.join(args)) + return True + except (IOError, OSError) as e: + raise IOError('Command failed: %s\n' + 'Check whhtmltopdf output without \'quiet\' option\n' + '%s ' % (' '.join(args), e)) def _normalize_options(self, options): """ Generator of 2-tuples (option-key, option-value). @@ -206,7 +211,6 @@ def _normalize_options(self, options): else: yield (normalized_key, str(value) if value else value) - def _normalize_arg(self, arg): return arg.lower() From ba42969e4e9456498cab7a589245ad6720e1cbd5 Mon Sep 17 00:00:00 2001 From: Michael Kim Date: Sat, 4 Aug 2018 16:10:48 -0700 Subject: [PATCH 15/68] handle_error method --- pdfkit/pdfkit.py | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 8153b3d..178a13a 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -125,6 +125,23 @@ def _command(self, path=None): def command(self, path=None): return list(self._command(path)) + @staticmethod + def handle_error(exit_code, stderr): + if exit_code == 0: + return + + if 'cannot connect to X server' in stderr: + raise IOError('%s\n' + 'You will need to run wkhtmltopdf within a "virtual" X server.\n' + 'Go to the link below for more information\n' + 'https://github.com/JazzCore/python-pdfkit/wiki/Using-wkhtmltopdf-without-X-server' % stderr) + + if 'Error' in stderr: + raise IOError('wkhtmltopdf reported an error:\n' + stderr) + + error_msg = stderr or 'Unknown Error' + raise IOError("wkhtmltopdf exited with non-zero code {0}. error:\n{1}".format(exit_code, error_msg)) + def to_pdf(self, path=None): args = self.command(path) @@ -151,19 +168,7 @@ def to_pdf(self, path=None): stderr = stderr or stdout stderr = stderr.decode('utf-8', errors='replace') exit_code = result.returncode - - if exit_code != 0: - if 'cannot connect to X server' in stderr: - raise IOError('%s\n' - 'You will need to run wkhtmltopdf within a "virtual" X server.\n' - 'Go to the link below for more information\n' - 'https://github.com/JazzCore/python-pdfkit/wiki/Using-wkhtmltopdf-without-X-server' % stderr) - - if 'Error' in stderr: - raise IOError('wkhtmltopdf reported an error:\n' + stderr) - - error_msg = stderr or 'Unknown Error' - raise IOError("wkhtmltopdf exited with non-zero code {0}. error:\n{1}".format(exit_code, error_msg)) + self.handle_error(exit_code, stderr) # Since wkhtmltopdf sends its output to stderr we will capture it # and properly send to stdout From 440596e0772c57fc9ea0d11411c5550959fda6de Mon Sep 17 00:00:00 2001 From: Michael Kim Date: Sat, 4 Aug 2018 16:17:25 -0700 Subject: [PATCH 16/68] [FIX] look for 'Done' in stderr Sometimes wkhtmltopdf will exit with non-zero even if the generation is successful. --- pdfkit/pdfkit.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 178a13a..7613b1d 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -130,6 +130,12 @@ def handle_error(exit_code, stderr): if exit_code == 0: return + # Sometimes wkhtmltopdf will exit with non-zero + # even if it finishes generation. + # If will display 'Done' in the second last line + if stderr.splitlines()[-2].strip() == 'Done': + return + if 'cannot connect to X server' in stderr: raise IOError('%s\n' 'You will need to run wkhtmltopdf within a "virtual" X server.\n' From 2b9a87c03ca96a456a506392dc72f493d5416337 Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Tue, 28 Aug 2018 05:00:35 -0400 Subject: [PATCH 17/68] Allow creation of pdfs containing unicode characters --- pdfkit/pdfkit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 6de7f5e..6f137dc 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -204,7 +204,7 @@ def _normalize_options(self, options): for optval in value: yield (normalized_key, optval) else: - yield (normalized_key, str(value) if value else value) + yield (normalized_key, unicode(value) if value else value) def _normalize_arg(self, arg): From 0aa6afe9c9f04d0fe15c1bd1f298b63f0eb8d744 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Mon, 22 Oct 2018 08:50:35 -0700 Subject: [PATCH 18/68] support unicode keyword on Python 3 --- pdfkit/pdfkit.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index e54ddee..15d1d76 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -10,8 +10,10 @@ try: # Python 2.x and 3.x support for checking string types assert basestring + assert unicode except NameError: basestring = str + unicode = str class PDFKit(object): @@ -53,7 +55,8 @@ def __init__(self, url_or_file, type_, options=None, toc=None, cover=None, self.environ = self.configuration.environ - if options is not None: self.options.update(options) + if options is not None: + self.options.update(options) self.toc = {} if toc is None else toc self.cover = cover @@ -211,7 +214,7 @@ def _normalize_options(self, options): """ for key, value in list(options.items()): - if not '--' in key: + if '--' not in key: normalized_key = '--%s' % self._normalize_arg(key) else: normalized_key = self._normalize_arg(key) From 844b0bb9c5f89db88ed0be9bd439dd7bff7e797f Mon Sep 17 00:00:00 2001 From: Niklas Baumstark Date: Mon, 9 Dec 2019 14:48:54 +0100 Subject: [PATCH 19/68] Update source.py --- pdfkit/source.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdfkit/source.py b/pdfkit/source.py index 44ca1bf..28e9659 100644 --- a/pdfkit/source.py +++ b/pdfkit/source.py @@ -8,7 +8,7 @@ def __init__(self, url_or_file, type_): self.source = url_or_file self.type = type_ - if self.type is 'file': + if self.type == 'file': self.checkFiles() def isUrl(self): From 704087d9a204f05ebdfe22da26375d10aba49131 Mon Sep 17 00:00:00 2001 From: Cong Zhang Date: Mon, 23 Mar 2020 19:06:38 +0800 Subject: [PATCH 20/68] Update README.rst fix example --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index b565263..6e7f074 100644 --- a/README.rst +++ b/README.rst @@ -84,9 +84,9 @@ You can specify all wkhtmltopdf `options Date: Thu, 23 Apr 2020 19:20:52 +0100 Subject: [PATCH 21/68] Fix SyntaxWarning with literal equality check `.venv/lib/python3.8/site-packages/pdfkit/source.py:11: SyntaxWarning: "is" with a literal. Did you mean "=="?` --- pdfkit/source.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdfkit/source.py b/pdfkit/source.py index 44ca1bf..28e9659 100644 --- a/pdfkit/source.py +++ b/pdfkit/source.py @@ -8,7 +8,7 @@ def __init__(self, url_or_file, type_): self.source = url_or_file self.type = type_ - if self.type is 'file': + if self.type == 'file': self.checkFiles() def isUrl(self): From 2247e1ce00bc30c16c998b4a0c880814b5a0f05e Mon Sep 17 00:00:00 2001 From: Marcello Dalponte Date: Thu, 23 Apr 2020 19:28:21 +0100 Subject: [PATCH 22/68] Remove python 3.2 and 3.3 and add 3.6, 3.7, 3.8 It looks like 3.2 and 3.3 are not available on travis anymore https://travis-ci.org/github/JazzCore/python-pdfkit/jobs/665811141 --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0c5007c..5404159 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,11 @@ language: python python: - 2.7 - - 3.2 - - 3.3 - 3.4 - 3.5 + - 3.6 + - 3.7 + - 3.8 before_script: "./travis/before-script.sh" script: nosetests -w tests notifications: From 517c05cbb843042fd2ccf6b6df70cc28f27af0dd Mon Sep 17 00:00:00 2001 From: sudharshansudhu Date: Thu, 2 Jul 2020 18:52:37 +0530 Subject: [PATCH 23/68] Update api.py Corrected the function docstring. --- pdfkit/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pdfkit/api.py b/pdfkit/api.py index 6520bf8..d5495d8 100644 --- a/pdfkit/api.py +++ b/pdfkit/api.py @@ -15,7 +15,7 @@ def from_url(url, output_path, options=None, toc=None, cover=None, :param toc: (optional) dict with toc-specific wkhtmltopdf options, with or w/o '--' :param cover: (optional) string with url/filename with a cover html page :param configuration: (optional) instance of pdfkit.configuration.Configuration() - :param configuration_first: (optional) if True, cover always precedes TOC + :param cover_first: (optional) if True, cover always precedes TOC Returns: True on success """ @@ -38,7 +38,7 @@ def from_file(input, output_path, options=None, toc=None, cover=None, css=None, :param cover: (optional) string with url/filename with a cover html page :param css: (optional) string with path to css file which will be added to a single input file :param configuration: (optional) instance of pdfkit.configuration.Configuration() - :param configuration_first: (optional) if True, cover always precedes TOC + :param cover_first: (optional) if True, cover always precedes TOC Returns: True on success """ @@ -61,7 +61,7 @@ def from_string(input, output_path, options=None, toc=None, cover=None, css=None :param cover: (optional) string with url/filename with a cover html page :param css: (optional) string with path to css file which will be added to a input string :param configuration: (optional) instance of pdfkit.configuration.Configuration() - :param configuration_first: (optional) if True, cover always precedes TOC + :param cover_first: (optional) if True, cover always precedes TOC Returns: True on success """ From 9a8f74d00a5d0c6da6b32db75162b00a4005f14f Mon Sep 17 00:00:00 2001 From: Fasih Ahmad Fakhri Date: Fri, 7 Aug 2020 13:16:26 +0530 Subject: [PATCH 24/68] Update AUTHORS.rst --- AUTHORS.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index 62bdf43..07d9fd0 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -16,5 +16,5 @@ Contributors * `Pietro Delsante `_ * `Hung Le `_ * `Zachary Kazanski `_ -* `Fasih Ahmad Fakhri `_ +* `Fasih Ahmad Fakhri `_ * `Alan Hamlett `_ From 3977d3b7ac48d77c9497323088e014e6a2248be2 Mon Sep 17 00:00:00 2001 From: Sammy Taylor Date: Thu, 24 Sep 2020 10:01:33 -0500 Subject: [PATCH 25/68] Update README.rst Update `brew install` command for macOS. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index b565263..5c4785c 100644 --- a/README.rst +++ b/README.rst @@ -33,7 +33,7 @@ Installation .. code-block:: bash - $ brew install caskroom/cask/wkhtmltopdf + $ brew install homebrew/cask/wkhtmltopdf **Warning!** Version in debian/ubuntu repos have reduced functionality (because it compiled without the wkhtmltopdf QT patches), such as adding outlines, headers, footers, TOC etc. To use this options you should install static binary from `wkhtmltopdf `_ site or you can use `this script `_. From 1d6145fd2acbd0c3dc6a67616e7529ccfaca7084 Mon Sep 17 00:00:00 2001 From: Jan-Frederik Konopka Date: Fri, 13 Nov 2020 01:03:59 +0100 Subject: [PATCH 26/68] fix: prevent configuration failing if multiple paths available If "where wkhtmltopdf" returns 2 or more lines, the configuration currently fails with "No wkhtmltopdf executable found". --- pdfkit/configuration.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pdfkit/configuration.py b/pdfkit/configuration.py index b086995..e3e3990 100644 --- a/pdfkit/configuration.py +++ b/pdfkit/configuration.py @@ -13,10 +13,10 @@ def __init__(self, wkhtmltopdf='', meta_tag_prefix='pdfkit-', environ=''): if not self.wkhtmltopdf: if sys.platform == 'win32': self.wkhtmltopdf = subprocess.Popen( - ['where', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].strip() + ['where', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].split()[0].strip() else: self.wkhtmltopdf = subprocess.Popen( - ['which', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].strip() + ['which', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].split()[0].strip() try: with open(self.wkhtmltopdf) as f: @@ -34,4 +34,4 @@ def __init__(self, wkhtmltopdf='', meta_tag_prefix='pdfkit-', environ=''): for key in self.environ.keys(): if not isinstance(self.environ[key], str): - self.environ[key] = str(self.environ[key]) \ No newline at end of file + self.environ[key] = str(self.environ[key]) From d866477d2b5d46239613d41f33dbd86da886ebb6 Mon Sep 17 00:00:00 2001 From: Osama Gadit Date: Tue, 24 Nov 2020 02:58:50 +0500 Subject: [PATCH 27/68] Changed where to where.exe Changed where to where.exe as Powershell has a native where command which was messing up the script if run through a Powershell console on Windows --- pdfkit/configuration.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdfkit/configuration.py b/pdfkit/configuration.py index b086995..9a73c02 100644 --- a/pdfkit/configuration.py +++ b/pdfkit/configuration.py @@ -13,7 +13,7 @@ def __init__(self, wkhtmltopdf='', meta_tag_prefix='pdfkit-', environ=''): if not self.wkhtmltopdf: if sys.platform == 'win32': self.wkhtmltopdf = subprocess.Popen( - ['where', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].strip() + ['where.exe', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].strip() else: self.wkhtmltopdf = subprocess.Popen( ['which', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].strip() @@ -34,4 +34,4 @@ def __init__(self, wkhtmltopdf='', meta_tag_prefix='pdfkit-', environ=''): for key in self.environ.keys(): if not isinstance(self.environ[key], str): - self.environ[key] = str(self.environ[key]) \ No newline at end of file + self.environ[key] = str(self.environ[key]) From 81ce7fe63926660a0075751e699eea3d03c24459 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Thu, 4 Feb 2021 18:35:22 +0100 Subject: [PATCH 28/68] Make from_url/from_file/from_string output_path parameter optional --- README.rst | 6 +++--- pdfkit/api.py | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index b565263..afb4210 100644 --- a/README.rst +++ b/README.rst @@ -28,7 +28,7 @@ Installation .. code-block:: bash $ sudo apt-get install wkhtmltopdf - + * macOS: .. code-block:: bash @@ -70,8 +70,8 @@ If you wish to further process generated PDF, you can read it to a variable: .. code-block:: python - # Use False instead of output path to save pdf to a variable - pdf = pdfkit.from_url('http://google.com', False) + # Without output_path, PDF is returned for assigning to a variable + pdf = pdfkit.from_url('http://google.com') You can specify all wkhtmltopdf `options `_. You can drop '--' in option name. If option without value, use *None, False* or *''* for dict value:. For repeatable options (incl. allow, cookie, custom-header, post, postfile, run-script, replace) you may use a list or a tuple. With option that need multiple values (e.g. --custom-header Authorization secret) we may use a 2-tuple (see example below). diff --git a/pdfkit/api.py b/pdfkit/api.py index 6520bf8..8932970 100644 --- a/pdfkit/api.py +++ b/pdfkit/api.py @@ -4,13 +4,13 @@ from .pdfkit import Configuration -def from_url(url, output_path, options=None, toc=None, cover=None, +def from_url(url, output_path=None, options=None, toc=None, cover=None, configuration=None, cover_first=False): """ Convert file of files from URLs to PDF document :param url: URL or list of URLs to be saved - :param output_path: path to output PDF file. False means file will be returned as string. + :param output_path: (optional) path to output PDF file. By default, PDF will be returned for assigning to a variable. :param options: (optional) dict with wkhtmltopdf global and page options, with or w/o '--' :param toc: (optional) dict with toc-specific wkhtmltopdf options, with or w/o '--' :param cover: (optional) string with url/filename with a cover html page @@ -26,13 +26,13 @@ def from_url(url, output_path, options=None, toc=None, cover=None, return r.to_pdf(output_path) -def from_file(input, output_path, options=None, toc=None, cover=None, css=None, +def from_file(input, output_path=None, options=None, toc=None, cover=None, css=None, configuration=None, cover_first=False): """ Convert HTML file or files to PDF document :param input: path to HTML file or list with paths or file-like object - :param output_path: path to output PDF file. False means file will be returned as string. + :param output_path: (optional) path to output PDF file. By default, PDF will be returned for assigning to a variable. :param options: (optional) dict with wkhtmltopdf options, with or w/o '--' :param toc: (optional) dict with toc-specific wkhtmltopdf options, with or w/o '--' :param cover: (optional) string with url/filename with a cover html page @@ -49,13 +49,13 @@ def from_file(input, output_path, options=None, toc=None, cover=None, css=None, return r.to_pdf(output_path) -def from_string(input, output_path, options=None, toc=None, cover=None, css=None, +def from_string(input, output_path=None, options=None, toc=None, cover=None, css=None, configuration=None, cover_first=False): """ Convert given string or strings to PDF document :param input: string with a desired text. Could be a raw text or a html file - :param output_path: path to output PDF file. False means file will be returned as string. + :param output_path: (optional) path to output PDF file. By default, PDF will be returned for assigning to a variable. :param options: (optional) dict with wkhtmltopdf options, with or w/o '--' :param toc: (optional) dict with toc-specific wkhtmltopdf options, with or w/o '--' :param cover: (optional) string with url/filename with a cover html page From ac092fec86f713200bb874412b470574e2107154 Mon Sep 17 00:00:00 2001 From: Ajin Abraham Date: Sat, 25 Apr 2020 06:15:28 +0530 Subject: [PATCH 29/68] Support Python3.8 Python 3.8 throws warning ``` source.py:11: SyntaxWarning: "is" with a literal. Did you mean "=="? if self.type is 'file': ``` --- pdfkit/source.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdfkit/source.py b/pdfkit/source.py index 44ca1bf..28e9659 100644 --- a/pdfkit/source.py +++ b/pdfkit/source.py @@ -8,7 +8,7 @@ def __init__(self, url_or_file, type_): self.source = url_or_file self.type = type_ - if self.type is 'file': + if self.type == 'file': self.checkFiles() def isUrl(self): From c18af15ac404439fb769b04cb2ad6c5092a84e53 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Fri, 19 Mar 2021 18:56:46 +0300 Subject: [PATCH 30/68] add test for #181 --- tests/pdfkit-tests.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/pdfkit-tests.py b/tests/pdfkit-tests.py index 78fc329..82da788 100644 --- a/tests/pdfkit-tests.py +++ b/tests/pdfkit-tests.py @@ -309,6 +309,11 @@ def test_pdf_generation(self): pdf = r.to_pdf('out.pdf') self.assertTrue(pdf) + def test_pdf_generation_into_variable(self): + r = pdfkit.PDFKit('html', 'string', options={'page-size': 'Letter'}) + pdf = r.to_pdf() + self.assertTrue(pdf[0:4].decode('ascii').startswith('%PDF')) + def test_raise_error_with_invalid_url(self): r = pdfkit.PDFKit('wrongurl', 'url') with self.assertRaises(IOError): From afa1efcf239480deb75cb1a3f018e9f428ceb60e Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Fri, 19 Mar 2021 21:01:31 +0300 Subject: [PATCH 31/68] Add test for #42 --- tests/fixtures/issue_42_bad_char_page.html | 6 ++++++ tests/pdfkit-tests.py | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/fixtures/issue_42_bad_char_page.html diff --git a/tests/fixtures/issue_42_bad_char_page.html b/tests/fixtures/issue_42_bad_char_page.html new file mode 100644 index 0000000..a6044d5 --- /dev/null +++ b/tests/fixtures/issue_42_bad_char_page.html @@ -0,0 +1,6 @@ + + + + This is a bad character -->   <-- + + diff --git a/tests/pdfkit-tests.py b/tests/pdfkit-tests.py index 82da788..f3e0520 100644 --- a/tests/pdfkit-tests.py +++ b/tests/pdfkit-tests.py @@ -413,5 +413,12 @@ def test_raise_error_if_bad_wkhtmltopdf_option(self): raised_exception = cm.exception self.assertRegex(str(raised_exception), '^wkhtmltopdf exited with non-zero code 1. error:\nUnknown long argument --bad-option\r?\n') + def test_issue_42_encode_file_with_unicode_char(self): + with open('fixtures/issue_42_bad_char_page.html', 'r') as f: + data = f.read() + r = pdfkit.PDFKit(data, 'string') + output = r.to_pdf() + self.assertEqual(output[:4].decode('utf-8'), '%PDF') + if __name__ == "__main__": unittest.main() From 9c27001a6845bb9f30f63d88f8574cc5a854abf0 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Fri, 19 Mar 2021 21:01:48 +0300 Subject: [PATCH 32/68] Force decode input string to unicode on python 2 Fixes #42 --- pdfkit/source.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pdfkit/source.py b/pdfkit/source.py index 28e9659..7b115b6 100644 --- a/pdfkit/source.py +++ b/pdfkit/source.py @@ -1,6 +1,14 @@ # -*- coding: utf-8 -*- import os import io +try: + # Python 2.x and 3.x support for checking string types + assert basestring + assert unicode +except NameError: + basestring = str + unicode = str + class Source(object): @@ -38,4 +46,12 @@ def isFileObj(self): return hasattr(self.source, 'read') def to_s(self): - return self.source + # String should be in unicode(python2)/str(python3) type since we will + # later encode it to utf-8 bytes array to pipe into subprocess + # With some charachters on python 2 it sets to str type (bytes) which is wrong + # and cant later encode properly, this is a workaround for this. + # See issue #42 + if isinstance(self.source, unicode): + return self.source + else: + return unicode(self.source, 'utf-8') From ac0406a707ba54ac7a20264b0847c6c50e523254 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Fri, 19 Mar 2021 23:48:45 +0300 Subject: [PATCH 33/68] update README --- README.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.rst b/README.rst index 8b27754..ad49c8c 100644 --- a/README.rst +++ b/README.rst @@ -164,6 +164,16 @@ Example - for when ``wkhtmltopdf`` is not on ``$PATH``: config = pdfkit.configuration(wkhtmltopdf='/opt/bin/wkhtmltopdf') pdfkit.from_string(html_string, output_file, configuration=config) +Also you can use ``configuration()`` call to check if wkhtmltopdf is present in ``$PATH``: + +.. code-block:: python + + try: + config = pdfkit.configuration() + pdfkit.from_string(html_string, output_file) + except OSError: + #not present in PATH + Troubleshooting --------------- From ea99799eaa5751348888ee59233db1ca95917c8a Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Fri, 19 Mar 2021 23:58:21 +0300 Subject: [PATCH 34/68] update travis wkhtmltopdf version to 0.12.6-1 --- travis/before-script.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/travis/before-script.sh b/travis/before-script.sh index 984d40a..3e2194e 100755 --- a/travis/before-script.sh +++ b/travis/before-script.sh @@ -1,10 +1,8 @@ #!/usr/bin/env sh -WKHTML2PDF_VERSION='0.12.4' +WKHTML2PDF_VERSION='0.12.6-1' sudo apt-get install -y openssl build-essential xorg libssl-dev -wget "https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/${WKHTML2PDF_VERSION}/wkhtmltox-${WKHTML2PDF_VERSION}_linux-generic-amd64.tar.xz" -tar -xJf "wkhtmltox-${WKHTML2PDF_VERSION}_linux-generic-amd64.tar.xz" -cd wkhtmltox -sudo chown root:root bin/wkhtmltopdf -sudo cp -r * /usr/ +https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb +wget "https://github.com/wkhtmltopdf/packaging/releases/download/${WKHTML2PDF_VERSION}/wkhtmltox_${WKHTML2PDF_VERSION}.focal_amd64.deb" +sudo dpkg -i wkhtmltox_${WKHTML2PDF_VERSION}.focal_amd64.deb From a86cbe54cd805072318e87555b4d9ddb2dd9ea88 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 00:09:08 +0300 Subject: [PATCH 35/68] More travis build deps --- travis/before-script.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/travis/before-script.sh b/travis/before-script.sh index 3e2194e..d9a307c 100755 --- a/travis/before-script.sh +++ b/travis/before-script.sh @@ -2,7 +2,8 @@ WKHTML2PDF_VERSION='0.12.6-1' -sudo apt-get install -y openssl build-essential xorg libssl-dev +sudo apt-get install -y openssl build-essential xorg libssl-dev libxrender1 libfontconfig1 libx11-dev libjpeg62 libxtst6 fontconfig xfonts-75dpi xfonts-base libpng12-0 https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb wget "https://github.com/wkhtmltopdf/packaging/releases/download/${WKHTML2PDF_VERSION}/wkhtmltox_${WKHTML2PDF_VERSION}.focal_amd64.deb" sudo dpkg -i wkhtmltox_${WKHTML2PDF_VERSION}.focal_amd64.deb +sudo apt-get -f install \ No newline at end of file From e852d274b78b1afea4033d3cd7af0579a7d03227 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 00:26:10 +0300 Subject: [PATCH 36/68] update error handling in Configuration class --- pdfkit/configuration.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/pdfkit/configuration.py b/pdfkit/configuration.py index bec847d..4555fca 100644 --- a/pdfkit/configuration.py +++ b/pdfkit/configuration.py @@ -2,6 +2,10 @@ import os import subprocess import sys +try: + FileNotFoundError +except NameError: + FileNotFoundError = IOError class Configuration(object): @@ -10,23 +14,29 @@ def __init__(self, wkhtmltopdf='', meta_tag_prefix='pdfkit-', environ=''): self.wkhtmltopdf = wkhtmltopdf - if not self.wkhtmltopdf: - if sys.platform == 'win32': - self.wkhtmltopdf = subprocess.Popen( - ['where.exe', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].split()[0].strip() - else: - self.wkhtmltopdf = subprocess.Popen( - ['which', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].split()[0].strip() - try: + if not self.wkhtmltopdf: + if sys.platform == 'win32': + self.wkhtmltopdf = subprocess.Popen( + ['where.exe', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0] + else: + self.wkhtmltopdf = subprocess.Popen( + ['which', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0] + + lines = self.wkhtmltopdf.splitlines() + if len(lines) > 0: + self.wkhtmltopdf = lines[0].strip() + with open(self.wkhtmltopdf) as f: pass - except IOError: + except (IOError, FileNotFoundError) as e: raise IOError('No wkhtmltopdf executable found: "%s"\n' 'If this file exists please check that this process can ' - 'read it. Otherwise please install wkhtmltopdf - ' + 'read it or you can pass path to it manually in method call, ' + 'check README. Otherwise please install wkhtmltopdf - ' 'https://github.com/JazzCore/python-pdfkit/wiki/Installing-wkhtmltopdf' % self.wkhtmltopdf) + self.environ = environ if not self.environ: From 214255312922c9448a28300dd725596c18e83aff Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 00:33:37 +0300 Subject: [PATCH 37/68] More Travis updates --- .travis.yml | 1 + travis/before-script.sh | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5404159..06ee64d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,5 +8,6 @@ python: - 3.8 before_script: "./travis/before-script.sh" script: nosetests -w tests +dist: xenial notifications: email: false diff --git a/travis/before-script.sh b/travis/before-script.sh index d9a307c..f7c361b 100755 --- a/travis/before-script.sh +++ b/travis/before-script.sh @@ -2,8 +2,7 @@ WKHTML2PDF_VERSION='0.12.6-1' -sudo apt-get install -y openssl build-essential xorg libssl-dev libxrender1 libfontconfig1 libx11-dev libjpeg62 libxtst6 fontconfig xfonts-75dpi xfonts-base libpng12-0 -https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb -wget "https://github.com/wkhtmltopdf/packaging/releases/download/${WKHTML2PDF_VERSION}/wkhtmltox_${WKHTML2PDF_VERSION}.focal_amd64.deb" -sudo dpkg -i wkhtmltox_${WKHTML2PDF_VERSION}.focal_amd64.deb +sudo apt-get install -y openssl build-essential libssl-dev libpthread-stubs0-dev libxau-dev xorg-sgml-doctools libxdmcp-dev x11proto-core-dev x11proto-input-dev x11proto-kb-dev xtrans-dev libx11-dev libxcb1-dev libjpeg62 libxtst6 libfontenc1 libxfont1 x11-common xfonts-encodings xfonts-utils fontconfig xfonts-base xfonts-75dpi +wget "https://github.com/wkhtmltopdf/packaging/releases/download/${WKHTML2PDF_VERSION}/wkhtmltox_${WKHTML2PDF_VERSION}.xenial_amd64.deb" +sudo dpkg -i wkhtmltox_${WKHTML2PDF_VERSION}.xenial_amd64.deb sudo apt-get -f install \ No newline at end of file From 30e0d3b5395b03cc0e6f47aa78499133edb406c0 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 00:55:16 +0300 Subject: [PATCH 38/68] Switch Travis to Bionic --- .travis.yml | 2 +- travis/before-script.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 06ee64d..2df813d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,6 @@ python: - 3.8 before_script: "./travis/before-script.sh" script: nosetests -w tests -dist: xenial +dist: bionic notifications: email: false diff --git a/travis/before-script.sh b/travis/before-script.sh index f7c361b..58d7286 100755 --- a/travis/before-script.sh +++ b/travis/before-script.sh @@ -2,7 +2,7 @@ WKHTML2PDF_VERSION='0.12.6-1' -sudo apt-get install -y openssl build-essential libssl-dev libpthread-stubs0-dev libxau-dev xorg-sgml-doctools libxdmcp-dev x11proto-core-dev x11proto-input-dev x11proto-kb-dev xtrans-dev libx11-dev libxcb1-dev libjpeg62 libxtst6 libfontenc1 libxfont1 x11-common xfonts-encodings xfonts-utils fontconfig xfonts-base xfonts-75dpi -wget "https://github.com/wkhtmltopdf/packaging/releases/download/${WKHTML2PDF_VERSION}/wkhtmltox_${WKHTML2PDF_VERSION}.xenial_amd64.deb" -sudo dpkg -i wkhtmltox_${WKHTML2PDF_VERSION}.xenial_amd64.deb +sudo apt-get install -y openssl build-essential libssl-dev libxrender1 libfontconfig1 libx11-dev fontconfig xfonts-75dpi xfonts-base +wget "https://github.com/wkhtmltopdf/packaging/releases/download/${WKHTML2PDF_VERSION}/wkhtmltox_${WKHTML2PDF_VERSION}.bionic_amd64.deb" +sudo dpkg -i wkhtmltox_${WKHTML2PDF_VERSION}.bionic_amd64.deb sudo apt-get -f install \ No newline at end of file From 044210d188e91bd29216908de0731c50c3a7d117 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 00:57:03 +0300 Subject: [PATCH 39/68] Add test for #140 --- tests/pdfkit-tests.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/pdfkit-tests.py b/tests/pdfkit-tests.py index f3e0520..896efd5 100644 --- a/tests/pdfkit-tests.py +++ b/tests/pdfkit-tests.py @@ -107,6 +107,21 @@ def test_repeatable_options(self): self.assertTrue(test_command[idx3 + 1] == 'test_cookie2') self.assertTrue(test_command[idx3 + 2] == 'cookie_value2') + def test_empty_cookie_value(self): + roptions = { + '--page-size': 'Letter', + 'cookies': [ + ('test_cookie1',''), + ('test_cookie2','cookie_value2'), + ] + } + + r = pdfkit.PDFKit('html', 'string', options=roptions) + + test_command = r.command('test') + + self.assertTrue(test_command[idx1 + 1] == 'Letter') + def test_custom_configuration(self): conf = pdfkit.configuration() self.assertEqual('pdfkit-', conf.meta_tag_prefix) From ec22673d4e31f317ff50aa4664024f3afc23bb7e Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 01:05:15 +0300 Subject: [PATCH 40/68] Travis still fails --- travis/before-script.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/travis/before-script.sh b/travis/before-script.sh index 58d7286..81fda49 100755 --- a/travis/before-script.sh +++ b/travis/before-script.sh @@ -2,7 +2,6 @@ WKHTML2PDF_VERSION='0.12.6-1' -sudo apt-get install -y openssl build-essential libssl-dev libxrender1 libfontconfig1 libx11-dev fontconfig xfonts-75dpi xfonts-base +sudo apt-get install -y build-essential xorg libssl-dev libxrender-dev wget gdebi wget "https://github.com/wkhtmltopdf/packaging/releases/download/${WKHTML2PDF_VERSION}/wkhtmltox_${WKHTML2PDF_VERSION}.bionic_amd64.deb" -sudo dpkg -i wkhtmltox_${WKHTML2PDF_VERSION}.bionic_amd64.deb -sudo apt-get -f install \ No newline at end of file +sudo gdebi --n wkhtmltox_${WKHTML2PDF_VERSION}.bionic_amd64.deb From c8a896c7ee34d152caf1b8feee456d2b171e5538 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 10:36:55 +0300 Subject: [PATCH 41/68] hide cmd window on Windows when running subprocess --- pdfkit/configuration.py | 7 ++++++- pdfkit/pdfkit.py | 29 ++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/pdfkit/configuration.py b/pdfkit/configuration.py index 4555fca..11785e1 100644 --- a/pdfkit/configuration.py +++ b/pdfkit/configuration.py @@ -17,8 +17,13 @@ def __init__(self, wkhtmltopdf='', meta_tag_prefix='pdfkit-', environ=''): try: if not self.wkhtmltopdf: if sys.platform == 'win32': + #hide cmd window + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = subprocess.SW_HIDE + self.wkhtmltopdf = subprocess.Popen( - ['where.exe', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0] + ['where.exe', 'wkhtmltopdf'], stdout=subprocess.PIPE, startupinfo=startupinfo).communicate()[0] else: self.wkhtmltopdf = subprocess.Popen( ['which', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0] diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 15d1d76..64c9951 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -154,13 +154,28 @@ def handle_error(exit_code, stderr): def to_pdf(self, path=None): args = self.command(path) - result = subprocess.Popen( - args, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - env=self.environ - ) + if sys.platform == 'win32': + #hide cmd window + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = subprocess.SW_HIDE + + result = subprocess.Popen( + args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=self.environ, + startupinfo=startupinfo + ) + else: + result = subprocess.Popen( + args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=self.environ + ) # If the source is a string then we will pipe it into wkhtmltopdf. # If we want to add custom CSS to file then we read input file to From 5bd73d2f84cd77464f97526a306766dc8a666df3 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 00:26:10 +0300 Subject: [PATCH 42/68] update error handling in Configuration class --- pdfkit/configuration.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/pdfkit/configuration.py b/pdfkit/configuration.py index bec847d..4555fca 100644 --- a/pdfkit/configuration.py +++ b/pdfkit/configuration.py @@ -2,6 +2,10 @@ import os import subprocess import sys +try: + FileNotFoundError +except NameError: + FileNotFoundError = IOError class Configuration(object): @@ -10,23 +14,29 @@ def __init__(self, wkhtmltopdf='', meta_tag_prefix='pdfkit-', environ=''): self.wkhtmltopdf = wkhtmltopdf - if not self.wkhtmltopdf: - if sys.platform == 'win32': - self.wkhtmltopdf = subprocess.Popen( - ['where.exe', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].split()[0].strip() - else: - self.wkhtmltopdf = subprocess.Popen( - ['which', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].split()[0].strip() - try: + if not self.wkhtmltopdf: + if sys.platform == 'win32': + self.wkhtmltopdf = subprocess.Popen( + ['where.exe', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0] + else: + self.wkhtmltopdf = subprocess.Popen( + ['which', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0] + + lines = self.wkhtmltopdf.splitlines() + if len(lines) > 0: + self.wkhtmltopdf = lines[0].strip() + with open(self.wkhtmltopdf) as f: pass - except IOError: + except (IOError, FileNotFoundError) as e: raise IOError('No wkhtmltopdf executable found: "%s"\n' 'If this file exists please check that this process can ' - 'read it. Otherwise please install wkhtmltopdf - ' + 'read it or you can pass path to it manually in method call, ' + 'check README. Otherwise please install wkhtmltopdf - ' 'https://github.com/JazzCore/python-pdfkit/wiki/Installing-wkhtmltopdf' % self.wkhtmltopdf) + self.environ = environ if not self.environ: From 5077924e311f02afef8b523637e26337a6c66660 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 00:57:03 +0300 Subject: [PATCH 43/68] Add test for #140 --- tests/pdfkit-tests.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/pdfkit-tests.py b/tests/pdfkit-tests.py index f3e0520..896efd5 100644 --- a/tests/pdfkit-tests.py +++ b/tests/pdfkit-tests.py @@ -107,6 +107,21 @@ def test_repeatable_options(self): self.assertTrue(test_command[idx3 + 1] == 'test_cookie2') self.assertTrue(test_command[idx3 + 2] == 'cookie_value2') + def test_empty_cookie_value(self): + roptions = { + '--page-size': 'Letter', + 'cookies': [ + ('test_cookie1',''), + ('test_cookie2','cookie_value2'), + ] + } + + r = pdfkit.PDFKit('html', 'string', options=roptions) + + test_command = r.command('test') + + self.assertTrue(test_command[idx1 + 1] == 'Letter') + def test_custom_configuration(self): conf = pdfkit.configuration() self.assertEqual('pdfkit-', conf.meta_tag_prefix) From ee1a7bc1953e12465395582c330a78115206bd15 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 10:36:55 +0300 Subject: [PATCH 44/68] hide cmd window on Windows when running subprocess Fixes #144 --- pdfkit/configuration.py | 7 ++++++- pdfkit/pdfkit.py | 29 ++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/pdfkit/configuration.py b/pdfkit/configuration.py index 4555fca..11785e1 100644 --- a/pdfkit/configuration.py +++ b/pdfkit/configuration.py @@ -17,8 +17,13 @@ def __init__(self, wkhtmltopdf='', meta_tag_prefix='pdfkit-', environ=''): try: if not self.wkhtmltopdf: if sys.platform == 'win32': + #hide cmd window + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = subprocess.SW_HIDE + self.wkhtmltopdf = subprocess.Popen( - ['where.exe', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0] + ['where.exe', 'wkhtmltopdf'], stdout=subprocess.PIPE, startupinfo=startupinfo).communicate()[0] else: self.wkhtmltopdf = subprocess.Popen( ['which', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0] diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 15d1d76..64c9951 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -154,13 +154,28 @@ def handle_error(exit_code, stderr): def to_pdf(self, path=None): args = self.command(path) - result = subprocess.Popen( - args, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - env=self.environ - ) + if sys.platform == 'win32': + #hide cmd window + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = subprocess.SW_HIDE + + result = subprocess.Popen( + args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=self.environ, + startupinfo=startupinfo + ) + else: + result = subprocess.Popen( + args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=self.environ + ) # If the source is a string then we will pipe it into wkhtmltopdf. # If we want to add custom CSS to file then we read input file to From a84800103cd23b02dc68f6c965a7627645172bcf Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 15:22:24 +0300 Subject: [PATCH 45/68] update test for issue 140 --- tests/pdfkit-tests.py | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/tests/pdfkit-tests.py b/tests/pdfkit-tests.py index 896efd5..4be9d92 100644 --- a/tests/pdfkit-tests.py +++ b/tests/pdfkit-tests.py @@ -107,21 +107,6 @@ def test_repeatable_options(self): self.assertTrue(test_command[idx3 + 1] == 'test_cookie2') self.assertTrue(test_command[idx3 + 2] == 'cookie_value2') - def test_empty_cookie_value(self): - roptions = { - '--page-size': 'Letter', - 'cookies': [ - ('test_cookie1',''), - ('test_cookie2','cookie_value2'), - ] - } - - r = pdfkit.PDFKit('html', 'string', options=roptions) - - test_command = r.command('test') - - self.assertTrue(test_command[idx1 + 1] == 'Letter') - def test_custom_configuration(self): conf = pdfkit.configuration() self.assertEqual('pdfkit-', conf.meta_tag_prefix) @@ -435,5 +420,31 @@ def test_issue_42_encode_file_with_unicode_char(self): output = r.to_pdf() self.assertEqual(output[:4].decode('utf-8'), '%PDF') + def test_issue_140_empty_cookie_value(self): + roptions_bad = { + '--page-size': 'Letter', + 'cookie': [ + ('test_cookie1',''), + ('test_cookie2','cookie_value2'), + ] + } + + roptions_good = { + '--page-size': 'Letter', + 'cookie': [ + ('test_cookie1','""'), + ('test_cookie2','cookie_value2'), + ] + } + + r1 = pdfkit.PDFKit('html', 'string', options=roptions_bad) + + self.assertRaises(AssertionError, r1.to_pdf) + + r2 = pdfkit.PDFKit('html', 'string', options=roptions_good) + output2 = r2.to_pdf() + + self.assertEqual(output2[:4].decode('utf-8'), '%PDF') + if __name__ == "__main__": unittest.main() From 1417a96202043f8da41e96b368ad41ad7f3ac8bc Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 15:23:29 +0300 Subject: [PATCH 46/68] update README with empty cookie value example --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index ad49c8c..52f0559 100644 --- a/README.rst +++ b/README.rst @@ -88,6 +88,7 @@ You can specify all wkhtmltopdf `options Date: Sat, 20 Mar 2021 15:29:01 +0300 Subject: [PATCH 47/68] Remove assert in check for basestring Fixes #157 --- pdfkit/pdfkit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 64c9951..c3807b2 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -9,8 +9,8 @@ import codecs try: # Python 2.x and 3.x support for checking string types - assert basestring - assert unicode + basestring + unicode except NameError: basestring = str unicode = str From bc7e71dc1ed2828f204a91b58e4e846cc310c16e Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 16:01:23 +0300 Subject: [PATCH 48/68] Normalize Boolean argument values in options to empty string Fixes #169 --- pdfkit/pdfkit.py | 3 ++- tests/pdfkit-tests.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index c3807b2..c30880f 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -238,7 +238,8 @@ def _normalize_options(self, options): for optval in value: yield (normalized_key, optval) else: - yield (normalized_key, unicode(value) if value else value) + normalized_value = '' if isinstance(value,bool) else value + yield (normalized_key, unicode(normalized_value) if value else value) def _normalize_arg(self, arg): return arg.lower() diff --git a/tests/pdfkit-tests.py b/tests/pdfkit-tests.py index 4be9d92..2593f0c 100644 --- a/tests/pdfkit-tests.py +++ b/tests/pdfkit-tests.py @@ -446,5 +446,16 @@ def test_issue_140_empty_cookie_value(self): self.assertEqual(output2[:4].decode('utf-8'), '%PDF') + def test_issue_169_quiet_boolean_True(self): + options = { + 'outline': '', + 'footer-line': None, + 'quiet': True + } + + r = pdfkit.PDFKit('html', 'string', options=options) + output = r.to_pdf() + self.assertEqual(output[:4].decode('utf-8'), '%PDF') + if __name__ == "__main__": unittest.main() From 5a992b7eb550619f6ec2d6404002bbac0e357b60 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 18:11:36 +0300 Subject: [PATCH 49/68] Switch to quiet output by default, Add verbose parameter to API calls Fixes #84 --- README.rst | 31 +++++++++++++++++++++++++------ pdfkit/api.py | 15 +++++++++------ pdfkit/pdfkit.py | 10 ++++++++-- tests/pdfkit-tests.py | 37 ++++++++++++++++++++++++++++--------- 4 files changed, 70 insertions(+), 23 deletions(-) diff --git a/README.rst b/README.rst index 52f0559..a225c26 100644 --- a/README.rst +++ b/README.rst @@ -97,15 +97,11 @@ You can specify all wkhtmltopdf `options 1 and stderr.splitlines()[-2].strip() == 'Done': return if 'cannot connect to X server' in stderr: diff --git a/tests/pdfkit-tests.py b/tests/pdfkit-tests.py index 2593f0c..b183a7a 100644 --- a/tests/pdfkit-tests.py +++ b/tests/pdfkit-tests.py @@ -201,8 +201,9 @@ def test_skip_nonpdfkit_tags(self): def test_toc_handling_without_options(self): r = pdfkit.PDFKit('hmtl', 'string', toc={'xsl-style-sheet': 'test.xsl'}) - self.assertEqual(r.command()[1], 'toc') - self.assertEqual(r.command()[2], '--xsl-style-sheet') + self.assertEqual(r.command()[1], '--quiet') + self.assertEqual(r.command()[2], 'toc') + self.assertEqual(r.command()[3], '--xsl-style-sheet') def test_toc_with_options(self): options = { @@ -217,16 +218,18 @@ def test_toc_with_options(self): command = r.command() - self.assertEqual(command[1 + len(options) * 2], 'toc') - self.assertEqual(command[1 + len(options) * 2 + 1], '--xsl-style-sheet') + self.assertEqual(command[1 + len(options) * 2], '--quiet') + self.assertEqual(command[2 + len(options) * 2], 'toc') + self.assertEqual(command[2 + len(options) * 2 + 1], '--xsl-style-sheet') def test_cover_without_options(self): r = pdfkit.PDFKit('html', 'string', cover='test.html') command = r.command() - self.assertEqual(command[1], 'cover') - self.assertEqual(command[2], 'test.html') + self.assertEqual(command[1], '--quiet') + self.assertEqual(command[2], 'cover') + self.assertEqual(command[3], 'test.html') def test_cover_with_options(self): options = { @@ -241,8 +244,9 @@ def test_cover_with_options(self): command = r.command() - self.assertEqual(command[1 + len(options) * 2], 'cover') - self.assertEqual(command[1 + len(options) * 2 + 1], 'test.html') + self.assertEqual(command[1 + len(options) * 2], '--quiet') + self.assertEqual(command[2 + len(options) * 2], 'cover') + self.assertEqual(command[2 + len(options) * 2 + 1], 'test.html') def test_cover_and_toc(self): options = { @@ -289,10 +293,25 @@ def test_filter_empty_and_none_values_in_opts(self): 'quiet': False } - r = pdfkit.PDFKit('html', 'string', options=options) + r = pdfkit.PDFKit('html', 'string', options=options, verbose=True) cmd = r.command() self.assertEqual(len(cmd), 6) + def test_verbose_option(self): + options = { + 'outline': '', + 'footer-line': None, + 'quiet': True + } + + r = pdfkit.PDFKit('html', 'string') + cmd = r.command() + self.assertTrue('--quiet' in cmd) + + r = pdfkit.PDFKit('html', 'string', options=options) + cmd = r.command() + self.assertTrue('--quiet' in cmd) + class TestPDFKitGeneration(unittest.TestCase): """Test to_pdf() method""" From 42ef3bb73914291994883346e166a944cba1878c Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 18:16:36 +0300 Subject: [PATCH 50/68] Fix README typos --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index a225c26..6a8c13a 100644 --- a/README.rst +++ b/README.rst @@ -178,13 +178,13 @@ Troubleshooting Debugging issues with PDF generation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If you struggling to generate correct PDF firstly you should check wkhtmltopdf output for some clues, you can get it by passing ``verbose=True`` to API calls: +If you struggling to generate correct PDF firstly you should check ``wkhtmltopdf`` output for some clues, you can get it by passing ``verbose=True`` to API calls: .. code-block:: python pdfkit.from_url('http://google.com', 'out.pdf', verbose=True) -If you are getting strage results in PDF or some option looks like its ignored you should try to run ``wkhtmltopdf`` directly to see if it produces the same result. You can get CLI command by creating ``pdfkit.PDFKit`` class directly and then calling its ``command()`` method: +If you are getting strange results in PDF or some option looks like its ignored you should try to run ``wkhtmltopdf`` directly to see if it produces the same result. You can get CLI command by creating ``pdfkit.PDFKit`` class directly and then calling its ``command()`` method: .. code-block:: python From 0d6c4a106621f0f07829bc5a1c020d6426f6defc Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sat, 20 Mar 2021 18:56:30 +0300 Subject: [PATCH 51/68] Update changelog --- HISTORY.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/HISTORY.rst b/HISTORY.rst index 4c8715d..7e009bf 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,5 +1,13 @@ Changelog --------- +* `1.0.0` + * By default PDFKit now passes "quiet" option to wkhtmltopdf. Now if you need to get output you should pass "verbose=True" to API calls + * Fix different issues with searching for wkhtmltopdf binary + * Update error handling for wkhtmltopdf + * Fix different issues with options handling + * Better handling of unicode input + * Actualize Travis build scripts + * Update README * `0.6.1` * Fix regression on python 3+ when trying to decode pdf output * `0.6.0` From d364d6d8d52698f50007caf309730d4dd14db5e9 Mon Sep 17 00:00:00 2001 From: Camilo Nova Date: Wed, 4 Aug 2021 09:52:26 -0500 Subject: [PATCH 52/68] Fixes typo --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 6a8c13a..c26fae2 100644 --- a/README.rst +++ b/README.rst @@ -149,7 +149,7 @@ You can also pass any options through meta tags in your HTML: Configuration ------------- -Each API call takes an optional configuration paramater. This should be an instance of ``pdfkit.configuration()`` API call. It takes the configuration options as initial paramaters. The available options are: +Each API call takes an optional configuration parameter. This should be an instance of ``pdfkit.configuration()`` API call. It takes the configuration options as initial parameters. The available options are: * ``wkhtmltopdf`` - the location of the ``wkhtmltopdf`` binary. By default ``pdfkit`` will attempt to locate this using ``which`` (on UNIX type systems) or ``where`` (on Windows). * ``meta_tag_prefix`` - the prefix for ``pdfkit`` specific meta tags - by default this is ``pdfkit-`` From 640d10b52dd5a2a8d971ae6f761ff01dc016b0b9 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sun, 14 Nov 2021 19:47:57 +0300 Subject: [PATCH 53/68] fix test for empty cookie value --- tests/pdfkit-tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/pdfkit-tests.py b/tests/pdfkit-tests.py index da408bd..969afbd 100644 --- a/tests/pdfkit-tests.py +++ b/tests/pdfkit-tests.py @@ -111,7 +111,7 @@ def test_empty_cookie_value(self): roptions = { '--page-size': 'Letter', 'cookies': [ - ('test_cookie1',''), + ('test_cookie1','""'), ('test_cookie2','cookie_value2'), ] } @@ -120,6 +120,7 @@ def test_empty_cookie_value(self): test_command = r.command('test') + idx1 = test_command.index('--page-size') # Raise exception in case of not found self.assertTrue(test_command[idx1 + 1] == 'Letter') def test_custom_configuration(self): From cdc54a4979a88ba69d48c7b7cd871ce1e3bcdacf Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sun, 14 Nov 2021 19:59:20 +0300 Subject: [PATCH 54/68] Handle None stderr and stdout returns from communicate in to_pdf Fixes #187 --- pdfkit/pdfkit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 2078a59..784aad0 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -195,7 +195,7 @@ def to_pdf(self, path=None): input = None stdout, stderr = result.communicate(input=input) - stderr = stderr or stdout + stderr = stderr or stdout or b"" stderr = stderr.decode('utf-8', errors='replace') exit_code = result.returncode self.handle_error(exit_code, stderr) From 142c4a578659dc94dc37084065d42072fd310f2e Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sun, 14 Nov 2021 20:41:48 +0300 Subject: [PATCH 55/68] add github actions CI --- .github/workflows/main.yaml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/main.yaml diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 0000000..0232039 --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,28 @@ +name: Run Tests + +on: [push, pull_request] + +jobs: + testing: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9] + fail-fast: false + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + ./travis/before-script.sh + python -m pip install --upgrade pip + pip install nose + + - name: Run tests + run: nosetests -w tests \ No newline at end of file From 1c44826c9f4ffa5b90e83859ca6e6c2ae61ae7e1 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sun, 14 Nov 2021 20:47:32 +0300 Subject: [PATCH 56/68] remove 3.4 from ci --- .github/workflows/main.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 0232039..cf59521 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9] + python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9] fail-fast: false steps: From 403e1b205a8962a3361656a92c55fb8ce22e9d57 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sun, 14 Nov 2021 20:50:17 +0300 Subject: [PATCH 57/68] remove travis files --- .github/workflows/main.yaml | 4 ++-- .travis.yml | 13 ------------- 2 files changed, 2 insertions(+), 15 deletions(-) delete mode 100644 .travis.yml diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index cf59521..4de9cfc 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -1,4 +1,4 @@ -name: Run Tests +name: Build on: [push, pull_request] @@ -20,7 +20,7 @@ jobs: - name: Install dependencies run: | - ./travis/before-script.sh + ./ci/before-script.sh python -m pip install --upgrade pip pip install nose diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2df813d..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: python -python: - - 2.7 - - 3.4 - - 3.5 - - 3.6 - - 3.7 - - 3.8 -before_script: "./travis/before-script.sh" -script: nosetests -w tests -dist: bionic -notifications: - email: false From 630c66377b55fc28e4139a28c8efac58436172e9 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sun, 14 Nov 2021 20:52:34 +0300 Subject: [PATCH 58/68] change readme from travis to gh actions --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 6a8c13a..57bc700 100644 --- a/README.rst +++ b/README.rst @@ -2,8 +2,8 @@ Python-PDFKit: HTML to PDF wrapper ================================== -.. image:: https://travis-ci.org/JazzCore/python-pdfkit.png?branch=master - :target: https://travis-ci.org/JazzCore/python-pdfkit +.. image:: https://github.com/JazzCore/python-pdfkit/actions/workflows/main.yaml/badge.svg?branch=master + :target: https://github.com/JazzCore/python-pdfkit/actions/workflows/main.yaml .. image:: https://badge.fury.io/py/pdfkit.svg :target: http://badge.fury.io/py/pdfkit From 677532df4b64ae6eacf0c8231cd27bc06500b628 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sun, 14 Nov 2021 20:54:21 +0300 Subject: [PATCH 59/68] rename travis dir to ci --- {travis => ci}/before-script.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {travis => ci}/before-script.sh (100%) mode change 100755 => 100644 diff --git a/travis/before-script.sh b/ci/before-script.sh old mode 100755 new mode 100644 similarity index 100% rename from travis/before-script.sh rename to ci/before-script.sh From 7f5c68e9e76c6828e81e3adfeb7ed60fba96dd08 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sun, 14 Nov 2021 20:57:55 +0300 Subject: [PATCH 60/68] fix gh actions --- .github/workflows/main.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 4de9cfc..451b8b5 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -20,6 +20,7 @@ jobs: - name: Install dependencies run: | + chmod +x ./ci/before-script.sh ./ci/before-script.sh python -m pip install --upgrade pip pip install nose From d3b92e767266561e2237ede3af98847717b14236 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sun, 14 Nov 2021 21:18:57 +0300 Subject: [PATCH 61/68] update changelog --- HISTORY.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.rst b/HISTORY.rst index 7e009bf..7e1809d 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -6,7 +6,7 @@ Changelog * Update error handling for wkhtmltopdf * Fix different issues with options handling * Better handling of unicode input - * Actualize Travis build scripts + * Switch from Travis to GitHub Actions * Update README * `0.6.1` * Fix regression on python 3+ when trying to decode pdf output From 80956064ac71e517da4a45e1b7fca3d751637b6e Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sun, 14 Nov 2021 21:23:58 +0300 Subject: [PATCH 62/68] bump version to 1.0.0 --- pdfkit/__init__.py | 2 +- setup.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pdfkit/__init__.py b/pdfkit/__init__.py index 4d064d9..a54653a 100644 --- a/pdfkit/__init__.py +++ b/pdfkit/__init__.py @@ -4,7 +4,7 @@ """ __author__ = 'Golovanov Stanislav' -__version__ = '0.6.1' +__version__ = '1.0.0' __license__ = 'MIT' from .pdfkit import PDFKit diff --git a/setup.py b/setup.py index 251c3ab..ce454fa 100644 --- a/setup.py +++ b/setup.py @@ -43,6 +43,12 @@ def long_description(): 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', 'Topic :: Text Processing', 'Topic :: Text Processing :: General', 'Topic :: Text Processing :: Markup', From c7c609f46512f40e3bd6009bcb17bc1201316753 Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Sun, 14 Nov 2021 22:16:09 +0300 Subject: [PATCH 63/68] fix setup.py for pypi packaging --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index ce454fa..5aadd99 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ -import codecs from distutils.core import setup from setuptools.command.test import test as TestCommand import re @@ -20,7 +19,7 @@ def run_tests(self): def long_description(): """Pre-process the README so that PyPi can render it properly.""" - with codecs.open('README.rst', encoding='utf8') as f: + with open('README.rst') as f: rst = f.read() code_block = '(:\n\n)?\.\. code-block::.*' rst = re.sub(code_block, '::', rst) From c83fa250f85b210f4a0f05ca613ec0fb9580732e Mon Sep 17 00:00:00 2001 From: Stanislav Golovanov Date: Tue, 30 Nov 2021 12:40:41 +0300 Subject: [PATCH 64/68] Fix README link to debian/ubuntu build script Fixes #211 #213 --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 9119ea3..602d2e2 100644 --- a/README.rst +++ b/README.rst @@ -35,7 +35,7 @@ Installation $ brew install homebrew/cask/wkhtmltopdf -**Warning!** Version in debian/ubuntu repos have reduced functionality (because it compiled without the wkhtmltopdf QT patches), such as adding outlines, headers, footers, TOC etc. To use this options you should install static binary from `wkhtmltopdf `_ site or you can use `this script `_. +**Warning!** Version in debian/ubuntu repos have reduced functionality (because it compiled without the wkhtmltopdf QT patches), such as adding outlines, headers, footers, TOC etc. To use this options you should install static binary from `wkhtmltopdf `_ site or you can use `this script `_ (written for CI servers with Ubuntu 18.04 Bionic, but it could work on other Ubuntu/Debian versions). * Windows and other options: check wkhtmltopdf `homepage `_ for binary installers From 49b4550a6baac721a2e5c6efd65a2d5c869d27c6 Mon Sep 17 00:00:00 2001 From: Greg Klupar Date: Tue, 22 Feb 2022 09:29:45 -0900 Subject: [PATCH 65/68] Fix for issue #218 --- pdfkit/pdfkit.py | 11 ++++------- pdfkit/source.py | 10 +++------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 784aad0..cde58d1 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -7,13 +7,10 @@ from .configuration import Configuration import io import codecs -try: - # Python 2.x and 3.x support for checking string types - basestring - unicode -except NameError: - basestring = str - unicode = str + +# Python 2.x and 3.x support for checking string types +basestring = str.__mro__[-2] +unicode = type(u'') class PDFKit(object): diff --git a/pdfkit/source.py b/pdfkit/source.py index 7b115b6..3005bbd 100644 --- a/pdfkit/source.py +++ b/pdfkit/source.py @@ -1,14 +1,10 @@ # -*- coding: utf-8 -*- import os import io -try: - # Python 2.x and 3.x support for checking string types - assert basestring - assert unicode -except NameError: - basestring = str - unicode = str +# Python 2.x and 3.x support for checking string types +basestring = str.__mro__[-2] +unicode = type(u'') class Source(object): From 86cbaa88958cf869c14edcd1abe3ad226f947831 Mon Sep 17 00:00:00 2001 From: Keegan Date: Mon, 30 Jan 2023 10:46:49 +0200 Subject: [PATCH 66/68] Add support for Python 3.10 and Python 3.11 --- .github/workflows/main.yaml | 2 +- HISTORY.rst | 2 ++ pdfkit/__init__.py | 2 +- setup.py | 2 ++ tox.ini | 2 +- 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 451b8b5..72b597e 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9] + python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11] fail-fast: false steps: diff --git a/HISTORY.rst b/HISTORY.rst index 7e1809d..f0abb06 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,5 +1,7 @@ Changelog --------- +* `1.0.1` + * Add support for Python 3.10 and Python 3.11 * `1.0.0` * By default PDFKit now passes "quiet" option to wkhtmltopdf. Now if you need to get output you should pass "verbose=True" to API calls * Fix different issues with searching for wkhtmltopdf binary diff --git a/pdfkit/__init__.py b/pdfkit/__init__.py index a54653a..31c052e 100644 --- a/pdfkit/__init__.py +++ b/pdfkit/__init__.py @@ -4,7 +4,7 @@ """ __author__ = 'Golovanov Stanislav' -__version__ = '1.0.0' +__version__ = '1.0.1' __license__ = 'MIT' from .pdfkit import PDFKit diff --git a/setup.py b/setup.py index 5aadd99..99262c4 100644 --- a/setup.py +++ b/setup.py @@ -48,6 +48,8 @@ def long_description(): 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', 'Topic :: Text Processing', 'Topic :: Text Processing :: General', 'Topic :: Text Processing :: Markup', diff --git a/tox.ini b/tox.ini index 61a0a83..a193343 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27,py33,py34,py35 +envlist = py27,py33,py34,py35,py36,py37,py38,py39,py310,py311 [testenv] deps = pytest From b7bf798b946fa5655f8e82f0d80dec6b6b13d414 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Thu, 14 Sep 2023 10:02:50 +0300 Subject: [PATCH 67/68] Drop support for Python <= 3.7 --- .github/workflows/main.yaml | 8 ++++---- HISTORY.rst | 4 ++-- README.rst | 4 ++-- ci/before-script.sh | 4 ++-- pdfkit/__init__.py | 2 +- pdfkit/pdfkit.py | 12 ++++-------- setup.py | 7 ------- tox.ini | 2 +- 8 files changed, 16 insertions(+), 27 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 72b597e..ed3ed7e 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -7,13 +7,13 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11] + python-version: [3.8, 3.9, '3.10', 3.11] fail-fast: false steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -23,7 +23,7 @@ jobs: chmod +x ./ci/before-script.sh ./ci/before-script.sh python -m pip install --upgrade pip - pip install nose + pip install pynose - name: Run tests - run: nosetests -w tests \ No newline at end of file + run: nosetests -w tests diff --git a/HISTORY.rst b/HISTORY.rst index f0abb06..7470f24 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,7 +1,7 @@ Changelog --------- -* `1.0.1` - * Add support for Python 3.10 and Python 3.11 +* `2.0.0` + * Drop support for Python <= 3.7 * `1.0.0` * By default PDFKit now passes "quiet" option to wkhtmltopdf. Now if you need to get output you should pass "verbose=True" to API calls * Fix different issues with searching for wkhtmltopdf binary diff --git a/README.rst b/README.rst index 602d2e2..f0c9bd3 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ Python-PDFKit: HTML to PDF wrapper .. image:: https://badge.fury.io/py/pdfkit.svg :target: http://badge.fury.io/py/pdfkit -Python 2 and 3 wrapper for wkhtmltopdf utility to convert HTML to PDF using Webkit. +Python 3 wrapper for wkhtmltopdf utility to convert HTML to PDF using Webkit. This is adapted version of `ruby PDFKit `_ library, so big thanks to them! @@ -19,7 +19,7 @@ Installation .. code-block:: bash - $ pip install pdfkit (or pip3 for python3) + $ pip install pdfkit 2. Install wkhtmltopdf: diff --git a/ci/before-script.sh b/ci/before-script.sh index 81fda49..92ae41b 100644 --- a/ci/before-script.sh +++ b/ci/before-script.sh @@ -2,6 +2,6 @@ WKHTML2PDF_VERSION='0.12.6-1' -sudo apt-get install -y build-essential xorg libssl-dev libxrender-dev wget gdebi +sudo apt install -y build-essential xorg libssl-dev libxrender-dev wget wget "https://github.com/wkhtmltopdf/packaging/releases/download/${WKHTML2PDF_VERSION}/wkhtmltox_${WKHTML2PDF_VERSION}.bionic_amd64.deb" -sudo gdebi --n wkhtmltox_${WKHTML2PDF_VERSION}.bionic_amd64.deb +sudo apt install -y ./wkhtmltox_${WKHTML2PDF_VERSION}.bionic_amd64.deb diff --git a/pdfkit/__init__.py b/pdfkit/__init__.py index 31c052e..027c95c 100644 --- a/pdfkit/__init__.py +++ b/pdfkit/__init__.py @@ -4,7 +4,7 @@ """ __author__ = 'Golovanov Stanislav' -__version__ = '1.0.1' +__version__ = '2.0.0' __license__ = 'MIT' from .pdfkit import PDFKit diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index cde58d1..88b3c92 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -8,10 +8,6 @@ import io import codecs -# Python 2.x and 3.x support for checking string types -basestring = str.__mro__[-2] -unicode = type(u'') - class PDFKit(object): """ @@ -113,7 +109,7 @@ def _command(self, path=None): if self.source.isString() or self.source.isFileObj(): yield '-' else: - if isinstance(self.source.source, basestring): + if isinstance(self.source.source, str): yield self.source.to_s() else: for s in self.source.source: @@ -158,7 +154,7 @@ def to_pdf(self, path=None): args = self.command(path) if sys.platform == 'win32': - #hide cmd window + # hide cmd window startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW startupinfo.wShowWindow = subprocess.SW_HIDE @@ -241,8 +237,8 @@ def _normalize_options(self, options): for optval in value: yield (normalized_key, optval) else: - normalized_value = '' if isinstance(value,bool) else value - yield (normalized_key, unicode(normalized_value) if value else value) + normalized_value = '' if isinstance(value, bool) else value + yield (normalized_key, str(normalized_value) if value else value) def _normalize_arg(self, arg): return arg.lower() diff --git a/setup.py b/setup.py index 99262c4..4006a34 100644 --- a/setup.py +++ b/setup.py @@ -39,13 +39,6 @@ def long_description(): author_email='stgolovanov@gmail.com', classifiers=[ 'Programming Language :: Python', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.2', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', diff --git a/tox.ini b/tox.ini index a193343..2ccafd3 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27,py33,py34,py35,py36,py37,py38,py39,py310,py311 +envlist = py38,py39,py310,py311 [testenv] deps = pytest From 9962afa17c958869a8d33144044703d1746cf588 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Thu, 14 Sep 2023 10:15:01 +0300 Subject: [PATCH 68/68] deprecation warning --- README.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.rst b/README.rst index f0c9bd3..2822f0c 100644 --- a/README.rst +++ b/README.rst @@ -12,6 +12,11 @@ Python 3 wrapper for wkhtmltopdf utility to convert HTML to PDF using Webkit. This is adapted version of `ruby PDFKit `_ library, so big thanks to them! +Deprecation Warning +------------------- + +This library has been deprecated to match the `wkhtmltopdf project status `_. + Installation ------------