Compare commits

...
15 Commits
Author SHA1 Message Date
James R. Barlow 3438afaffe Support pdfminer.six 20191020 2019-11-04 03:15:59 -08:00
James R. Barlow 681fa039cc Update release notes; disable Py3.8 test again 2019-11-04 03:00:15 -08:00
James R. Barlow 69e80f1545 docker-compose.test does not seem to be ready for production use 2019-11-04 02:58:57 -08:00
James R. Barlow 983835cce4 docs: add remark about optimizing without OCR 2019-11-04 02:32:29 -08:00
James R. Barlow 6c23b137e2 Docker: relocate dockerfile 2019-11-04 02:27:30 -08:00
James R. Barlow d656b2b3f2 docs: remove comment about Ubuntu image
[ci skip]
2019-11-04 02:08:42 -08:00
James R. Barlow 031b800aac Docker autotest: fix, maybe? 2019-11-04 02:04:07 -08:00
James R. Barlow 05eb85ee77 Docker: try adding automated test 2019-11-04 01:23:54 -08:00
James R. Barlow 4da5214ca9 Drop support for unpaper 6.1 on Ubuntu 14.04 2019-11-04 00:09:04 -08:00
James R. Barlow 1ee829dd59 Travis: enable Python 3.8 testing 2019-11-04 00:05:18 -08:00
James R. Barlow 99db5d91ae Fix issue "MANIFEST.in exists" by removing MANIFEST.in
MANIFEST.in is always an issue
2019-11-04 00:03:49 -08:00
James R. Barlow 3a4490ee36 Dockerfile: fix jbig2 not copied over 2019-11-03 23:52:08 -08:00
James R. Barlow a492e3b472 Dockerfile: fix errors are trying to build unneeded cached wheels 2019-11-03 23:51:55 -08:00
James R. Barlow c3719d3b72 Dockerfile: remove venv from Ubuntu image; tweak reqs 2019-11-03 23:39:40 -08:00
James R. Barlow ad48fc6415 Remove Alpine Docker image 2019-11-03 22:35:15 -08:00
16 changed files with 115 additions and 242 deletions
+14 -20
View File
@@ -1,6 +1,6 @@
# OCRmyPDF # OCRmyPDF
# #
FROM ubuntu:19.04 as base FROM ubuntu:19.10 as base
FROM base as builder FROM base as builder
@@ -10,16 +10,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential autoconf automake libtool \ build-essential autoconf automake libtool \
libleptonica-dev \ libleptonica-dev \
zlib1g-dev \ zlib1g-dev \
ocrmypdf \ python3-setuptools \
pngquant \
python3-pip \ python3-pip \
python3-venv \
tesseract-ocr \
unpaper \
wget \ wget \
git git
# Compile and install jbig2 # Compile and install jbig2
# Needs libleptonica-dev, zlib1g-dev # Needs libleptonica-dev, zlib1g-dev
RUN \ RUN \
@@ -31,15 +26,15 @@ RUN \
&& cd .. \ && cd .. \
&& rm -rf jbig2 && rm -rf jbig2
RUN python3 -m venv /appenv
COPY . /app COPY . /app
WORKDIR /app WORKDIR /app
RUN . /appenv/bin/activate; \ RUN pip3 install --no-cache-dir \
pip install --upgrade pip \ -r requirements/main.txt \
&& pip install . -r requirements/webservice.txt \
-r requirements/test.txt \
.
FROM base FROM base
@@ -53,7 +48,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
zlib1g \ zlib1g \
pngquant \ pngquant \
python3 \ python3 \
python3-venv \
qpdf \ qpdf \
tesseract-ocr \ tesseract-ocr \
tesseract-ocr-chi-sim \ tesseract-ocr-chi-sim \
@@ -62,10 +56,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
tesseract-ocr-fra \ tesseract-ocr-fra \
tesseract-ocr-por \ tesseract-ocr-por \
tesseract-ocr-spa \ tesseract-ocr-spa \
unpaper \ unpaper
wget
WORKDIR /app
COPY --from=builder /usr/local/lib/ /usr/local/lib/
COPY --from=builder /usr/local/bin/ /usr/local/bin/
# Copy
COPY --from=builder /app/misc/webservice.py /app/ COPY --from=builder /app/misc/webservice.py /app/
# Copy minimal project files to get the test suite. # Copy minimal project files to get the test suite.
@@ -74,7 +71,4 @@ COPY --from=builder /app/requirements /app/requirements
COPY --from=builder /app/tests /app/tests COPY --from=builder /app/tests /app/tests
COPY --from=builder /app/src /app/src COPY --from=builder /app/src /app/src
COPY --from=builder /appenv /appenv ENTRYPOINT ["/usr/local/bin/ocrmypdf"]
COPY --from=builder /usr/local /usr/local
ENTRYPOINT ["/appenv/bin/ocrmypdf"]
-91
View File
@@ -1,91 +0,0 @@
FROM alpine:3.9 as base
FROM base as builder
ENV LANG=C.UTF-8
# Normally:
# echo '@testing http://nl.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories
RUN \
echo -e '@testing http://nl.alpinelinux.org/alpine/edge/testing\n@community http://nl.alpinelinux.org/alpine/edge/community'\
>> /etc/apk/repositories \
# Add runtime dependencies
&& apk add --update \
python3-dev \
py3-setuptools \
jbig2enc@community \
ghostscript \
qpdf@community \
qpdf-dev@community \
tesseract-ocr \
unpaper \
pngquant \
libxml2-dev \
libxslt-dev \
zlib-dev \
libffi-dev \
leptonica-dev \
binutils \
&& pip3 install --upgrade pip \
# Install pybind11 for pikepdf
&& pip3 install pybind11 \
# Install flask for the webservice
&& pip3 install flask \
# Add build dependencies
&& apk add --virtual build-dependencies \
build-base \
git
COPY . /app
WORKDIR /app
RUN pip3 install .
FROM base
ENV LANG=C.UTF-8
# Normally:
# echo '@testing http://nl.alpinelinux.org/alpine/edge/testing' >> /etc/apk/repositories
RUN \
echo -e '@testing http://nl.alpinelinux.org/alpine/edge/testing\n@community http://nl.alpinelinux.org/alpine/edge/community'\
>> /etc/apk/repositories \
# Add runtime dependencies
&& apk add --update \
python3 \
jbig2enc@community \
ghostscript \
qpdf@community \
qpdf-dev@community \
tesseract-ocr \
tesseract-ocr-data-deu \
tesseract-ocr-data-chi_sim \
unpaper \
pngquant \
libxml2 \
libxslt \
zlib \
libffi \
leptonica-dev \
binutils \
&& mkdir /app
WORKDIR /app
# Copy build artifacts (python site-packages)
COPY --from=builder /usr/lib/python3.6/site-packages /usr/lib/python3.6/site-packages
COPY --from=builder /usr/bin/ocrmypdf /usr/bin/dumppdf.py /usr/bin/latin2ascii.py /usr/bin/pdf2txt.py /usr/bin/img2pdf /usr/bin/chardetect /usr/bin/
# Copy
COPY --from=builder /app/misc/webservice.py /app/
# Copy minimal project files to get the test suite.
COPY --from=builder /app/setup.cfg /app/setup.py /app/README.md /app/
COPY --from=builder /app/requirements /app/requirements
COPY --from=builder /app/tests /app/tests
COPY --from=builder /app/src /app/src
ENTRYPOINT ["/usr/bin/ocrmypdf"]
+3 -8
View File
@@ -62,8 +62,6 @@ matrix:
mkdir -p bin packages mkdir -p bin packages
pip3 install --upgrade pip pip3 install --upgrade pip
pip3 install --upgrade wheel pip3 install --upgrade wheel
wget -q 'https://www.dropbox.com/s/vaq0kbwi6e6au80/unpaper_6.1-1.deb?raw=1' -O packages/unpaper_6.1-1.deb
sudo dpkg -i packages/unpaper_6.1-1.deb
- os: linux - os: linux
dist: xenial dist: xenial
sudo: required sudo: required
@@ -89,12 +87,12 @@ matrix:
- tesseract-ocr-fra - tesseract-ocr-fra
- unpaper - unpaper
# - os: linux # - os: linux
# dist: xenial # dist: bionic
# sudo: required # sudo: required
# language: python # language: python
# python: "3.8" # python: "3.8"
# env: # env:
# - DIST=xenial # - DIST=bionic
# addons: # addons:
# apt: # apt:
# update: true # update: true
@@ -138,10 +136,7 @@ before_cache:
install: install:
- mkdir -p bin - mkdir -p bin
- export PATH=$PWD/bin:$PATH - export PATH=$PWD/bin:$PATH
- pip3 install pycparser # py3.7 workaround for https://github.com/eliben/pycparser/issues/251 - pip3 install -r requirements/main.txt -r requirements/test.txt .
- pip3 install -r requirements/main.txt
- pip3 install --no-deps .
- pip3 install -r requirements/test.txt
script: script:
- tesseract --version - tesseract --version
-43
View File
@@ -1,43 +0,0 @@
# requirements
recursive-include requirements *
# git
include .git_archival.txt
# docker
include .dockerignore
recursive-include .docker *
# tests
include .coveragerc
recursive-include tests *.bin
recursive-include tests *.jpg
recursive-include tests *.jsonl
recursive-include tests *.png
recursive-include tests *.pdf
recursive-include tests *.py
recursive-include tests *.rst
recursive-include tests *.txt
recursive-exclude tests/resources/private *
# documentation
include LICENSE
include *.rst
recursive-exclude .github *
recursive-include docs *.py
recursive-include docs *.rst
recursive-include docs *.svg
recursive-exclude docs/_build *
# support files
recursive-include src/ocrmypdf/data *
include *.py
exclude tasks.py
recursive-exclude .travis *
exclude .travis*
# code
exclude src/ocrmypdf/lib/_leptonica.py
exclude scratch.py
+1 -1
View File
@@ -47,7 +47,7 @@ where the PDFs are stored):
.. code-block:: bash .. code-block:: bash
find . -printf '%p' -name '*.pdf' -exec docker run --rm -v <host dir>:<container dir> jbarlow83/ocrmypdf-alpine '<container dir>/{}' '<container dir>/{}' \; find . -printf '%p' -name '*.pdf' -exec docker run --rm -v <host dir>:<container dir> jbarlow83/ocrmypdf '<container dir>/{}' '<container dir>/{}' \;
This only runs one ``ocrmypdf`` process at a time. This variation uses This only runs one ``ocrmypdf`` process at a time. This variation uses
``find`` to create a directory list and ``parallel`` to parallelize runs ``find`` to create a directory list and ``parallel`` to parallelize runs
+9
View File
@@ -216,6 +216,15 @@ processing or PDF/A conversion.
ocrmypdf --tesseract-timeout=0 --remove-background input.pdf output.pdf ocrmypdf --tesseract-timeout=0 --remove-background input.pdf output.pdf
Optimize images without performing OCR
--------------------------------------
You can also optimize all images without performing any OCR:
.. code-block:: bash
ocrmypdf --tesseract-timeout=0 --optimize 3 --skip-text input.pdf output.pdf
Redo existing OCR Redo existing OCR
================= =================
+22 -27
View File
@@ -22,21 +22,20 @@ Installing the Docker image
If you have `Docker <https://docs.docker.com/>`__ installed on your If you have `Docker <https://docs.docker.com/>`__ installed on your
system, you can install a Docker image of the latest release. system, you can install a Docker image of the latest release.
The recommended OCRmyPDF Docker image is currently named If you can run this command successfully, your system is ready to download and
``ocrmypdf-alpine``:
.. code-block:: bash
docker pull jbarlow83/ocrmypdf-alpine
Follow the Docker installation instructions for your platform. If you
can run this command successfully, your system is ready to download and
execute the image: execute the image:
.. code-block:: bash .. code-block:: bash
docker run hello-world docker run hello-world
The recommended OCRmyPDF Docker image is currently named ``ocrmypdf``:
.. code-block:: bash
docker pull jbarlow83/ocrmypdf
OCRmyPDF will use all available CPU cores. By default, the VirtualBox OCRmyPDF will use all available CPU cores. By default, the VirtualBox
machine instance on Windows and macOS has only a single CPU core machine instance on Windows and macOS has only a single CPU core
enabled. Use the VirtualBox Manager to determine the name of your Docker enabled. Use the VirtualBox Manager to determine the name of your Docker
@@ -51,6 +50,9 @@ CPUs:
docker-machine start "yourVM" docker-machine start "yourVM"
eval $(docker-machine env "yourVM") eval $(docker-machine env "yourVM")
See the Docker documentation for
`adjusting memory and CPU on other platforms <https://docs.docker.com/config/containers/resource_constraints/>`__.
Using the Docker image on the command line Using the Docker image on the command line
========================================== ==========================================
@@ -63,7 +65,7 @@ To start a Docker container (instance of the image):
.. code-block:: bash .. code-block:: bash
docker tag jbarlow83/ocrmypdf-alpine ocrmypdf docker tag jbarlow83/ocrmypdf ocrmypdf
docker run --rm -i ocrmypdf (... all other arguments here...) docker run --rm -i ocrmypdf (... all other arguments here...)
For convenience, create a shell alias to hide the Docker command. It is For convenience, create a shell alias to hide the Docker command. It is
@@ -103,7 +105,7 @@ on the public one:
.. code-block:: dockerfile .. code-block:: dockerfile
FROM jbarlow83/ocrmypdf-alpine FROM jbarlow83/ocrmypdf
# Add French # Add French
RUN apk add tesseract-ocr-data-fra RUN apk add tesseract-ocr-data-fra
@@ -117,17 +119,16 @@ The OCRmyPDF test suite is installed with image. To run it:
.. code-block:: bash .. code-block:: bash
docker run --entrypoint python3 jbarlow83/ocrmypdf-alpine setup.py test docker run --entrypoint python3 jbarlow83/ocrmypdf -m pytest
Accessing the shell Accessing the shell
=================== ===================
``bash`` is not installed in the image. To use the busybox shell in the To use the bash shell in the Docker image:
Docker image:
.. code-block:: bash .. code-block:: bash
docker run -it --entrypoint busybox jbarlow83/ocrmypdf-alpine sh docker run -it --entrypoint bash jbarlow83/ocrmypdf
Using the OCRmyPDF web service wrapper Using the OCRmyPDF web service wrapper
====================================== ======================================
@@ -137,7 +138,12 @@ service. The webservice may be launched as follows:
.. code-block:: bash .. code-block:: bash
docker run --entrypoint python3 -p 5000:5000 jbarlow83/ocrmypdf-alpine webservice.py docker run --entrypoint python3 -p 5000:5000 jbarlow83/ocrmypdf webservice.py
This will configure the machine to listen on port 5000. On Linux machines
this is port 5000 of localhost. On macOS or Windows machines running
Docker, this is port 5000 of the virtual machine that runs your Docker
images. You can find its IP address using the command ``docker-machine ip``.
Unlike command line usage this program will open a socket and wait for Unlike command line usage this program will open a socket and wait for
connections. connections.
@@ -162,14 +168,3 @@ also licensed in this way.
In addition to the above, please read our In addition to the above, please read our
:ref:`general remarks on using OCRmyPDF as a service <ocr-service>`. :ref:`general remarks on using OCRmyPDF as a service <ocr-service>`.
Ubuntu-based Docker image
=========================
A Ubuntu-based OCRmyPDF image is also available. The main advantage this
image offers is that it supports manylinux Python wheels (which are not
supported on Alpine Linux). This may be useful for plugins.
.. code-block:: bash
docker pull jbarlow83/ocrmypdf
+5 -9
View File
@@ -272,15 +272,11 @@ Now we need to install ``pip`` and let it install ocrmypdf:
curl https://bootstrap.pypa.io/ez_setup.py -o - | python3.6 && python3.6 -m easy_install pip curl https://bootstrap.pypa.io/ez_setup.py -o - | python3.6 && python3.6 -m easy_install pip
pip3.6 install ocrmypdf pip3.6 install ocrmypdf
These installation instructions omit the optional dependency The optional dependency ``unpaper`` is only available at 0.4.2 in Ubuntu 14.04,
``unpaper``, which is only available at version 0.4.2 in Ubuntu 14.04. and no backports are available. Previously the author maintained a backported
The author could not find a backport of ``unpaper``, and created a .deb .deb package for unpaper 6.1, but since Ubuntu 14.04 is now end of life, this is
package to do the job of installing unpaper 6.1 (for x86 64-bit only): not supported. As such, ``unpaper`` is not available on Ubuntu 14.04 or must by
compiled by hand.
.. code-block:: bash
wget -q 'https://www.dropbox.com/s/vaq0kbwi6e6au80/unpaper_6.1-1.deb?raw=1' -O unpaper_6.1-1.deb
sudo dpkg -i unpaper_6.1-1.deb
To add JBIG2 encoding, see :ref:`jbig2`. To add JBIG2 encoding, see :ref:`jbig2`.
+1 -1
View File
@@ -208,7 +208,7 @@ consider one of these similar open source programs:
Web front-ends Web front-ends
============== ==============
The Docker image ``ocrmypdf-alpine`` provides a web service front-end The Docker image ``ocrmypdf`` provides a web service front-end
that allows files to submitted over HTTP and the results "downloaded". that allows files to submitted over HTTP and the results "downloaded".
This is an HTTP server intended to simplify web services deployments; it This is an HTTP server intended to simplify web services deployments; it
is not intended to be deployed on the public internet and no real is not intended to be deployed on the public internet and no real
+10
View File
@@ -13,6 +13,16 @@ Note that it is licensed under GPLv3, so scripts that
``import ocrmypdf`` and are released publicly should probably also be ``import ocrmypdf`` and are released publicly should probably also be
licensed under GPLv3. licensed under GPLv3.
v9.0.5
======
- The Alpine Docker image (jbarlow83/ocrmypdf-alpine) has been dropped due to
the difficulties of supporting Alpine Linux.
- The primary Docker image (jbarlow83/ocrmypdf) has been improved to take on
the extra features that used to be exclusive to the Alpine image.
- No changes to application code.
- pdfminer.six version 20191020 is now supported.
v9.0.4 v9.0.4
====== ======
+4 -7
View File
@@ -1,13 +1,10 @@
# requirements.txt can be used to replicate the developer's build environment # requirements.txt can be used to replicate the developer's build environment
# setup.py lists a separate set of requirements that are looser to simplify # setup.py lists a separate set of requirements that are looser to simplify
# installation # installation
chardet == 3.0.4 cffi == 1.13.2
cffi == 1.12.2
img2pdf == 0.3.3 img2pdf == 0.3.3
pdfminer.six == 20181108 pdfminer.six == 20191020
pikepdf == 1.6.5 pikepdf == 1.6.5
Pillow >= 6.2.0 Pillow >= 6.2.0
pycparser == 2.19 reportlab == 3.5.32
python-xmp-toolkit == 2.0.1 tqdm == 4.37.0
reportlab == 3.5.13
tqdm == 4.32.1
+1 -1
View File
@@ -2,7 +2,7 @@ pytest >= 5.0.0
pytest-helpers-namespace >= 2019.1.8 pytest-helpers-namespace >= 2019.1.8
pytest-xdist >= 1.29.0 # For DumpError fix pytest-xdist >= 1.29.0 # For DumpError fix
pytest-cov >= 2.6.1 pytest-cov >= 2.6.1
python-xmp-toolkit # requires apt-get install libexempi3 python-xmp-toolkit == 2.0.1 # requires apt-get install libexempi3
# or brew install exempi # or brew install exempi
PyPDF2 >= 1.26.0 PyPDF2 >= 1.26.0
#PyMuPDF == 1.13.4 # optional #PyMuPDF == 1.13.4 # optional
+1
View File
@@ -0,0 +1 @@
Flask >= 1, < 2
+1 -1
View File
@@ -96,7 +96,7 @@ setup(
'chardet >= 3.0.4, < 4', # unlisted requirement of pdfminer.six 20181108 'chardet >= 3.0.4, < 4', # unlisted requirement of pdfminer.six 20181108
'cffi >= 1.9.1', # must be a setup and install requirement 'cffi >= 1.9.1', # must be a setup and install requirement
'img2pdf >= 0.3.0, < 0.4', # pure Python, so track HEAD closely 'img2pdf >= 0.3.0, < 0.4', # pure Python, so track HEAD closely
'pdfminer.six == 20181108', 'pdfminer.six >= 20181108, <= 20191020',
'pikepdf >= 1.6.5, < 2', 'pikepdf >= 1.6.5, < 2',
'Pillow >= 6.2.0', 'Pillow >= 6.2.0',
'reportlab >= 3.3.0', # oldest released version with sane image handling 'reportlab >= 3.3.0', # oldest released version with sane image handling
+38 -33
View File
@@ -20,6 +20,7 @@ from math import copysign
from pathlib import Path from pathlib import Path
from unittest.mock import patch from unittest.mock import patch
import pdfminer
import pdfminer.encodingdb import pdfminer.encodingdb
import pdfminer.pdfdevice import pdfminer.pdfdevice
import pdfminer.pdfinterp import pdfminer.pdfinterp
@@ -36,51 +37,54 @@ from ..exceptions import EncryptedPdfError
STRIP_NAME = re.compile(r'[0-9]+') STRIP_NAME = re.compile(r'[0-9]+')
# #
# Unconditional pdfminer patches # pdfminer 20181108 patches
# #
if pdfminer.__version__ == '20181108':
def name2unicode(name): def name2unicode(name):
"""Fix pdfminer's name2unicode function """Fix pdfminer's name2unicode function
Font cids that are mapped to names of the form /g123 seem to be, by convention Font cids that are mapped to names of the form /g123 seem to be, by convention
characters with no corresponding Unicode entry. These can be subsetted fonts characters with no corresponding Unicode entry. These can be subsetted fonts
or symbolic fonts. There seems to be no way to map /g123 fonts to Unicode, or symbolic fonts. There seems to be no way to map /g123 fonts to Unicode,
barring a ToUnicode data structure. barring a ToUnicode data structure.
""" """
if name in glyphname2unicode: if name in glyphname2unicode:
return glyphname2unicode[name] return glyphname2unicode[name]
if name.startswith('g') or name.startswith('a'): if name.startswith('g') or name.startswith('a'):
raise KeyError(name)
if name.startswith('uni'):
try:
return chr(int(name[3:], 16))
except ValueError: # Not hexadecimal
raise KeyError(name) raise KeyError(name)
m = STRIP_NAME.search(name) if name.startswith('uni'):
if not m: try:
raise KeyError(name) return chr(int(name[3:], 16))
return chr(int(m.group(0))) except ValueError: # Not hexadecimal
raise KeyError(name)
m = STRIP_NAME.search(name)
if not m:
raise KeyError(name)
return chr(int(m.group(0)))
pdfminer.encodingdb.name2unicode = name2unicode
pdfminer.encodingdb.name2unicode = name2unicode original_PDFFont_init = PDFFont.__init__
original_PDFFont_init = PDFFont.__init__ def PDFFont__init__(self, descriptor, widths, default_width=None):
original_PDFFont_init(self, descriptor, widths, default_width)
# PDF spec says descent should be negative
# A font with a positive descent implies it floats entirely above the
# baseline, i.e. it's not really a baseline anymore. I have fonts that
# claim a positive descent, but treating descent as positive always seems
# to misposition text.
if self.descent > 0:
self.descent = -self.descent
PDFFont.__init__ = PDFFont__init__
def PDFFont__init__(self, descriptor, widths, default_width=None): #
original_PDFFont_init(self, descriptor, widths, default_width) # end of pdfminer 20181108 patches
# PDF spec says descent should be negative #
# A font with a positive descent implies it floats entirely above the
# baseline, i.e. it's not really a baseline anymore. I have fonts that
# claim a positive descent, but treating descent as positive always seems
# to misposition text.
if self.descent > 0:
self.descent = -self.descent
PDFFont.__init__ = PDFFont__init__
original_PDFSimpleFont_init = PDFSimpleFont.__init__ original_PDFSimpleFont_init = PDFSimpleFont.__init__
@@ -97,6 +101,7 @@ def PDFSimpleFont__init__(self, descriptor, widths, spec):
PDFSimpleFont.__init__ = PDFSimpleFont__init__ PDFSimpleFont.__init__ = PDFSimpleFont__init__
# #
# pdfminer patches when creator is PScript5.dll # pdfminer patches when creator is PScript5.dll
# #
+5
View File
@@ -19,6 +19,11 @@ from subprocess import run, PIPE
import pytest import pytest
pytestmark = pytest.mark.skipif(
pytest.helpers.running_in_docker(), # pylint: disable=no-member
reason="docker can't complete",
)
def test_fish(): def test_fish():
try: try: