Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae123fd209 | ||
|
|
454ad0acc5 | ||
|
|
0c306ac328 | ||
|
|
52d99732b1 | ||
|
|
aac913c666 | ||
|
|
b5e73ac4e4 | ||
|
|
9e98c90891 |
@@ -133,6 +133,7 @@ jobs:
|
|||||||
ghostscript \
|
ghostscript \
|
||||||
jbig2enc \
|
jbig2enc \
|
||||||
openjpeg \
|
openjpeg \
|
||||||
|
openssl \
|
||||||
pngquant \
|
pngquant \
|
||||||
tesseract
|
tesseract
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -12,12 +12,12 @@ OCRmyPDF is also available in Docker images that packages recent
|
|||||||
versions of all dependencies.
|
versions of all dependencies.
|
||||||
|
|
||||||
For users who already have Docker installed this may be an easy and
|
For users who already have Docker installed this may be an easy and
|
||||||
convenient option. However, it is less performant than a system
|
convenient option.
|
||||||
installation and may require Docker engine configuration. OCRmyPDF
|
|
||||||
needs a generous amount of RAM, CPU cores, temporary storage
|
On platforms other than Linux, Docker runs in a virtual machine, and so may
|
||||||
space, whether running in a Docker container or on its own. It may be
|
be less performant. You may also want to adjust the Docker virtual machine's
|
||||||
necessary to ensure the container is provisioned with additional
|
memory and CPU allocation. On Linux, the Docker image runs natively and
|
||||||
resources.
|
performance is comparable to a system installation.
|
||||||
|
|
||||||
.. _docker-install:
|
.. _docker-install:
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,13 @@ tagged yet.
|
|||||||
|
|
||||||
.. |OCRmyPDF PyPI| image:: https://img.shields.io/pypi/v/ocrmypdf.svg
|
.. |OCRmyPDF PyPI| image:: https://img.shields.io/pypi/v/ocrmypdf.svg
|
||||||
|
|
||||||
|
v15.3.1
|
||||||
|
=======
|
||||||
|
|
||||||
|
- Fixed an issue with logging settings for misc/watcher.py introduced in the
|
||||||
|
previous release. :issue:`1180`
|
||||||
|
- Updated documentation on Docker performance concerns.
|
||||||
|
|
||||||
v15.3.0
|
v15.3.0
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -260,12 +260,12 @@ def main(
|
|||||||
ocrmypdf.configure_logging(
|
ocrmypdf.configure_logging(
|
||||||
verbosity=(
|
verbosity=(
|
||||||
ocrmypdf.Verbosity.default
|
ocrmypdf.Verbosity.default
|
||||||
if loglevel != 'DEBUG'
|
if loglevel != LoggingLevelEnum.DEBUG
|
||||||
else ocrmypdf.Verbosity.debug
|
else ocrmypdf.Verbosity.debug
|
||||||
),
|
),
|
||||||
manage_root_logger=True,
|
manage_root_logger=True,
|
||||||
)
|
)
|
||||||
log.setLevel(loglevel)
|
log.setLevel(loglevel.value)
|
||||||
log.info(
|
log.info(
|
||||||
f"Starting OCRmyPDF watcher with config:\n"
|
f"Starting OCRmyPDF watcher with config:\n"
|
||||||
f"Input Directory: {input_dir}\n"
|
f"Input Directory: {input_dir}\n"
|
||||||
@@ -285,7 +285,7 @@ def main(
|
|||||||
f"POLL_NEW_FILE_SECONDS: {poll_new_file_seconds}\n"
|
f"POLL_NEW_FILE_SECONDS: {poll_new_file_seconds}\n"
|
||||||
f"RETRIES_LOADING_FILE: {retries_loading_file}\n"
|
f"RETRIES_LOADING_FILE: {retries_loading_file}\n"
|
||||||
f"USE_POLLING: {use_polling}\n"
|
f"USE_POLLING: {use_polling}\n"
|
||||||
f"LOGLEVEL: {loglevel}"
|
f"LOGLEVEL: {loglevel.value}"
|
||||||
)
|
)
|
||||||
|
|
||||||
json_settings = json.loads(ocr_json_settings.read() if ocr_json_settings else '{}')
|
json_settings = json.loads(ocr_json_settings.read() if ocr_json_settings else '{}')
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
from contextlib import suppress
|
||||||
from math import pi
|
from math import pi
|
||||||
from os import fspath
|
from os import fspath
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -350,7 +351,7 @@ def generate_hocr(
|
|||||||
tesseract_log_output(stdout)
|
tesseract_log_output(stdout)
|
||||||
# The sidecar text file will get the suffix .txt; rename it to
|
# The sidecar text file will get the suffix .txt; rename it to
|
||||||
# whatever caller wants it named
|
# whatever caller wants it named
|
||||||
if prefix.with_suffix('.txt').exists():
|
with suppress(FileNotFoundError):
|
||||||
prefix.with_suffix('.txt').replace(output_text)
|
prefix.with_suffix('.txt').replace(output_text)
|
||||||
|
|
||||||
|
|
||||||
@@ -406,7 +407,7 @@ def generate_pdf(
|
|||||||
try:
|
try:
|
||||||
p = run(args_tesseract, stdout=PIPE, stderr=STDOUT, timeout=timeout, check=True)
|
p = run(args_tesseract, stdout=PIPE, stderr=STDOUT, timeout=timeout, check=True)
|
||||||
stdout = p.stdout
|
stdout = p.stdout
|
||||||
if prefix.with_suffix('.txt').exists():
|
with suppress(FileNotFoundError):
|
||||||
prefix.with_suffix('.txt').replace(output_text)
|
prefix.with_suffix('.txt').replace(output_text)
|
||||||
except TimeoutExpired:
|
except TimeoutExpired:
|
||||||
page_timedout(timeout)
|
page_timedout(timeout)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from collections.abc import Iterable, Iterator, Sequence
|
|||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from shutil import copyfileobj
|
from shutil import copyfileobj, copystat
|
||||||
from typing import Any, BinaryIO, TypeVar, cast
|
from typing import Any, BinaryIO, TypeVar, cast
|
||||||
|
|
||||||
import img2pdf
|
import img2pdf
|
||||||
@@ -1090,14 +1090,14 @@ def merge_sidecars(txt_files: Iterable[Path | None], context: PdfContext) -> Pat
|
|||||||
|
|
||||||
|
|
||||||
def copy_final(
|
def copy_final(
|
||||||
input_file: Path, output_file: str | Path | BinaryIO, _context: PdfContext
|
input_file: Path, output_file: str | Path | BinaryIO, context: PdfContext
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Copy the final temporary file to the output destination.
|
"""Copy the final temporary file to the output destination.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
input_file (Path): The input file to copy.
|
input_file (Path): The intermediate input file to copy.
|
||||||
output_file (str | Path | BinaryIO): The output file to copy to.
|
output_file (str | Path | BinaryIO): The output file to copy to.
|
||||||
_context (PdfContext): The PDF context.
|
context (PdfContext): The PDF context.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
None
|
None
|
||||||
@@ -1116,5 +1116,11 @@ def copy_final(
|
|||||||
# At this point we overwrite the output_file specified by the user
|
# At this point we overwrite the output_file specified by the user
|
||||||
# use copyfileobj because then we use open() to create the file and
|
# use copyfileobj because then we use open() to create the file and
|
||||||
# get the appropriate umask, ownership, etc.
|
# get the appropriate umask, ownership, etc.
|
||||||
with open(output_file, 'wb') as output_stream:
|
with open(output_file, 'w+b') as output_stream:
|
||||||
copyfileobj(input_stream, output_stream)
|
copyfileobj(input_stream, output_stream)
|
||||||
|
# Attempt to copy file attributes from input to output
|
||||||
|
with suppress(OSError):
|
||||||
|
# Copy original file's permissions, ownership, etc. if possible
|
||||||
|
copystat(context.options.input_file, output_file)
|
||||||
|
# Set output file's modification time to now
|
||||||
|
Path(output_file).touch(exist_ok=True)
|
||||||
|
|||||||
+2
-3
@@ -25,9 +25,8 @@ def is_macos():
|
|||||||
|
|
||||||
|
|
||||||
def running_in_docker():
|
def running_in_docker():
|
||||||
# Docker creates a file named /.dockerenv (newer versions) or
|
# Docker creates a file named /.dockerenv in all supported versions
|
||||||
# /.dockerinit (older) -- this is undocumented, not an offical test
|
return Path('/.dockerenv').exists()
|
||||||
return Path('/.dockerenv').exists() or Path('/.dockerinit').exists()
|
|
||||||
|
|
||||||
|
|
||||||
def have_unpaper():
|
def have_unpaper():
|
||||||
|
|||||||
Reference in New Issue
Block a user