diff --git a/misc/webservice.py b/misc/webservice.py index 677561d5..ed2a0374 100644 --- a/misc/webservice.py +++ b/misc/webservice.py @@ -23,21 +23,22 @@ to emphasize that SaaS deployments should make sure they comply with Ghostscript's license as well as OCRmyPDF's. """ +import os +import shlex +from subprocess import PIPE, run +from tempfile import TemporaryDirectory + from flask import ( Flask, Response, - flash, - request, - redirect, - url_for, abort, + flash, + redirect, + request, send_from_directory, + url_for, ) -from subprocess import run, PIPE -from tempfile import TemporaryDirectory from werkzeug.utils import secure_filename -import os -import shlex app = Flask(__name__) app.secret_key = "secret" diff --git a/src/ocrmypdf/__init__.py b/src/ocrmypdf/__init__.py index ad4b3068..9bbd2aa3 100644 --- a/src/ocrmypdf/__init__.py +++ b/src/ocrmypdf/__init__.py @@ -24,24 +24,19 @@ __version__ = pkg_resources.get_distribution('ocrmypdf').version VERSION = __version__ +from . import helpers, hocrtransform, leptonica, pdfa, pdfinfo +from .api import Verbosity, configure_logging, ocr from .exceptions import ( - ExitCode, BadArgsError, - PdfMergeFailedError, - MissingDependencyError, - UnsupportedImageFormatError, DpiError, - OutputFileAccessError, - PriorOcrFoundError, - InputFileError, - SubprocessOutputError, EncryptedPdfError, + ExitCode, + InputFileError, + MissingDependencyError, + OutputFileAccessError, + PdfMergeFailedError, + PriorOcrFoundError, + SubprocessOutputError, TesseractConfigError, + UnsupportedImageFormatError, ) - -from . import helpers -from . import hocrtransform -from . import leptonica -from . import pdfa -from . import pdfinfo -from .api import ocr, configure_logging, Verbosity diff --git a/src/ocrmypdf/__main__.py b/src/ocrmypdf/__main__.py index c24796af..bcfd6528 100755 --- a/src/ocrmypdf/__main__.py +++ b/src/ocrmypdf/__main__.py @@ -21,12 +21,12 @@ import os import sys from . import __version__ -from .cli import parser -from .api import configure_logging, Verbosity from ._jobcontext import make_logger from ._sync import run_pipeline from ._validation import check_closed_streams, check_options -from .exceptions import ExitCode, BadArgsError, MissingDependencyError +from .api import Verbosity, configure_logging +from .cli import parser +from .exceptions import BadArgsError, ExitCode, MissingDependencyError def run(args=None): diff --git a/src/ocrmypdf/_jobcontext.py b/src/ocrmypdf/_jobcontext.py index 96ad6c7e..e50aa75a 100644 --- a/src/ocrmypdf/_jobcontext.py +++ b/src/ocrmypdf/_jobcontext.py @@ -16,9 +16,9 @@ # along with OCRmyPDF. If not, see . import logging +import os import shutil import sys -import os class PicklableLoggerMixin: diff --git a/src/ocrmypdf/_pipeline.py b/src/ocrmypdf/_pipeline.py index 02042112..0a846bfd 100644 --- a/src/ocrmypdf/_pipeline.py +++ b/src/ocrmypdf/_pipeline.py @@ -22,18 +22,17 @@ from datetime import datetime, timezone from shutil import copyfileobj import img2pdf -from PIL import Image - import pikepdf from pikepdf.models.metadata import encode_pdf_date +from PIL import Image from . import PROGRAM_NAME, VERSION, leptonica from .exceptions import ( DpiError, EncryptedPdfError, InputFileError, - UnsupportedImageFormatError, PriorOcrFoundError, + UnsupportedImageFormatError, ) from .exec import ghostscript, tesseract from .helpers import re_symlink diff --git a/src/ocrmypdf/_sync.py b/src/ocrmypdf/_sync.py index b2c9461e..5cb7bd8a 100644 --- a/src/ocrmypdf/_sync.py +++ b/src/ocrmypdf/_sync.py @@ -28,6 +28,7 @@ from tempfile import mkdtemp from tqdm import tqdm from . import __version__ +from ._graft import OcrGrafter from ._jobcontext import PDFContext, cleanup_working_files, make_logger from ._pipeline import ( convert_to_pdfa, @@ -59,7 +60,6 @@ from ._validation import ( create_input_file, report_output_file_size, ) -from ._graft import OcrGrafter from .exceptions import ExitCode, ExitCodeException from .exec import qpdf from .helpers import available_cpu_count diff --git a/src/ocrmypdf/_validation.py b/src/ocrmypdf/_validation.py index 5c9bc2a1..c957d989 100644 --- a/src/ocrmypdf/_validation.py +++ b/src/ocrmypdf/_validation.py @@ -41,7 +41,7 @@ from .exec import ( tesseract, unpaper, ) -from .helpers import is_file_writable, re_symlink, is_iterable_notstr, monotonic +from .helpers import is_file_writable, is_iterable_notstr, monotonic, re_symlink # ------------- # External dependencies diff --git a/src/ocrmypdf/api.py b/src/ocrmypdf/api.py index bc4a4e5a..2c862d81 100644 --- a/src/ocrmypdf/api.py +++ b/src/ocrmypdf/api.py @@ -23,9 +23,9 @@ from pathlib import Path from tqdm import tqdm -from .cli import parser from ._sync import run_pipeline from ._validation import check_options +from .cli import parser class TqdmConsole: diff --git a/src/ocrmypdf/exec/__init__.py b/src/ocrmypdf/exec/__init__.py index 28193a01..c1a18c9a 100644 --- a/src/ocrmypdf/exec/__init__.py +++ b/src/ocrmypdf/exec/__init__.py @@ -21,9 +21,10 @@ import logging import os import re import sys -from subprocess import run, STDOUT, PIPE, CalledProcessError -from ..exceptions import MissingDependencyError, ExitCode from collections.abc import Mapping +from subprocess import PIPE, STDOUT, CalledProcessError, run + +from ..exceptions import ExitCode, MissingDependencyError log = logging.Logger(__name__) diff --git a/src/ocrmypdf/exec/ghostscript.py b/src/ocrmypdf/exec/ghostscript.py index b39ff628..48cceff2 100644 --- a/src/ocrmypdf/exec/ghostscript.py +++ b/src/ocrmypdf/exec/ghostscript.py @@ -28,7 +28,6 @@ from PIL import Image from ..exceptions import SubprocessOutputError from . import get_version - gslog = logging.getLogger() diff --git a/src/ocrmypdf/exec/jbig2enc.py b/src/ocrmypdf/exec/jbig2enc.py index 771e58a3..696c899c 100644 --- a/src/ocrmypdf/exec/jbig2enc.py +++ b/src/ocrmypdf/exec/jbig2enc.py @@ -18,8 +18,8 @@ from functools import lru_cache from subprocess import PIPE, run -from . import get_version from ..exceptions import MissingDependencyError +from . import get_version @lru_cache(maxsize=1) diff --git a/src/ocrmypdf/exec/pngquant.py b/src/ocrmypdf/exec/pngquant.py index 536dca1c..f22bb68e 100644 --- a/src/ocrmypdf/exec/pngquant.py +++ b/src/ocrmypdf/exec/pngquant.py @@ -21,8 +21,8 @@ from tempfile import NamedTemporaryFile from PIL import Image -from . import get_version from ..exceptions import MissingDependencyError +from . import get_version @lru_cache(maxsize=1) diff --git a/src/ocrmypdf/exec/tesseract.py b/src/ocrmypdf/exec/tesseract.py index 863047a1..3b5a647a 100644 --- a/src/ocrmypdf/exec/tesseract.py +++ b/src/ocrmypdf/exec/tesseract.py @@ -24,13 +24,13 @@ from functools import lru_cache from os import fspath from subprocess import PIPE, STDOUT, CalledProcessError, TimeoutExpired, run -from . import get_version from ..exceptions import ( MissingDependencyError, - TesseractConfigError, SubprocessOutputError, + TesseractConfigError, ) from ..helpers import page_number +from . import get_version OrientationConfidence = namedtuple('OrientationConfidence', ('angle', 'confidence')) diff --git a/src/ocrmypdf/exec/unpaper.py b/src/ocrmypdf/exec/unpaper.py index 9c9db5d5..d3ee1ea4 100644 --- a/src/ocrmypdf/exec/unpaper.py +++ b/src/ocrmypdf/exec/unpaper.py @@ -26,11 +26,11 @@ from functools import lru_cache from subprocess import PIPE, STDOUT, CalledProcessError from tempfile import TemporaryDirectory -from . import get_version -from ..exceptions import MissingDependencyError, SubprocessOutputError - from PIL import Image +from ..exceptions import MissingDependencyError, SubprocessOutputError +from . import get_version + @lru_cache(maxsize=1) def version(): diff --git a/src/ocrmypdf/filters.py b/src/ocrmypdf/filters.py index e51381bf..7e904876 100644 --- a/src/ocrmypdf/filters.py +++ b/src/ocrmypdf/filters.py @@ -1,5 +1,5 @@ -from PIL import Image import PIL.ImageOps +from PIL import Image def invert(im): diff --git a/src/ocrmypdf/optimize.py b/src/ocrmypdf/optimize.py index 405f48af..eb559eb9 100644 --- a/src/ocrmypdf/optimize.py +++ b/src/ocrmypdf/optimize.py @@ -22,15 +22,15 @@ from collections import defaultdict from os import fspath from pathlib import Path +import pikepdf +from pikepdf import Dictionary, Name from PIL import Image from tqdm import tqdm -import pikepdf -from pikepdf import Name, Dictionary from . import leptonica from ._jobcontext import PDFContext -from .exec import jbig2enc, pngquant from .exceptions import OutputFileAccessError +from .exec import jbig2enc, pngquant from .helpers import re_symlink DEFAULT_JPEG_QUALITY = 75 diff --git a/src/ocrmypdf/pdfa.py b/src/ocrmypdf/pdfa.py index 684254e7..93dfd849 100644 --- a/src/ocrmypdf/pdfa.py +++ b/src/ocrmypdf/pdfa.py @@ -36,9 +36,8 @@ from binascii import hexlify from pathlib import Path from string import Template -import pkg_resources - import pikepdf +import pkg_resources ICC_PROFILE_RELPATH = 'data/sRGB.icc' diff --git a/src/ocrmypdf/pdfinfo/__init__.py b/src/ocrmypdf/pdfinfo/__init__.py index 83cf9a48..093fea5e 100644 --- a/src/ocrmypdf/pdfinfo/__init__.py +++ b/src/ocrmypdf/pdfinfo/__init__.py @@ -16,4 +16,4 @@ # You should have received a copy of the GNU General Public License # along with OCRmyPDF. If not, see . -from .info import PdfInfo, Colorspace, Encoding +from .info import Colorspace, Encoding, PdfInfo diff --git a/src/ocrmypdf/pdfinfo/info.py b/src/ocrmypdf/pdfinfo/info.py index 4d93d4f7..964c3036 100644 --- a/src/ocrmypdf/pdfinfo/info.py +++ b/src/ocrmypdf/pdfinfo/info.py @@ -16,23 +16,24 @@ # You should have received a copy of the GNU General Public License # along with OCRmyPDF. If not, see . +import logging +import re from collections import namedtuple from decimal import Decimal from enum import Enum -import logging from math import hypot, isclose from os import fspath from pathlib import Path from warnings import warn -import re -from pikepdf import PdfMatrix import pikepdf +from pikepdf import PdfMatrix from tqdm import tqdm +from ocrmypdf.exceptions import EncryptedPdfError, MissingDependencyError + from . import ghosttext from .layout import get_page_analysis, get_text_boxes -from ocrmypdf.exceptions import EncryptedPdfError, MissingDependencyError logger = logging.getLogger() diff --git a/tests/cache/graph_ocred/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin b/tests/cache/graph_ocred/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin new file mode 100644 index 00000000..ce1b6144 Binary files /dev/null and b/tests/cache/graph_ocred/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin differ diff --git a/tests/cache/graph_ocred/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stderr.bin b/tests/cache/graph_ocred/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stderr.bin new file mode 100644 index 00000000..61f78d82 --- /dev/null +++ b/tests/cache/graph_ocred/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stderr.bin @@ -0,0 +1 @@ +Tesseract Open Source OCR Engine v4.0.0 with Leptonica diff --git a/tests/cache/graph_ocred/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stdout.bin b/tests/cache/graph_ocred/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/stdout.bin new file mode 100644 index 00000000..e69de29b diff --git a/tests/cache/graph_ocred/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/txt.bin b/tests/cache/graph_ocred/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/txt.bin new file mode 100644 index 00000000..25fdded2 --- /dev/null +++ b/tests/cache/graph_ocred/__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt/txt.bin @@ -0,0 +1,13 @@ +Portez ce vieux whisky au juge +blond qui fume sur son Ile +interieure, a cöte de l'alcöve +ovoide, oU les büches se +consument dans l'ätre, ce qui +lui permet de penser & la +caenogenese de |'etre dont il +est question dans la cause +ambigu& entendue a MoY, dans +un capharnaüm qui, pense-t-il, +diminue ca et la la qualite de son +ceuvre. + \ No newline at end of file diff --git a/tests/cache/manifest.jsonl b/tests/cache/manifest.jsonl index c9a1fc25..73520981 100644 --- a/tests/cache/manifest.jsonl +++ b/tests/cache/manifest.jsonl @@ -65,3 +65,4 @@ {"tesseract_version": "tesseract 4.0.0 leptonica-1.78.0 libgif 5.1.4 : libjpeg 9c : libpng 1.6.37 : libtiff 4.0.10 : zlib 1.2.11 : libwebp 1.0.2 : libopenjp2 2.3.1 Found AVX2 Found AVX Found SSE ", "platform": "Darwin-18.5.0-x86_64-i386-64bit", "python": "3.7.3", "argv_slug": "__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/poster.pdf", "args": ["-l", "eng", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]} {"tesseract_version": "tesseract 4.0.0 leptonica-1.78.0 libgif 5.1.4 : libjpeg 9c : libpng 1.6.37 : libtiff 4.0.10 : zlib 1.2.11 : libwebp 1.0.2 : libopenjp2 2.3.1 Found AVX2 Found AVX Found SSE ", "platform": "Darwin-18.6.0-x86_64-i386-64bit", "python": "3.7.3", "argv_slug": "__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/cmyk.pdf", "args": ["-l", "deu", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]} {"tesseract_version": "tesseract 4.0.0 leptonica-1.78.0 libgif 5.1.4 : libjpeg 9c : libpng 1.6.37 : libtiff 4.0.10 : zlib 1.2.11 : libwebp 1.0.2 : libopenjp2 2.3.1 Found AVX2 Found AVX Found SSE ", "platform": "Darwin-18.6.0-x86_64-i386-64bit", "python": "3.7.3", "argv_slug": "__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/lichtenstein.pdf", "args": ["-l", "deu", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]} +{"tesseract_version": "tesseract 4.0.0 leptonica-1.78.0 libgif 5.1.4 : libjpeg 9c : libpng 1.6.37 : libtiff 4.0.10 : zlib 1.2.11 : libwebp 1.0.3 : libopenjp2 2.3.1 Found AVX2 Found AVX Found SSE ", "platform": "Darwin-18.6.0-x86_64-i386-64bit", "python": "3.7.4", "argv_slug": "__-l__deu__000001_ocr.png__000001_ocr_tess__pdf__txt", "sourcefile": "resources/graph_ocred.pdf", "args": ["-l", "deu", "-c", "textonly_pdf=1", "$TMPDIR/000001_ocr.png", "$TMPDIR/000001_ocr_tess", "pdf", "txt"]}