We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG] DOUBLE Patch-T document seperator always leads to a failed task
### Description

Using the "patch-T" document seperator always leads to a failed task. Documents are seperated and stored properly. The failed tasks drag attention even though it's not necessary.


Seperator is [Patch-T](https://www.alliancegroup.co.uk/downloads/patches-for-printing-on-a4-paper.pdf).

![image](https://user-images.githubusercontent.com/113503248/190173386-e8604473-484a-4ba4-b18a-6a9bbbbf000f.png)


### Steps to reproduce

Source document format is pdf , it has 5 pages, page 3 is "patch-t" seperator.


### Webserver logs

```bash
Unable to get page count.
Syntax Error: Invalid page count 0
Command Line Error: Wrong page range given: the first page (1) can not be after the last page (0).
 : Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/pdf2image/pdf2image.py", line 479, in pdfinfo_from_path
    raise ValueError
ValueError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/paperless/src/docker/src/django-q/django_q/cluster.py", line 434, in worker
    res = f(*task["args"], **task["kwargs"])
  File "/usr/src/paperless/src/documents/tasks.py", line 109, in consume_file
    separators = barcodes.scan_file_for_separating_barcodes(file_to_process)
  File "/usr/src/paperless/src/documents/barcodes.py", line 110, in scan_file_for_separating_barcodes
    pages_from_path = convert_from_path(filepath, output_folder=path)
  File "/usr/local/lib/python3.9/site-packages/pdf2image/pdf2image.py", line 98, in convert_from_path
    page_count = pdfinfo_from_path(pdf_path, userpw, poppler_path=poppler_path)["Pages"]
  File "/usr/local/lib/python3.9/site-packages/pdf2image/pdf2image.py", line 488, in pdfinfo_from_path
    raise PDFPageCountError(
pdf2image.exceptions.PDFPageCountError: Unable to get page count.
Syntax Error: Invalid page count 0
Command Line Error: Wrong page range given: the first page (1) can not be after the last page (0).
```


### Paperless-ngx version

1.8

### Host OS

Linux 3.10.108 #42661 SMP (x86_64)

### Installation method

Docker - official image

### Browser

Chrome

### 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/documents/barcodes.py`
Content:
```
1 import logging
2 import os
3 import shutil
4 import tempfile
5 from functools import lru_cache
6 from typing import List  # for type hinting. Can be removed, if only Python >3.8 is used
7 
8 import magic
9 from django.conf import settings
10 from pdf2image import convert_from_path
11 from pikepdf import Pdf
12 from PIL import Image
13 from PIL import ImageSequence
14 from pyzbar import pyzbar
15 
16 logger = logging.getLogger("paperless.barcodes")
17 
18 
19 @lru_cache(maxsize=8)
20 def supported_file_type(mime_type) -> bool:
21     """
22     Determines if the file is valid for barcode
23     processing, based on MIME type and settings
24 
25     :return: True if the file is supported, False otherwise
26     """
27     supported_mime = ["application/pdf"]
28     if settings.CONSUMER_BARCODE_TIFF_SUPPORT:
29         supported_mime += ["image/tiff"]
30 
31     return mime_type in supported_mime
32 
33 
34 def barcode_reader(image) -> List[str]:
35     """
36     Read any barcodes contained in image
37     Returns a list containing all found barcodes
38     """
39     barcodes = []
40     # Decode the barcode image
41     detected_barcodes = pyzbar.decode(image)
42 
43     if detected_barcodes:
44         # Traverse through all the detected barcodes in image
45         for barcode in detected_barcodes:
46             if barcode.data:
47                 decoded_barcode = barcode.data.decode("utf-8")
48                 barcodes.append(decoded_barcode)
49                 logger.debug(
50                     f"Barcode of type {str(barcode.type)} found: {decoded_barcode}",
51                 )
52     return barcodes
53 
54 
55 def get_file_mime_type(path: str) -> str:
56     """
57     Determines the file type, based on MIME type.
58 
59     Returns the MIME type.
60     """
61     mime_type = magic.from_file(path, mime=True)
62     logger.debug(f"Detected mime type: {mime_type}")
63     return mime_type
64 
65 
66 def convert_from_tiff_to_pdf(filepath: str) -> str:
67     """
68     converts a given TIFF image file to pdf into a temporary directory.
69 
70     Returns the new pdf file.
71     """
72     file_name = os.path.splitext(os.path.basename(filepath))[0]
73     mime_type = get_file_mime_type(filepath)
74     tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR)
75     # use old file name with pdf extension
76     if mime_type == "image/tiff":
77         newpath = os.path.join(tempdir, file_name + ".pdf")
78     else:
79         logger.warning(
80             f"Cannot convert mime type {str(mime_type)} from {str(filepath)} to pdf.",
81         )
82         return None
83     with Image.open(filepath) as image:
84         images = []
85         for i, page in enumerate(ImageSequence.Iterator(image)):
86             page = page.convert("RGB")
87             images.append(page)
88         try:
89             if len(images) == 1:
90                 images[0].save(newpath)
91             else:
92                 images[0].save(newpath, save_all=True, append_images=images[1:])
93         except OSError as e:
94             logger.warning(
95                 f"Could not save the file as pdf. Error: {str(e)}",
96             )
97             return None
98     return newpath
99 
100 
101 def scan_file_for_separating_barcodes(filepath: str) -> List[int]:
102     """
103     Scan the provided pdf file for page separating barcodes
104     Returns a list of pagenumbers, which separate the file
105     """
106     separator_page_numbers = []
107     separator_barcode = str(settings.CONSUMER_BARCODE_STRING)
108     # use a temporary directory in case the file os too big to handle in memory
109     with tempfile.TemporaryDirectory() as path:
110         pages_from_path = convert_from_path(filepath, output_folder=path)
111         for current_page_number, page in enumerate(pages_from_path):
112             current_barcodes = barcode_reader(page)
113             if separator_barcode in current_barcodes:
114                 separator_page_numbers.append(current_page_number)
115     return separator_page_numbers
116 
117 
118 def separate_pages(filepath: str, pages_to_split_on: List[int]) -> List[str]:
119     """
120     Separate the provided pdf file on the pages_to_split_on.
121     The pages which are defined by page_numbers will be removed.
122     Returns a list of (temporary) filepaths to consume.
123     These will need to be deleted later.
124     """
125     os.makedirs(settings.SCRATCH_DIR, exist_ok=True)
126     tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR)
127     fname = os.path.splitext(os.path.basename(filepath))[0]
128     pdf = Pdf.open(filepath)
129     document_paths = []
130     logger.debug(f"Temp dir is {str(tempdir)}")
131     if not pages_to_split_on:
132         logger.warning("No pages to split on!")
133     else:
134         # go from the first page to the first separator page
135         dst = Pdf.new()
136         for n, page in enumerate(pdf.pages):
137             if n < pages_to_split_on[0]:
138                 dst.pages.append(page)
139         output_filename = f"{fname}_document_0.pdf"
140         savepath = os.path.join(tempdir, output_filename)
141         with open(savepath, "wb") as out:
142             dst.save(out)
143         document_paths = [savepath]
144 
145         # iterate through the rest of the document
146         for count, page_number in enumerate(pages_to_split_on):
147             logger.debug(f"Count: {str(count)} page_number: {str(page_number)}")
148             dst = Pdf.new()
149             try:
150                 next_page = pages_to_split_on[count + 1]
151             except IndexError:
152                 next_page = len(pdf.pages)
153             # skip the first page_number. This contains the barcode page
154             for page in range(page_number + 1, next_page):
155                 logger.debug(
156                     f"page_number: {str(page_number)} next_page: {str(next_page)}",
157                 )
158                 dst.pages.append(pdf.pages[page])
159             output_filename = f"{fname}_document_{str(count + 1)}.pdf"
160             logger.debug(f"pdf no:{str(count)} has {str(len(dst.pages))} pages")
161             savepath = os.path.join(tempdir, output_filename)
162             with open(savepath, "wb") as out:
163                 dst.save(out)
164             document_paths.append(savepath)
165     logger.debug(f"Temp files are {str(document_paths)}")
166     return document_paths
167 
168 
169 def save_to_dir(
170     filepath: str,
171     newname: str = None,
172     target_dir: str = settings.CONSUMPTION_DIR,
173 ):
174     """
175     Copies filepath to target_dir.
176     Optionally rename the file.
177     """
178     if os.path.isfile(filepath) and os.path.isdir(target_dir):
179         dst = shutil.copy(filepath, target_dir)
180         logging.debug(f"saved {str(filepath)} to {str(dst)}")
181         if newname:
182             dst_new = os.path.join(target_dir, newname)
183             logger.debug(f"moving {str(dst)} to {str(dst_new)}")
184             os.rename(dst, dst_new)
185     else:
186         logger.warning(f"{str(filepath)} or {str(target_dir)} don't exist.")
187
```
--- 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/documents/barcodes.py b/src/documents/barcodes.py
--- a/src/documents/barcodes.py
+++ b/src/documents/barcodes.py
@@ -8,6 +8,7 @@
 import magic
 from django.conf import settings
 from pdf2image import convert_from_path
+from pikepdf import Page
 from pikepdf import Pdf
 from PIL import Image
 from PIL import ImageSequence
@@ -122,47 +123,56 @@
     Returns a list of (temporary) filepaths to consume.
     These will need to be deleted later.
     """
+
+    document_paths = []
+
+    if not pages_to_split_on:
+        logger.warning("No pages to split on!")
+        return document_paths
+
     os.makedirs(settings.SCRATCH_DIR, exist_ok=True)
     tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR)
     fname = os.path.splitext(os.path.basename(filepath))[0]
     pdf = Pdf.open(filepath)
-    document_paths = []
-    logger.debug(f"Temp dir is {str(tempdir)}")
-    if not pages_to_split_on:
-        logger.warning("No pages to split on!")
-    else:
-        # go from the first page to the first separator page
+
+    # A list of documents, ie a list of lists of pages
+    documents: List[List[Page]] = []
+    # A single document, ie a list of pages
+    document: List[Page] = []
+
+    for idx, page in enumerate(pdf.pages):
+        # Keep building the new PDF as long as it is not a
+        # separator index
+        if idx not in pages_to_split_on:
+            document.append(page)
+            # Make sure to append the very last document to the documents
+            if idx == (len(pdf.pages) - 1):
+                documents.append(document)
+                document = []
+        else:
+            # This is a split index, save the current PDF pages, and restart
+            # a new destination page listing
+            logger.debug(f"Starting new document at idx {idx}")
+            documents.append(document)
+            document = []
+
+    documents = [x for x in documents if len(x)]
+
+    logger.debug(f"Split into {len(documents)} new documents")
+
+    # Write the new documents out
+    for doc_idx, document in enumerate(documents):
         dst = Pdf.new()
-        for n, page in enumerate(pdf.pages):
-            if n < pages_to_split_on[0]:
-                dst.pages.append(page)
-        output_filename = f"{fname}_document_0.pdf"
+        dst.pages.extend(document)
+
+        output_filename = f"{fname}_document_{doc_idx}.pdf"
+
+        logger.debug(f"pdf no:{doc_idx} has {len(dst.pages)} pages")
         savepath = os.path.join(tempdir, output_filename)
         with open(savepath, "wb") as out:
             dst.save(out)
-        document_paths = [savepath]
-
-        # iterate through the rest of the document
-        for count, page_number in enumerate(pages_to_split_on):
-            logger.debug(f"Count: {str(count)} page_number: {str(page_number)}")
-            dst = Pdf.new()
-            try:
-                next_page = pages_to_split_on[count + 1]
-            except IndexError:
-                next_page = len(pdf.pages)
-            # skip the first page_number. This contains the barcode page
-            for page in range(page_number + 1, next_page):
-                logger.debug(
-                    f"page_number: {str(page_number)} next_page: {str(next_page)}",
-                )
-                dst.pages.append(pdf.pages[page])
-            output_filename = f"{fname}_document_{str(count + 1)}.pdf"
-            logger.debug(f"pdf no:{str(count)} has {str(len(dst.pages))} pages")
-            savepath = os.path.join(tempdir, output_filename)
-            with open(savepath, "wb") as out:
-                dst.save(out)
-            document_paths.append(savepath)
-    logger.debug(f"Temp files are {str(document_paths)}")
+        document_paths.append(savepath)
+
     return document_paths

{"golden_diff": "diff --git a/src/documents/barcodes.py b/src/documents/barcodes.py\n--- a/src/documents/barcodes.py\n+++ b/src/documents/barcodes.py\n@@ -8,6 +8,7 @@\n import magic\n from django.conf import settings\n from pdf2image import convert_from_path\n+from pikepdf import Page\n from pikepdf import Pdf\n from PIL import Image\n from PIL import ImageSequence\n@@ -122,47 +123,56 @@\n     Returns a list of (temporary) filepaths to consume.\n     These will need to be deleted later.\n     \"\"\"\n+\n+    document_paths = []\n+\n+    if not pages_to_split_on:\n+        logger.warning(\"No pages to split on!\")\n+        return document_paths\n+\n     os.makedirs(settings.SCRATCH_DIR, exist_ok=True)\n     tempdir = tempfile.mkdtemp(prefix=\"paperless-\", dir=settings.SCRATCH_DIR)\n     fname = os.path.splitext(os.path.basename(filepath))[0]\n     pdf = Pdf.open(filepath)\n-    document_paths = []\n-    logger.debug(f\"Temp dir is {str(tempdir)}\")\n-    if not pages_to_split_on:\n-        logger.warning(\"No pages to split on!\")\n-    else:\n-        # go from the first page to the first separator page\n+\n+    # A list of documents, ie a list of lists of pages\n+    documents: List[List[Page]] = []\n+    # A single document, ie a list of pages\n+    document: List[Page] = []\n+\n+    for idx, page in enumerate(pdf.pages):\n+        # Keep building the new PDF as long as it is not a\n+        # separator index\n+        if idx not in pages_to_split_on:\n+            document.append(page)\n+            # Make sure to append the very last document to the documents\n+            if idx == (len(pdf.pages) - 1):\n+                documents.append(document)\n+                document = []\n+        else:\n+            # This is a split index, save the current PDF pages, and restart\n+            # a new destination page listing\n+            logger.debug(f\"Starting new document at idx {idx}\")\n+            documents.append(document)\n+            document = []\n+\n+    documents = [x for x in documents if len(x)]\n+\n+    logger.debug(f\"Split into {len(documents)} new documents\")\n+\n+    # Write the new documents out\n+    for doc_idx, document in enumerate(documents):\n         dst = Pdf.new()\n-        for n, page in enumerate(pdf.pages):\n-            if n < pages_to_split_on[0]:\n-                dst.pages.append(page)\n-        output_filename = f\"{fname}_document_0.pdf\"\n+        dst.pages.extend(document)\n+\n+        output_filename = f\"{fname}_document_{doc_idx}.pdf\"\n+\n+        logger.debug(f\"pdf no:{doc_idx} has {len(dst.pages)} pages\")\n         savepath = os.path.join(tempdir, output_filename)\n         with open(savepath, \"wb\") as out:\n             dst.save(out)\n-        document_paths = [savepath]\n-\n-        # iterate through the rest of the document\n-        for count, page_number in enumerate(pages_to_split_on):\n-            logger.debug(f\"Count: {str(count)} page_number: {str(page_number)}\")\n-            dst = Pdf.new()\n-            try:\n-                next_page = pages_to_split_on[count + 1]\n-            except IndexError:\n-                next_page = len(pdf.pages)\n-            # skip the first page_number. This contains the barcode page\n-            for page in range(page_number + 1, next_page):\n-                logger.debug(\n-                    f\"page_number: {str(page_number)} next_page: {str(next_page)}\",\n-                )\n-                dst.pages.append(pdf.pages[page])\n-            output_filename = f\"{fname}_document_{str(count + 1)}.pdf\"\n-            logger.debug(f\"pdf no:{str(count)} has {str(len(dst.pages))} pages\")\n-            savepath = os.path.join(tempdir, output_filename)\n-            with open(savepath, \"wb\") as out:\n-                dst.save(out)\n-            document_paths.append(savepath)\n-    logger.debug(f\"Temp files are {str(document_paths)}\")\n+        document_paths.append(savepath)\n+\n     return document_paths\n", "issue": "[BUG] DOUBLE Patch-T document seperator always leads to a failed task\n### Description\n\nUsing the \"patch-T\" document seperator always leads to a failed task. Documents are seperated and stored properly. The failed tasks drag attention even though it's not necessary.\r\n\r\n\r\nSeperator is [Patch-T](https://www.alliancegroup.co.uk/downloads/patches-for-printing-on-a4-paper.pdf).\r\n\r\n![image](https://user-images.githubusercontent.com/113503248/190173386-e8604473-484a-4ba4-b18a-6a9bbbbf000f.png)\r\n\n\n### Steps to reproduce\n\nSource document format is pdf , it has 5 pages, page 3 is \"patch-t\" seperator.\r\n\n\n### Webserver logs\n\n```bash\nUnable to get page count.\r\nSyntax Error: Invalid page count 0\r\nCommand Line Error: Wrong page range given: the first page (1) can not be after the last page (0).\r\n : Traceback (most recent call last):\r\n  File \"/usr/local/lib/python3.9/site-packages/pdf2image/pdf2image.py\", line 479, in pdfinfo_from_path\r\n    raise ValueError\r\nValueError\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n  File \"/usr/src/paperless/src/docker/src/django-q/django_q/cluster.py\", line 434, in worker\r\n    res = f(*task[\"args\"], **task[\"kwargs\"])\r\n  File \"/usr/src/paperless/src/documents/tasks.py\", line 109, in consume_file\r\n    separators = barcodes.scan_file_for_separating_barcodes(file_to_process)\r\n  File \"/usr/src/paperless/src/documents/barcodes.py\", line 110, in scan_file_for_separating_barcodes\r\n    pages_from_path = convert_from_path(filepath, output_folder=path)\r\n  File \"/usr/local/lib/python3.9/site-packages/pdf2image/pdf2image.py\", line 98, in convert_from_path\r\n    page_count = pdfinfo_from_path(pdf_path, userpw, poppler_path=poppler_path)[\"Pages\"]\r\n  File \"/usr/local/lib/python3.9/site-packages/pdf2image/pdf2image.py\", line 488, in pdfinfo_from_path\r\n    raise PDFPageCountError(\r\npdf2image.exceptions.PDFPageCountError: Unable to get page count.\r\nSyntax Error: Invalid page count 0\r\nCommand Line Error: Wrong page range given: the first page (1) can not be after the last page (0).\n```\n\n\n### Paperless-ngx version\n\n1.8\n\n### Host OS\n\nLinux 3.10.108 #42661 SMP (x86_64)\n\n### Installation method\n\nDocker - official image\n\n### Browser\n\nChrome\n\n### Configuration changes\n\n_No response_\n\n### Other\n\n_No response_\n", "before_files": [{"content": "import logging\nimport os\nimport shutil\nimport tempfile\nfrom functools import lru_cache\nfrom typing import List  # for type hinting. Can be removed, if only Python >3.8 is used\n\nimport magic\nfrom django.conf import settings\nfrom pdf2image import convert_from_path\nfrom pikepdf import Pdf\nfrom PIL import Image\nfrom PIL import ImageSequence\nfrom pyzbar import pyzbar\n\nlogger = logging.getLogger(\"paperless.barcodes\")\n\n\n@lru_cache(maxsize=8)\ndef supported_file_type(mime_type) -> bool:\n    \"\"\"\n    Determines if the file is valid for barcode\n    processing, based on MIME type and settings\n\n    :return: True if the file is supported, False otherwise\n    \"\"\"\n    supported_mime = [\"application/pdf\"]\n    if settings.CONSUMER_BARCODE_TIFF_SUPPORT:\n        supported_mime += [\"image/tiff\"]\n\n    return mime_type in supported_mime\n\n\ndef barcode_reader(image) -> List[str]:\n    \"\"\"\n    Read any barcodes contained in image\n    Returns a list containing all found barcodes\n    \"\"\"\n    barcodes = []\n    # Decode the barcode image\n    detected_barcodes = pyzbar.decode(image)\n\n    if detected_barcodes:\n        # Traverse through all the detected barcodes in image\n        for barcode in detected_barcodes:\n            if barcode.data:\n                decoded_barcode = barcode.data.decode(\"utf-8\")\n                barcodes.append(decoded_barcode)\n                logger.debug(\n                    f\"Barcode of type {str(barcode.type)} found: {decoded_barcode}\",\n                )\n    return barcodes\n\n\ndef get_file_mime_type(path: str) -> str:\n    \"\"\"\n    Determines the file type, based on MIME type.\n\n    Returns the MIME type.\n    \"\"\"\n    mime_type = magic.from_file(path, mime=True)\n    logger.debug(f\"Detected mime type: {mime_type}\")\n    return mime_type\n\n\ndef convert_from_tiff_to_pdf(filepath: str) -> str:\n    \"\"\"\n    converts a given TIFF image file to pdf into a temporary directory.\n\n    Returns the new pdf file.\n    \"\"\"\n    file_name = os.path.splitext(os.path.basename(filepath))[0]\n    mime_type = get_file_mime_type(filepath)\n    tempdir = tempfile.mkdtemp(prefix=\"paperless-\", dir=settings.SCRATCH_DIR)\n    # use old file name with pdf extension\n    if mime_type == \"image/tiff\":\n        newpath = os.path.join(tempdir, file_name + \".pdf\")\n    else:\n        logger.warning(\n            f\"Cannot convert mime type {str(mime_type)} from {str(filepath)} to pdf.\",\n        )\n        return None\n    with Image.open(filepath) as image:\n        images = []\n        for i, page in enumerate(ImageSequence.Iterator(image)):\n            page = page.convert(\"RGB\")\n            images.append(page)\n        try:\n            if len(images) == 1:\n                images[0].save(newpath)\n            else:\n                images[0].save(newpath, save_all=True, append_images=images[1:])\n        except OSError as e:\n            logger.warning(\n                f\"Could not save the file as pdf. Error: {str(e)}\",\n            )\n            return None\n    return newpath\n\n\ndef scan_file_for_separating_barcodes(filepath: str) -> List[int]:\n    \"\"\"\n    Scan the provided pdf file for page separating barcodes\n    Returns a list of pagenumbers, which separate the file\n    \"\"\"\n    separator_page_numbers = []\n    separator_barcode = str(settings.CONSUMER_BARCODE_STRING)\n    # use a temporary directory in case the file os too big to handle in memory\n    with tempfile.TemporaryDirectory() as path:\n        pages_from_path = convert_from_path(filepath, output_folder=path)\n        for current_page_number, page in enumerate(pages_from_path):\n            current_barcodes = barcode_reader(page)\n            if separator_barcode in current_barcodes:\n                separator_page_numbers.append(current_page_number)\n    return separator_page_numbers\n\n\ndef separate_pages(filepath: str, pages_to_split_on: List[int]) -> List[str]:\n    \"\"\"\n    Separate the provided pdf file on the pages_to_split_on.\n    The pages which are defined by page_numbers will be removed.\n    Returns a list of (temporary) filepaths to consume.\n    These will need to be deleted later.\n    \"\"\"\n    os.makedirs(settings.SCRATCH_DIR, exist_ok=True)\n    tempdir = tempfile.mkdtemp(prefix=\"paperless-\", dir=settings.SCRATCH_DIR)\n    fname = os.path.splitext(os.path.basename(filepath))[0]\n    pdf = Pdf.open(filepath)\n    document_paths = []\n    logger.debug(f\"Temp dir is {str(tempdir)}\")\n    if not pages_to_split_on:\n        logger.warning(\"No pages to split on!\")\n    else:\n        # go from the first page to the first separator page\n        dst = Pdf.new()\n        for n, page in enumerate(pdf.pages):\n            if n < pages_to_split_on[0]:\n                dst.pages.append(page)\n        output_filename = f\"{fname}_document_0.pdf\"\n        savepath = os.path.join(tempdir, output_filename)\n        with open(savepath, \"wb\") as out:\n            dst.save(out)\n        document_paths = [savepath]\n\n        # iterate through the rest of the document\n        for count, page_number in enumerate(pages_to_split_on):\n            logger.debug(f\"Count: {str(count)} page_number: {str(page_number)}\")\n            dst = Pdf.new()\n            try:\n                next_page = pages_to_split_on[count + 1]\n            except IndexError:\n                next_page = len(pdf.pages)\n            # skip the first page_number. This contains the barcode page\n            for page in range(page_number + 1, next_page):\n                logger.debug(\n                    f\"page_number: {str(page_number)} next_page: {str(next_page)}\",\n                )\n                dst.pages.append(pdf.pages[page])\n            output_filename = f\"{fname}_document_{str(count + 1)}.pdf\"\n            logger.debug(f\"pdf no:{str(count)} has {str(len(dst.pages))} pages\")\n            savepath = os.path.join(tempdir, output_filename)\n            with open(savepath, \"wb\") as out:\n                dst.save(out)\n            document_paths.append(savepath)\n    logger.debug(f\"Temp files are {str(document_paths)}\")\n    return document_paths\n\n\ndef save_to_dir(\n    filepath: str,\n    newname: str = None,\n    target_dir: str = settings.CONSUMPTION_DIR,\n):\n    \"\"\"\n    Copies filepath to target_dir.\n    Optionally rename the file.\n    \"\"\"\n    if os.path.isfile(filepath) and os.path.isdir(target_dir):\n        dst = shutil.copy(filepath, target_dir)\n        logging.debug(f\"saved {str(filepath)} to {str(dst)}\")\n        if newname:\n            dst_new = os.path.join(target_dir, newname)\n            logger.debug(f\"moving {str(dst)} to {str(dst_new)}\")\n            os.rename(dst, dst_new)\n    else:\n        logger.warning(f\"{str(filepath)} or {str(target_dir)} don't exist.\")\n", "path": "src/documents/barcodes.py"}], "after_files": [{"content": "import logging\nimport os\nimport shutil\nimport tempfile\nfrom functools import lru_cache\nfrom typing import List  # for type hinting. Can be removed, if only Python >3.8 is used\n\nimport magic\nfrom django.conf import settings\nfrom pdf2image import convert_from_path\nfrom pikepdf import Page\nfrom pikepdf import Pdf\nfrom PIL import Image\nfrom PIL import ImageSequence\nfrom pyzbar import pyzbar\n\nlogger = logging.getLogger(\"paperless.barcodes\")\n\n\n@lru_cache(maxsize=8)\ndef supported_file_type(mime_type) -> bool:\n    \"\"\"\n    Determines if the file is valid for barcode\n    processing, based on MIME type and settings\n\n    :return: True if the file is supported, False otherwise\n    \"\"\"\n    supported_mime = [\"application/pdf\"]\n    if settings.CONSUMER_BARCODE_TIFF_SUPPORT:\n        supported_mime += [\"image/tiff\"]\n\n    return mime_type in supported_mime\n\n\ndef barcode_reader(image) -> List[str]:\n    \"\"\"\n    Read any barcodes contained in image\n    Returns a list containing all found barcodes\n    \"\"\"\n    barcodes = []\n    # Decode the barcode image\n    detected_barcodes = pyzbar.decode(image)\n\n    if detected_barcodes:\n        # Traverse through all the detected barcodes in image\n        for barcode in detected_barcodes:\n            if barcode.data:\n                decoded_barcode = barcode.data.decode(\"utf-8\")\n                barcodes.append(decoded_barcode)\n                logger.debug(\n                    f\"Barcode of type {str(barcode.type)} found: {decoded_barcode}\",\n                )\n    return barcodes\n\n\ndef get_file_mime_type(path: str) -> str:\n    \"\"\"\n    Determines the file type, based on MIME type.\n\n    Returns the MIME type.\n    \"\"\"\n    mime_type = magic.from_file(path, mime=True)\n    logger.debug(f\"Detected mime type: {mime_type}\")\n    return mime_type\n\n\ndef convert_from_tiff_to_pdf(filepath: str) -> str:\n    \"\"\"\n    converts a given TIFF image file to pdf into a temporary directory.\n\n    Returns the new pdf file.\n    \"\"\"\n    file_name = os.path.splitext(os.path.basename(filepath))[0]\n    mime_type = get_file_mime_type(filepath)\n    tempdir = tempfile.mkdtemp(prefix=\"paperless-\", dir=settings.SCRATCH_DIR)\n    # use old file name with pdf extension\n    if mime_type == \"image/tiff\":\n        newpath = os.path.join(tempdir, file_name + \".pdf\")\n    else:\n        logger.warning(\n            f\"Cannot convert mime type {str(mime_type)} from {str(filepath)} to pdf.\",\n        )\n        return None\n    with Image.open(filepath) as image:\n        images = []\n        for i, page in enumerate(ImageSequence.Iterator(image)):\n            page = page.convert(\"RGB\")\n            images.append(page)\n        try:\n            if len(images) == 1:\n                images[0].save(newpath)\n            else:\n                images[0].save(newpath, save_all=True, append_images=images[1:])\n        except OSError as e:\n            logger.warning(\n                f\"Could not save the file as pdf. Error: {str(e)}\",\n            )\n            return None\n    return newpath\n\n\ndef scan_file_for_separating_barcodes(filepath: str) -> List[int]:\n    \"\"\"\n    Scan the provided pdf file for page separating barcodes\n    Returns a list of pagenumbers, which separate the file\n    \"\"\"\n    separator_page_numbers = []\n    separator_barcode = str(settings.CONSUMER_BARCODE_STRING)\n    # use a temporary directory in case the file os too big to handle in memory\n    with tempfile.TemporaryDirectory() as path:\n        pages_from_path = convert_from_path(filepath, output_folder=path)\n        for current_page_number, page in enumerate(pages_from_path):\n            current_barcodes = barcode_reader(page)\n            if separator_barcode in current_barcodes:\n                separator_page_numbers.append(current_page_number)\n    return separator_page_numbers\n\n\ndef separate_pages(filepath: str, pages_to_split_on: List[int]) -> List[str]:\n    \"\"\"\n    Separate the provided pdf file on the pages_to_split_on.\n    The pages which are defined by page_numbers will be removed.\n    Returns a list of (temporary) filepaths to consume.\n    These will need to be deleted later.\n    \"\"\"\n\n    document_paths = []\n\n    if not pages_to_split_on:\n        logger.warning(\"No pages to split on!\")\n        return document_paths\n\n    os.makedirs(settings.SCRATCH_DIR, exist_ok=True)\n    tempdir = tempfile.mkdtemp(prefix=\"paperless-\", dir=settings.SCRATCH_DIR)\n    fname = os.path.splitext(os.path.basename(filepath))[0]\n    pdf = Pdf.open(filepath)\n\n    # A list of documents, ie a list of lists of pages\n    documents: List[List[Page]] = []\n    # A single document, ie a list of pages\n    document: List[Page] = []\n\n    for idx, page in enumerate(pdf.pages):\n        # Keep building the new PDF as long as it is not a\n        # separator index\n        if idx not in pages_to_split_on:\n            document.append(page)\n            # Make sure to append the very last document to the documents\n            if idx == (len(pdf.pages) - 1):\n                documents.append(document)\n                document = []\n        else:\n            # This is a split index, save the current PDF pages, and restart\n            # a new destination page listing\n            logger.debug(f\"Starting new document at idx {idx}\")\n            documents.append(document)\n            document = []\n\n    documents = [x for x in documents if len(x)]\n\n    logger.debug(f\"Split into {len(documents)} new documents\")\n\n    # Write the new documents out\n    for doc_idx, document in enumerate(documents):\n        dst = Pdf.new()\n        dst.pages.extend(document)\n\n        output_filename = f\"{fname}_document_{doc_idx}.pdf\"\n\n        logger.debug(f\"pdf no:{doc_idx} has {len(dst.pages)} pages\")\n        savepath = os.path.join(tempdir, output_filename)\n        with open(savepath, \"wb\") as out:\n            dst.save(out)\n        document_paths.append(savepath)\n\n    return document_paths\n\n\ndef save_to_dir(\n    filepath: str,\n    newname: str = None,\n    target_dir: str = settings.CONSUMPTION_DIR,\n):\n    \"\"\"\n    Copies filepath to target_dir.\n    Optionally rename the file.\n    \"\"\"\n    if os.path.isfile(filepath) and os.path.isdir(target_dir):\n        dst = shutil.copy(filepath, target_dir)\n        logging.debug(f\"saved {str(filepath)} to {str(dst)}\")\n        if newname:\n            dst_new = os.path.join(target_dir, newname)\n            logger.debug(f\"moving {str(dst)} to {str(dst_new)}\")\n            os.rename(dst, dst_new)\n    else:\n        logger.warning(f\"{str(filepath)} or {str(target_dir)} don't exist.\")\n", "path": "src/documents/barcodes.py"}]}