We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG] HTTP 500 in Tika for some OpenDocument Documents
### Description

When recreating my local paperless instance, I had to rerun the document archival and thumbnail jobs for all documents.

Those failed for all OpenDocument Documents from my originals. 

I noticed this being related to the latest changes in paperless_tika/parser.py. After testing the parser.py from 1.15 all worked.

I am already working on further investigation on my fork and will start the corresponding pull request.



### Steps to reproduce

upload ODT document -> parsing fails

### Webserver logs

```bash
---TIKA---
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:190)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:191)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.Server.handle(Server.java:516)
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
	at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.io.IOException: Stream Closed
	at java.base/java.io.FileInputStream.available0(Native Method)
	at java.base/java.io.FileInputStream.available(FileInputStream.java:415)
	at org.apache.cxf.attachment.DelegatingInputStream.available(DelegatingInputStream.java:75)
	at org.apache.cxf.helpers.IOUtils.consume(IOUtils.java:382)
	at org.apache.cxf.attachment.DelegatingInputStream.close(DelegatingInputStream.java:46)
	at org.apache.tika.server.core.resource.TikaResource.parse(TikaResource.java:374)
	at org.apache.tika.server.core.resource.TikaResource.parseToMetadata(TikaResource.java:611)
	at org.apache.tika.server.core.resource.TikaResource.getJsonFromMultipart(TikaResource.java:564)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179)
	at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
	... 28 more

---PAPERLESS---
[2023-07-06 17:57:46,034] [INFO] [paperless.consumer] Consuming 2023-03-28 Johannes Gutenberg-Universität Mainz Datenbank Praktikum Gruppe 3.odt
[2023-07-06 17:57:46,112] [INFO] [paperless.parsing.tika] Sending /tmp/paperless/paperless-ngxzed2cbo7/2023-03-28 Johannes Gutenberg-Universität Mainz Datenbank Praktikum Gruppe 3.odt to Tika server
[2023-07-06 17:57:47,289] [ERROR] [paperless.consumer] Error while consuming document 2023-03-28 Johannes Gutenberg-Universität Mainz Datenbank Praktikum Gruppe 3.odt: Could not parse /tmp/paperless/paperless-ngxzed2cbo7/2023-03-28 Johannes Gutenberg-Universität Mainz Datenbank Praktikum Gruppe 3.odt with tika server at http://localhost:9998: Server error '500 Server Error' for url 'http://localhost:9998/tika/form/text'
For more information check: https://httpstatuses.com/500
Traceback (most recent call last):
  File "/usr/src/paperless/src/paperless_tika/parsers.py", line 54, in parse
    parsed = client.tika.as_text.from_file(document_path, mime_type)
  File "/usr/local/lib/python3.9/site-packages/tika_client/_resource_tika.py", line 36, in from_file
    return self._decoded_response(self._put_multipart(self.MULTI_PART_PLAIN_TEXT_CONTENT, filepath, mime_type))
  File "/usr/local/lib/python3.9/site-packages/tika_client/_utils.py", line 46, in _put_multipart
    resp.raise_for_status()
  File "/usr/local/lib/python3.9/site-packages/httpx/_models.py", line 749, in raise_for_status
    raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Server error '500 Server Error' for url 'http://localhost:9998/tika/form/text'
For more information check: https://httpstatuses.com/500

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/paperless/src/documents/consumer.py", line 382, in try_consume_file
    document_parser.parse(self.path, mime_type, self.filename)
  File "/usr/src/paperless/src/paperless_tika/parsers.py", line 56, in parse
    raise ParseError(
documents.parsers.ParseError: Could not parse /tmp/paperless/paperless-ngxzed2cbo7/2023-03-28 Johannes Gutenberg-Universität Mainz Datenbank Praktikum Gruppe 3.odt with tika server at http://localhost:9998: Server error '500 Server Error' for url 'http://localhost:9998/tika/form/text'
For more information check: https://httpstatuses.com/500
[2023-07-06 17:57:47,309] [ERROR] [celery.app.trace] Task documents.tasks.consume_file[1a0c8479-65a4-4de7-a431-29ecb537a030] raised unexpected: ConsumerError("2023-03-28 Johannes Gutenberg-Universität Mainz Datenbank Praktikum Gruppe 3.odt: Error while consuming document 2023-03-28 Johannes Gutenberg-Universität Mainz Datenbank Praktikum Gruppe 3.odt: Could not parse /tmp/paperless/paperless-ngxzed2cbo7/2023-03-28 Johannes Gutenberg-Universität Mainz Datenbank Praktikum Gruppe 3.odt with tika server at http://localhost:9998: Server error '500 Server Error' for url 'http://localhost:9998/tika/form/text'\nFor more information check: https://httpstatuses.com/500")
Traceback (most recent call last):
  File "/usr/src/paperless/src/paperless_tika/parsers.py", line 54, in parse
    parsed = client.tika.as_text.from_file(document_path, mime_type)
  File "/usr/local/lib/python3.9/site-packages/tika_client/_resource_tika.py", line 36, in from_file
    return self._decoded_response(self._put_multipart(self.MULTI_PART_PLAIN_TEXT_CONTENT, filepath, mime_type))
  File "/usr/local/lib/python3.9/site-packages/tika_client/_utils.py", line 46, in _put_multipart
    resp.raise_for_status()
  File "/usr/local/lib/python3.9/site-packages/httpx/_models.py", line 749, in raise_for_status
    raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Server error '500 Server Error' for url 'http://localhost:9998/tika/form/text'
For more information check: https://httpstatuses.com/500
```


### Browser logs

_No response_

### Paperless-ngx version

1.16.5

### Host OS

Truenas

### Installation method

Docker - official image

### Browser

_No response_

### Configuration changes

_No response_

### Other

_No response_

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/paperless_tika/parsers.py`
Content:
```
1 import os
2 from pathlib import Path
3 
4 import httpx
5 from django.conf import settings
6 from django.utils import timezone
7 from tika_client import TikaClient
8 
9 from documents.parsers import DocumentParser
10 from documents.parsers import ParseError
11 from documents.parsers import make_thumbnail_from_pdf
12 
13 
14 class TikaDocumentParser(DocumentParser):
15     """
16     This parser sends documents to a local tika server
17     """
18 
19     logging_name = "paperless.parsing.tika"
20 
21     def get_thumbnail(self, document_path, mime_type, file_name=None):
22         if not self.archive_path:
23             self.archive_path = self.convert_to_pdf(document_path, file_name)
24 
25         return make_thumbnail_from_pdf(
26             self.archive_path,
27             self.tempdir,
28             self.logging_group,
29         )
30 
31     def extract_metadata(self, document_path, mime_type):
32         try:
33             with TikaClient(tika_url=settings.TIKA_ENDPOINT) as client:
34                 parsed = client.metadata.from_file(document_path, mime_type)
35                 return [
36                     {
37                         "namespace": "",
38                         "prefix": "",
39                         "key": key,
40                         "value": parsed.data[key],
41                     }
42                     for key in parsed.data
43                 ]
44         except Exception as e:
45             self.log.warning(
46                 f"Error while fetching document metadata for {document_path}: {e}",
47             )
48             return []
49 
50     def parse(self, document_path: Path, mime_type: str, file_name=None):
51         self.log.info(f"Sending {document_path} to Tika server")
52 
53         try:
54             with TikaClient(tika_url=settings.TIKA_ENDPOINT) as client:
55                 parsed = client.tika.as_text.from_file(document_path, mime_type)
56         except Exception as err:
57             raise ParseError(
58                 f"Could not parse {document_path} with tika server at "
59                 f"{settings.TIKA_ENDPOINT}: {err}",
60             ) from err
61 
62         self.text = parsed.content
63         if self.text is not None:
64             self.text = self.text.strip()
65 
66         self.date = parsed.created
67         if self.date is not None and timezone.is_naive(self.date):
68             self.date = timezone.make_aware(self.date)
69 
70         self.archive_path = self.convert_to_pdf(document_path, file_name)
71 
72     def convert_to_pdf(self, document_path, file_name):
73         pdf_path = os.path.join(self.tempdir, "convert.pdf")
74         gotenberg_server = settings.TIKA_GOTENBERG_ENDPOINT
75         url = gotenberg_server + "/forms/libreoffice/convert"
76 
77         self.log.info(f"Converting {document_path} to PDF as {pdf_path}")
78         with open(document_path, "rb") as document_handle:
79             files = {
80                 "files": (
81                     "convert" + os.path.splitext(document_path)[-1],
82                     document_handle,
83                 ),
84             }
85             headers = {}
86             data = {}
87 
88             # Set the output format of the resulting PDF
89             # Valid inputs: https://gotenberg.dev/docs/modules/pdf-engines#uno
90             if settings.OCR_OUTPUT_TYPE in {"pdfa", "pdfa-2"}:
91                 data["pdfFormat"] = "PDF/A-2b"
92             elif settings.OCR_OUTPUT_TYPE == "pdfa-1":
93                 data["pdfFormat"] = "PDF/A-1a"
94             elif settings.OCR_OUTPUT_TYPE == "pdfa-3":
95                 data["pdfFormat"] = "PDF/A-3b"
96 
97             try:
98                 response = httpx.post(
99                     url,
100                     files=files,
101                     headers=headers,
102                     data=data,
103                     timeout=settings.CELERY_TASK_TIME_LIMIT,
104                 )
105                 response.raise_for_status()  # ensure we notice bad responses
106             except Exception as err:
107                 raise ParseError(
108                     f"Error while converting document to PDF: {err}",
109                 ) from err
110 
111         with open(pdf_path, "wb") as file:
112             file.write(response.content)
113             file.close()
114 
115         return pdf_path
116
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/paperless_tika/parsers.py b/src/paperless_tika/parsers.py
--- a/src/paperless_tika/parsers.py
+++ b/src/paperless_tika/parsers.py
@@ -52,7 +52,18 @@
 
         try:
             with TikaClient(tika_url=settings.TIKA_ENDPOINT) as client:
-                parsed = client.tika.as_text.from_file(document_path, mime_type)
+                try:
+                    parsed = client.tika.as_text.from_file(document_path, mime_type)
+                except httpx.HTTPStatusError as err:
+                    # Workaround https://issues.apache.org/jira/browse/TIKA-4110
+                    # Tika fails with some files as multi-part form data
+                    if err.response.status_code == httpx.codes.INTERNAL_SERVER_ERROR:
+                        parsed = client.tika.as_text.from_buffer(
+                            document_path.read_bytes(),
+                            mime_type,
+                        )
+                    else:  # pragma: nocover
+                        raise
         except Exception as err:
             raise ParseError(
                 f"Could not parse {document_path} with tika server at "

{"golden_diff": "diff --git a/src/paperless_tika/parsers.py b/src/paperless_tika/parsers.py\n--- a/src/paperless_tika/parsers.py\n+++ b/src/paperless_tika/parsers.py\n@@ -52,7 +52,18 @@\n \n         try:\n             with TikaClient(tika_url=settings.TIKA_ENDPOINT) as client:\n-                parsed = client.tika.as_text.from_file(document_path, mime_type)\n+                try:\n+                    parsed = client.tika.as_text.from_file(document_path, mime_type)\n+                except httpx.HTTPStatusError as err:\n+                    # Workaround https://issues.apache.org/jira/browse/TIKA-4110\n+                    # Tika fails with some files as multi-part form data\n+                    if err.response.status_code == httpx.codes.INTERNAL_SERVER_ERROR:\n+                        parsed = client.tika.as_text.from_buffer(\n+                            document_path.read_bytes(),\n+                            mime_type,\n+                        )\n+                    else:  # pragma: nocover\n+                        raise\n         except Exception as err:\n             raise ParseError(\n                 f\"Could not parse {document_path} with tika server at \"\n", "issue": "[BUG] HTTP 500 in Tika for some OpenDocument Documents\n### Description\n\nWhen recreating my local paperless instance, I had to rerun the document archival and thumbnail jobs for all documents.\r\n\r\nThose failed for all OpenDocument Documents from my originals. \r\n\r\nI noticed this being related to the latest changes in paperless_tika/parser.py. After testing the parser.py from 1.15 all worked.\r\n\r\nI am already working on further investigation on my fork and will start the corresponding pull request.\r\n\r\n\n\n### Steps to reproduce\n\nupload ODT document -> parsing fails\n\n### Webserver logs\n\n```bash\n---TIKA---\r\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)\r\n\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:190)\r\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)\r\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\r\n\tat org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:191)\r\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)\r\n\tat org.eclipse.jetty.server.Server.handle(Server.java:516)\r\n\tat org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)\r\n\tat org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)\r\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)\r\n\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)\r\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)\r\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)\r\n\tat org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)\r\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)\r\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)\r\n\tat java.base/java.lang.Thread.run(Thread.java:833)\r\nCaused by: java.io.IOException: Stream Closed\r\n\tat java.base/java.io.FileInputStream.available0(Native Method)\r\n\tat java.base/java.io.FileInputStream.available(FileInputStream.java:415)\r\n\tat org.apache.cxf.attachment.DelegatingInputStream.available(DelegatingInputStream.java:75)\r\n\tat org.apache.cxf.helpers.IOUtils.consume(IOUtils.java:382)\r\n\tat org.apache.cxf.attachment.DelegatingInputStream.close(DelegatingInputStream.java:46)\r\n\tat org.apache.tika.server.core.resource.TikaResource.parse(TikaResource.java:374)\r\n\tat org.apache.tika.server.core.resource.TikaResource.parseToMetadata(TikaResource.java:611)\r\n\tat org.apache.tika.server.core.resource.TikaResource.getJsonFromMultipart(TikaResource.java:564)\r\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)\r\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:568)\r\n\tat org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179)\r\n\tat org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)\r\n\t... 28 more\r\n\r\n---PAPERLESS---\r\n[2023-07-06 17:57:46,034] [INFO] [paperless.consumer] Consuming 2023-03-28 Johannes Gutenberg-Universit\u00e4t Mainz Datenbank Praktikum Gruppe 3.odt\r\n[2023-07-06 17:57:46,112] [INFO] [paperless.parsing.tika] Sending /tmp/paperless/paperless-ngxzed2cbo7/2023-03-28 Johannes Gutenberg-Universit\u00e4t Mainz Datenbank Praktikum Gruppe 3.odt to Tika server\r\n[2023-07-06 17:57:47,289] [ERROR] [paperless.consumer] Error while consuming document 2023-03-28 Johannes Gutenberg-Universit\u00e4t Mainz Datenbank Praktikum Gruppe 3.odt: Could not parse /tmp/paperless/paperless-ngxzed2cbo7/2023-03-28 Johannes Gutenberg-Universit\u00e4t Mainz Datenbank Praktikum Gruppe 3.odt with tika server at http://localhost:9998: Server error '500 Server Error' for url 'http://localhost:9998/tika/form/text'\r\nFor more information check: https://httpstatuses.com/500\r\nTraceback (most recent call last):\r\n  File \"/usr/src/paperless/src/paperless_tika/parsers.py\", line 54, in parse\r\n    parsed = client.tika.as_text.from_file(document_path, mime_type)\r\n  File \"/usr/local/lib/python3.9/site-packages/tika_client/_resource_tika.py\", line 36, in from_file\r\n    return self._decoded_response(self._put_multipart(self.MULTI_PART_PLAIN_TEXT_CONTENT, filepath, mime_type))\r\n  File \"/usr/local/lib/python3.9/site-packages/tika_client/_utils.py\", line 46, in _put_multipart\r\n    resp.raise_for_status()\r\n  File \"/usr/local/lib/python3.9/site-packages/httpx/_models.py\", line 749, in raise_for_status\r\n    raise HTTPStatusError(message, request=request, response=self)\r\nhttpx.HTTPStatusError: Server error '500 Server Error' for url 'http://localhost:9998/tika/form/text'\r\nFor more information check: https://httpstatuses.com/500\r\n\r\nThe above exception was the direct cause of the following exception:\r\n\r\nTraceback (most recent call last):\r\n  File \"/usr/src/paperless/src/documents/consumer.py\", line 382, in try_consume_file\r\n    document_parser.parse(self.path, mime_type, self.filename)\r\n  File \"/usr/src/paperless/src/paperless_tika/parsers.py\", line 56, in parse\r\n    raise ParseError(\r\ndocuments.parsers.ParseError: Could not parse /tmp/paperless/paperless-ngxzed2cbo7/2023-03-28 Johannes Gutenberg-Universit\u00e4t Mainz Datenbank Praktikum Gruppe 3.odt with tika server at http://localhost:9998: Server error '500 Server Error' for url 'http://localhost:9998/tika/form/text'\r\nFor more information check: https://httpstatuses.com/500\r\n[2023-07-06 17:57:47,309] [ERROR] [celery.app.trace] Task documents.tasks.consume_file[1a0c8479-65a4-4de7-a431-29ecb537a030] raised unexpected: ConsumerError(\"2023-03-28 Johannes Gutenberg-Universit\u00e4t Mainz Datenbank Praktikum Gruppe 3.odt: Error while consuming document 2023-03-28 Johannes Gutenberg-Universit\u00e4t Mainz Datenbank Praktikum Gruppe 3.odt: Could not parse /tmp/paperless/paperless-ngxzed2cbo7/2023-03-28 Johannes Gutenberg-Universit\u00e4t Mainz Datenbank Praktikum Gruppe 3.odt with tika server at http://localhost:9998: Server error '500 Server Error' for url 'http://localhost:9998/tika/form/text'\\nFor more information check: https://httpstatuses.com/500\")\r\nTraceback (most recent call last):\r\n  File \"/usr/src/paperless/src/paperless_tika/parsers.py\", line 54, in parse\r\n    parsed = client.tika.as_text.from_file(document_path, mime_type)\r\n  File \"/usr/local/lib/python3.9/site-packages/tika_client/_resource_tika.py\", line 36, in from_file\r\n    return self._decoded_response(self._put_multipart(self.MULTI_PART_PLAIN_TEXT_CONTENT, filepath, mime_type))\r\n  File \"/usr/local/lib/python3.9/site-packages/tika_client/_utils.py\", line 46, in _put_multipart\r\n    resp.raise_for_status()\r\n  File \"/usr/local/lib/python3.9/site-packages/httpx/_models.py\", line 749, in raise_for_status\r\n    raise HTTPStatusError(message, request=request, response=self)\r\nhttpx.HTTPStatusError: Server error '500 Server Error' for url 'http://localhost:9998/tika/form/text'\r\nFor more information check: https://httpstatuses.com/500\n```\n\n\n### Browser logs\n\n_No response_\n\n### Paperless-ngx version\n\n1.16.5\n\n### Host OS\n\nTruenas\n\n### Installation method\n\nDocker - official image\n\n### Browser\n\n_No response_\n\n### Configuration changes\n\n_No response_\n\n### Other\n\n_No response_\n", "before_files": [{"content": "import os\nfrom pathlib import Path\n\nimport httpx\nfrom django.conf import settings\nfrom django.utils import timezone\nfrom tika_client import TikaClient\n\nfrom documents.parsers import DocumentParser\nfrom documents.parsers import ParseError\nfrom documents.parsers import make_thumbnail_from_pdf\n\n\nclass TikaDocumentParser(DocumentParser):\n    \"\"\"\n    This parser sends documents to a local tika server\n    \"\"\"\n\n    logging_name = \"paperless.parsing.tika\"\n\n    def get_thumbnail(self, document_path, mime_type, file_name=None):\n        if not self.archive_path:\n            self.archive_path = self.convert_to_pdf(document_path, file_name)\n\n        return make_thumbnail_from_pdf(\n            self.archive_path,\n            self.tempdir,\n            self.logging_group,\n        )\n\n    def extract_metadata(self, document_path, mime_type):\n        try:\n            with TikaClient(tika_url=settings.TIKA_ENDPOINT) as client:\n                parsed = client.metadata.from_file(document_path, mime_type)\n                return [\n                    {\n                        \"namespace\": \"\",\n                        \"prefix\": \"\",\n                        \"key\": key,\n                        \"value\": parsed.data[key],\n                    }\n                    for key in parsed.data\n                ]\n        except Exception as e:\n            self.log.warning(\n                f\"Error while fetching document metadata for {document_path}: {e}\",\n            )\n            return []\n\n    def parse(self, document_path: Path, mime_type: str, file_name=None):\n        self.log.info(f\"Sending {document_path} to Tika server\")\n\n        try:\n            with TikaClient(tika_url=settings.TIKA_ENDPOINT) as client:\n                parsed = client.tika.as_text.from_file(document_path, mime_type)\n        except Exception as err:\n            raise ParseError(\n                f\"Could not parse {document_path} with tika server at \"\n                f\"{settings.TIKA_ENDPOINT}: {err}\",\n            ) from err\n\n        self.text = parsed.content\n        if self.text is not None:\n            self.text = self.text.strip()\n\n        self.date = parsed.created\n        if self.date is not None and timezone.is_naive(self.date):\n            self.date = timezone.make_aware(self.date)\n\n        self.archive_path = self.convert_to_pdf(document_path, file_name)\n\n    def convert_to_pdf(self, document_path, file_name):\n        pdf_path = os.path.join(self.tempdir, \"convert.pdf\")\n        gotenberg_server = settings.TIKA_GOTENBERG_ENDPOINT\n        url = gotenberg_server + \"/forms/libreoffice/convert\"\n\n        self.log.info(f\"Converting {document_path} to PDF as {pdf_path}\")\n        with open(document_path, \"rb\") as document_handle:\n            files = {\n                \"files\": (\n                    \"convert\" + os.path.splitext(document_path)[-1],\n                    document_handle,\n                ),\n            }\n            headers = {}\n            data = {}\n\n            # Set the output format of the resulting PDF\n            # Valid inputs: https://gotenberg.dev/docs/modules/pdf-engines#uno\n            if settings.OCR_OUTPUT_TYPE in {\"pdfa\", \"pdfa-2\"}:\n                data[\"pdfFormat\"] = \"PDF/A-2b\"\n            elif settings.OCR_OUTPUT_TYPE == \"pdfa-1\":\n                data[\"pdfFormat\"] = \"PDF/A-1a\"\n            elif settings.OCR_OUTPUT_TYPE == \"pdfa-3\":\n                data[\"pdfFormat\"] = \"PDF/A-3b\"\n\n            try:\n                response = httpx.post(\n                    url,\n                    files=files,\n                    headers=headers,\n                    data=data,\n                    timeout=settings.CELERY_TASK_TIME_LIMIT,\n                )\n                response.raise_for_status()  # ensure we notice bad responses\n            except Exception as err:\n                raise ParseError(\n                    f\"Error while converting document to PDF: {err}\",\n                ) from err\n\n        with open(pdf_path, \"wb\") as file:\n            file.write(response.content)\n            file.close()\n\n        return pdf_path\n", "path": "src/paperless_tika/parsers.py"}], "after_files": [{"content": "import os\nfrom pathlib import Path\n\nimport httpx\nfrom django.conf import settings\nfrom django.utils import timezone\nfrom tika_client import TikaClient\n\nfrom documents.parsers import DocumentParser\nfrom documents.parsers import ParseError\nfrom documents.parsers import make_thumbnail_from_pdf\n\n\nclass TikaDocumentParser(DocumentParser):\n    \"\"\"\n    This parser sends documents to a local tika server\n    \"\"\"\n\n    logging_name = \"paperless.parsing.tika\"\n\n    def get_thumbnail(self, document_path, mime_type, file_name=None):\n        if not self.archive_path:\n            self.archive_path = self.convert_to_pdf(document_path, file_name)\n\n        return make_thumbnail_from_pdf(\n            self.archive_path,\n            self.tempdir,\n            self.logging_group,\n        )\n\n    def extract_metadata(self, document_path, mime_type):\n        try:\n            with TikaClient(tika_url=settings.TIKA_ENDPOINT) as client:\n                parsed = client.metadata.from_file(document_path, mime_type)\n                return [\n                    {\n                        \"namespace\": \"\",\n                        \"prefix\": \"\",\n                        \"key\": key,\n                        \"value\": parsed.data[key],\n                    }\n                    for key in parsed.data\n                ]\n        except Exception as e:\n            self.log.warning(\n                f\"Error while fetching document metadata for {document_path}: {e}\",\n            )\n            return []\n\n    def parse(self, document_path: Path, mime_type: str, file_name=None):\n        self.log.info(f\"Sending {document_path} to Tika server\")\n\n        try:\n            with TikaClient(tika_url=settings.TIKA_ENDPOINT) as client:\n                try:\n                    parsed = client.tika.as_text.from_file(document_path, mime_type)\n                except httpx.HTTPStatusError as err:\n                    # Workaround https://issues.apache.org/jira/browse/TIKA-4110\n                    # Tika fails with some files as multi-part form data\n                    if err.response.status_code == httpx.codes.INTERNAL_SERVER_ERROR:\n                        parsed = client.tika.as_text.from_buffer(\n                            document_path.read_bytes(),\n                            mime_type,\n                        )\n                    else:  # pragma: nocover\n                        raise\n        except Exception as err:\n            raise ParseError(\n                f\"Could not parse {document_path} with tika server at \"\n                f\"{settings.TIKA_ENDPOINT}: {err}\",\n            ) from err\n\n        self.text = parsed.content\n        if self.text is not None:\n            self.text = self.text.strip()\n\n        self.date = parsed.created\n        if self.date is not None and timezone.is_naive(self.date):\n            self.date = timezone.make_aware(self.date)\n\n        self.archive_path = self.convert_to_pdf(document_path, file_name)\n\n    def convert_to_pdf(self, document_path, file_name):\n        pdf_path = os.path.join(self.tempdir, \"convert.pdf\")\n        gotenberg_server = settings.TIKA_GOTENBERG_ENDPOINT\n        url = gotenberg_server + \"/forms/libreoffice/convert\"\n\n        self.log.info(f\"Converting {document_path} to PDF as {pdf_path}\")\n        with open(document_path, \"rb\") as document_handle:\n            files = {\n                \"files\": (\n                    \"convert\" + os.path.splitext(document_path)[-1],\n                    document_handle,\n                ),\n            }\n            headers = {}\n            data = {}\n\n            # Set the output format of the resulting PDF\n            # Valid inputs: https://gotenberg.dev/docs/modules/pdf-engines#uno\n            if settings.OCR_OUTPUT_TYPE in {\"pdfa\", \"pdfa-2\"}:\n                data[\"pdfFormat\"] = \"PDF/A-2b\"\n            elif settings.OCR_OUTPUT_TYPE == \"pdfa-1\":\n                data[\"pdfFormat\"] = \"PDF/A-1a\"\n            elif settings.OCR_OUTPUT_TYPE == \"pdfa-3\":\n                data[\"pdfFormat\"] = \"PDF/A-3b\"\n\n            try:\n                response = httpx.post(\n                    url,\n                    files=files,\n                    headers=headers,\n                    data=data,\n                    timeout=settings.CELERY_TASK_TIME_LIMIT,\n                )\n                response.raise_for_status()  # ensure we notice bad responses\n            except Exception as err:\n                raise ParseError(\n                    f\"Error while converting document to PDF: {err}\",\n                ) from err\n\n        with open(pdf_path, \"wb\") as file:\n            file.write(response.content)\n            file.close()\n\n        return pdf_path\n", "path": "src/paperless_tika/parsers.py"}]}