Repository: paperless-ngx/paperless-ngx

Issue:
[BUG] OCR_USER_ARGS not used when forcing ocr
### Description

During a fallback ocr attempt with force_ocr: true, any provided OCR_USER_ARGS are ignored.

### Steps to reproduce

1. Have a file with both a digital signature and a user fillable form.
2. Have `"invalidate_digital_signatures": true` set in `PAPERLESS_OCR_USER_ARGS` so digital signatures are ignored when consuming.
3. Attempt to consume or to redo ocr on the file.
4. First attempt to ocr will fail because of the form.
5. Second automated attempt with `'force_ocr': true` will also fail because this time `PAPERLESS_OCR_USER_ARGS` will not be used at all and an error will be thrown because of the included signature.

### Webserver logs

```bash
[2023-12-13 21:49:04,119] [DEBUG] [paperless.parsing.tesseract] Calling OCRmyPDF with args: {'input_file': PosixPath('/tmp/paperless/paperless-ngx1fy9lzv9/Consors_Contract_iPhone_15_Pro.pdf'), 'output_file': PosixPath('/tmp/paperless/paperless-jz9xb_sg/archive.pdf'), 'use_threads': True, 'jobs': 4, 'language': 'eng+deu+pol', 'output_type': 'pdfa', 'progress_bar': False, 'color_conversion_strategy': 'RGB', 'redo_ocr': True, 'clean': True, 'rotate_pages': True, 'rotate_pages_threshold': 12.0, 'sidecar': PosixPath('/tmp/paperless/paperless-jz9xb_sg/sidecar.txt'), 'invalidate_digital_signatures': True}

[2023-12-13 21:49:11,642] [WARNING] [paperless.parsing.tesseract] Encountered an error while running OCR: This PDF has a user fillable form. --redo-ocr is not currently possible on such files.. Attempting force OCR to get the text.

[2023-12-13 21:49:11,642] [DEBUG] [paperless.parsing.tesseract] Fallback: Calling OCRmyPDF with args: {'input_file': PosixPath('/tmp/paperless/paperless-ngx1fy9lzv9/Consors_Contract_iPhone_15_Pro.pdf'), 'output_file': PosixPath('/tmp/paperless/paperless-jz9xb_sg/archive-fallback.pdf'), 'use_threads': True, 'jobs': 4, 'language': 'eng+deu+pol', 'output_type': 'pdfa', 'progress_bar': False, 'color_conversion_strategy': 'RGB', 'force_ocr': True, 'clean': True, 'rotate_pages': True, 'rotate_pages_threshold': 12.0, 'sidecar': PosixPath('/tmp/paperless/paperless-jz9xb_sg/sidecar-fallback.txt')}

[2023-12-13 21:49:12,793] [ERROR] [paperless.consumer] Error occurred while consuming document Consors_Contract_iPhone_15_Pro.pdf: DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,

invalidating the signature.

Traceback (most recent call last):

  File "/usr/src/paperless/src/paperless_tesseract/parsers.py", line 330, in parse

    ocrmypdf.ocr(**args)

  File "/usr/local/lib/python3.11/site-packages/ocrmypdf/api.py", line 375, in ocr

    return run_pipeline(options=options, plugin_manager=plugin_manager)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 225, in run_pipeline

    return _run_pipeline(options, plugin_manager)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 189, in _run_pipeline

    validate_pdfinfo_options(context)

  File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipeline.py", line 205, in validate_pdfinfo_options

    raise InputFileError(

ocrmypdf.exceptions.InputFileError: This PDF has a user fillable form. --redo-ocr is not currently possible on such files.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

  File "/usr/src/paperless/src/paperless_tesseract/parsers.py", line 381, in parse

    ocrmypdf.ocr(**args)

  File "/usr/local/lib/python3.11/site-packages/ocrmypdf/api.py", line 375, in ocr

    return run_pipeline(options=options, plugin_manager=plugin_manager)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 225, in run_pipeline

    return _run_pipeline(options, plugin_manager)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipelines/ocr.py", line 189, in _run_pipeline

    validate_pdfinfo_options(context)

  File "/usr/local/lib/python3.11/site-packages/ocrmypdf/_pipeline.py", line 202, in validate_pdfinfo_options

    raise DigitalSignatureError()

ocrmypdf.exceptions.DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,

invalidating the signature.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

  File "/usr/local/lib/python3.11/site-packages/asgiref/sync.py", line 349, in main_wrap

    raise exc_info[1]

  File "/usr/src/paperless/src/documents/consumer.py", line 446, in try_consume_file

    document_parser.parse(self.path, mime_type, self.filename)

  File "/usr/src/paperless/src/paperless_tesseract/parsers.py", line 393, in parse

    raise ParseError(f"{e.__class__.__name__}: {e!s}") from e

documents.parsers.ParseError: DigitalSignatureError: Input PDF has a digital signature. OCR would alter the document,

invalidating the signature.
```


### Browser logs

_No response_

### Paperless-ngx version

2.1.2

### Host OS

Paperless runs in Docker on QNAP NAS with Intel CPU

### Installation method

Docker - official image

### Browser

_No response_

### Configuration changes

      PAPERLESS_OCR_LANGUAGES: eng deu pol       PAPERLESS_OCR_LANGUAGE: eng+deu+pol       PAPERLESS_OCR_MODE: redo       PAPERLESS_OCR_USER_ARGS: '{"invalidate_digital_signatures": true}'

### Other

The first three lines of the logs show what I assume to be the cause of the error, the argument is not visible in the third line. 


Discussion:
Environment variables require recrration of a docker container to be picked up.
This is actually the fallback that is failing, which very deliberatly does not apply user arguments:
https://github.com/paperless-ngx/paperless-ngx/blob/cd38c39908ea2013d6a7f63f55534b583c4a2c2d/src/paperless_tesseract/parsers.py#L257-L261

I assume this was a choice for a reason, but I will have to examine the history to see if I can find out why
Ah, my bad, thanks
I have to admit @shamoon, after putting in the effort to report a bug properly, and the log showing in the very first line that the arg was used (so the container was recreated), then such a quick and dismissive closure of this issue feels disheartening.

Thanks @stumpylog for looking into this, and no problem if this cannot be fixed because there is a good reason to not use args in the fallback.
Give me a break, it was a mistake, I already apologized. We handle numerous "bug reports", the vast majority are user error, there were a few related to a similar thing earlier today.

If you had pointed out my mistake I would have been happy to re-open it as well, but yes, Im glad stumpylog did.

Please keep the drama out of it.
Providing feedback does not equal drama. I think we might have different communication styles, that happens. 

And rather than debate that further I fully agree with you to no longer distract from the actual software issue at hand.
Well, the protection was added in ce121a261d3c4f88b829002106d172e9c892f8f5.  I was hoping for a little more explanation or a pull request I could read through.  I assume it was added because a user's settings could override something when we're forcing OCR that ends up either failing or not being compatible.

I'm of the mind to remove that (assuming no tests fail) and adding a warning that setting things may end up being incompatible and we don't support issue with that.  The user is presumably already advanced enough to have read the documentation to find out what they want to set.  Thoughts?
Yea, that sounds good. i suppose risk is we trade one issue for another but I agree that makes more sense

Resolving patch:
diff --git a/src/paperless_tesseract/parsers.py b/src/paperless_tesseract/parsers.py
--- a/src/paperless_tesseract/parsers.py
+++ b/src/paperless_tesseract/parsers.py
@@ -254,7 +254,7 @@ def construct_ocrmypdf_parameters(
                     f"Image DPI of {ocrmypdf_args['image_dpi']} is low, OCR may fail",
                 )
 
-        if settings.OCR_USER_ARGS and not safe_fallback:
+        if settings.OCR_USER_ARGS:
             try:
                 user_args = json.loads(settings.OCR_USER_ARGS)
                 ocrmypdf_args = {**ocrmypdf_args, **user_args}


Test patch: