Skip to content

Commit

Permalink
update files based on codacy suggestion
Browse files Browse the repository at this point in the history
  • Loading branch information
jarrekk authored and JackjiaSAP committed Mar 18, 2021
1 parent a09dc98 commit 14d5870
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 96 deletions.
50 changes: 23 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/aa1f67f04ff24bb080b7f8c8a9b7b8b1)](https://www.codacy.com/app/jarrekk/imgkit?utm_source=github.com&utm_medium=referral&utm_content=jarrekk/imgkit&utm_campaign=Badge_Grade)
[![PyPI version](https://badge.fury.io/py/imgkit.svg)](https://badge.fury.io/py/imgkit)

```
``` text
_____ __ __ _____ _ __ _ _
|_ _| | \/ | / ____| | |/ / (_) | |
| | | \ / | | | __ | ' / _ | |_
Expand All @@ -27,21 +27,23 @@ Python 2 and 3 wrapper for wkhtmltoimage utility to convert HTML to IMG using We

2. Install wkhtmltopdf:

* Debian/Ubuntu:
* Debian/Ubuntu:

``` bash
sudo apt-get install wkhtmltopdf
```
``` bash
sudo apt-get install 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](http://wkhtmltopdf.org/) site or you can use this [script](https://github.com/jarrekk/imgkit/blob/master/travis/init.sh).

**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](http://wkhtmltopdf.org/) site or you can use this [script](https://github.com/jarrekk/imgkit/blob/master/travis/init.sh).
* MacOSX:

* MacOSX
``` bash
brew install --cask wkhtmltopdf
```

``` bash
brew install wkhtmltopdf
```

* Windows and other options: check [wkhtmltopdf homepage](http://wkhtmltopdf.org/) for binary installers or [wiki page](https://github.com/pdfkit/pdfkit/wiki/Installing-WKHTMLTOPDF).
* Windows and other options:

Check [wkhtmltopdf homepage](http://wkhtmltopdf.org/) for binary installers or [wiki page](https://github.com/pdfkit/pdfkit/wiki/Installing-WKHTMLTOPDF).

## Usage

Expand All @@ -55,13 +57,6 @@ imgkit.from_file('test.html', 'out.jpg')
imgkit.from_string('Hello!', 'out.jpg')
```

You can pass a list with multiple URLs or files:

``` python
imgkit.from_url(['google.com', 'yandex.ru', 'engadget.com'], 'out.jpg')
imgkit.from_file(['file1.html', 'file2.html'], 'out.jpg')
```

Also you can pass an opened file:

``` python
Expand Down Expand Up @@ -167,9 +162,9 @@ imgkit.from_string(body, 'out.png')

Each API call takes an optional config paramater. This should be an instance of `imgkit.config()` API call. It takes the config options as initial paramaters. The available options are:

* `wkhtmltoimage` - the location of the `wkhtmltoimage` binary. By default `imgkit` will attempt to locate this using which` (on UNIX type systems) or where` (on Windows).
* `xvfb` - the location of the `xvfb-run` binary. By default `imgkit` will attempt to locate this using which` (on UNIX type systems) or where` (on Windows).
* `meta_tag_prefix` - the prefix for `imgkit` specific meta tags - by default this is `imgkit-`
* `wkhtmltoimage` - the location of the `wkhtmltoimage` binary. By default `imgkit` will attempt to locate this using which` (on UNIX type systems) or where` (on Windows).
* `xvfb` - the location of the `xvfb-run` binary. By default `imgkit` will attempt to locate this using which` (on UNIX type systems) or where` (on Windows).
* `meta_tag_prefix` - the prefix for `imgkit` specific meta tags - by default this is `imgkit-`

Example - for when `wkhtmltopdf` or `xvfb` is not in `$PATH`:

Expand All @@ -178,18 +173,19 @@ config = imgkit.config(wkhtmltoimage='/opt/bin/wkhtmltoimage', xvfb='/opt/bin/xv
imgkit.from_string(html_string, output_file, config=config)
```


## Troubleshooting

* `IOError: 'No wkhtmltopdf executable found'`:

Make sure that you have wkhtmltoimage in your `$PATH` or set via custom configuration (see preceding section). *where wkhtmltoimage* in Windows or *which wkhtmltoimage* on Linux should return actual path to binary.

Make sure that you have wkhtmltoimage in your `$PATH` or set via custom configuration (see preceding section). *where wkhtmltoimage* in Windows or *which wkhtmltoimage* on Linux should return actual path to binary.
* `IOError: 'No xvfb executable found'`:

Make sure that you have xvfb-run in your `$PATH` or set via custom configuration (see preceding section). *where xvfb* in Windows or *which xvfb-run* or *which Xvfb* on Linux should return actual path to binary.

Make sure that you have xvfb-run in your `$PATH` or set via custom configuration (see preceding section). *where xvfb* in Windows or *which xvfb-run* or *which Xvfb* on Linux should return actual path to binary.
* `IOError: 'Command Failed'`:

This error means that IMGKit was unable to process an input. You can try to directly run a command from error message and see what error caused failure (on some wkhtmltoimage versions this can be cause by segmentation faults)
This error means that IMGKit was unable to process an input. You can try to directly run a command from error message and see what error caused failure (on some wkhtmltoimage versions this can be cause by segmentation faults)

## Credit

Expand Down
14 changes: 6 additions & 8 deletions imgkit/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# -*- coding: utf-8 -*-
"""
Wkhtmltopdf python wrapper to convert html to image using the webkit rendering engine and qt
"""
"Wkhtmltopdf python wrapper to convert html to image using the webkit rendering engine and qt"

__author__ = 'jarrekk'
__contact__ = '[email protected]'
__version__ = '1.0.5'
__homepage__ = 'https://github.com/jarrekk/imgkit'
__license__ = 'MIT'
__author__ = "jarrekk"
__contact__ = "[email protected]"
__version__ = "1.1.0"
__homepage__ = "https://github.com/jarrekk/imgkit"
__license__ = "MIT"

from .imgkit import IMGKit
from .api import from_url, from_file, from_string, config
1 change: 0 additions & 1 deletion imgkit/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ def from_url(url,
: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
:param css: style of input
:param config: (optional) instance of imgkit.config.Config()
:param cover_first: (optional) if True, cover always precedes TOC
:return: True when success
Expand Down
60 changes: 36 additions & 24 deletions imgkit/config.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
# -*- coding: utf-8 -*-
import subprocess
import sys
from subprocess import CalledProcessError


class Config(object):
def __init__(self, wkhtmltoimage='', xvfb='', meta_tag_prefix='imgkit-'):
self.meta_tag_prefix = meta_tag_prefix

"""
:param wkhtmltoimage: wkhtmltoimage path
:param xvfb: xvfb path
:param meta_tag_prefix: the prefix for `imgkit` specific meta tags - by default this is `imgkit-`
"""
self.wkhtmltoimage = wkhtmltoimage

self.xvfb = xvfb
self.meta_tag_prefix = meta_tag_prefix

if not self.wkhtmltoimage:
if sys.platform == 'win32':
self.wkhtmltoimage = subprocess.Popen(['where', 'wkhtmltoimage'],
stdout=subprocess.PIPE).communicate()[0].strip()
else:
self.wkhtmltoimage = subprocess.Popen(['which', 'wkhtmltoimage'],
stdout=subprocess.PIPE).communicate()[0].strip()
# get wkhtmltoimage in *nix/windows server
# see https://github.com/jarrekk/imgkit/issues/57 for windows condition
for find_cmd in ('where', 'which'):
try:
self.wkhtmltoimage = subprocess.check_output([find_cmd, 'wkhtmltoimage']).strip()
break
except CalledProcessError:
self.wkhtmltoimage = ''
except OSError:
self.wkhtmltoimage = ''

if not self.xvfb:
if sys.platform == 'win32':
self.xvfb = subprocess.Popen(['where', 'xvfb-run'],
stdout=subprocess.PIPE).communicate()[0].strip()
else:
self.xvfb = subprocess.Popen(['which', 'xvfb-run'],
stdout=subprocess.PIPE).communicate()[0].strip()
# get xvfb in *nix/windows server
# see https://github.com/jarrekk/imgkit/issues/57 for windows condition
for find_cmd in ('where', 'which'):
try:
self.xvfb = subprocess.check_output([find_cmd, 'xvfb-run']).strip()
break
except CalledProcessError:
self.xvfb = ''
except OSError:
self.xvfb = ''

try:
with open(self.wkhtmltoimage):
Expand All @@ -34,11 +46,11 @@ def __init__(self, wkhtmltoimage='', xvfb='', meta_tag_prefix='imgkit-'):
'If this file exists please check that this process can '
'read it. Otherwise please install wkhtmltopdf - '
'http://wkhtmltopdf.org\n'.format(self.wkhtmltoimage))
else:
try:
with open(self.xvfb):
pass
except IOError:
raise IOError('No xvfb executable found: "{0}"\n'
'If this file exists please check that this process can '
'read it. Otherwise please install xvfb -'.format(self.xvfb))
if self.xvfb:
try:
with open(self.xvfb):
pass
except IOError:
raise IOError('No xvfb executable found: "{0}"\n'
'If this file exists please check that this process can '
'read it. Otherwise please install xvfb -'.format(self.xvfb))
43 changes: 22 additions & 21 deletions imgkit/imgkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,19 +143,21 @@ def _normalize_options(self, options):
if '--' in key:
normalized_key = self._normalize_arg(key)
else:
normalized_key = '--%s' % self._normalize_arg(key)
normalized_key = '--{}'.format(self._normalize_arg(key))

if isinstance(value, (list, tuple)):
for opt_val in value:
yield (normalized_key, opt_val)
yield normalized_key, opt_val
else:
yield (normalized_key, str(value) if value else value)
yield normalized_key, str(value) if value else value

def _normalize_arg(self, arg):
@staticmethod
def _normalize_arg(arg):
return arg.lower()

def _style_tag(self, stylesheet):
return "<style>%s</style>" % stylesheet
@staticmethod
def _style_tag(stylesheet):
return "<style>{}</style>".format(stylesheet)

def _prepend_css(self, path):
if self.source.isUrl() or isinstance(self.source.source, list):
Expand Down Expand Up @@ -193,24 +195,22 @@ def _find_options_in_meta(self, content):
dict: {config option: value}
"""
if (isinstance(content, io.IOBase)
or content.__class__.__name__ == 'StreamReaderWriter'):
or content.__class__.__name__ == 'StreamReaderWriter'):
content = content.read()

found = {}

for x in re.findall('<meta [^>]*>', content):
if re.search('name=["\']%s' % self.config.meta_tag_prefix, x):
name = re.findall('name=["\']%s([^"\']*)' %
self.config.meta_tag_prefix, x)[0]
if re.search('name=["\']{}'.format(self.config.meta_tag_prefix), x):
name = re.findall('name=["\']{}([^"\']*)'.format(self.config.meta_tag_prefix), x)[0]
found[name] = re.findall('content=["\']([^"\']*)', x)[0]

return found

def to_img(self, path=None):
args = self.command(path)

result = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# If the source is a string then we will pipe it into wkhtmltoimage.
# If we want to add custom CSS to file then we read input file to
Expand All @@ -231,10 +231,10 @@ def to_img(self, path=None):
exit_code = result.returncode

if 'cannot connect to X server' in stderr:
raise IOError('%s\n'
raise IOError('{}\n'
'You will need to run wkhtmltoimage within a "virtual" X server.\n'
'Go to the link below for more information\n'
'http://wkhtmltopdf.org' % stderr)
'http://wkhtmltopdf.org'.format(stderr))

if 'Error' in stderr:
raise IOError('wkhtmltoimage reported an error:\n' + stderr)
Expand All @@ -243,7 +243,8 @@ def to_img(self, path=None):
xvfb_error = ''
if 'QXcbConnection' in stderr:
xvfb_error = 'You need to install xvfb(sudo apt-get install xvfb, yum install xorg-x11-server-Xvfb, etc), then add option: {"xvfb": ""}.'
raise IOError("wkhtmltoimage exited with non-zero code {0}. error:\n{1}\n\n{2}".format(exit_code, stderr, xvfb_error))
raise IOError(
"wkhtmltoimage exited with non-zero code {0}. error:\n{1}\n\n{2}".format(exit_code, stderr, xvfb_error))

# Since wkhtmltoimage sends its output to stderr we will capture it
# and properly send to stdout
Expand All @@ -257,11 +258,11 @@ def to_img(self, path=None):
with codecs.open(path, mode='rb') as f:
text = f.read(4)
if text == '':
raise IOError('Command failed: %s\n'
'Check whhtmltoimage output without \'quiet\' '
'option' % ' '.join(args))
raise IOError("Command failed: {}\n"
"Check whhtmltoimage output without "
"'quiet' option".format(' '.join(args)))
return True
except IOError as e:
raise IOError('Command failed: %s\n'
'Check whhtmltoimage output without \'quiet\' option\n'
'%s ' % (' '.join(args)), e)
raise IOError("Command failed: {0}\n"
"Check whhtmltoimage output without "
"'quiet' option\n{1} ".format(' '.join(args), e))
6 changes: 3 additions & 3 deletions imgkit/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -26,10 +26,10 @@ def checkFiles(self):
if isinstance(self.source, list):
for path in self.source:
if not os.path.exists(path):
raise IOError('No such file: %s' % path)
raise IOError('No such file: {}'.format(path))
else:
if not hasattr(self.source, 'read') and not os.path.exists(self.source):
raise IOError('No such file: %s' % self.source)
raise IOError('No such file: {}'.format(self.source))

def isString(self):
return 'string' in self.type
Expand Down
5 changes: 2 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,10 @@ def long_description():
classifiers=[
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'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',
Expand Down
5 changes: 0 additions & 5 deletions test/__init__.py

This file was deleted.

8 changes: 4 additions & 4 deletions test/imgkit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ def test_stylesheet_adding_to_the_head(self):
css = f.read()

r._prepend_css('fixtures/example.css')
self.assertIn('<style>%s</style>' % css, r.source.to_s())
self.assertIn('<style>{}</style>'.format(css), r.source.to_s())

def test_stylesheet_adding_without_head_tag(self):
r = imgkit.IMGKit('<html><body>Hai!</body></html>', 'string',
Expand All @@ -340,7 +340,7 @@ def test_stylesheet_adding_without_head_tag(self):
css = f.read()

r._prepend_css('fixtures/example.css')
self.assertIn('<style>%s</style><html>' % css, r.source.to_s())
self.assertIn('<style>{}</style><html>'.format(css), r.source.to_s())

def test_multiple_stylesheets_adding_to_the_head(self):
css_files = ['fixtures/example.css', 'fixtures/example2.css']
Expand All @@ -353,7 +353,7 @@ def test_multiple_stylesheets_adding_to_the_head(self):
css.append(f.read())

r._prepend_css(css_files)
self.assertIn('<style>%s</style>' % "\n".join(css), r.source.to_s())
self.assertIn('<style>{}</style>'.format("\n".join(css)), r.source.to_s())

def test_multiple_stylesheet_adding_without_head_tag(self):
css_files = ['fixtures/example.css', 'fixtures/example2.css']
Expand All @@ -366,7 +366,7 @@ def test_multiple_stylesheet_adding_without_head_tag(self):
css.append(f.read())

r._prepend_css(css_files)
self.assertIn('<style>%s</style><html>' % "\n".join(css), r.source.to_s())
self.assertIn('<style>{}</style><html>'.format("\n".join(css)), r.source.to_s())

def test_stylesheet_throw_error_when_url(self):
r = imgkit.IMGKit('http://ya.ru', 'url', css='fixtures/example.css')
Expand Down

0 comments on commit 14d5870

Please sign in to comment.