From c666be32f47abd21873ace4ae06f28997b205843 Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Sat, 19 Mar 2022 18:03:56 +0100 Subject: [PATCH 01/26] add barcode packages Signed-off-by: florian on nixos (Florian Brandes) --- Pipfile | 2 ++ Pipfile.lock | 24 ++++++++++++++++++++++++ requirements.txt | 1 + 3 files changed, 27 insertions(+) diff --git a/Pipfile b/Pipfile index 196bae4c9..0ab6775e6 100644 --- a/Pipfile +++ b/Pipfile @@ -51,6 +51,8 @@ concurrent-log-handler = "*" "backports.zoneinfo" = {version = "*", markers = "python_version < '3.9'"} "importlib-resources" = {version = "*", markers = "python_version < '3.9'"} zipp = {version = "*", markers = "python_version < '3.9'"} +pyzbar = "*" +pdf2image = "*" [dev-packages] coveralls = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 34068d8cc..d944f06aa 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -693,6 +693,14 @@ "index": "pypi", "version": "==2.5.0" }, + "pdf2image": { + "hashes": [ + "sha256:84f79f2b8fad943e36323ea4e937fcb05f26ded0caa0a01181df66049e42fb65", + "sha256:d58ed94d978a70c73c2bb7fdf8acbaf2a7089c29ff8141be5f45433c0c4293bb" + ], + "index": "pypi", + "version": "==1.16.0" + }, "pdfminer.six": { "hashes": [ "sha256:af0630f98a292bad4170f54e80f82ca81b916dd0b2c996437ec45c02f11d8762", @@ -960,6 +968,15 @@ ], "version": "==6.0" }, + "pyzbar": { + "hashes": [ + "sha256:13e3ee5a2f3a545204a285f41814d5c0db571967e8d4af8699a03afc55182a9c", + "sha256:4559628b8192feb25766d954b36a3753baaf5c97c03135aec7e4a026036b475d", + "sha256:8f4c5264c9c7c6b9f20d01efc52a4eba1ded47d9ba857a94130afe33703eb518" + ], + "index": "pypi", + "version": "==0.1.9" + }, "redis": { "hashes": [ "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2", @@ -1784,6 +1801,13 @@ ], "version": "==1.6.0" }, + "mypy-extensions": { + "hashes": [ + "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", + "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" + ], + "version": "==0.4.3" + }, "packaging": { "hashes": [ "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", diff --git a/requirements.txt b/requirements.txt index 787fdd381..afc8b9f51 100644 --- a/requirements.txt +++ b/requirements.txt @@ -79,6 +79,7 @@ python-magic==0.4.25 pytz-deprecation-shim==0.1.0.post0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' pytz==2022.1 pyyaml==6.0 +pyzbar==0.1.9 redis==3.5.3 regex==2022.3.2; python_version >= '3.6' reportlab==3.6.9; python_version >= '3.7' and python_version < '4' From 76e43bcb89dc96f18c966fab273f439f7efe2e12 Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Wed, 23 Mar 2022 13:26:43 +0100 Subject: [PATCH 02/26] add first tests for barcode reader Signed-off-by: florian on nixos (Florian Brandes) --- src/documents/tasks.py | 77 +++++++++++++++++++ src/documents/tests/samples/patch-code-t.pbm | Bin 0 -> 484186 bytes src/documents/tests/samples/patch-code-t.pdf | Bin 0 -> 40893 bytes src/documents/tests/test_tasks.py | 11 +++ 4 files changed, 88 insertions(+) create mode 100644 src/documents/tests/samples/patch-code-t.pbm create mode 100644 src/documents/tests/samples/patch-code-t.pdf diff --git a/src/documents/tasks.py b/src/documents/tasks.py index b43f211de..dc646ddfc 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -16,6 +16,13 @@ from documents.models import Tag from documents.sanity_checker import SanityCheckFailedException from whoosh.writing import AsyncWriter +# barcode decoder +import os +from pyzbar import pyzbar +from pdf2image import convert_from_path +import tempfile +from pikepdf import Pdf + logger = logging.getLogger("paperless.tasks") @@ -62,6 +69,71 @@ def train_classifier(): logger.warning("Classifier error: " + str(e)) + +def barcode_reader(page) -> list: + """ + Read any barcodes contained in page + Returns a list containing all found barcodes + """ + barcodes = [ ] + # Decode the barcode image + detected_barcodes = pyzbar.decode(page) + + if not detected_barcodes: + logger.debug(f"No barcode detected") + else: + # Traverse through all the detected barcodes in image + for barcode in detected_barcodes: + if barcode.data!="": + barcodes = barcodes + [str(barcode.data)] + logger.debug(f"Barcode of type {str(barcode.type)} found: {str(barcode.data)}") + return barcodes + +def scan_file_for_seperating_barcodes(filepath) -> list: + """ + Scan the provided file for page seperating barcodes + Returns a list of pagenumbers, which seperate the file + """ + seperator_page_numbers = [ ] + # use a temporary directory in case the file os too big to handle in memory + with tempfile.TemporaryDirectory() as path: + pages_from_path = convert_from_path(filepath, output_folder=path) + for current_page_number, page in enumerate(pages_from_path): + current_barcodes = barcode_reader(page) + if current_barcodes.isin("PATCHT"): + seperator_page_numbers = seperator_page_numbers + current_page_number + return seperator_page_numbers + +def seperate_pages(filepath, pages_to_split_on: list): + """ + Seperate the provided file on the pages_to_split_on. + The pages which are defined by page_numbers will be removed. + """ + pages_to_split_on = scan_file_for_seperating_barcodes(filepath) + fname = os.path.splitext(os.path.basename(filepath))[0] + pdf = Pdf.open(filepath) + # TODO: Get the directory of the file and save the other files there + # TODO: Return list of new paths of the new files + for count, page_number in enumerate(pages_to_split_on): + # First element, so iterate from zero to the first seperator page + if count == 0: + dst = Pdf.new() + for page in range(0, page_number): + dst.pages.append(page) + output_filename = '{}_page_{}.pdf'.format( + fname, str(count)) + with open(output_filename, 'wb') as out: + dst.save(out) + else: + dst = Pdf.new() + for page in range(pages_to_split_on[count-1], page_number): + dst.pages.append(page) + output_filename = '{}_page_{}.pdf'.format( + fname, page+1) + with open(output_filename, 'wb') as out: + dst.save(out) + + def consume_file( path, override_filename=None, @@ -72,6 +144,11 @@ def consume_file( task_id=None, ): + # check for seperators in current document + seperator_page_numbers = scan_file_for_seperating_barcodes(path) + if seperator_page_numbers != [ ]: + logger.debug(f"Pages with seperators found: {str(seperator_page_numbers)}") + document = Consumer().try_consume_file( path, override_filename=override_filename, diff --git a/src/documents/tests/samples/patch-code-t.pbm b/src/documents/tests/samples/patch-code-t.pbm new file mode 100644 index 0000000000000000000000000000000000000000..7e721407032ca07ea287cbaa8568bc51890665fe GIT binary patch literal 484186 zcmeI5e{dUTe%^P16#@Au5`a{PvJeu6aLVPXG&HH|pfMw^ZP)^@%EfjrjW5%=LMIL! z&!{OCcU)?skruLQ0(Z1X$mx}=b&+%DCX@Wpk*iK;ZjwKsP`0E7lHyA{BTeoy(2qOK zbljAZW_of*WA^*LyP#GS@d{YISYqL4M*wsw%?)0ib(PLS_<+aa5rkk8vvSm`ycfxFWVa)K%o#pT5KF8k=+%_e6&V0c%D zRq_zOQ{(QmL(ewkFOjgekz?!G+QA*jY32R`?!X<_Y5=ggR@Dwp)V}Tn?l`E97E5At zr^QO-xef1wT94tHd; zU+Hhjw%uT%EJxyg5H*}BpF3#Z;x+hHQntYVrHd9I^-p>^xKv67LT!JyIxvmuM_ zboaNFoG<8#s&;i7joI3ou^DV7MfHb0&l`7ybp-_5Dpg(e(@JaBc%7xqWC1iTkOeR((G054|nNa%8igE~BcZd0vj`2;GAI4J~K!z8upL8X!<# z(3kMMJC-ACfY1h8)e$y)YoiTvTG>qIj;iRoqR>C@Z%hu|>(CbCuO5BTL)4?uKPE@} z<~M)4_)Smua0au1R)camuf6m;FTLhvIqEO`hkt+lw+~x#MqYaPr4diddE)E;{11PJ z9_4a(ye}v6^{@Zo%QiW`>1}tG%K3Hg%lVPzj`urimE3u!3Y+<)KxciOS2u$d-0G;k zs=-!no$XtfQQKj!@3M}%jW)<>Wi#Op+;Oc20Gn%7?chXk$3dmJmIUs&R@Dwp1a}-% znrlhmj%!uz;6!l8L8ZBt1n#(2)ecSscN|ojYf0daYgO&wL~zGJrMZ>_?zmRf4o(Dj z98{WXN#KraRqfzJaK}NVxt0X(xK`B;P6T%xRGMo^;Erom?chXk$3dmJmIUs&R@Dwp z1a}-%nrlhmj%!uz;6!l8L8ZBt1n#(2)ecSscN|ojYf0daYgO&wL~zGJrMZ@5sXKv% zJ4#@IHuko-tN7WW72T*t`1#q}eY^Kn738dpNpOd1z}8@FyJ$PIkpygjO*T_C^8;*v zttK3@0{|Oflg(7k`~X{R*eGP>H}0I2@y^O?p%OrjZB$^}Z3%PWPOafvOW1?9V{0(B z-Ig#1Z3k_~JrL0q*xJ8s*F6VBXM#I6OKiKMI&&`!?$|7`?cy0VCqv>3F)a@^%)Uu< zhGhkJs0M89-?odcKr(B9ja}bugxPih8(49U&kx0|6UglgX1XFTe)agn-Bl z1Z;p!CQrh=02^Qv0wOaIumLuiJPGpxY=BJ&h|EC12H0fsB+Lu20X88ZG6MnI=LR+s zy7C)m7wf25HQfKL-j%n8N&t6k6QZ`=mM{nI)S9_&3473XYz@Y?+Y;uW?V#ZMWI=USIxj z$7YFbx4znIb}YDKv&6RB?0T;+f4F0_#I{>s?KL|V+_70=+iiBe*Ox!su~}lhdZ_gW81|ecX^nZIRQ4R0UKeqUBCv|gf)P+gSI0CL}nmh18g#R z66OWi0GkjHnSp=}u*u{}m=|CJY(hX}1_Cy~CX**&UVsg-2?3EA2-pCdOrC^!0XD!U z1Vm;aU;}J2c@pLY*lNQ@AuGRe_ppwdRRh*hHycO5W}AJt?KZpK>&qYR*etQ_)>nJY zjsuKGIim*)AUBcDCMW+TkD3)tkdCh<$k z=nCZ9gRa2V{%yPH3gokfuAtUe$kDUOr>(VmHg(~%N0ZoEa)#MLpXIhbUQYIMce&uj zV?3Ia6;lsyJN&0-jKx#;@IBQmXo-E`5%|%7Rq6$Ue^mO+SoGRrau&?;(d!W3v&-Ry zuCT-2k;9A2iu|CQgUkb7{oawY*fj60dX3oMw$y0I`8;`kT zbEl81S*UnR4y%2(Js@Y;l*4HB4s5*ksl=+;3ESKuHLR~@eSwGM%u{h`dq55et0?RW zLxG-UH0eLx;K0zz8W5qqgLhkc^AfXSaJg9CFdYJzSJES&A(vz%0ATC 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 Date: Wed, 23 Mar 2022 22:49:29 +0100 Subject: [PATCH 03/26] working split pages Signed-off-by: florian on nixos (Florian Brandes) --- src/documents/tasks.py | 85 +++++++++++------- .../tests/samples/patch-code-t-middle.pdf | Bin 0 -> 35388 bytes src/documents/tests/test_tasks.py | 36 +++++++- 3 files changed, 87 insertions(+), 34 deletions(-) create mode 100644 src/documents/tests/samples/patch-code-t-middle.pdf diff --git a/src/documents/tasks.py b/src/documents/tasks.py index dc646ddfc..1dd41b740 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -69,69 +69,92 @@ def train_classifier(): logger.warning("Classifier error: " + str(e)) - -def barcode_reader(page) -> list: +def barcode_reader(image) -> list: """ - Read any barcodes contained in page + Read any barcodes contained in image Returns a list containing all found barcodes """ - barcodes = [ ] + barcodes = [] # Decode the barcode image - detected_barcodes = pyzbar.decode(page) + detected_barcodes = pyzbar.decode(image) if not detected_barcodes: logger.debug(f"No barcode detected") else: # Traverse through all the detected barcodes in image for barcode in detected_barcodes: - if barcode.data!="": + if barcode.data != "": barcodes = barcodes + [str(barcode.data)] - logger.debug(f"Barcode of type {str(barcode.type)} found: {str(barcode.data)}") + logger.debug( + f"Barcode of type {str(barcode.type)} found: {str(barcode.data)}" + ) return barcodes -def scan_file_for_seperating_barcodes(filepath) -> list: + +def scan_file_for_seperating_barcodes(filepath: str) -> list: """ Scan the provided file for page seperating barcodes Returns a list of pagenumbers, which seperate the file """ - seperator_page_numbers = [ ] + seperator_page_numbers = [] # use a temporary directory in case the file os too big to handle in memory with tempfile.TemporaryDirectory() as path: pages_from_path = convert_from_path(filepath, output_folder=path) for current_page_number, page in enumerate(pages_from_path): current_barcodes = barcode_reader(page) - if current_barcodes.isin("PATCHT"): - seperator_page_numbers = seperator_page_numbers + current_page_number + if "b'PATCHT'" in current_barcodes: + seperator_page_numbers = seperator_page_numbers + [current_page_number] return seperator_page_numbers -def seperate_pages(filepath, pages_to_split_on: list): + +def seperate_pages(filepath: str, pages_to_split_on: list) -> list: """ Seperate the provided file on the pages_to_split_on. The pages which are defined by page_numbers will be removed. + Returns a list of (temporary) filepaths to consume. + These will need to be deleted later. """ - pages_to_split_on = scan_file_for_seperating_barcodes(filepath) + 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)}") # TODO: Get the directory of the file and save the other files there # TODO: Return list of new paths of the new files + if len(pages_to_split_on) <= 0: + logger.warning(f"No pages to split on!") + else: + # go from the first page to the first separator page + dst = Pdf.new() + for n, page in enumerate(pdf.pages): + if n < pages_to_split_on[0]: + dst.pages.append(page) + output_filename = "{}_document_0.pdf".format(fname) + savepath = os.path.join(tempdir, output_filename) + with open(savepath, "wb") as out: + dst.save(out) + document_paths = [savepath] + for count, page_number in enumerate(pages_to_split_on): - # First element, so iterate from zero to the first seperator page - if count == 0: - dst = Pdf.new() - for page in range(0, page_number): - dst.pages.append(page) - output_filename = '{}_page_{}.pdf'.format( - fname, str(count)) - with open(output_filename, 'wb') as out: - dst.save(out) - else: - dst = Pdf.new() - for page in range(pages_to_split_on[count-1], page_number): - dst.pages.append(page) - output_filename = '{}_page_{}.pdf'.format( - fname, page+1) - with open(output_filename, 'wb') as out: - dst.save(out) + 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 = "{}_document_{}.pdf".format(fname, str(count + 1)) + 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 = document_paths + [savepath] + logger.debug(f"Temp files are {str(document_paths)}") + return document_paths def consume_file( @@ -146,7 +169,7 @@ def consume_file( # check for seperators in current document seperator_page_numbers = scan_file_for_seperating_barcodes(path) - if seperator_page_numbers != [ ]: + if seperator_page_numbers != []: logger.debug(f"Pages with seperators found: {str(seperator_page_numbers)}") document = Consumer().try_consume_file( diff --git a/src/documents/tests/samples/patch-code-t-middle.pdf b/src/documents/tests/samples/patch-code-t-middle.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2ccb76947e4e47dfc2e482326391cdac74f177e2 GIT binary patch literal 35388 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 literal 0 HcmV?d00001 diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index 94df0fc73..02c747e3e 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -93,13 +93,43 @@ class TestTasks(DirectoriesMixin, TestCase): def test_barcode_reader(self): test_file = os.path.join( - os.path.dirname(__file__), - "samples", - "patch-code-t.pbm" + os.path.dirname(__file__), "samples", "patch-code-t.pbm" ) img = Image.open(test_file) self.assertEqual(tasks.barcode_reader(img), ["b'PATCHT'"]) + def test_barcode_reader2(self): + test_file = os.path.join(os.path.dirname(__file__), "samples", "simple.png") + img = Image.open(test_file) + self.assertEqual(tasks.barcode_reader(img), []) + + def test_scan_file_for_seperating_barcodes(self): + test_file = os.path.join( + os.path.dirname(__file__), "samples", "patch-code-t.pdf" + ) + pages = tasks.scan_file_for_seperating_barcodes(test_file) + self.assertEqual(pages, [0]) + + def test_scan_file_for_seperating_barcodes2(self): + test_file = os.path.join(os.path.dirname(__file__), "samples", "simple.pdf") + pages = tasks.scan_file_for_seperating_barcodes(test_file) + self.assertEqual(pages, []) + + def test_scan_file_for_seperating_barcodes3(self): + test_file = os.path.join( + os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf" + ) + pages = tasks.scan_file_for_seperating_barcodes(test_file) + self.assertEqual(pages, [1]) + + def test_seperate_pages(self): + test_file = os.path.join( + os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf" + ) + pages = tasks.seperate_pages(test_file, [1]) + + self.assertEqual(len(pages), 2) + @mock.patch("documents.tasks.sanity_checker.check_sanity") def test_sanity_check_success(self, m): m.return_value = SanityCheckMessages() From 4fe966f53402c40d48be8a1972aa7297dd3dd7d0 Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Thu, 24 Mar 2022 11:33:24 +0100 Subject: [PATCH 04/26] more work on barcode Signed-off-by: florian on nixos (Florian Brandes) --- src/documents/tasks.py | 33 +++++++++++------- src/documents/tests/test_tasks.py | 58 ++++++++++++++++++++++++++----- 2 files changed, 70 insertions(+), 21 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 1dd41b740..5161fcc01 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -22,6 +22,7 @@ from pyzbar import pyzbar from pdf2image import convert_from_path import tempfile from pikepdf import Pdf +import shutil logger = logging.getLogger("paperless.tasks") @@ -91,25 +92,25 @@ def barcode_reader(image) -> list: return barcodes -def scan_file_for_seperating_barcodes(filepath: str) -> list: +def scan_file_for_separating_barcodes(filepath: str) -> list: """ - Scan the provided file for page seperating barcodes - Returns a list of pagenumbers, which seperate the file + Scan the provided file for page separating barcodes + Returns a list of pagenumbers, which separate the file """ - seperator_page_numbers = [] + separator_page_numbers = [] # use a temporary directory in case the file os too big to handle in memory with tempfile.TemporaryDirectory() as path: pages_from_path = convert_from_path(filepath, output_folder=path) for current_page_number, page in enumerate(pages_from_path): current_barcodes = barcode_reader(page) if "b'PATCHT'" in current_barcodes: - seperator_page_numbers = seperator_page_numbers + [current_page_number] - return seperator_page_numbers + separator_page_numbers = separator_page_numbers + [current_page_number] + return separator_page_numbers -def seperate_pages(filepath: str, pages_to_split_on: list) -> list: +def separate_pages(filepath: str, pages_to_split_on: list) -> list: """ - Seperate the provided file on the pages_to_split_on. + Separate the provided file on the pages_to_split_on. The pages which are defined by page_numbers will be removed. Returns a list of (temporary) filepaths to consume. These will need to be deleted later. @@ -156,6 +157,14 @@ def seperate_pages(filepath: str, pages_to_split_on: list) -> list: logger.debug(f"Temp files are {str(document_paths)}") return document_paths +def save_to_dir(filepath, target_dir=settings.CONSUMPTION_DIR): + """ + Copies filepath to target_dir. + """ + if os.path.isfile(filepath) and os.path.isdir(target_dir): + shutil.copy(filepath, target_dir) + else: + logger.warning(f"{str(filepath)} or {str(target_dir)} don't exist.") def consume_file( path, @@ -167,10 +176,10 @@ def consume_file( task_id=None, ): - # check for seperators in current document - seperator_page_numbers = scan_file_for_seperating_barcodes(path) - if seperator_page_numbers != []: - logger.debug(f"Pages with seperators found: {str(seperator_page_numbers)}") + # check for separators in current document + separator_page_numbers = scan_file_for_separating_barcodes(path) + if separator_page_numbers != []: + logger.debug(f"Pages with separators found: {str(separator_page_numbers)}") document = Consumer().try_consume_file( path, diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index 02c747e3e..fcb6909ff 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -14,6 +14,7 @@ from documents.sanity_checker import SanityCheckMessages from documents.tests.utils import DirectoriesMixin from PIL import Image +import tempfile class TestTasks(DirectoriesMixin, TestCase): @@ -103,33 +104,72 @@ class TestTasks(DirectoriesMixin, TestCase): img = Image.open(test_file) self.assertEqual(tasks.barcode_reader(img), []) - def test_scan_file_for_seperating_barcodes(self): + def test_scan_file_for_separating_barcodes(self): test_file = os.path.join( os.path.dirname(__file__), "samples", "patch-code-t.pdf" ) - pages = tasks.scan_file_for_seperating_barcodes(test_file) + pages = tasks.scan_file_for_separating_barcodes(test_file) self.assertEqual(pages, [0]) - def test_scan_file_for_seperating_barcodes2(self): + def test_scan_file_for_separating_barcodes2(self): test_file = os.path.join(os.path.dirname(__file__), "samples", "simple.pdf") - pages = tasks.scan_file_for_seperating_barcodes(test_file) + pages = tasks.scan_file_for_separating_barcodes(test_file) self.assertEqual(pages, []) - def test_scan_file_for_seperating_barcodes3(self): + def test_scan_file_for_separating_barcodes3(self): test_file = os.path.join( os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf" ) - pages = tasks.scan_file_for_seperating_barcodes(test_file) + pages = tasks.scan_file_for_separating_barcodes(test_file) self.assertEqual(pages, [1]) - def test_seperate_pages(self): + def test_separate_pages(self): test_file = os.path.join( os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf" ) - pages = tasks.seperate_pages(test_file, [1]) - + pages = tasks.separate_pages(test_file, [1]) self.assertEqual(len(pages), 2) + def test_save_to_dir(self): + test_file = os.path.join( + os.path.dirname(__file__), "samples", "patch-code-t.pdf" + ) + tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) + tasks.save_to_dir(test_file, tempdir) + target_file = os.path.join(tempdir, "patch-code-t.pdf") + self.assertTrue(os.path.isfile(target_file)) + + def test_save_to_dir2(self): + test_file = os.path.join( + os.path.dirname(__file__), "samples", "patch-code-t.pdf" + ) + nonexistingdir = "/nowhere" + if not os.path.isdir(nonexistingdir): + with self.assertLogs("paperless.tasks", level="WARNING") as cm: + tasks.save_to_dir(test_file, nonexistingdir) + self.assertEqual( + cm.output, + [ + f"WARNING:paperless.tasks:{str(test_file)} or {str(nonexistingdir)} don't exist." + ], + ) + + def test_barcode_splitter(self): + test_file = os.path.join( + os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf" + ) + tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) + separators = tasks.scan_file_for_separating_barcodes(test_file) + self.assertTrue(separators != []) + document_list = tasks.separate_pages(test_file, separators) + self.assertTrue(document_list != []) + for document in document_list: + tasks.save_to_dir(document, tempdir) + target_file1 = os.path.join(tempdir, "patch-code-t-middle_document_0.pdf") + target_file2 = os.path.join(tempdir, "patch-code-t-middle_document_1.pdf") + self.assertTrue(os.path.isfile(target_file1)) + self.assertTrue(os.path.isfile(target_file2)) + @mock.patch("documents.tasks.sanity_checker.check_sanity") def test_sanity_check_success(self, m): m.return_value = SanityCheckMessages() From b5f77fd6e7b41b4023655ad35db13f8e21082bdc Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Thu, 24 Mar 2022 12:24:26 +0100 Subject: [PATCH 05/26] skip test if dir exists Signed-off-by: florian on nixos (Florian Brandes) --- src/documents/tests/test_tasks.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index fcb6909ff..a23e00c93 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -144,7 +144,9 @@ class TestTasks(DirectoriesMixin, TestCase): os.path.dirname(__file__), "samples", "patch-code-t.pdf" ) nonexistingdir = "/nowhere" - if not os.path.isdir(nonexistingdir): + if os.path.isdir(nonexistingdir): + self.skipTest("non-existing dir exists") + else: with self.assertLogs("paperless.tasks", level="WARNING") as cm: tasks.save_to_dir(test_file, nonexistingdir) self.assertEqual( From b22742791625370641de9a213186e63b56db3a2f Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Wed, 6 Apr 2022 21:22:07 +0200 Subject: [PATCH 06/26] add split logic to consume_file Signed-off-by: florian on nixos (Florian Brandes) --- requirements.txt | 1 + src/documents/tasks.py | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index afc8b9f51..26ec003f8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -61,6 +61,7 @@ ocrmypdf==13.4.2 packaging==21.3; python_version >= '3.6' pathvalidate==2.5.0 pdfminer.six==20220319 +pdf2image==1.16.0 pikepdf==5.1.1 pillow==9.1.0 pluggy==1.0.0; python_version >= '3.6' diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 5161fcc01..eff46436e 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -177,10 +177,26 @@ def consume_file( ): # check for separators in current document - separator_page_numbers = scan_file_for_separating_barcodes(path) - if separator_page_numbers != []: - logger.debug(f"Pages with separators found: {str(separator_page_numbers)}") + separators = scan_file_for_separating_barcodes(path) + document_list = [] + if separators == []: + pass + else: + logger.debug(f"Pages with separators found in: {str(path)}") + document_list = separate_pages(path, separators) + if document_list == []: + pass + else: + for document in document_list: + # save to consumption dir + save_to_dir(document) + # if we got here, the document was successfully split + # and can safely be deleted + logger.debug("Deleting file {}".format(path)) + os.unlink(path) + return "File successfully split" + # continue with consumption if no barcode was found document = Consumer().try_consume_file( path, override_filename=override_filename, From 911f5bc78e8ddf3efbc8a9dd1b3e4e0c97c2328c Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Thu, 24 Mar 2022 18:17:29 +0100 Subject: [PATCH 07/26] reorder imports Signed-off-by: florian on nixos (Florian Brandes) --- src/documents/tasks.py | 13 ++++++------- src/documents/tests/test_tasks.py | 3 +-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index eff46436e..a5d2d26ca 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -1,4 +1,7 @@ import logging +import os +import shutil +import tempfile import tqdm from django.conf import settings @@ -14,15 +17,11 @@ from documents.models import Document from documents.models import DocumentType from documents.models import Tag from documents.sanity_checker import SanityCheckFailedException -from whoosh.writing import AsyncWriter - -# barcode decoder -import os -from pyzbar import pyzbar from pdf2image import convert_from_path -import tempfile from pikepdf import Pdf -import shutil +from pyzbar import pyzbar +from whoosh.writing import AsyncWriter +# barcode decoder logger = logging.getLogger("paperless.tasks") diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index a23e00c93..17a36e5cb 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -1,4 +1,5 @@ import os +import tempfile from unittest import mock from django.conf import settings @@ -12,9 +13,7 @@ from documents.models import Tag from documents.sanity_checker import SanityCheckFailedException from documents.sanity_checker import SanityCheckMessages from documents.tests.utils import DirectoriesMixin - from PIL import Image -import tempfile class TestTasks(DirectoriesMixin, TestCase): From 78ca2ffabac1642c4c99c6ba1357f40a0d3a2b51 Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Thu, 24 Mar 2022 21:26:30 +0100 Subject: [PATCH 08/26] add trailing commas Signed-off-by: florian on nixos (Florian Brandes) --- src/documents/tasks.py | 2 +- src/documents/tests/test_tasks.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index a5d2d26ca..2f0fe30c4 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -86,7 +86,7 @@ def barcode_reader(image) -> list: if barcode.data != "": barcodes = barcodes + [str(barcode.data)] logger.debug( - f"Barcode of type {str(barcode.type)} found: {str(barcode.data)}" + f"Barcode of type {str(barcode.type)} found: {str(barcode.data)}", ) return barcodes diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index 17a36e5cb..2cf68c216 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -93,7 +93,7 @@ class TestTasks(DirectoriesMixin, TestCase): def test_barcode_reader(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t.pbm" + os.path.dirname(__file__), "samples", "patch-code-t.pbm", ) img = Image.open(test_file) self.assertEqual(tasks.barcode_reader(img), ["b'PATCHT'"]) @@ -105,7 +105,7 @@ class TestTasks(DirectoriesMixin, TestCase): def test_scan_file_for_separating_barcodes(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t.pdf" + os.path.dirname(__file__), "samples", "patch-code-t.pdf", ) pages = tasks.scan_file_for_separating_barcodes(test_file) self.assertEqual(pages, [0]) @@ -117,21 +117,21 @@ class TestTasks(DirectoriesMixin, TestCase): def test_scan_file_for_separating_barcodes3(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf" + os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf", ) pages = tasks.scan_file_for_separating_barcodes(test_file) self.assertEqual(pages, [1]) def test_separate_pages(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf" + os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf", ) pages = tasks.separate_pages(test_file, [1]) self.assertEqual(len(pages), 2) def test_save_to_dir(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t.pdf" + os.path.dirname(__file__), "samples", "patch-code-t.pdf", ) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) tasks.save_to_dir(test_file, tempdir) @@ -140,7 +140,7 @@ class TestTasks(DirectoriesMixin, TestCase): def test_save_to_dir2(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t.pdf" + os.path.dirname(__file__), "samples", "patch-code-t.pdf", ) nonexistingdir = "/nowhere" if os.path.isdir(nonexistingdir): @@ -151,13 +151,13 @@ class TestTasks(DirectoriesMixin, TestCase): self.assertEqual( cm.output, [ - f"WARNING:paperless.tasks:{str(test_file)} or {str(nonexistingdir)} don't exist." + f"WARNING:paperless.tasks:{str(test_file)} or {str(nonexistingdir)} don't exist.", ], ) def test_barcode_splitter(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf" + os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf", ) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) separators = tasks.scan_file_for_separating_barcodes(test_file) From 50f474ae92b26447fda99a72ee9174a944254bba Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Thu, 24 Mar 2022 21:30:34 +0100 Subject: [PATCH 09/26] run black Signed-off-by: florian on nixos (Florian Brandes) --- src/documents/tasks.py | 3 +++ src/documents/tests/test_tasks.py | 28 +++++++++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 2f0fe30c4..4bb3804d2 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -21,6 +21,7 @@ from pdf2image import convert_from_path from pikepdf import Pdf from pyzbar import pyzbar from whoosh.writing import AsyncWriter + # barcode decoder logger = logging.getLogger("paperless.tasks") @@ -156,6 +157,7 @@ def separate_pages(filepath: str, pages_to_split_on: list) -> list: logger.debug(f"Temp files are {str(document_paths)}") return document_paths + def save_to_dir(filepath, target_dir=settings.CONSUMPTION_DIR): """ Copies filepath to target_dir. @@ -165,6 +167,7 @@ def save_to_dir(filepath, target_dir=settings.CONSUMPTION_DIR): else: logger.warning(f"{str(filepath)} or {str(target_dir)} don't exist.") + def consume_file( path, override_filename=None, diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index 2cf68c216..ab692f6b3 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -93,7 +93,9 @@ class TestTasks(DirectoriesMixin, TestCase): def test_barcode_reader(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t.pbm", + os.path.dirname(__file__), + "samples", + "patch-code-t.pbm", ) img = Image.open(test_file) self.assertEqual(tasks.barcode_reader(img), ["b'PATCHT'"]) @@ -105,7 +107,9 @@ class TestTasks(DirectoriesMixin, TestCase): def test_scan_file_for_separating_barcodes(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t.pdf", + os.path.dirname(__file__), + "samples", + "patch-code-t.pdf", ) pages = tasks.scan_file_for_separating_barcodes(test_file) self.assertEqual(pages, [0]) @@ -117,21 +121,27 @@ class TestTasks(DirectoriesMixin, TestCase): def test_scan_file_for_separating_barcodes3(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf", + os.path.dirname(__file__), + "samples", + "patch-code-t-middle.pdf", ) pages = tasks.scan_file_for_separating_barcodes(test_file) self.assertEqual(pages, [1]) def test_separate_pages(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf", + os.path.dirname(__file__), + "samples", + "patch-code-t-middle.pdf", ) pages = tasks.separate_pages(test_file, [1]) self.assertEqual(len(pages), 2) def test_save_to_dir(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t.pdf", + os.path.dirname(__file__), + "samples", + "patch-code-t.pdf", ) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) tasks.save_to_dir(test_file, tempdir) @@ -140,7 +150,9 @@ class TestTasks(DirectoriesMixin, TestCase): def test_save_to_dir2(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t.pdf", + os.path.dirname(__file__), + "samples", + "patch-code-t.pdf", ) nonexistingdir = "/nowhere" if os.path.isdir(nonexistingdir): @@ -157,7 +169,9 @@ class TestTasks(DirectoriesMixin, TestCase): def test_barcode_splitter(self): test_file = os.path.join( - os.path.dirname(__file__), "samples", "patch-code-t-middle.pdf", + os.path.dirname(__file__), + "samples", + "patch-code-t-middle.pdf", ) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) separators = tasks.scan_file_for_separating_barcodes(test_file) From 488fe28ad32849c4aec3bd1db5d97c7e5d495631 Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Thu, 24 Mar 2022 21:36:57 +0100 Subject: [PATCH 10/26] flake8 Signed-off-by: florian on nixos (Florian Brandes) --- src/documents/tasks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 4bb3804d2..23c81e051 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -80,7 +80,7 @@ def barcode_reader(image) -> list: detected_barcodes = pyzbar.decode(image) if not detected_barcodes: - logger.debug(f"No barcode detected") + logger.debug("No barcode detected") else: # Traverse through all the detected barcodes in image for barcode in detected_barcodes: @@ -124,7 +124,7 @@ def separate_pages(filepath: str, pages_to_split_on: list) -> list: # TODO: Get the directory of the file and save the other files there # TODO: Return list of new paths of the new files if len(pages_to_split_on) <= 0: - logger.warning(f"No pages to split on!") + logger.warning("No pages to split on!") else: # go from the first page to the first separator page dst = Pdf.new() From 06cac44d021ffe1c5b0876c2731b9f6e48d73f85 Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Thu, 24 Mar 2022 21:50:03 +0100 Subject: [PATCH 11/26] update ci.yml to include new dependency Signed-off-by: florian on nixos (Florian Brandes) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22b90b5e0..0bac7f852 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -132,7 +132,7 @@ jobs: name: Install system dependencies run: | sudo apt-get update -qq - sudo apt-get install -qq --no-install-recommends unpaper tesseract-ocr imagemagick ghostscript optipng + sudo apt-get install -qq --no-install-recommends unpaper tesseract-ocr imagemagick ghostscript optipng libzbar0 poppler-utils - name: Install Python dependencies run: | From e89ef5de25ebea1565ceaed2ecbd33df29e09e78 Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Sat, 26 Mar 2022 08:41:50 +0100 Subject: [PATCH 12/26] renaming of documents to align with front end Signed-off-by: florian on nixos (Florian Brandes) --- src/documents/tasks.py | 35 +++++++++++++++++++++++++------ src/documents/tests/test_tasks.py | 17 ++++++++++++--- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 23c81e051..2b5ce8bdc 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -21,6 +21,8 @@ from pdf2image import convert_from_path from pikepdf import Pdf from pyzbar import pyzbar from whoosh.writing import AsyncWriter +from asgiref.sync import async_to_sync +from channels.layers import get_channel_layer # barcode decoder @@ -121,8 +123,6 @@ def separate_pages(filepath: str, pages_to_split_on: list) -> list: pdf = Pdf.open(filepath) document_paths = [] logger.debug(f"Temp dir is {str(tempdir)}") - # TODO: Get the directory of the file and save the other files there - # TODO: Return list of new paths of the new files if len(pages_to_split_on) <= 0: logger.warning("No pages to split on!") else: @@ -158,12 +158,19 @@ def separate_pages(filepath: str, pages_to_split_on: list) -> list: return document_paths -def save_to_dir(filepath, target_dir=settings.CONSUMPTION_DIR): +def save_to_dir(filepath, newname=None, target_dir=settings.CONSUMPTION_DIR): """ Copies filepath to target_dir. + Optionally rename the file. """ + logger.debug(f"filepath: {str(filepath)}") + logger.debug(f"newname: {str(newname)}") + logger.debug(f"target_dir: {str(target_dir)}") if os.path.isfile(filepath) and os.path.isdir(target_dir): - shutil.copy(filepath, target_dir) + dst = shutil.copy(filepath, target_dir) + if newname: + dst_new = os.path.join(target_dir, newname) + os.rename(dst, dst_new) else: logger.warning(f"{str(filepath)} or {str(target_dir)} don't exist.") @@ -189,13 +196,29 @@ def consume_file( if document_list == []: pass else: - for document in document_list: + for n, document in enumerate(document_list): # save to consumption dir - save_to_dir(document) + # rename it to the original filename with number prefix + newname = f"{str(n)}_" + override_filename + save_to_dir(document, newname=newname) # if we got here, the document was successfully split # and can safely be deleted logger.debug("Deleting file {}".format(path)) os.unlink(path) + # notify the sender, otherwise the progress bar + # in the UI stays stuck + payload = { + "filename": override_filename, + "task_id": task_id, + "current_progress": 100, + "max_progress": 100, + "status": "SUCCESS", + "message": "finished" + } + async_to_sync(get_channel_layer().group_send)( + "status_updates", + {"type": "status_update", "data": payload}, + ) return "File successfully split" # continue with consumption if no barcode was found diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index ab692f6b3..b5eabdd1a 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -144,7 +144,7 @@ class TestTasks(DirectoriesMixin, TestCase): "patch-code-t.pdf", ) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) - tasks.save_to_dir(test_file, tempdir) + tasks.save_to_dir(test_file, target_dir=tempdir) target_file = os.path.join(tempdir, "patch-code-t.pdf") self.assertTrue(os.path.isfile(target_file)) @@ -159,7 +159,7 @@ class TestTasks(DirectoriesMixin, TestCase): self.skipTest("non-existing dir exists") else: with self.assertLogs("paperless.tasks", level="WARNING") as cm: - tasks.save_to_dir(test_file, nonexistingdir) + tasks.save_to_dir(test_file, target_dir=nonexistingdir) self.assertEqual( cm.output, [ @@ -167,6 +167,17 @@ class TestTasks(DirectoriesMixin, TestCase): ], ) + def test_save_to_dir3(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "patch-code-t.pdf", + ) + tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) + tasks.save_to_dir(test_file, newname="newname.pdf", target_dir=tempdir) + target_file = os.path.join(tempdir, "newname.pdf") + self.assertTrue(os.path.isfile(target_file)) + def test_barcode_splitter(self): test_file = os.path.join( os.path.dirname(__file__), @@ -179,7 +190,7 @@ class TestTasks(DirectoriesMixin, TestCase): document_list = tasks.separate_pages(test_file, separators) self.assertTrue(document_list != []) for document in document_list: - tasks.save_to_dir(document, tempdir) + tasks.save_to_dir(document, target_dir=tempdir) target_file1 = os.path.join(tempdir, "patch-code-t-middle_document_0.pdf") target_file2 = os.path.join(tempdir, "patch-code-t-middle_document_1.pdf") self.assertTrue(os.path.isfile(target_file1)) From 37b3fde4e1a5f08d2e5c4c69400a373753dc38d6 Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Sat, 26 Mar 2022 09:28:19 +0100 Subject: [PATCH 13/26] pre-commit hooks Signed-off-by: florian on nixos (Florian Brandes) --- src/documents/tasks.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 2b5ce8bdc..e7d20eff8 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -4,6 +4,8 @@ import shutil import tempfile import tqdm +from asgiref.sync import async_to_sync +from channels.layers import get_channel_layer from django.conf import settings from django.db.models.signals import post_save from documents import index @@ -21,8 +23,6 @@ from pdf2image import convert_from_path from pikepdf import Pdf from pyzbar import pyzbar from whoosh.writing import AsyncWriter -from asgiref.sync import async_to_sync -from channels.layers import get_channel_layer # barcode decoder @@ -213,7 +213,7 @@ def consume_file( "current_progress": 100, "max_progress": 100, "status": "SUCCESS", - "message": "finished" + "message": "finished", } async_to_sync(get_channel_layer().group_send)( "status_updates", From c024b846c3d728733ba23f61450a4eccb566cbf2 Mon Sep 17 00:00:00 2001 From: "florian on nixos (Florian Brandes)" Date: Sat, 26 Mar 2022 10:16:23 +0100 Subject: [PATCH 14/26] add config options and documentation Signed-off-by: florian on nixos (Florian Brandes) --- docs/configuration.rst | 21 +++++++++++++++++++++ paperless.conf.example | 2 ++ src/documents/tasks.py | 14 +++++++------- src/documents/tests/test_tasks.py | 3 ++- src/paperless/settings.py | 7 +++++++ 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index f53266481..a5db8fffa 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -588,6 +588,27 @@ PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS= Defaults to false. +PAPERLESS_CONSUMER_ENABLE_BARCODES= + Enables the scanning and page separation based on detected barcodes. + This allows for scanning and adding multiple documents per uploaded + file, which are separated by one or multiple barcode pages. + + For ease of use, it is suggested to use a standardized separation page, + e.g. `here `_. + + If no barcodes are detected in the uploaded file, no page separation + will happen. + + Defaults to true. + + +PAPERLESS_CONSUMER_BARCODE_STRING=PATCHT + Defines the string to be detected as a separator barcode. + If paperless is used with the PATCH-T separator pages, users + shouldn't change this. + + Defaults to "PATCHT" + PAPERLESS_CONVERT_MEMORY_LIMIT= On smaller systems, or even in the case of Very Large Documents, the consumer diff --git a/paperless.conf.example b/paperless.conf.example index de24bde74..cad13257c 100644 --- a/paperless.conf.example +++ b/paperless.conf.example @@ -60,6 +60,8 @@ #PAPERLESS_CONSUMER_RECURSIVE=false #PAPERLESS_CONSUMER_IGNORE_PATTERNS=[".DS_STORE/*", "._*", ".stfolder/*", ".stversions/*", ".localized/*", "desktop.ini"] #PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS=false +#PAPERLESS_CONSUMER_ENABLE_BARCODES=true +#PAPERLESS_CONSUMER_ENABLE_BARCODES=PATCHT #PAPERLESS_OPTIMIZE_THUMBNAILS=true #PAPERLESS_PRE_CONSUME_SCRIPT=/path/to/an/arbitrary/script.sh #PAPERLESS_POST_CONSUME_SCRIPT=/path/to/an/arbitrary/script.sh diff --git a/src/documents/tasks.py b/src/documents/tasks.py index e7d20eff8..3abb3227b 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -24,8 +24,6 @@ from pikepdf import Pdf from pyzbar import pyzbar from whoosh.writing import AsyncWriter -# barcode decoder - logger = logging.getLogger("paperless.tasks") @@ -100,12 +98,13 @@ def scan_file_for_separating_barcodes(filepath: str) -> list: Returns a list of pagenumbers, which separate the file """ separator_page_numbers = [] + separator_barcode = "b'" + str(settings.CONSUMER_BARCODE_STRING) + "'" # use a temporary directory in case the file os too big to handle in memory with tempfile.TemporaryDirectory() as path: pages_from_path = convert_from_path(filepath, output_folder=path) for current_page_number, page in enumerate(pages_from_path): current_barcodes = barcode_reader(page) - if "b'PATCHT'" in current_barcodes: + if separator_barcode in current_barcodes: separator_page_numbers = separator_page_numbers + [current_page_number] return separator_page_numbers @@ -163,13 +162,12 @@ def save_to_dir(filepath, newname=None, target_dir=settings.CONSUMPTION_DIR): Copies filepath to target_dir. Optionally rename the file. """ - logger.debug(f"filepath: {str(filepath)}") - logger.debug(f"newname: {str(newname)}") - logger.debug(f"target_dir: {str(target_dir)}") if os.path.isfile(filepath) and os.path.isdir(target_dir): dst = shutil.copy(filepath, target_dir) + logging.debug(f"saved {str(filepath)} to {str(dst)}") if newname: dst_new = os.path.join(target_dir, newname) + logger.debug(f"moving {str(dst)} to {str(dst_new)}") os.rename(dst, dst_new) else: logger.warning(f"{str(filepath)} or {str(target_dir)} don't exist.") @@ -186,7 +184,9 @@ def consume_file( ): # check for separators in current document - separators = scan_file_for_separating_barcodes(path) + separators = [] + if settings.CONSUMER_ENABLE_BARCODES: + separators = scan_file_for_separating_barcodes(path) document_list = [] if separators == []: pass diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index b5eabdd1a..3e019b51e 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -98,7 +98,8 @@ class TestTasks(DirectoriesMixin, TestCase): "patch-code-t.pbm", ) img = Image.open(test_file) - self.assertEqual(tasks.barcode_reader(img), ["b'PATCHT'"]) + separator_barcode = "b'" + str(settings.CONSUMER_BARCODE_STRING) + "'" + self.assertEqual(tasks.barcode_reader(img), [separator_barcode]) def test_barcode_reader2(self): test_file = os.path.join(os.path.dirname(__file__), "samples", "simple.png") diff --git a/src/paperless/settings.py b/src/paperless/settings.py index 39b850813..934d19910 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -462,6 +462,13 @@ CONSUMER_IGNORE_PATTERNS = list( CONSUMER_SUBDIRS_AS_TAGS = __get_boolean("PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS") +CONSUMER_ENABLE_BARCODES = __get_boolean( + "PAPERLESS_CONSUMER_ENABLE_BARCODES", + default="YES", +) + +CONSUMER_BARCODE_STRING = os.getenv("PAPERLESS_CONSUMER_BARCODE_STRING", "PATCHT") + OPTIMIZE_THUMBNAILS = __get_boolean("PAPERLESS_OPTIMIZE_THUMBNAILS", "true") OCR_PAGES = int(os.getenv("PAPERLESS_OCR_PAGES", 0)) From 0ea5f5d584b772d302d8dcea548c391f72bf8d6e Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Tue, 29 Mar 2022 16:42:16 +0200 Subject: [PATCH 15/26] use append method for lists Signed-off-by: Florian Brandes --- src/documents/tasks.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 3abb3227b..422353a90 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -85,7 +85,7 @@ def barcode_reader(image) -> list: # Traverse through all the detected barcodes in image for barcode in detected_barcodes: if barcode.data != "": - barcodes = barcodes + [str(barcode.data)] + barcodes.append(str(barcode.data)) logger.debug( f"Barcode of type {str(barcode.type)} found: {str(barcode.data)}", ) @@ -105,7 +105,7 @@ def scan_file_for_separating_barcodes(filepath: str) -> list: for current_page_number, page in enumerate(pages_from_path): current_barcodes = barcode_reader(page) if separator_barcode in current_barcodes: - separator_page_numbers = separator_page_numbers + [current_page_number] + separator_page_numbers.append(current_page_number) return separator_page_numbers @@ -152,7 +152,7 @@ def separate_pages(filepath: str, pages_to_split_on: list) -> list: savepath = os.path.join(tempdir, output_filename) with open(savepath, "wb") as out: dst.save(out) - document_paths = document_paths + [savepath] + document_paths.append(savepath) logger.debug(f"Temp files are {str(document_paths)}") return document_paths From 793f641af63faa90a459cea8919960f69761996b Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Tue, 29 Mar 2022 17:56:11 +0200 Subject: [PATCH 16/26] make list checks consistent Signed-off-by: Florian Brandes --- src/documents/tasks.py | 16 +++++----------- src/documents/tests/test_tasks.py | 4 ++-- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 422353a90..61f0b9419 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -79,12 +79,10 @@ def barcode_reader(image) -> list: # Decode the barcode image detected_barcodes = pyzbar.decode(image) - if not detected_barcodes: - logger.debug("No barcode detected") - else: + if detected_barcodes: # Traverse through all the detected barcodes in image for barcode in detected_barcodes: - if barcode.data != "": + if barcode.data: barcodes.append(str(barcode.data)) logger.debug( f"Barcode of type {str(barcode.type)} found: {str(barcode.data)}", @@ -122,7 +120,7 @@ def separate_pages(filepath: str, pages_to_split_on: list) -> list: pdf = Pdf.open(filepath) document_paths = [] logger.debug(f"Temp dir is {str(tempdir)}") - if len(pages_to_split_on) <= 0: + if not pages_to_split_on: logger.warning("No pages to split on!") else: # go from the first page to the first separator page @@ -188,14 +186,10 @@ def consume_file( if settings.CONSUMER_ENABLE_BARCODES: separators = scan_file_for_separating_barcodes(path) document_list = [] - if separators == []: - pass - else: + if separators: logger.debug(f"Pages with separators found in: {str(path)}") document_list = separate_pages(path, separators) - if document_list == []: - pass - else: + if document_list: for n, document in enumerate(document_list): # save to consumption dir # rename it to the original filename with number prefix diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index 3e019b51e..9ac8c5fae 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -187,9 +187,9 @@ class TestTasks(DirectoriesMixin, TestCase): ) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) separators = tasks.scan_file_for_separating_barcodes(test_file) - self.assertTrue(separators != []) + self.assertTrue(separators) document_list = tasks.separate_pages(test_file, separators) - self.assertTrue(document_list != []) + self.assertTrue(document_list) for document in document_list: tasks.save_to_dir(document, target_dir=tempdir) target_file1 = os.path.join(tempdir, "patch-code-t-middle_document_0.pdf") From 422ac9befe37d89db0a23324f9f13f8cfefafe65 Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Tue, 29 Mar 2022 18:05:20 +0200 Subject: [PATCH 17/26] decode bytecode in string Signed-off-by: Florian Brandes --- src/documents/tasks.py | 7 ++++--- src/documents/tests/test_tasks.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 61f0b9419..a17b5b57b 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -83,9 +83,10 @@ def barcode_reader(image) -> list: # Traverse through all the detected barcodes in image for barcode in detected_barcodes: if barcode.data: - barcodes.append(str(barcode.data)) + decoded_barcode = barcode.data.decode("utf-8") + barcodes.append(decoded_barcode) logger.debug( - f"Barcode of type {str(barcode.type)} found: {str(barcode.data)}", + f"Barcode of type {str(barcode.type)} found: {decoded_barcode}", ) return barcodes @@ -96,7 +97,7 @@ def scan_file_for_separating_barcodes(filepath: str) -> list: Returns a list of pagenumbers, which separate the file """ separator_page_numbers = [] - separator_barcode = "b'" + str(settings.CONSUMER_BARCODE_STRING) + "'" + separator_barcode = str(settings.CONSUMER_BARCODE_STRING) # use a temporary directory in case the file os too big to handle in memory with tempfile.TemporaryDirectory() as path: pages_from_path = convert_from_path(filepath, output_folder=path) diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index 9ac8c5fae..2f950e28b 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -98,7 +98,7 @@ class TestTasks(DirectoriesMixin, TestCase): "patch-code-t.pbm", ) img = Image.open(test_file) - separator_barcode = "b'" + str(settings.CONSUMER_BARCODE_STRING) + "'" + separator_barcode = str(settings.CONSUMER_BARCODE_STRING) self.assertEqual(tasks.barcode_reader(img), [separator_barcode]) def test_barcode_reader2(self): From 9d2bcf807e5481331d84e61115d2eadd6d0e722a Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Tue, 29 Mar 2022 18:12:17 +0200 Subject: [PATCH 18/26] add more type hinting Signed-off-by: Florian Brandes --- src/documents/tasks.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index a17b5b57b..930619fc4 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -70,7 +70,7 @@ def train_classifier(): logger.warning("Classifier error: " + str(e)) -def barcode_reader(image) -> list: +def barcode_reader(image) -> list[str]: """ Read any barcodes contained in image Returns a list containing all found barcodes @@ -91,7 +91,7 @@ def barcode_reader(image) -> list: return barcodes -def scan_file_for_separating_barcodes(filepath: str) -> list: +def scan_file_for_separating_barcodes(filepath: str) -> list[int]: """ Scan the provided file for page separating barcodes Returns a list of pagenumbers, which separate the file @@ -108,7 +108,7 @@ def scan_file_for_separating_barcodes(filepath: str) -> list: return separator_page_numbers -def separate_pages(filepath: str, pages_to_split_on: list) -> list: +def separate_pages(filepath: str, pages_to_split_on: list[int]) -> list[str]: """ Separate the provided file on the pages_to_split_on. The pages which are defined by page_numbers will be removed. @@ -156,7 +156,9 @@ def separate_pages(filepath: str, pages_to_split_on: list) -> list: return document_paths -def save_to_dir(filepath, newname=None, target_dir=settings.CONSUMPTION_DIR): +def save_to_dir( + filepath: str, newname: str = None, target_dir: str = settings.CONSUMPTION_DIR +): """ Copies filepath to target_dir. Optionally rename the file. From 553153ba92234c91f40af2c291fe1a6705a0c12a Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Tue, 29 Mar 2022 18:14:11 +0200 Subject: [PATCH 19/26] put code under CONSUMER_ENABLE_BARCODES Signed-off-by: Florian Brandes --- src/documents/tasks.py | 60 +++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 930619fc4..161c05dfc 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -185,38 +185,38 @@ def consume_file( ): # check for separators in current document - separators = [] if settings.CONSUMER_ENABLE_BARCODES: + separators = [] + document_list = [] separators = scan_file_for_separating_barcodes(path) - document_list = [] - if separators: - logger.debug(f"Pages with separators found in: {str(path)}") - document_list = separate_pages(path, separators) - if document_list: - for n, document in enumerate(document_list): - # save to consumption dir - # rename it to the original filename with number prefix - newname = f"{str(n)}_" + override_filename - save_to_dir(document, newname=newname) - # if we got here, the document was successfully split - # and can safely be deleted - logger.debug("Deleting file {}".format(path)) - os.unlink(path) - # notify the sender, otherwise the progress bar - # in the UI stays stuck - payload = { - "filename": override_filename, - "task_id": task_id, - "current_progress": 100, - "max_progress": 100, - "status": "SUCCESS", - "message": "finished", - } - async_to_sync(get_channel_layer().group_send)( - "status_updates", - {"type": "status_update", "data": payload}, - ) - return "File successfully split" + if separators: + logger.debug(f"Pages with separators found in: {str(path)}") + document_list = separate_pages(path, separators) + if document_list: + for n, document in enumerate(document_list): + # save to consumption dir + # rename it to the original filename with number prefix + newname = f"{str(n)}_" + override_filename + save_to_dir(document, newname=newname) + # if we got here, the document was successfully split + # and can safely be deleted + logger.debug("Deleting file {}".format(path)) + os.unlink(path) + # notify the sender, otherwise the progress bar + # in the UI stays stuck + payload = { + "filename": override_filename, + "task_id": task_id, + "current_progress": 100, + "max_progress": 100, + "status": "SUCCESS", + "message": "finished", + } + async_to_sync(get_channel_layer().group_send)( + "status_updates", + {"type": "status_update", "data": payload}, + ) + return "File successfully split" # continue with consumption if no barcode was found document = Consumer().try_consume_file( From c696b4f2f2c8b25a36e5747cc38f59e3c30781aa Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Wed, 30 Mar 2022 17:20:22 +0200 Subject: [PATCH 20/26] set barcode reader default to disabled Signed-off-by: Florian Brandes --- src/paperless/settings.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/paperless/settings.py b/src/paperless/settings.py index 934d19910..dfd8848ea 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -464,7 +464,6 @@ CONSUMER_SUBDIRS_AS_TAGS = __get_boolean("PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS") CONSUMER_ENABLE_BARCODES = __get_boolean( "PAPERLESS_CONSUMER_ENABLE_BARCODES", - default="YES", ) CONSUMER_BARCODE_STRING = os.getenv("PAPERLESS_CONSUMER_BARCODE_STRING", "PATCHT") From e59a14852bd3518d810061d308060eb845dc6c80 Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Wed, 30 Mar 2022 17:24:01 +0200 Subject: [PATCH 21/26] code formatting Signed-off-by: Florian Brandes --- src/documents/tasks.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 161c05dfc..7fde919fc 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -157,7 +157,9 @@ def separate_pages(filepath: str, pages_to_split_on: list[int]) -> list[str]: def save_to_dir( - filepath: str, newname: str = None, target_dir: str = settings.CONSUMPTION_DIR + filepath: str, + newname: str = None, + target_dir: str = settings.CONSUMPTION_DIR, ): """ Copies filepath to target_dir. From 10ca515ac527b746d6a948d6aebca5d253923b64 Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Fri, 1 Apr 2022 12:26:39 +0200 Subject: [PATCH 22/26] addes tests: - barcode-39 - barcode-128 - qr barcodes - test for consumption Signed-off-by: Florian Brandes --- src/documents/tasks.py | 17 +- .../samples/barcodes/barcode-128-PATCHT.png | Bin 0 -> 836 bytes .../samples/barcodes/barcode-128-custom.pdf | Bin 0 -> 33165 bytes .../samples/barcodes/barcode-128-custom.png | Bin 0 -> 1274 bytes .../barcodes/barcode-39-PATCHT-distorsion.png | Bin 0 -> 33896 bytes .../barcode-39-PATCHT-distorsion2.png | Bin 0 -> 40381 bytes .../barcodes/barcode-39-PATCHT-unreadable.png | Bin 0 -> 9774 bytes .../samples/barcodes/barcode-39-PATCHT.png | Bin 0 -> 891 bytes .../samples/barcodes/barcode-39-custom.pdf | 243 ++++++++++++++++++ .../samples/barcodes/barcode-39-custom.png | Bin 0 -> 1357 bytes .../samples/barcodes/barcode-qr-custom.pdf | Bin 0 -> 18879 bytes .../samples/barcodes/barcode-qr-custom.png | Bin 0 -> 337 bytes .../{ => barcodes}/patch-code-t-middle.pdf | Bin .../samples/barcodes/patch-code-t-qr.pdf | Bin 0 -> 29646 bytes .../samples/{ => barcodes}/patch-code-t.pbm | Bin .../samples/{ => barcodes}/patch-code-t.pdf | Bin .../tests/samples/barcodes/qr-code-PATCHT.png | Bin 0 -> 7579 bytes src/documents/tests/test_tasks.py | 173 ++++++++++++- 18 files changed, 427 insertions(+), 6 deletions(-) create mode 100644 src/documents/tests/samples/barcodes/barcode-128-PATCHT.png create mode 100644 src/documents/tests/samples/barcodes/barcode-128-custom.pdf create mode 100644 src/documents/tests/samples/barcodes/barcode-128-custom.png create mode 100644 src/documents/tests/samples/barcodes/barcode-39-PATCHT-distorsion.png create mode 100644 src/documents/tests/samples/barcodes/barcode-39-PATCHT-distorsion2.png create mode 100644 src/documents/tests/samples/barcodes/barcode-39-PATCHT-unreadable.png create mode 100644 src/documents/tests/samples/barcodes/barcode-39-PATCHT.png create mode 100644 src/documents/tests/samples/barcodes/barcode-39-custom.pdf create mode 100644 src/documents/tests/samples/barcodes/barcode-39-custom.png create mode 100644 src/documents/tests/samples/barcodes/barcode-qr-custom.pdf create mode 100644 src/documents/tests/samples/barcodes/barcode-qr-custom.png rename src/documents/tests/samples/{ => barcodes}/patch-code-t-middle.pdf (100%) create mode 100644 src/documents/tests/samples/barcodes/patch-code-t-qr.pdf rename src/documents/tests/samples/{ => barcodes}/patch-code-t.pbm (100%) rename src/documents/tests/samples/{ => barcodes}/patch-code-t.pdf (100%) create mode 100644 src/documents/tests/samples/barcodes/qr-code-PATCHT.png diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 7fde919fc..7bd212399 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -198,7 +198,10 @@ def consume_file( for n, document in enumerate(document_list): # save to consumption dir # rename it to the original filename with number prefix - newname = f"{str(n)}_" + override_filename + if override_filename: + newname = f"{str(n)}_" + override_filename + else: + newname = None save_to_dir(document, newname=newname) # if we got here, the document was successfully split # and can safely be deleted @@ -214,10 +217,14 @@ def consume_file( "status": "SUCCESS", "message": "finished", } - async_to_sync(get_channel_layer().group_send)( - "status_updates", - {"type": "status_update", "data": payload}, - ) + try: + async_to_sync(get_channel_layer().group_send)( + "status_updates", + {"type": "status_update", "data": payload}, + ) + except OSError as e: + logger.warning("OSError. It could be, the broker cannot be reached.") + logger.warning(str(e)) return "File successfully split" # continue with consumption if no barcode was found diff --git a/src/documents/tests/samples/barcodes/barcode-128-PATCHT.png b/src/documents/tests/samples/barcodes/barcode-128-PATCHT.png new file mode 100644 index 0000000000000000000000000000000000000000..80517d56d0966c67b4d8fd4e1ac5cb34e7534f1c GIT binary patch literal 836 zcmeAS@N?(olHy`uVBq!ia0y~yV4MPEzu{m4l6Mv!f6u_c%Zu&YKp!xwbWZ-s||+bN3$Gd#!ZK_oQR*Prvz|w8VJtXB(~qoSotdaSV@G72+By z7(2v)1c;4I04#~D0xAGi4b*}v05h+HQVS4nLbZT)Hj?Zmiv38kjW}azx;F!AFde9M zS$j2&e{f4F>FLFLd!Kz<@zn11^O$-2x7Sxc`)>Doefr;=pH~ww!wt^!s${N%)C95k2iVG#ek^7<~ji3@?bgTd3)&t;ucLK6UKQa=Cy literal 0 HcmV?d00001 diff --git a/src/documents/tests/samples/barcodes/barcode-128-custom.pdf b/src/documents/tests/samples/barcodes/barcode-128-custom.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f603dff5f5e35907f8b44e9226927224c72cdfc9 GIT binary patch literal 33165 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 Kt}fSsNBIwWUGlvE literal 0 HcmV?d00001 diff --git a/src/documents/tests/samples/barcodes/barcode-128-custom.png b/src/documents/tests/samples/barcodes/barcode-128-custom.png new file mode 100644 index 0000000000000000000000000000000000000000..c3f1b803a6feeb605acf98946984aad487a98a45 GIT binary patch literal 1274 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 VAhG;7Fa`o5Ev_I|DPkD#e*j|y=5zo6 literal 0 HcmV?d00001 diff --git a/src/documents/tests/samples/barcodes/barcode-39-PATCHT-distorsion2.png b/src/documents/tests/samples/barcodes/barcode-39-PATCHT-distorsion2.png new file mode 100644 index 0000000000000000000000000000000000000000..cc81f8e360c13cad4c45191dcc6cc5f67cd2c4be GIT binary patch literal 40381 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%0DO|fUeB(K3 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 z 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

4-9@+R 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 literal 0 HcmV?d00001 diff --git a/src/documents/tests/samples/barcodes/barcode-39-PATCHT.png b/src/documents/tests/samples/barcodes/barcode-39-PATCHT.png new file mode 100644 index 0000000000000000000000000000000000000000..0078026c8f52af5f8b8d06e7b51203cc7b92f200 GIT binary patch literal 891 zcmeAS@N?(olHy`uVBq!ia0y~yV4MSFzu{m4lIP3Xr5PBQojhF}Ln>~)y?Ze4m4S%s zMTxKf>u<^$6sF4DycR_EORNSe8H3AS5?zDK7@()&4uu5(*wb)P%0dCzUJ3#e*%$#+ghK^Pw=*C@0*eI= zl3r`C#xm$Y;u-80h5ho|AJ}bav$blGd9h zm9TQ6`;)tiewfYNKK0su?+B1#>FfLd-Cd;P{bbhbGj-E}R(ki&annBht6)0N7v8-* z)hVs3yXw8(%`4~h=6%5b-`P50C1ZzF!wMjwkj1cw4N4r4{mW$kSLIUdZK+&freg4P L^>bP0l+XkKpsgQ( literal 0 HcmV?d00001 diff --git a/src/documents/tests/samples/barcodes/barcode-39-custom.pdf b/src/documents/tests/samples/barcodes/barcode-39-custom.pdf new file mode 100644 index 000000000..ca78b93be --- /dev/null +++ b/src/documents/tests/samples/barcodes/barcode-39-custom.pdf @@ -0,0 +1,243 @@ +%PDF-1.6 +%äüöß +2 0 obj +<> +stream +xœ]QËjÄ0 ¼û+t.Ä+ÙVlƒ1äµÐÞ=”žú:mË_ÙÞ¦¡b<£‘Ôßê¨ÑàÈÚx†àH‡žàú¦ïà³1ä\?Ô¸*"Ô¼ëuÖW8 D½¾?%¤L ZtÈØ£Ç;ÉÄl7àpÌ6á„s!3.¹ +å¸×æçõA-«:ýk€Å<⟿2¿þ¦ú—ËåΤZj}3ŠÅzØ(Ž¹óL ÎÒ•–zB ˆÈ “-¡#.Bêë<2sHäk&Ü +NYR±¦¡·Ç±~'ñ§6:-%.Õ['‚;n+Ùœ·%œàDQ›ÁYÖV¦7ÎÉèNïÿ•ä—uÕn"®g#¼œÕáþì`þ‚RôÒæmx +endstream +endobj + +3 0 obj +284 +endobj + +4 0 obj +<> +stream +xœíÛÁn`IŽdÑüÿŸîYÌ¢„`”ñòÝA8—¢é+½Mý÷ßÿÎÿüeþûËÏü÷—i~æ2j˜þÞ­ü­¾ô®¡ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ Îäý«î6ÏeþÔ@߸É审ï–vÒ¶ÆßØ’ÝƶիÉ$ò·z™mI¦ÁOw4›§¢—Á™¼ÕÝæ¹ÌŸè7¹Ü5ôݲÑNÚÖø[²Ûضz5™DþV/³-É4øéŽfóÔCô28“÷¯ºÛ<—ùS}Câ&—»†¾[6ÚIÛcKvÛV¯&“Èßêe¶%™?ÝÑlžzˆ^gòþUw›ç2j oHÜär×ÐwËF;i[ãolÉncÛêÕdù[½Ì¶$Óà§;šÍSÑËàLÞ¿ênó\æO ô ‰›\îúnÙh'mkü-Ùml[½šL"«—Ù–dütG³yê!zœÉûWÝmžËü©¾!q“Ë]Cß-í¤m¿±%»m«W“Iäoõ2Û’LƒŸîh6O=D/ƒ3yÿª»Ís™?5Ð7$nr¹kè»e£´­ñ7¶d·±mõj2‰ü­^f[’iðÓÍ橇èep&ï_u·y.ó§ú†ÄM.w }·l´“¶5þÆ–ì6¶­^M&‘¿ÕËlK2 ~º£Ù<õ½ ÎäÝÐýÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ\Nþÿÿ9áw™ÉpÎd’ßûóVž9ýùßýdŸöóÖ›7oÞ¼yó†˜ü¯üÏ ¿ËÌ¿ +g2Éïýy+Ïœþüï~²OûyëÍ›7oÞ¼y³;?ÿÍýÿ•øÉü_§¿ý篔¿ål©þöÛ“Ý?ÿõò'§Î7oÞ¼yóæÍͼo¶dÞ7Ûß2ß¼yóæÍ›7»³õ-´û“œóæ›ío¿ýßùÉŸç}ï½yóæÍ›7Óyßlï›í}³½yóæÍ›7ÎùÛ_ÞßýEþö¯üï~ûŸßi»ßl¾ûÕdøfëÿK{óæÍ›7oþµyßlï›íò·ÿ¼û¾ÙÞ¼yóæÍ›Ÿç¿?æÏÍsòýÛoüÝo1|³ý|ÉÆÙüäÍoOºÿ™ð»ÿÞ¼yóæÍ›s~þëI|üù{§Úæ·ÿí{#Éù9?ùù³ùɛߞtÿ3áwÿ ¼yóæÍ›7ÿòüî#ÿÉä_ó¿õÍooœ½êo_8^ ù™©™¸Òï.Öï¾yóæÍ›7ÿæüî[(ÿÉä_“ßõ;çï¾FòÉU?‰ýéüùg¦fâJ¿»X¿ûæÍ›7oÞüksÿ=@ä_#ùÜ| ý®û½3—üí¿º7oÞ¼yóæÍŸó¾Ù~ç¤ûûf{óæÍ›7oÞüßùÛ_^âo÷ÖWÓ¿üÍö·÷oÿ7š^ìwÿ¥½yóæÍ›7ÿò¼o¶iÎï¶Þ7[²û¾ÙÞ¼yóæÍ›d.¿…þo¶ÿ¿¾¯’Ÿœ6úyÞwÚ›7oÞ¼y3÷Í–ük¯r~‰å?ù¾ÙÞ¼yóæÍóü÷—¹ùÉ?·gþÝ’Ï´uòÛ§ÎÝË÷i?o½yóæÍ›7oˆÙý˜þäŸ[3IøÙÐtÉûÔ¹{ù>íç­7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞ¼yóæÍ›7oÞü;ógÞù +endstream +endobj + +5 0 obj +11207 +endobj + +7 0 obj +<> +stream +xœÝzy\U¶ð=U½A7ôBoС»š +„„¥ K²Q!lI0tD:ÑÐ 4ºCw—q‚£qAó—Qã22¾èsflLôEÇQttæ9Ž£>õ͸dd¾qyó&ŽèdÔ§¡øNݪf‰Ñù½÷ûþú +ªêÞsÏ9÷l÷Üs âƒ{ÂÄ@†K„ÎþPô†Ý B~CX:÷ƹ5M¶UØž „ù÷îè®þ;ÿõ‚Ó„¨Ž¢=¾«ïÒîŠýŒC!Ù¿é ‡º*—ŠYRŽ<–õ ,^ªÅ~ööôÇ/ù"uâìÆþwú"¡{?CÚö…þÐ%ÑÅÆé/ÿ_J¡“_wÈqr¼I.Tꈟô’=™{=C^E¨tùÉvòþ¶£äŽËxArHÒ䜗ŸÜNŽ‘_Í›ÅOúÉå(Ë£äMXJ^ÀP‰OAG®$Ï#×OvÞ¹X1éøè¦Íî9зÉ]Ì d#óvŽH#Œ1‘çÈÝ°9ÇQσ3¯þÓkÉøl&=d/¶é¥^sæ-’2ý7Ôê +²‘|¬#}s(ž„{ÙTô_ ¹mú …ù’ƒÚö"æ1†™º;7‘]x‡ug²ë¾ÁBÿã‹m%i°˜Í%)çeʉQü’)>Í.$©¤uz2 ›Þ4ý76$¨ÚU ÔkT/~Ûš›TýHM¦ß/»Ô›Õ ·ÄDQ¿c{ ­µ¥yëÓæó7mÜÐP_W[³¾zPµvÍêU++W,_V±´ÄW\T˜¿(/w!Ÿãõ8­f“1=MŸš¢ÓjÔ*–RÈ% X›`s9s]ˆ¯åC E…\­³§¦¨°–¯ &¸—À—*oh  >”à‚\"_¡9à`B@Ìî³0S˜Á·š¬–¦à¹ÄK5À%>¢íóh[•G;iØñz‘‚J%IËÕ&êöö ×QFÓ§®çׇS‹ +ÉXª›zl%òùèä¯Ú`òkWŽ1D—&M‹šÖ†ºþ-mµ5.¯7PT¸!‘Î×Ð!²ž²LhÖ'´”%×+‰NnàÆ +LJo¹Âu™4—…l‚M-ÕE…˜ÚªÇx¸n˘×5oo{Ü„uáu-m0À¬VÆâXÛãnÊHP (u8©#qÚŠÅw=.2DGU@û'€P˜. Òy‚‘a&y¢<:‘@QÉ#B[…0 ¢0zÉdBªZÐ )‚Ic\c AÈXǦ9f€4p!ÕV +>Cc)‚KÆB A–ðºÖÙ©[··3àîì¢Oœ¨Zº0\œ=èlÜVj¹.)P¾è¤ÅFìèü…ðkÑMüZDcH¤òáê„ž¯–àU¼J†k$¸Cì€äCè{¤ØÑæÅ%Ée½à6}$y*€IeØô~Z,Ï Ï` j…ÕÂI £gt¬Ín :Hauº3›Â)¬…!L{€Xªì`´Ã„ž¶Ã!;ì·C»ÈQøÅ“vxÙ#t,j‡&;xè€ OØá^:¡d‚J(±Ã»ttˆÂK(dÕ4G&;DšèØ$…'’sÈ¥™¤ŒÆé4CtEó%ç¸pæÚ¼•kçYð¯Hc¤ªÀLÊœôi.súÚw^Xf¶€£Ò\¶´Ä[±ÜÌç7{Íü¢b(³Ã«Þ(›ºÐµ^uwËýëK–¾QáRÝn}V‰Ï¿ªÕu±«B*¨€X±r{ÏÙä áRbµf¦¥§§d¦¸=ÙYþ@6±bÇ‘é¶ †Q«Í[jÓˆ&<0*±sØQ=à÷€àpðÐaJŽâÐ+”2á‘9ð¹ÆœgEwÔºªLj”Q3X u—––€U»ÊJí6T\²F9Ÿ£Uš‹*¼P§møת˾3(^|Å;¯Ú/ví»JÙÏzŠ¯þ§k§nË,*ÊdvŽfOeH-5ã,Â…S€õ©EÝHôxZºGè&ƒÆlvØÙ”æaÁIJ6ÁfñlFƒÙhöŒ6«T¨<í€Ã`¢:ÀïÁãH8`„v9˜@0I!ˆ:s~ŒH&h§V˜q?Érš~‹Î§0—)Êkøœ¼ŠòehvVéË…¢BA(,R(fŽ€Õ»r_øj¥¤'ËeJk°eúóû<É'¡Ü«µf¥aH,^’æe·?àr˜X½? eíCK º‚KÀ¿¸%ððh_MK )/A÷ê# AßÈBg$\TQæ°—•V”û ˜¡â:lü¢<>Gc³Ún–ymì'u?*)Zºé’g”þèð®»|K*·´ž·ù–íU<èn<œmùðªš.+ÏöÖtÖ}çç¥~Ÿ¿¦rsViñúmÒ1ƒlœ>Å~ˆñœ=$4YUz’™iR™Üž “?þBgíÔÉ”‰ŒcK€±c˜ÖÏ\BƒtˆBäFÂï(Ñ9™’æôž Lêš\ Ï™Ë-¨iÞ@§H1 V4ÂrsÏ1¯í¾]ÜÿÖë}Í &.~!z†®Þ½=0(ž©ÛüÀá=pÚYôåã™EðÒS?[Ä|h¦:zÅF6>s/9 lqU‹Ã™êHÍá+F¥Õ•Æùiöl—Öµ% ÒšXâ°F‡!•%Ÿ]‚iå@]Ýœ¼Ò€ñ¹›}†¸p÷ëªÌºÜ\g0dªX<–æ¤æl 8mf3†§Ñì13- KµkU¯6bóˆih´/a`ãB”ˆÌD_™¥Ò''R©8É‘t®B%?.ÂÅh._ UP!y÷Še M›µ¬tÙrxõΛöˆbÆàØ'Fî8X¿±«9gÅ}@®º¦ýPMg)ûÌw¿7u ³hç 8w^¾ŽUݺÀ·ç%^t«Ô;§ä¯L±Žý‚% àO´Ùá48Ý™ŒÒT}¶3ÃlHÇEhKÇe¸%À’q7t»a›7|ê†÷Üðº~é†ÇÜp½p4迪ÝPꆅn°ºA㆞ÏÜðnxÖ ¸á¨nvÃÕyµ¸¡Žbç¸Áâ•N»áŠÿœŽ»á$þ :Ü°Õ 5n(wCžìIü9ŽÏç¾,ÍŠÏ(öŒ4·&¹ çÏ•g!•ˆ&Ý0á†W’ÝšäÞEu•¹Ÿ¦̸n8ì†!7DÝÐä£tÉlŸW;ì¦á9xÖ:÷Ú}Ö5ø­ørf/É4£KÕGrýãÚÏQ2ûZX.%9›Ö%¿ ùÕæFŸ×³¼¼mÃrñÎ ¿UüìØÙ!Þ´.ë,/«÷ÞÁFq}¸¦"Ì-ø¶ÙqÿármâÃÚä˜çqá +’‘áÔ Z§6Û½+’Æ ìØþ@ªÝfALÖ´5ÀšŽRÇ=Gý‚~¬|ÚV6lKÒ°èF»23†Å0¨ÅeƒÌϵ]ûÿªB™_ŸäÍ/PjÎûéJ¹>ÙÒº ”‹vï,¬œ)OÚšÛ•ú„îÛ,Y5ý¥êS¬uÄBòÈIá–”²@žn³yä¨òåš‚\‹GmP‚£ô¬ZíÌpÚÛNU0àd3lí ËH>·¡|ˆæC0„|˜È‡{)»~ +áòáÝ|§Ú%ù°òe:lʇIÊ‚PÊWòa„ò’)gŒöµ2W¶ž’¹h¾rÎd.ÙxŽ¹Æ+ÏÚ³Sm`¨-SË–ãp¿Ñhݘ»TÞ\ö©;òòÛ÷ ?ùòäðÝ?~èŒst” “éS7]õè/Å¿O±…ýâò¨¨í¯šúæ¦÷±(þAVÅíG÷>° ã'×=ó+úºßÜqg%[„"³V ƒÍ®1³É̤«Í,c5™Òü“QkHÅL–jk§u>*ät<³S–ѵb¦»¥¥²”ê‚5OŽfŽó¥m“¹£`eéõ¥?«÷íKÊê—V³Ï‹.ûTuÒã{J/×ÄfÜ?6£lvV›Õz»ÚîpêŒX¡ëLv+kÅŒj'NX+8¡Ä œLN˜tÂ+NqÂþ°Ú0§ÚÞ9³‡•ÍÆ-îdé •/R¡f– +5ÎLKvóÒÑíâò?¿yíÈò‚æ¸xúŸ|s_åÂÅðÉ_¦<â—øÄž×õJuŠ$ë#(k*Jû„p%JKÔ¥M÷t&ÆêÇ Di'œà§òÊÂNPyÇ R¦‚G¤âË$«î¥ ?ÍhJæÓË*Ëdø¼ð윷ók¹n&(çØLÞd}­-WêU Aö±áõßÿþÿxëøw¯¹jϾ+¯‚·E³øÉ_Ï|þ·ß?ûÄÄŸ~þýôMüh‡:´ƒ 3ÙAa{&€1Kg3ڲݙX—3=™¸Ñgf,»?`1Ô[ûLš›ŸpkÀ½c­Ÿfª7pn0ѽDNV³¥éœâDÖfv…% s91MJÛ¾ }“'9›3ÛUô–çjÍþ]Ën-)¹ÛÛ/þöièoï‰ÀÍÀ›–á#~‹~…§ø¨?ûTìÞ +w?xôØ)>;Pמ›–ë„-ù–Ü\‡Ãâa5ééDC + +ó3,–XÀ—¸C“¾ƒ‡Mô¸ñÞæáe<åáV®æ¡‡U<ðàáAÏÃE_ñð¯óðcîâá:ìâAÅÃi^¤p¤ìâA滇¯’¬~1-<ÔPd·Ræ%Ïv9–ÉÊ)¥Š’=ÇÃq:Óå”oK’ø4å0 ž˜¢<øyðQ9ñd•,ËÚÏõ©gÞÊüÚà¼d$•]¾²9¾ç¹µlöt‰![!Åó"%;©ÏÀµ÷ÞœpçÖÔT¬Ù +G“m¡iéõ/9oEÔÊeð²Êó7Íë^@÷™–éSª÷1v]d­à5³R8.ÈÖ¤·H*¤°©©U&Ÿ­Øϲ!¹øf"r&{ª9Ü7‰·Ô‘!}›ÂS¯Ù„âeUPÆjXø„x+섶W'5ÕîºÇƒâô©ÏO þzUî:Í;Vè¶Cg™øöO |â¿‹¿ß³¼øßÄç«$ ¦O©ïÆÈIn‚§Æ É̲¨Iš1­=ÀÙ[0’¡Ê‚ª®,hÉ‚š,(Ï‚…Y`Í‚ãYp4 nÍ‚«³ ž„›²±OgÁD0¯dA" F² šþ,øZ±ôÚœóqYÙÜmƒÁf«ŠçV˜åŽÉ‹ HuíqxaTüüŒøwñóQÆ9 +ã/©þšUQ‘uæÝO&?9É–ÓöÛâ-“ô¼óÈiôE‘ôÆ¡[ä&æEf_±[g]²DÝ€%VÖuVÕ¤&|ðŠÆ}0IŸ%>à|rÊ ×7~£É˜IÅšŠÙ=_ÚìÜxÓ87¬ãsm»ñž5ß=ðÝÎ5“oÜ÷Ô:¾û¶kn_Ó¹ÿÀþÎ5è{«zõ5únÃÎuEÅ+¶í¿pä±ñÏG7ö×m[Sè[µãªà³oäyi~ÄSÇè76;Y&¸‰Ac6˜N+Û°f¤§´ÒU¸¡WÉ{þîÝ;/<×Þl¡ÙásÖä•c#ûûÞëÍ>üÝ«Ì!¨F1!Ž‹Ïˆ fDü¹øÈõ°\âûâǪ́x?¦¶‡Äû0Š¬"DóGSW +–tܼ€¤XV§K³°Y™i'¦¿–¥¤5¤é5NsŠ^’‘ÑaŸÑ³ «ÓèpAØ4Œ  ñd U)„*HOÊ +ä&îSs‹^ewöò0['¦€@r—ÝÉ‹¶ãâòÑQ¸ ŽÃ;04::5q\uåW/»*äšöŒŠ=S‘õUí/•ë+!êêb$h>5§*Kš UZ“ŠÍ°¦¥›Óƒ‹Ù &ZeЪŒ`l¤‚å´Þ³ÂëVxÎ +Ç­pÔ +·Záj+Ä­Ðe…+ÔX¡Ü + ­`µ‚Ê +ÿSüÊo!˜‹­¢8ãV`V±Âa+ Y!j¿+”X³‚É +é,„&+œ{¥ÃÜYàx^&³‡¼2éƒ ®¨â™/-—•Òg úù«Lþ ÆzY`½ð’X¼ð¼ýÐÔ ÇLM^ 7|¯UHúâ+ä)¸J¼BÕ3µGöÆ¢ºcÑFÜd@Xk3™\i.=Íj¶˜Ó4*g ¸\)ª”LLvÚö@ +kJƒKHe1qð +QNÒ}0)ûì¡ë¬ÏDTº®f¯”ž±$ERfbðà‹SoÜ;ʬ?3yó•pñMâÓâµúýŸýxìØíL£¨JFáCO^󋼩ÿtU0pÅ‘+§~q€ê5}F½õJ!Ò(øÔV’fMsf:ðHêÀéƒ5á¾bÒ& ÉÄõŸ \&LdÂH&D3ég9í&Os²ñòÒùÐr&È婪£â«â‡Ç/¹ÿ³?O}1èÿEü‘˜3ŠçñšÉùêräà‘ëQñ8&ŠT²ðtD¨®@Y]è:†k&–ŒªÙ†Œ` Ý10E`‰Ád`RÔƒÊå²¢; =ನôÁ€Ši¨Ø‰lɆh6ø³AÚ,•Âü¬Ã/î-³9`iIHÆ—’0šÜ»¼ [^³—“öMïªÑQö¯Õ\ôõ·á" xÄÛ@Œ¿²:ã«WeÙŧßLŸ:="vÝ7uÒô…øOx +Y®n¡5ZPøo•FÏ›c‹'Û^©Ï°TÓ¤³éî +5VµŠÖCÖo(ÒvÌ)©f+4,šâ´bú¦ +­|~y&×Yç(Ò^§c3Sm¢gÄy‘’MÖo2¥žò©‡æˆ"×’F,ÛÚϵ¼Ï™þÁ˜äDºž|è2Ÿ‰Ž2ü•>Zà©ŠþiÃ.oŸ¹gÍÝßO¸óÖ×” ~ñ‚Ù6ûáµm^µe[ùuËV쨛ßUþn7}Š)R]‰;g½°(5=]›Á²§Ê 7ø1 è˜ëÍ[ð|q/=EW9ÁçTR€rÒ/K~Æ·T–Ò/j<äšù + 0[™—Ïx,„ÍÁö˯Wýîw«JV6óW[w1·-zã–©ýëªMëœ*ÆWæ‘þôÛÛ«ÿN<òÿ÷ý[Í+¿ýï-±wVé¿Þt‹ò…tZ¯XKΟA‚³þåË£©Äø'’«Âj“©$l6i‘ȱ¿o/³I¶3ñö©·‘UÌC¶û›ñíÇwÞÕØÞ†ã-ê_‘UŒ\ïm6Y…o«D‡ïU8×*Äë@¾V*Á³°že–àÏݬ•½Œ=¥6© iÔÜ©™ÔƵÿ¥‹ê>Hùm*—z«žè7êOΤmM;‘þƒô¨6RŒç 9£›ˆ`}Íü‚ý%¤Q7 Ìè¼mF@ÌmJ›!ZÒ­´YÌCýJ[…8×)m¬yÉJ[ƒûûýJ[K.#Ç•¶ŽX¡Xi§t¨VÚ©0~¥­' ˜§fþc¶˜yKi§‘ +V§´ÓI»F’^%ý§ß({¾Ò©X¥Ít¯´Y² ¹­Bœ]J[M²T×*m q«~¨´µä´êi¥­#ùêcJ;…,P¿­´S™wÔŸ+m=Y¡{MiÈ)z¥F.JIΕNÊS^­éÝÕï½,ÜÅu…â!®3½t°wWOœËï\Ì•–,-áê#‘]}an}d0 Å{#Å©ëÏF+å¶"‹†P¼Û0ÐYÜØÛ–q¹æð`o÷Öð®=}¡Áu±Îð@Wx+âÎÆ8»¿-<“:¥ÅK‹KfÏÆíq!.>ê +÷‡/æ"Ýóåàûzcñð {¸ÖâæbΊ‡â\h ‹k™!lêîîí S`gx0BäH¼%½hÏ`o¬«·Sš-V<£Àk4ÇÃ{ÃÜy¡x<‹ T‡b8JÖÒ;‰rûzz;{¸}¡×ŽõîÀÁŽK¹ù4Ž†P—È^d¹7\ˆrw†c=½»¸˜¤²BÍÅ{BqIéþp|°·3Ô×w)º¬?ŠTè£}½ñœ¸?ã6‡÷q[#ý¡‡ŠeQÐ6ÝhS®·?:ÙKe,Šu†Ã8Y¨+ÔÑÛ×Gn=¡ÁP'Z ÍÖÛ£ACpÑÐ@QížÁH4Œ’ž_ß8‹ˆÊÖŒEúöâÌö@8Ü%͈bï ÷!N܉\,éÓDA»â=Es$ïŽ Ä‘4Â…ººPq´V¤sO¿ä'4s<)\¨s0‚cѾP¹ôÇŠ{âñèJŸoß¾}Å!Å5è™bäìû¶±ø¥Ñ°âA‰K_#º@rÝê_I‰æ \SíS‡Âq +B!—ŒÌ¥ÅK•)ÐŒ½Ñx¬8ÖÛWÜåkªk$5¤—ìÂ;Ž÷e$Lº‡wû!lu’‰’KÉ ÅêA(Gòºߥ¤„,Å›#õˆÁñ>¤çÈzl"•ô Q¾2€i4•Ž|;·RlmU¤h Ô…ØÚ€ôÈ¡é:pt._Ž4SH/¦Y‰rÙƒr„²ŽÄ*Œ8]ƒÃ#8÷yü£ñm´›)E¹–â]rNÊÄ·9qÔÒq:"IÚO¥¿a¤û6{pˆ¦Þ‹áH˜öº(W‰w+b4S,?¥”,§³ P¬–sÌØ„3v#}'õd³“ò–"BæÁvbÓ‹ÐÞƒT‚.J—Ô-†3ÝçŽf*Ý^:çy.õct¬û1E/Ùf-TŠB%[ìCI¤y{h;DíÙE©¥P(;0ê¸o‡ShCŠ_è{)%šBÅÞÝô£óà•Oöòü¹9j§µºìé~SÜN„÷áÏ¥Ê*ëG«Èsu(ëh]•=ŠÆý”/G6ã{ŠõÛ€7‡úxÖ*rÜt+qÊQÚ(¶#T‹¤‹¨o$MÂTR©¢+¿)úèܲl=4:BÔ·aÅ×qªAÒ^]Š¦’ÔQ +)"µ4.¤õVlz>æ‰Æsr”-876%ŸôQycsxPi»ft”­-aõ)3É÷Ñ|tñŒºi¼Éí¢ÜŠ¾ÁæÝÔ6qeÖ•¨ d˱AÚ=Ôòz’£9þ5Ë…¨}# +]”f¥¸"K?]=4£d%–>”Nú)¦q8wÕt*k¦X‘Ù÷¿¦“äŠR Î]ƒ3²ô£ŒÊê˜Yu{æ¬ß¤'š15Ò|Uâ§N±wiÕœ3—Òœ9_ 9{±§òĨ-‹©»p¼ gh$J-N¦ Hç¸ÆRüë: Lz`É ’ÍÐNZaY¾«Æ÷zìKïbXC†o Â×b5ÂWaîôà³ +ï&¼á­Â[Æ(A ¾}J¿û…Hñ2>Þ´ +¡Ò{#öð]¯¼ë^‹ïZ¥¿ûø&AÐb^EŸOƒJ8SðòpS°ÿ+ðCŸþ”ùdr±çáɧ'™¦Û?~øc¶äc0~ :ò‘é#ÿGÁ¢|¤I5žù ˜ÿ4±Âóîš“­XóN+9‰š,9é?9t2qR}ØÖwX»Ç4ΗŒGLJÆ_ŸŸ× =uø)æçOú<Æ'=O2žcMÇöcƒ‚ñAσŒÿ®à]Ìá»Áx·çnßÝìGŠ=GêÝžÛo[䙸mò6æÄôø±ÛÒÌuOB4’5hÃÍÇØiÏÃëlpªeħoÞMxGð>„7žy݃·…lû÷A³ëæ‚›/¿ù†›ÕÑk†®9| ;tàðæá½OïebþÅžÈ@g ~‰'³ÌÙª-c[58 Î.lèÈͯ ¶ žvDÚ±½Ä³½~±'£ÌÒªF…Uˆhd=lÛÄFØCìÓ¬V·ÕïölÁ{Â?égŠ¡ÎØäiò5±'¦'„ð&/rÛÝ8´‘ÝP·ØÓP¿Âc¬÷Ôûê_®·þãzM{=Ü‹¿u×=]Ç +u‹}uBÛ[· ÁÕj/³µšÁØj*3¶2€Ž.#­>ã´‘1Ûû¬‘TfÈj8‡ÇZš +6ÐNoÝ”Ðùw$àºDn³ô¶lOh®KÖí;ÚÆþ)pààAR½)QÚÜ–f6%º°!H!l˜²Çì¤:‹Å èØÞƒOR°§;c2”ÌŒ“‚Ä0EÅ(HrðY !@¢¤Þ#ÒC,‰$ê˜ÂŽËÚpîü¿TQlV +endstream +endobj + +8 0 obj +8993 +endobj + +9 0 obj +<> +endobj + +10 0 obj +<> +stream +xœ]’Ënƒ0E÷|…—é"“‡„RH$}¨´@ì!E*9dÁß×3“¶R ãñ½Ã5㸬«ÚõsüêGÓÀ,ºÞY×ñæ ˆ3\z©DØÞÌ÷½ÍÐNQ¼Íra¨]7æy¿…½ëì±:Øñ Qüâ-øÞ]Äê£lº¹MÓ àf!£¢ºÐç©žÛbr­k¶ûyYËŸà}™@$´VÅŒ®SkÀ·îQ.e!òÓ©ˆÀÙ{©d˹3Ÿ­R¤RfºœovÈ)óYoSäŒ8‘ÈÖw˪ï¸^"ï™ò5Ôó‘ëGä’X'Èkˆ¬¡ïž˜Ã¡r%™3dΟ¢Fqþû+ÌŸH…ýçפáüy9Fuί©?ç×2çט_qþ ³)ίñìꞟzVü]<»âü[Mƒ¸ÿq Þ™ŸQ só>Œ™.Í'Û;ø½{Ó8¡‹žo@±g +endstream +endobj + +11 0 obj +<> +endobj + +12 0 obj +<> +stream +xœå8kxוçÎŒ~J²%¿Öȃm9~ÈØ1x0¶01‰_¸H€±„$#- IÆ!mŠišœPh“>iCÚ¦iK“xLšàд¡ÛM»» ]H›MÚ”†mÒí—MSè.IÛ$–÷Ü«±14Íýöߎ4sÏûž×½w¤d|4Ù0<Èþ_ÌY\.Àó$Ï¿7)>¶ËÓ‚ðEîàPlçÈ—Om» „tßÛ9¼oÈüµ¯[²déCA_ þ/‹j +— å!$ ¦>¡C|âKB#ÉÛ~¤/[‹ø8âòpÔﻹpI>âg/ñÝ;ÍŸçq1â >8qä-€"íÄ¢‰äK„ÌHIÊŃ1˜yd%â÷£OG‘FðC¯lµçxA£Õé32³²sr ðÿîÒ<¯yîÐ ìcÏk.a˜a `ö»úLmžýóÿ¥zö$ŤÞ†70~?‡Ó À¿.”&•¤ŠVäÁëp~ò÷¬¢=ÙÈÀWá<< Oü9¾CfàeRŒ}~ +!JkWÈúsi£p˜¼Oö;©]òuÔÖˆíE¡¶ÚšvÉåUDŸ¨à THŒ$ùÑ+*8ø½ŠŒ’C×IÊiIy^’Åfh¦SH¢r¶M§É–7‡Û$¨¼Åà[,T0$»5˜WÔ[±]qí M´{ÑG2••¹NZ̬­©Ì,³RRlŠ8ÖpŽöUSèsè´i»/ t÷¸ÛÛ¬v»§¶fƒ’+µ1¬c&í:EÇLŠaê:Ü#NÕœ™¸wÚ;¼ÕÙ)àÛæVxêNðíw+¦j¥JjSªn½#*5R[»RM­vöÎÏÓyuJ¢hÊ’8ñ6`8Ò[¸–âS)ÚrãÛ@A…[§^·^VæzbÂ%‰® ï„ozv|‡$¥‰©ìì‰X;¦ºÝhbzöô=VÅu¯G1zCd•G ÝÕÛ©ä÷lu+\¹K ù‚ßÉ~£Õnš—éþ{lÀ´`r0Ãv;MÃ=Ó2ì@Dïq§qvXO‚ì¬ö(œ—rÎÌq,ý”3>Ç™W÷JXÛÎ>÷„"”oHí˜ñ{|Êøì®]´0’QÉ}Çj—&òLâJ§‡ÉŠèÕ†@XT4˜$ÔZ¨€}CU&Œ É}'=¼eÅ *LyâJ ÍP;íR»Wýî ¡ÝQn„MnEnC@ö©kŸªw¢†Ï‹ ·±b*N)¦˜¥ÖùêR·ÚÃ}n¦¢ª)æu +xýª–âlgëJlŸð¶¥] ¶¤÷SÐ8{qj™h}¼–§ +¬Ã.«hŸp†›×Àu7$º­vEö`…=’;è¡m‡ªºheÍáa½²ÉÝÙ'uölqߨ:’fPsByûuf$·5mPÑ—ëE7gå=(hD‚èB@jmƧ¢+×ãmÄ„3*mÜÖfÑM¬0'n(Ub{°M•£ø5F5´ÖuÌYÓRí¬ë°Ú=öôU[Ã![T'F =MjÇ ·)dè±?×u0ÍemzÑ-%¹ÛMc£éaYV“Ár®ÖjÓ5Ø‚dašÀŽì9„&SqU[&WYÏðy´ã:ö†9¶8¡—:û&¨qI5èùh Ë7š¬l/  Z½W4â’f zbJ–éb­¢F¤ ©ÏÝ̤q?¹Ãz;+:Iç¦ÖÚÜÚZ§$r°gJ&û¶¸ŸÂ#W<¸É}’#Ü:o«gj òÜO‰ø†È¨¥R"EDŠPK½ˆè™¼õ)`œqF`¸š£éçhüÓ\šfLOTÁ&’CŽæÈsÒÒôiÚ8£±k +hÊäL¬—3äl.‡³NJ:‰”ÓxJfx<›äëjõ2ò4ŸÊ­i‰q”Óì¿:uÿ÷ãÙ€jì‰µÒ Û¥(„ÅÆc¥] ÐFù˜'4áõÐÅXü…Hk°LÒtD›­dJÁV%Kj¥ôJoIÓµ”®Ã%ÕDZöÝ +¡°ÕmÇ%)–ü³uÂø­”7• ãïjѹ³ø6Ò€ï<èÀ&çh9 Ïñz / ©å¬ó¬)¬\ij45.­Ï·›ìù&»é¬|ïØFþ¬æÀ»û5Mï +o¤_s¡­]h+ +ÁwÉ=ÙùùV«`È(¼ ¼]Ì6[ÍÖAÁl3sf¹ {ƒÙ,h4ùƒœpÑ GÈ{ÐNŽÚɸÄìÄk'Ýv"ÛI=ûŠv20°G½ ¥ŠZªMy°²ÈY=¸}€èl!s–}òV.­'f¡Š˜ì¢`1ku¥„,«0Š†åùË(¹a¹fWêâ,Ì´pwŽdÜuð»§>µo,…§Û{zS¯§&ÈOßI>{æÍÇ'oûæbó$yq°;õÍ©ŒŸ¤†wbÜ4ÏþAn… +h„¹eIe¥NgÉ5Ôð¼ÁÂ7-Ó:z=Z-xrù\m.á ¹¶\.CÈÍËËêñä‹àìò,±CÁ3M¤«‰ `l Õ&h¤ñA#Æ680Gü6<¬ˆ¦¬¢iÙòÒ„a•iuåkHcCÅd.hlXaÉ奲ŠJI›¯Ëå,”´†4‘C_U^9÷ÆÍ›nÝ‘zÅúæsgSU/–;µ¥»‚™Ú½ž£;z«×ßÔ:²ÆüÝcßV8aÅ®ë{søÆ¿œNíÝÚ®ý¢6S+„‚/rœ u4ßÒÙ±=ýUv7&"%tA¬‘Ëõ†¢Âœ¼n>Ǩ1€åxÙ_DΑÉ"2XDœEXKZMhiii¬^Ðd¦e•öRbi\Ã56Zh`Ó O²ùL¡Jv·.··- òÍž±º¼S¥ñZۆߚy‹¾¼C7ÖbÖ¢Zå%fKf†ç3,|I±6§Ë“™©5‚Ùkærx³ÀÔåAY’‹œ˜æ–ÆkRLÓ &#`J 5uD*3–¯Ðär\ï;©+$÷/ϼ+¦~—íuÿòB÷p)1xÁLʉ–d“ê3ßÉíó§>—šr¢ ²>¡¾Ý‡¾e᯴z¹Ä¤Í-dº<FÞÜåá b…Ä[H´÷|^ðw‹¹cv±H«, +÷¥~Jͤ.‘ð$ƒ¦~õñÛfᎽ„çJSM½HjÐ ©N½šúÓK}æ‰óeú² 9€+&òyyù‹3ò3ʤ<È.éò²Zz¤-KL"´NÔ%ö˜wËÔˆžÙëH“¤•Ê8“1檱÷s!a=i¡9ã7 +YÂÖÙüì—?M|«–ãH±>õÚh|OäBôvÃ>Ç?âïÁ ÜR˽ƒ'É=œ4ùƒSO§Žþx>oµ˜·<(†¨¼®0Óh*ÈÊâyS&o-)ÈêõئCÉÕ`ãiµù¸ÞŒÛãÙo$Fú…‚ãVµ’A+鲧•õÞ.3çÀÀ‚m„î"×®±«-g²ØÙ²ÒpWÆÌÝ|%õ.ɼòÆ;37CH¤ôïæÉCúˆ™Ø‰Û@L=—ú7ý_;€uá§&>vç´G³oUšÏƒ>'{uZë"KY6@Y¹q‘V[uC¹Éh2&<§MäK&rÐD\&Òl"%&’a"Ù&o3X­ØÁV«ÍV”ðØt|FÂ#꼺˜NÑÑiêu²n\wTwN§Ñéð—+võÀžt”jŸãÆèÜ>¾þvÛd{¦T¶¤²Ã]Ž;K5iJl‹Y¾„n1¸™ZJ‰P•zÿòk©+…¤Ôú|0vðS;¶í»Ý7°y·>õû»ð×cŸýú$¹û'/Ÿ¶ø¹ÀÎí×üÛ6û½nó“?û©òÉ‹„üI¬ïz¬o%æ£$è“ëJótÚ"Lˆ6/_b°'=ÙƒÍÀeðÜN-Ö„ÇÂB™‹oϵElœ+bãüÒ¡;!‹gE..dÜ41Šܲuÿ³cëIóW?ü¹ò[äfyÙj‹³çÀöc~þÓ%­k›+òJVlÃX‹gÿÈ}Fs#î²7É‹ó³³3sô9‚PP˜£ÑjðÐêõZÃüæÏ|75Î¥œ5ÍüÙj’šW4Z-’z¦jÉCûÔ¡/¸•³g›[ì«Cywâ>þÃTê‡3?ëêÌ}¬ Ô³Pûæºî“·VØô¶R£N_ªwT–ñflca o6flz°¼î ¿pO:È&¹ÉA^qï;ȱ9Ôé œÍAÀA.:È9Q七Œ;ˆ—ñÔU¼gÏàµâ¬‡°‰ +´Qúu(½]›ŒìHµ_=h±,…ê»Cš­3ñÙõïNý^=w—þK“vÅ—Çx8õÆC½a 7H?61ó4ß±9Z“ÿMÛÇbøx䥞題ã÷ÎÐu}7öÜõŒi–ÅÅZƒ!§rp1šñ„1™¹eáÅ.>vÆ°Óåšæ21rìUw;[ºFìž2ï'bDÕ ¨Â<”@X…0Ã*¬Áê}A…µ©°n‡S*¬3YªÂKÚU8“„IŸ +gÁ"îéùò븗U8šx­ +çB zB„ ÄáûU˜@©@T˜½`Sa– •*,€CتÂ(îTa-T_Ua\~¬ÂzphN©p,Ò¼ªÂ™Ü š÷T8 nÔŸUálØ–¡QáØ•áSá\X–ñ\[xg8¾=¾¤OôGcûâᡤèðW‰ õKëÅõÑèÎá ¸.Eã¾d8©Ë\w½XƒØ‹&:|ÉqCÄ_·1¼#˜–û|‘Dkt8°6áFÁ¸X+^ǽ©ôG‚ñ%4Ô-­«¿*@ùµ”¿@'œ}b2î G|ñÝbtèZWÄxpg8‘ Æ‘Žˆýu}ub·/Œ$E_$ nšWì +ûƒŒèÆ“>Ž&Cèð®Ñx8ûél‰ºù8$¤/Üoñ%“ÁD4ÒêKà\èÙÚxx$Z#Ž…Âþ8æKˆ`"¼3‚ÌûÄkuDäú0–H$ºMî Ö ßCñ`"Žì4-‰`<<¤š“!_’F>LÆÃ~ßðð>,ÝH Uw`­ÆÂÉÝ7|¢.í¦eS*†Gbñè^æ^mÂ#8/àÛ'ÑFÈ÷ù1Y˜±°?Á’9c¾Hmûh< ¢“›×o¼*ˆn¥™ˆï &˜t$ $h!â0*áÄÃÑènÊP4Žî’¡ÚþE#ITŠ¾@cÆDEý£#´D˜áäœs><Š¼Ø°/‰VFu¡d2¶Êé«ó©UñcQêвóÃxÉ}± ZŠ8µ22¼+¡Ue¥¥AômØ(vÅ0?.tNTjĹÆ\Z·TÓŽ%u‰ðp]4¾ÓÙåÚm¸!íÄ;‰÷í¸Q@ÄÛ‡¸!?D!û ΤBHñUÇU86@=,Å[„õ(Eþ0ꋸiGQ>Æž>f7 +¨ƒLÆùpk õª^t0í„6 ¾-lD½È]hW„>Ä"€VćQs-Â~”Š LeE¨ÅûÃu?œ+ÎÛþ“IÌK4 WKñ®ÿ@ súµóúL›vZDÕܽ'~è<¢ªëSëÁOeÓ^R5ßCì™`óFpá¹nI°8ìn ½YÆ|,ÿéš 7ÉdýHÆÏ>uÕ`~Ò³îP×Õ[¥¡ùØQÞ^Æ*{5énR»TdÔÂQæû\öjYE¨ÿAæ…|lÕï@a6OÚë «hP­p’y;—¥€õ0Æ(µÐκ®õ šÉ͸Glü@‹él-ìÈ[+{YÞ®ÚŽ0oŒÏ,•VgJG<Ìö¢ÝóUb]–Î^€Y«ý;ùb¹Iª³F™Gü¤ëœî¨(ꎲª¥WQº‡““9ËoTÕ‹!‡Î•öe„­Šë»¬ÂWJ'zG?u¬û®¿ºRêTŸÿk=êWŒep᪈Ïû2‚>nT×|d~­.Xµs•èÃg#Û%bjÿ¸Ổ×Y kåús)Û1¯"ÝaÄ“ÌŸËe‹a'ò»p†é÷çô/†¼p­í'-@ÈJè'kÔ±•Èøžm#kq´áx4’UH¿GäÃCø¼‚7G`5¾_÷Ówlâıq:Ö*˜EÍ*¤ß€¸é•8Vªxâå8–«¸Dʘ|™ŠW#Gè&:ú{NAî&çfÈ33Ä8C¢ïù=2þöÑ·|›ÿÓå&›óòñËÜà%â¼4x)zéø¥W/iþãuÑö»×WÛ~{±ÒöïWÛ^]}¡ÿ7«ñíýBýîáûk³H)Ú6âSÄ[Æ›Ÿ=CJeGñ"ׯùY¼B~%4Û~ñÂ"ÛÏ_¨°yÏ=æ :_,;*ª\¶IçdËäñIÁ0IäÉÜ<{tüQþ⣗å¾{¢Év¢»Âö±’’“ÍÔ£’'‰á;Äðmò4)$ùÐŒu°Èïn¶=p¬ÒöU¼¿‚÷ø1òE—Ãvü “_à>ïj²î·ÝÏÝw´ÂöÙÏTØ GlG¢Gö9rDóé{+l]‡‰á^"ß›epÙqŸºË`¼‹,ÿ„ëÜ^œ{ï$Þ ¼«bÄ#|Œ\‰‘‹ýGŒ ň'F¦g/ËwÄ0ÑH‡-âj°•¢þâÆ¢~]#߯źøP×;Ø`Äqû–Û6W¥më–Ûl[\Kmù yý¬®ÐÀ÷Gybà[ø.>Êïç5ƒ}DîsÔ¸ä¾Ò2|ä¹v÷~´÷ž^¾§k‘­ï⮪.ÎÓîâ¦Iž\ë*·mpÛ:\vÛz ú/.LYÔaí/h°ô›ˆ¡ßØ`èçv,ÌÚ¦‰é¤5£\‹£ÍÐb4ì7ƒÓÐeˆŽ^5Ìt-H»dà£@º€Œ ™&G§6õUWwNëf{;]÷V…TÊûèSîÙ¢h*пe«{ŠO{î:|Zw* }nÅ»ØÓ©)0Ž€qñT´zÉDr´Z½H"I CD‚²%Í‹0r"‘L&!­’¨N@5}"ƒàLe¨0µ¥~ }ŽMC˜d"I…˜ò(}2ŒR©!vá ‰ùé™åôPô?OAO3 +endstream +endobj + +13 0 obj +6443 +endobj + +14 0 obj +<> +endobj + +15 0 obj +<> +stream +xœ]‘Ín„ …÷<ËébâÿL'1&S­‰‹þ¤¶€pµ$ â·/\¦mÒä»ÜsnàÕ]Ó)i£W³ð,¥Öe3è“T$I©ÜÞ*ÜùÌ4‰œ·ßW s§Æ¥,Iôæz«5;=\Å2À‰^Œ#ÕDuïê~Óú fP–Ƥª¨€ÑÍybú™Í¡ëØ ×–v?:ËŸà}×@S¬“p¾X5ã`˜š€”q\Ѳm+Jüë%E° #ÿdÆI'ã<­§È§Äs†|Æó<œgž‹À­çSàÜó9páù9=_3ô^_> +endobj + +17 0 obj +<> +endobj + +18 0 obj +<> +/ProcSet[/PDF/Text/ImageC/ImageI/ImageB] +>> +endobj + +1 0 obj +<>/Contents 2 0 R>> +endobj + +6 0 obj +<> +endobj + +19 0 obj +<> +endobj + +20 0 obj +< +/Producer +/CreationDate(D:20220401110308+02'00')>> +endobj + +xref +0 21 +0000000000 65535 f +0000029273 00000 n +0000000019 00000 n +0000000374 00000 n +0000000394 00000 n +0000011762 00000 n +0000029442 00000 n +0000011784 00000 n +0000020862 00000 n +0000020883 00000 n +0000021078 00000 n +0000021508 00000 n +0000021790 00000 n +0000028320 00000 n +0000028342 00000 n +0000028545 00000 n +0000028904 00000 n +0000029131 00000 n +0000029174 00000 n +0000029541 00000 n +0000029638 00000 n +trailer +< +<77F1D5E7090F17C94EF7E43CF16B016F> ] +/DocChecksum /2F8AB12D558369FCB5C37CF4905E79AE +>> +startxref +29813 +%%EOF diff --git a/src/documents/tests/samples/barcodes/barcode-39-custom.png b/src/documents/tests/samples/barcodes/barcode-39-custom.png new file mode 100644 index 0000000000000000000000000000000000000000..5c2d7b4f77442acde7887c48f90a0153ded795cb GIT binary patch literal 1357 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 literal 0 HcmV?d00001 diff --git a/src/documents/tests/samples/patch-code-t.pbm b/src/documents/tests/samples/barcodes/patch-code-t.pbm similarity index 100% rename from src/documents/tests/samples/patch-code-t.pbm rename to src/documents/tests/samples/barcodes/patch-code-t.pbm diff --git a/src/documents/tests/samples/patch-code-t.pdf b/src/documents/tests/samples/barcodes/patch-code-t.pdf similarity index 100% rename from src/documents/tests/samples/patch-code-t.pdf rename to src/documents/tests/samples/barcodes/patch-code-t.pdf diff --git a/src/documents/tests/samples/barcodes/qr-code-PATCHT.png b/src/documents/tests/samples/barcodes/qr-code-PATCHT.png new file mode 100644 index 0000000000000000000000000000000000000000..6f1d587ff63ef4fc9d2c9b639e982a614fd1d863 GIT binary patch literal 7579 zcmeI1eN0+s6vhwLuGEae=33o4sm66{lO@&|ZJnZ2?bJ4@bzQ89R-D?I&4M;=3>!qO zMrUfrHkY)sXqWAeE>WS56tq$=wu5FLLKds24ACx=Od(*1;s=|1-+LFArpdCu%MFkV zh8@B zfT&ZsSx4WNC|%Pd!q}8O{9oqy?;Q+RM}3))U#c_;c8(p8p0K|<pg)ndlfL<> zS3@@*;u5v@UksgX{W;)#~xnaQ=b6>zlRVeaAW6KV(FMOs4AI zR^n`8csHev#E8+_j-U?kEGIsN$0Kb(ouAl<}tcw28lBAc*C~-na;B#wicCDP9IIrxf zoScp{k}x!TBk20YNpjn+4PTsHyKH{ZLAhSq1vrYGqYi{B}hel0vF#$ z=wJauTstbVTZxW1kldi9p-6f`dr@w`LN*`n#Z_UdKwqx&X|CJN8f;lIw`nc;vQN5) z_AM%lJVZ#)-B=xo@t~=0M(tjaPN_96v1~wV^Zgzuwh0Nb##kZY=a-0mbU^m zXY*?l&d%jQgb_8PvM!@+X_wR4={e}Bq2=0=3y3i?{g@(qvL~lSi>MPBh39ns1g~=- zhF&6&D-{z`=vfHd!!#kiFLI38%@)yOh#{R$HUI3G%2Btq^x>%p0gfkgrr+i-)A`QV zo689FlmsiBKEYK89sndpTu6C{P|1$_4Ua(X#`cC!{%iLD(M-z+gd;sY{Y)N19gZ?l ziuY=MQ11SyAcR+3!|z}O+cjTDAdg3xsOW}fQe8FCO0?0mx<#u1=0jV-TKjIj3Wc2^ zo?vJc@xzGYdwK;yZO_RSguaZ#hVu6DSTD=W_SDGC-(jMsMfz8y%Ij#w$5@TQBBd_< zH5X-0Xz0Kb(Gp<|)`2MM*)h9Y@c`Mn_l+HqP#XUDK)hcybeH{+O>LiOMZu?gE((3* z2_D}=#PtqgsNdK=y{=$j3)}{7;GH=&Q#L l?Z^Ai(-|ll({KNW4vetQoW5#L?jY7M_t?oSRYvKhzX1=Fd&U3& literal 0 HcmV?d00001 diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index 2f950e28b..1b59b7109 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -1,8 +1,10 @@ import os +import shutil import tempfile from unittest import mock from django.conf import settings +from django.test import override_settings from django.test import TestCase from django.utils import timezone from documents import tasks @@ -95,21 +97,118 @@ class TestTasks(DirectoriesMixin, TestCase): test_file = os.path.join( os.path.dirname(__file__), "samples", - "patch-code-t.pbm", + "barcodes", + "barcode-39-PATCHT.png", ) img = Image.open(test_file) separator_barcode = str(settings.CONSUMER_BARCODE_STRING) self.assertEqual(tasks.barcode_reader(img), [separator_barcode]) def test_barcode_reader2(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "patch-code-t.pbm", + ) + img = Image.open(test_file) + separator_barcode = str(settings.CONSUMER_BARCODE_STRING) + self.assertEqual(tasks.barcode_reader(img), [separator_barcode]) + + def test_barcode_reader_distorsion(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "barcode-39-PATCHT-distorsion.png", + ) + img = Image.open(test_file) + separator_barcode = str(settings.CONSUMER_BARCODE_STRING) + self.assertEqual(tasks.barcode_reader(img), [separator_barcode]) + + def test_barcode_reader_distorsion2(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "barcode-39-PATCHT-distorsion2.png", + ) + img = Image.open(test_file) + separator_barcode = str(settings.CONSUMER_BARCODE_STRING) + self.assertEqual(tasks.barcode_reader(img), [separator_barcode]) + + def test_barcode_reader_unreadable(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "barcode-39-PATCHT-unreadable.png", + ) + img = Image.open(test_file) + self.assertEqual(tasks.barcode_reader(img), []) + + def test_barcode_reader_qr(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "qr-code-PATCHT.png", + ) + img = Image.open(test_file) + separator_barcode = str(settings.CONSUMER_BARCODE_STRING) + self.assertEqual(tasks.barcode_reader(img), [separator_barcode]) + + def test_barcode_reader_128(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "barcode-128-PATCHT.png", + ) + img = Image.open(test_file) + separator_barcode = str(settings.CONSUMER_BARCODE_STRING) + self.assertEqual(tasks.barcode_reader(img), [separator_barcode]) + + def test_barcode_reader_no_barcode(self): test_file = os.path.join(os.path.dirname(__file__), "samples", "simple.png") img = Image.open(test_file) self.assertEqual(tasks.barcode_reader(img), []) + def test_barcode_reader_custom_separator(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "barcode-39-custom.png", + ) + img = Image.open(test_file) + self.assertEqual(tasks.barcode_reader(img), ["CUSTOM BARCODE"]) + + def test_barcode_reader_custom_qr_separator(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "barcode-qr-custom.png", + ) + img = Image.open(test_file) + self.assertEqual(tasks.barcode_reader(img), ["CUSTOM BARCODE"]) + + def test_barcode_reader_custom_128_separator(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "barcode-128-custom.png", + ) + img = Image.open(test_file) + self.assertEqual(tasks.barcode_reader(img), ["CUSTOM BARCODE"]) + def test_scan_file_for_separating_barcodes(self): test_file = os.path.join( os.path.dirname(__file__), "samples", + "barcodes", "patch-code-t.pdf", ) pages = tasks.scan_file_for_separating_barcodes(test_file) @@ -124,15 +223,70 @@ class TestTasks(DirectoriesMixin, TestCase): test_file = os.path.join( os.path.dirname(__file__), "samples", + "barcodes", "patch-code-t-middle.pdf", ) pages = tasks.scan_file_for_separating_barcodes(test_file) self.assertEqual(pages, [1]) + def test_scan_file_for_separating_qr_barcodes(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "patch-code-t-qr.pdf", + ) + pages = tasks.scan_file_for_separating_barcodes(test_file) + self.assertEqual(pages, [0]) + + @override_settings(CONSUMER_BARCODE_STRING="CUSTOM BARCODE") + def test_scan_file_for_separating_custom_barcodes(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "barcode-39-custom.pdf", + ) + pages = tasks.scan_file_for_separating_barcodes(test_file) + self.assertEqual(pages, [0]) + + @override_settings(CONSUMER_BARCODE_STRING="CUSTOM BARCODE") + def test_scan_file_for_separating_custom_qr_barcodes(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "barcode-qr-custom.pdf", + ) + pages = tasks.scan_file_for_separating_barcodes(test_file) + self.assertEqual(pages, [0]) + + @override_settings(CONSUMER_BARCODE_STRING="CUSTOM BARCODE") + def test_scan_file_for_separating_custom_128_barcodes(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "barcode-128-custom.pdf", + ) + pages = tasks.scan_file_for_separating_barcodes(test_file) + self.assertEqual(pages, [0]) + + def test_scan_file_for_separating_wrong_qr_barcodes(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "barcode-39-custom.pdf", + ) + pages = tasks.scan_file_for_separating_barcodes(test_file) + self.assertEqual(pages, []) + def test_separate_pages(self): test_file = os.path.join( os.path.dirname(__file__), "samples", + "barcodes", "patch-code-t-middle.pdf", ) pages = tasks.separate_pages(test_file, [1]) @@ -142,6 +296,7 @@ class TestTasks(DirectoriesMixin, TestCase): test_file = os.path.join( os.path.dirname(__file__), "samples", + "barcodes", "patch-code-t.pdf", ) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) @@ -153,6 +308,7 @@ class TestTasks(DirectoriesMixin, TestCase): test_file = os.path.join( os.path.dirname(__file__), "samples", + "barcodes", "patch-code-t.pdf", ) nonexistingdir = "/nowhere" @@ -172,6 +328,7 @@ class TestTasks(DirectoriesMixin, TestCase): test_file = os.path.join( os.path.dirname(__file__), "samples", + "barcodes", "patch-code-t.pdf", ) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) @@ -183,6 +340,7 @@ class TestTasks(DirectoriesMixin, TestCase): test_file = os.path.join( os.path.dirname(__file__), "samples", + "barcodes", "patch-code-t-middle.pdf", ) tempdir = tempfile.mkdtemp(prefix="paperless-", dir=settings.SCRATCH_DIR) @@ -197,6 +355,19 @@ class TestTasks(DirectoriesMixin, TestCase): self.assertTrue(os.path.isfile(target_file1)) self.assertTrue(os.path.isfile(target_file2)) + @override_settings(CONSUMER_ENABLE_BARCODES=True) + def test_consume_barcode_file(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "patch-code-t-middle.pdf", + ) + dst = os.path.join(settings.SCRATCH_DIR, "patch-code-t-middle.pd") + shutil.copy(test_file, dst) + + self.assertEqual(tasks.consume_file(dst), "File successfully split") + @mock.patch("documents.tasks.sanity_checker.check_sanity") def test_sanity_check_success(self, m): m.return_value = SanityCheckMessages() From 08fbcf51584481152766c711c8735459307ca7fc Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Fri, 1 Apr 2022 12:38:14 +0200 Subject: [PATCH 23/26] use imported List fail test if non-existing dir exists Signed-off-by: Florian Brandes --- src/documents/tasks.py | 8 +++++--- src/documents/tests/test_tasks.py | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 7bd212399..42d50549d 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -2,6 +2,7 @@ import logging import os import shutil import tempfile +from typing import List # for type hinting. Can be removed, if only Python >3.8 is used import tqdm from asgiref.sync import async_to_sync @@ -24,6 +25,7 @@ from pikepdf import Pdf from pyzbar import pyzbar from whoosh.writing import AsyncWriter + logger = logging.getLogger("paperless.tasks") @@ -70,7 +72,7 @@ def train_classifier(): logger.warning("Classifier error: " + str(e)) -def barcode_reader(image) -> list[str]: +def barcode_reader(image) -> List[str]: """ Read any barcodes contained in image Returns a list containing all found barcodes @@ -91,7 +93,7 @@ def barcode_reader(image) -> list[str]: return barcodes -def scan_file_for_separating_barcodes(filepath: str) -> list[int]: +def scan_file_for_separating_barcodes(filepath: str) -> List[int]: """ Scan the provided file for page separating barcodes Returns a list of pagenumbers, which separate the file @@ -108,7 +110,7 @@ def scan_file_for_separating_barcodes(filepath: str) -> list[int]: return separator_page_numbers -def separate_pages(filepath: str, pages_to_split_on: list[int]) -> list[str]: +def separate_pages(filepath: str, pages_to_split_on: List[int]) -> List[str]: """ Separate the provided file on the pages_to_split_on. The pages which are defined by page_numbers will be removed. diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index 1b59b7109..46be59d53 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -313,7 +313,7 @@ class TestTasks(DirectoriesMixin, TestCase): ) nonexistingdir = "/nowhere" if os.path.isdir(nonexistingdir): - self.skipTest("non-existing dir exists") + self.fail("non-existing dir exists") else: with self.assertLogs("paperless.tasks", level="WARNING") as cm: tasks.save_to_dir(test_file, target_dir=nonexistingdir) From e214f719c9555542bd05f9410198d73f261bb93a Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Sat, 2 Apr 2022 10:21:51 +0200 Subject: [PATCH 24/26] add more tests Signed-off-by: Florian Brandes --- .../barcodes/patch-code-t-middle_reverse.pdf | Bin 0 -> 34337 bytes .../samples/barcodes/several-patcht-codes.pdf | Bin 0 -> 78234 bytes src/documents/tests/test_tasks.py | 20 ++++++++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 src/documents/tests/samples/barcodes/patch-code-t-middle_reverse.pdf create mode 100644 src/documents/tests/samples/barcodes/several-patcht-codes.pdf diff --git a/src/documents/tests/samples/barcodes/patch-code-t-middle_reverse.pdf b/src/documents/tests/samples/barcodes/patch-code-t-middle_reverse.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e1f8bc39c05057443802310ad697aaf930e51364 GIT binary patch literal 34337 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 M2!mn7Gp#KD4UYY6%m4rY literal 0 HcmV?d00001 diff --git a/src/documents/tests/samples/barcodes/several-patcht-codes.pdf b/src/documents/tests/samples/barcodes/several-patcht-codes.pdf new file mode 100644 index 0000000000000000000000000000000000000000..de4c715c82f3642d5faa6f9ac0d8789059507cd4 GIT binary patch literal 78234 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 DTZsR{ literal 0 HcmV?d00001 diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index 46be59d53..8160dd3f3 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -229,6 +229,26 @@ class TestTasks(DirectoriesMixin, TestCase): pages = tasks.scan_file_for_separating_barcodes(test_file) self.assertEqual(pages, [1]) + def test_scan_file_for_separating_barcodes4(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "several-patcht-codes.pdf", + ) + pages = tasks.scan_file_for_separating_barcodes(test_file) + self.assertEqual(pages, [2, 5]) + + def test_scan_file_for_separating_barcodes_upsidedown(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "patch-code-t-middle_reverse.pdf", + ) + pages = tasks.scan_file_for_separating_barcodes(test_file) + self.assertEqual(pages, [1]) + def test_scan_file_for_separating_qr_barcodes(self): test_file = os.path.join( os.path.dirname(__file__), From cdf5602dfbea88c548cc1e599738e260d98cfa15 Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Sat, 2 Apr 2022 11:44:35 +0200 Subject: [PATCH 25/26] update documentation Signed-off-by: Florian Brandes --- docs/configuration.rst | 2 +- paperless.conf.example | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index a5db8fffa..f156a352f 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -599,7 +599,7 @@ PAPERLESS_CONSUMER_ENABLE_BARCODES= If no barcodes are detected in the uploaded file, no page separation will happen. - Defaults to true. + Defaults to false. PAPERLESS_CONSUMER_BARCODE_STRING=PATCHT diff --git a/paperless.conf.example b/paperless.conf.example index cad13257c..ad081b152 100644 --- a/paperless.conf.example +++ b/paperless.conf.example @@ -60,7 +60,7 @@ #PAPERLESS_CONSUMER_RECURSIVE=false #PAPERLESS_CONSUMER_IGNORE_PATTERNS=[".DS_STORE/*", "._*", ".stfolder/*", ".stversions/*", ".localized/*", "desktop.ini"] #PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS=false -#PAPERLESS_CONSUMER_ENABLE_BARCODES=true +#PAPERLESS_CONSUMER_ENABLE_BARCODES=false #PAPERLESS_CONSUMER_ENABLE_BARCODES=PATCHT #PAPERLESS_OPTIMIZE_THUMBNAILS=true #PAPERLESS_PRE_CONSUME_SCRIPT=/path/to/an/arbitrary/script.sh From 5fae5a9ee067694427294dfe3b64498c79bcdaf3 Mon Sep 17 00:00:00 2001 From: Florian Brandes Date: Fri, 8 Apr 2022 08:07:23 +0200 Subject: [PATCH 26/26] fix conditional in separate_pages add additional test for separate_pages Signed-off-by: Florian Brandes --- src/documents/tasks.py | 37 +++++++++++++++++-------------- src/documents/tests/test_tasks.py | 17 ++++++++++++++ 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index 42d50549d..e9a015d67 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -137,23 +137,26 @@ def separate_pages(filepath: str, pages_to_split_on: List[int]) -> List[str]: dst.save(out) document_paths = [savepath] - 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 = "{}_document_{}.pdf".format(fname, str(count + 1)) - 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) + # 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 = "{}_document_{}.pdf".format(fname, str(count + 1)) + 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)}") return document_paths diff --git a/src/documents/tests/test_tasks.py b/src/documents/tests/test_tasks.py index 8160dd3f3..c78fa16c2 100644 --- a/src/documents/tests/test_tasks.py +++ b/src/documents/tests/test_tasks.py @@ -312,6 +312,23 @@ class TestTasks(DirectoriesMixin, TestCase): pages = tasks.separate_pages(test_file, [1]) self.assertEqual(len(pages), 2) + def test_separate_pages_no_list(self): + test_file = os.path.join( + os.path.dirname(__file__), + "samples", + "barcodes", + "patch-code-t-middle.pdf", + ) + with self.assertLogs("paperless.tasks", level="WARNING") as cm: + pages = tasks.separate_pages(test_file, []) + self.assertEqual(pages, []) + self.assertEqual( + cm.output, + [ + f"WARNING:paperless.tasks:No pages to split on!", + ], + ) + def test_save_to_dir(self): test_file = os.path.join( os.path.dirname(__file__),