summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohannes 'josch' Schauer <josch@debian.org>2020-04-28 13:41:41 +0200
committerJohannes 'josch' Schauer <josch@debian.org>2020-04-28 13:41:41 +0200
commitbfa3c202c5b422b27b6ffc074697f6e64a53b6b3 (patch)
tree43cf2aa36a1ef5a008078c8b47f33ad5e9850c25 /src
parente7866e5e3c125b734332dd93843ef683332c0a43 (diff)
New upstream version 0.3.5
Diffstat (limited to 'src')
-rw-r--r--src/img2pdf.egg-info/PKG-INFO6
-rwxr-xr-xsrc/img2pdf.py181
-rw-r--r--src/tests/__init__.py42
3 files changed, 79 insertions, 150 deletions
diff --git a/src/img2pdf.egg-info/PKG-INFO b/src/img2pdf.egg-info/PKG-INFO
index 9919a51..8fa2d93 100644
--- a/src/img2pdf.egg-info/PKG-INFO
+++ b/src/img2pdf.egg-info/PKG-INFO
@@ -1,12 +1,12 @@
Metadata-Version: 2.1
Name: img2pdf
-Version: 0.3.4
+Version: 0.3.5
Summary: Convert images to PDF via direct JPEG inclusion.
Home-page: https://gitlab.mister-muffin.de/josch/img2pdf
Author: Johannes 'josch' Schauer
Author-email: josch@mister-muffin.de
License: LGPL
-Download-URL: https://gitlab.mister-muffin.de/josch/img2pdf/repository/archive.tar.gz?ref=0.3.4
+Download-URL: https://gitlab.mister-muffin.de/josch/img2pdf/repository/archive.tar.gz?ref=0.3.5
Description: [![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=master)](https://travis-ci.org/josch/img2pdf)
[![Appveyor Status](https://ci.appveyor.com/api/projects/status/2kws3wkqvi526llj/branch/master?svg=true)](https://ci.appveyor.com/project/josch/img2pdf/branch/master)
@@ -303,8 +303,6 @@ Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Other Audience
Classifier: Environment :: Console
Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: Implementation :: CPython
diff --git a/src/img2pdf.py b/src/img2pdf.py
index 764e745..ef438b5 100755
--- a/src/img2pdf.py
+++ b/src/img2pdf.py
@@ -34,9 +34,15 @@ import logging
import struct
import platform
-PY3 = sys.version_info[0] >= 3
+with_pdfrw = False
+try:
+ import pdfrw
-__version__ = "0.3.4"
+ with_pdfrw = True
+except ImportError:
+ pass
+
+__version__ = "0.3.5"
default_dpi = 96.0
papersizes = {
"letter": "8.5inx11in",
@@ -566,49 +572,26 @@ class MyPdfWriter:
self.addobj(page)
-if PY3:
-
- class MyPdfString:
- @classmethod
- def encode(cls, string, hextype=False):
- if hextype:
- return (
- b"< "
- + b" ".join(("%06x" % c).encode("ascii") for c in string)
- + b" >"
- )
- else:
- try:
- string = string.encode("ascii")
- except UnicodeEncodeError:
- string = b"\xfe\xff" + string.encode("utf-16-be")
- # We should probably encode more here because at least
- # ghostscript interpretes a carriage return byte (0x0D) as a
- # new line byte (0x0A)
- # PDF supports: \n, \r, \t, \b and \f
- string = string.replace(b"\\", b"\\\\")
- string = string.replace(b"(", b"\\(")
- string = string.replace(b")", b"\\)")
- return b"(" + string + b")"
-
-
-else:
-
- class MyPdfString(object):
- @classmethod
- def encode(cls, string, hextype=False):
- if hextype:
- return (
- b"< "
- + b" ".join(("%06x" % c).encode("ascii") for c in string)
- + b" >"
- )
- else:
- # This mimics exactely to what pdfrw does.
- string = string.replace(b"\\", b"\\\\")
- string = string.replace(b"(", b"\\(")
- string = string.replace(b")", b"\\)")
- return b"(" + string + b")"
+class MyPdfString:
+ @classmethod
+ def encode(cls, string, hextype=False):
+ if hextype:
+ return (
+ b"< " + b" ".join(("%06x" % c).encode("ascii") for c in string) + b" >"
+ )
+ else:
+ try:
+ string = string.encode("ascii")
+ except UnicodeEncodeError:
+ string = b"\xfe\xff" + string.encode("utf-16-be")
+ # We should probably encode more here because at least
+ # ghostscript interpretes a carriage return byte (0x0D) as a
+ # new line byte (0x0A)
+ # PDF supports: \n, \r, \t, \b and \f
+ string = string.replace(b"\\", b"\\\\")
+ string = string.replace(b"(", b"\\(")
+ string = string.replace(b")", b"\\)")
+ return b"(" + string + b")"
class pdfdoc(object):
@@ -631,25 +614,14 @@ class pdfdoc(object):
fit_window=False,
center_window=False,
fullscreen=False,
- with_pdfrw=True,
):
if with_pdfrw:
- try:
- from pdfrw import PdfWriter, PdfDict, PdfName, PdfString
-
- self.with_pdfrw = True
- except ImportError:
- PdfWriter = MyPdfWriter
- PdfDict = MyPdfDict
- PdfName = MyPdfName
- PdfString = MyPdfString
- self.with_pdfrw = False
+ from pdfrw import PdfWriter, PdfDict, PdfName, PdfString
else:
PdfWriter = MyPdfWriter
PdfDict = MyPdfDict
PdfName = MyPdfName
PdfString = MyPdfString
- self.with_pdfrw = False
now = datetime.now()
self.info = PdfDict(indirect=True)
@@ -690,7 +662,7 @@ class pdfdoc(object):
self.writer.version = version
# this is done because pdfrw adds info, catalog and pages as the first
# three objects in this order
- if not self.with_pdfrw:
+ if not with_pdfrw:
self.writer.addobj(self.info)
self.writer.addobj(self.writer.catalog)
self.writer.addobj(self.writer.pages)
@@ -726,7 +698,7 @@ class pdfdoc(object):
trimborder=None,
artborder=None,
):
- if self.with_pdfrw:
+ if with_pdfrw:
from pdfrw import PdfDict, PdfName, PdfObject, PdfString
from pdfrw.py23_diffs import convert_load
else:
@@ -743,7 +715,7 @@ class pdfdoc(object):
elif color == Colorspace.CMYK or color == Colorspace["CMYK;I"]:
colorspace = PdfName.DeviceCMYK
elif color == Colorspace.P:
- if self.with_pdfrw:
+ if with_pdfrw:
raise Exception(
"pdfrw does not support hex strings for "
"palette image input, re-run with "
@@ -871,7 +843,7 @@ class pdfdoc(object):
self.writer.addpage(page)
- if not self.with_pdfrw:
+ if not with_pdfrw:
self.writer.addobj(content)
self.writer.addobj(image)
@@ -881,7 +853,7 @@ class pdfdoc(object):
return stream.getvalue()
def tostream(self, outputstream):
- if self.with_pdfrw:
+ if with_pdfrw:
from pdfrw import PdfDict, PdfName, PdfArray, PdfObject
else:
PdfDict = MyPdfDict
@@ -899,7 +871,7 @@ class pdfdoc(object):
# is added, so we can only start using it after all pages have been
# written.
- if self.with_pdfrw:
+ if with_pdfrw:
catalog = self.writer.trailer.Root
else:
catalog = self.writer.catalog
@@ -1005,7 +977,7 @@ class pdfdoc(object):
raise ValueError("unknown page layout: %s" % self.page_layout)
# now write out the PDF
- if self.with_pdfrw:
+ if with_pdfrw:
self.writer.trailer.Info = self.info
self.writer.write(outputstream)
else:
@@ -1809,7 +1781,6 @@ def convert(*images, **kwargs):
viewer_fit_window=False,
viewer_center_window=False,
viewer_fullscreen=False,
- with_pdfrw=True,
outputstream=None,
first_frame_only=False,
allow_oversized=True,
@@ -1821,6 +1792,9 @@ def convert(*images, **kwargs):
for kwname, default in _default_kwargs.items():
if kwname not in kwargs:
kwargs[kwname] = default
+ if "with_pdfrw" in kwargs:
+ global with_pdfrw
+ with_pdfrw = kwargs["with_pdfrw"]
pdf = pdfdoc(
"1.3",
@@ -1840,7 +1814,6 @@ def convert(*images, **kwargs):
kwargs["viewer_fit_window"],
kwargs["viewer_center_window"],
kwargs["viewer_fullscreen"],
- kwargs["with_pdfrw"],
)
# backwards compatibility with older img2pdf versions where the first
@@ -2111,39 +2084,23 @@ def parse_borderarg(string):
def input_images(path):
if path == "-":
# we slurp in all data from stdin because we need to seek in it later
- if PY3:
- result = sys.stdin.buffer.read()
- else:
- result = sys.stdin.read()
+ result = sys.stdin.buffer.read()
if len(result) == 0:
raise argparse.ArgumentTypeError('"%s" is empty' % path)
else:
- if PY3:
- try:
- if os.path.getsize(path) == 0:
- raise argparse.ArgumentTypeError('"%s" is empty' % path)
- # test-read a byte from it so that we can abort early in case
- # we cannot read data from the file
- with open(path, "rb") as im:
- im.read(1)
- except IsADirectoryError:
- raise argparse.ArgumentTypeError('"%s" is a directory' % path)
- except PermissionError:
- raise argparse.ArgumentTypeError('"%s" permission denied' % path)
- except FileNotFoundError:
- raise argparse.ArgumentTypeError('"%s" does not exist' % path)
- else:
- try:
- if os.path.getsize(path) == 0:
- raise argparse.ArgumentTypeError('"%s" is empty' % path)
- # test-read a byte from it so that we can abort early in case
- # we cannot read data from the file
- with open(path, "rb") as im:
- im.read(1)
- except IOError as err:
- raise argparse.ArgumentTypeError(str(err))
- except OSError as err:
- raise argparse.ArgumentTypeError(str(err))
+ try:
+ if os.path.getsize(path) == 0:
+ raise argparse.ArgumentTypeError('"%s" is empty' % path)
+ # test-read a byte from it so that we can abort early in case
+ # we cannot read data from the file
+ with open(path, "rb") as im:
+ im.read(1)
+ except IsADirectoryError:
+ raise argparse.ArgumentTypeError('"%s" is a directory' % path)
+ except PermissionError:
+ raise argparse.ArgumentTypeError('"%s" permission denied' % path)
+ except FileNotFoundError:
+ raise argparse.ArgumentTypeError('"%s" does not exist' % path)
result = path
return result
@@ -2492,6 +2449,9 @@ def gui():
v for v in Colorspace if v.name == args["colorspace"].get()
)
+ global with_pdfrw
+ if with_pdfrw:
+ with_pdfrw = not args["without_pdfrw"].get()
convert(
*infiles,
title=args["title"].get() if args["title"].get() else None,
@@ -2516,7 +2476,6 @@ def gui():
viewer_fit_window=(args["viewer_fit_window"].get() or None),
viewer_center_window=(args["viewer_center_window"].get() or None),
viewer_fullscreen=(args["viewer_fullscreen"].get() or None),
- with_pdfrw=not args["without_pdfrw"].get(),
outputstream=stream,
first_frame_only=args["first_frame_only"].get(),
cropborder=None,
@@ -2631,6 +2590,7 @@ def gui():
variable=args["nodate"],
state=tkinter.DISABLED,
).grid(row=1, column=0, columnspan=2, sticky=tkinter.W)
+ # TODO: only have this checkbox enabled if pdfrw is installed
tkinter.Checkbutton(
output_options,
text="without pdfrw",
@@ -3085,23 +3045,9 @@ Report bugs at https://gitlab.mister-muffin.de/josch/img2pdf/issues
version="%(prog)s " + __version__,
help="Prints version information and exits.",
)
- gui_group = parser.add_mutually_exclusive_group(required=False)
- gui_group.add_argument(
- "--gui",
- dest="gui",
- action="store_true",
- help="run tkinter gui (default on Windows)",
- )
- gui_group.add_argument(
- "--nogui",
- dest="gui",
- action="store_false",
- help="don't run tkinter gui (default elsewhere)",
+ parser.add_argument(
+ "--gui", dest="gui", action="store_true", help="run experimental tkinter gui"
)
- if platform.system() == "Windows":
- parser.set_defaults(gui=True)
- else:
- parser.set_defaults(gui=False)
outargs = parser.add_argument_group(
title="General output arguments",
@@ -3465,10 +3411,7 @@ and left/right, respectively. It is not possible to specify asymmetric borders.
if len(args.images) == 0:
logging.info("reading image from standard input")
try:
- if PY3:
- args.images = [sys.stdin.buffer.read()]
- else:
- args.images = [sys.stdin.read()]
+ args.images = [sys.stdin.buffer.read()]
except KeyboardInterrupt:
exit(0)
@@ -3490,6 +3433,9 @@ and left/right, respectively. It is not possible to specify asymmetric borders.
)
exit(2)
+ global with_pdfrw
+ if with_pdfrw:
+ with_pdfrw = not args.without_pdfrw
try:
convert(
*args.images,
@@ -3511,7 +3457,6 @@ and left/right, respectively. It is not possible to specify asymmetric borders.
viewer_fit_window=args.viewer_fit_window,
viewer_center_window=args.viewer_center_window,
viewer_fullscreen=args.viewer_fullscreen,
- with_pdfrw=not args.without_pdfrw,
outputstream=args.output,
first_frame_only=args.first_frame_only,
cropborder=args.crop_border,
diff --git a/src/tests/__init__.py b/src/tests/__init__.py
index 807aa84..7997218 100644
--- a/src/tests/__init__.py
+++ b/src/tests/__init__.py
@@ -10,12 +10,7 @@ from io import StringIO, BytesIO, TextIOWrapper
HERE = os.path.dirname(__file__)
-PY3 = sys.version_info[0] >= 3
-
-if PY3:
- PdfReaderIO = StringIO
-else:
- PdfReaderIO = BytesIO
+PdfReaderIO = StringIO
# Recompressing the image stream makes the comparison robust against output
# preserving changes in the zlib compress output bitstream
@@ -480,29 +475,15 @@ def tiff_header_for_ccitt(width, height, img_size, ccitt_group=4):
class CommandLineTests(unittest.TestCase):
def test_main_help(self):
- if PY3:
- from contextlib import redirect_stdout
- f = StringIO()
- with redirect_stdout(f):
- try:
- img2pdf.main(['img2pdf', '--help'])
- except SystemExit:
- pass
- res = f.getvalue()
- self.assertIn('img2pdf', res)
- else:
- # silence output
- sys_stdout = sys.stdout
- sys.stdout = BytesIO()
-
+ from contextlib import redirect_stdout
+ f = StringIO()
+ with redirect_stdout(f):
try:
img2pdf.main(['img2pdf', '--help'])
except SystemExit:
- # argparse does sys.exit(0) on --help
- res = sys.stdout.getvalue()
- self.assertIn('img2pdf', res)
- finally:
- sys.stdout = sys_stdout
+ pass
+ res = f.getvalue()
+ self.assertIn('img2pdf', res)
def test_suite():
@@ -554,12 +535,17 @@ def test_suite():
assert os.path.isfile(outputf)
def handle(self, f=inputf, out=outputf, with_pdfrw=with_pdfrw):
+ try:
+ from pdfrw import PdfReader, PdfName, PdfWriter
+ from pdfrw.py23_diffs import convert_load, convert_store
+ except ImportError:
+ # the test requires pdfrw
+ self.skipTest("this test requires pdfrw")
+ return
with open(f, "rb") as inf:
orig_imgdata = inf.read()
output = img2pdf.convert(orig_imgdata, nodate=True,
with_pdfrw=with_pdfrw)
- from pdfrw import PdfReader, PdfName, PdfWriter
- from pdfrw.py23_diffs import convert_load, convert_store
x = PdfReader(PdfReaderIO(convert_load(output)))
self.assertEqual(sorted(x.keys()), [PdfName.Info, PdfName.Root,
PdfName.Size])