diff --git a/froide/helper/redaction.py b/froide/helper/redaction.py index 0922132de..4c93b294f 100644 --- a/froide/helper/redaction.py +++ b/froide/helper/redaction.py @@ -81,7 +81,11 @@ def try_redacting_file(pdf_file, outpath, instructions): if rewritten_pdf_file is None: # Possibly encrypted with password, let's just try it anyway rewritten_pdf_file = pdf_file - return _redact_file(rewritten_pdf_file, outpath, instructions) + + output_filename = os.path.join(outpath, "final.pdf") + with open(output_filename, "wb") as output_file: + _redact_file(rewritten_pdf_file, output_file, instructions) + return output_filename except PDFException as e: tries += 1 if tries > 2: @@ -98,7 +102,7 @@ def try_redacting_file(pdf_file, outpath, instructions): pdf_file = next_pdf_file -def _redact_file(pdf_file, outpath, instructions, tries=0): +def _redact_file(pdf_file, output_file, instructions): dpi = 300 load_invisible_font() output = PdfWriter() @@ -149,11 +153,7 @@ def get_page_iterator(page_instructions, image_generator): raise PDFException(e, "rewrite") from None output.add_page(page) - - output_filename = os.path.join(outpath, "final.pdf") - with open(output_filename, "wb") as f: - output.write(f) - return output_filename + output.write(output_file) def get_redacted_page(image_filename, instr, dpi): diff --git a/froide/helper/tests/test_redaction.py b/froide/helper/tests/test_redaction.py new file mode 100644 index 000000000..3f2962569 --- /dev/null +++ b/froide/helper/tests/test_redaction.py @@ -0,0 +1,73 @@ +import os +from io import BytesIO +from pathlib import Path +from unittest import TestCase + +import pytest + +from froide.helper.redaction import _redact_file + +redaction_test_data_path = ( + Path(os.path.dirname(os.path.realpath(__file__))) / "testdata" / "redaction" +) +hello_world_pdf_path = redaction_test_data_path / "minimal_hello_world.pdf" +hello_world_pdf_empty_instructions_redacted_path = ( + redaction_test_data_path / "minimal_hello_world_empty_instructions_redacted.pdf" +) +hello_world_pdf_right_halve_redacted_path = ( + redaction_test_data_path / "minimal_hello_world_right_halve_redacted.pdf" +) + + +def get_file_content(file): + file.seek(0) + return file.read() + + +class Test(TestCase): + def setUp(self): + self.input = hello_world_pdf_path.open("rb", buffering=0) + self.expected = hello_world_pdf_empty_instructions_redacted_path.read_bytes() + + def tearDown(self): + self.input.close() + + @pytest.mark.asyncio(loop_scope="session") + def test__redact_file_empty_instructions(self): + in_memory_outfile = BytesIO() + empty_instructions = {"pages": [{"width": 1, "rects": []}]} + + _redact_file(self.input, in_memory_outfile, empty_instructions) + + self.assertEqual( + hello_world_pdf_empty_instructions_redacted_path.read_bytes(), + get_file_content(in_memory_outfile), + ) + + @pytest.mark.asyncio(loop_scope="session") + def test__redact_file_right_halve_rect_instructions(self): + in_memory_outfile = BytesIO() + right_halve = (150, 0, 300, 144) + text_position = (175, 72, 72, 10) + instructions = { + "pages": [ + { + "width": 300, + "rects": [right_halve], + "texts": [ + { + "text": "right halve redacted", + "fontSize": "6px", + "pos": text_position, + } + ], + } + ] + } + + _redact_file(self.input, in_memory_outfile, instructions) + + self.assertEqual( + hello_world_pdf_right_halve_redacted_path.read_bytes(), + get_file_content(in_memory_outfile), + ) diff --git a/froide/helper/tests/testdata/redaction/README.md b/froide/helper/tests/testdata/redaction/README.md new file mode 100644 index 000000000..ed8e6dc94 --- /dev/null +++ b/froide/helper/tests/testdata/redaction/README.md @@ -0,0 +1,7 @@ +# Minimal PDF + +## minimal_hello_world.pdf +It's from https://brendanzagaeski.appspot.com/0004.html under MIT License. +License: ./minimal_hello_world_license.txt + +Other redaction test pdf's in this folder are derived from it and share the license. \ No newline at end of file diff --git a/froide/helper/tests/testdata/redaction/minimal_hello_world.pdf b/froide/helper/tests/testdata/redaction/minimal_hello_world.pdf new file mode 100644 index 000000000..1c641810a Binary files /dev/null and b/froide/helper/tests/testdata/redaction/minimal_hello_world.pdf differ diff --git a/froide/helper/tests/testdata/redaction/minimal_hello_world_empty_instructions_redacted.pdf b/froide/helper/tests/testdata/redaction/minimal_hello_world_empty_instructions_redacted.pdf new file mode 100644 index 000000000..71bacfc86 Binary files /dev/null and b/froide/helper/tests/testdata/redaction/minimal_hello_world_empty_instructions_redacted.pdf differ diff --git a/froide/helper/tests/testdata/redaction/minimal_hello_world_license.txt b/froide/helper/tests/testdata/redaction/minimal_hello_world_license.txt new file mode 100644 index 000000000..0d43f7c90 --- /dev/null +++ b/froide/helper/tests/testdata/redaction/minimal_hello_world_license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Brendan Zagaeski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/froide/helper/tests/testdata/redaction/minimal_hello_world_right_halve_redacted.pdf b/froide/helper/tests/testdata/redaction/minimal_hello_world_right_halve_redacted.pdf new file mode 100644 index 000000000..fdb9354e1 Binary files /dev/null and b/froide/helper/tests/testdata/redaction/minimal_hello_world_right_halve_redacted.pdf differ