diff --git a/OpenOversight/app/custom.py b/OpenOversight/app/custom.py deleted file mode 100644 index 3bd8d362b..000000000 --- a/OpenOversight/app/custom.py +++ /dev/null @@ -1,41 +0,0 @@ -# Monkeypatch bug in imagehdr -from imghdr import tests - - -def test_jpeg1(h, f): - """JPEG data in JFIF format""" - if b"JFIF" in h[:23]: - return "jpeg" - - -JPEG_MARK = ( - b"\xff\xd8\xff\xdb\x00C\x00\x08\x06\x06" - b"\x07\x06\x05\x08\x07\x07\x07\t\t\x08\n\x0c\x14\r\x0c\x0b\x0b\x0c\x19\x12\x13\x0f" -) - - -def test_jpeg2(h, f): - """JPEG with small header""" - if len(h) >= 32 and 67 == h[5] and h[:32] == JPEG_MARK: - return "jpeg" - - -def test_jpeg3(h, f): - """JPEG data in JFIF or Exif format""" - if h[6:10] in (b"JFIF", b"Exif") or h[:2] == b"\xff\xd8": - return "jpeg" - - -def add_jpeg_patch(): - """Add a custom JPEG identification patch. - - It turns out that imghdr sucks at identifying jpegs and needs a custom patch to - behave correctly. This function adds that. - - Sources: - - https://stackoverflow.com/a/57693121/3277713 - - https://bugs.python.org/issue28591 - """ - tests.append(test_jpeg1) - tests.append(test_jpeg2) - tests.append(test_jpeg3) diff --git a/OpenOversight/app/utils/cloud.py b/OpenOversight/app/utils/cloud.py index 2e1d1c9d4..629cdc3e5 100644 --- a/OpenOversight/app/utils/cloud.py +++ b/OpenOversight/app/utils/cloud.py @@ -1,6 +1,5 @@ import datetime import hashlib -import imghdr as imghdr import os import sys from io import BytesIO @@ -83,9 +82,9 @@ def upload_obj_to_s3(file_obj, dest_filename): # Folder to store files in on S3 is first two chars of dest_filename s3_folder = dest_filename[0:2] s3_filename = dest_filename[2:] - file_ending = imghdr.what(None, h=file_obj.read()) + pimage = Pimage.open(file_obj) file_obj.seek(0) - s3_content_type = f"image/{file_ending}" + s3_content_type = f"image/{pimage.format.lower()}" s3_path = f"{s3_folder}/{s3_filename}" s3_client.upload_fileobj( file_obj, @@ -106,22 +105,23 @@ def upload_obj_to_s3(file_obj, dest_filename): def upload_image_to_s3_and_store_in_db(image_buf, user_id, department_id=None): """ - Just a quick explaination of the order of operations here... - we have to scrub the image before we do anything else like hash it + Just a quick explanation of the order of operations here... + we have to scrub the image before we do anything else like hash it, but we also have to get the date for the image before we scrub it. """ image_buf.seek(0) - image_type = imghdr.what(image_buf) - if image_type not in current_app.config["ALLOWED_EXTENSIONS"]: - raise ValueError(f"Attempted to pass invalid data type: {image_type}") - image_buf.seek(0) pimage = Pimage.open(image_buf) + image_format = pimage.format.lower() + if image_format not in current_app.config["ALLOWED_EXTENSIONS"]: + raise ValueError(f"Attempted to pass invalid data type: {image_format}") + image_buf.seek(0) + date_taken = find_date_taken(pimage) if date_taken: date_taken = datetime.datetime.strptime(date_taken, "%Y:%m:%d %H:%M:%S") pimage.getexif().clear() scrubbed_image_buf = BytesIO() - pimage.save(scrubbed_image_buf, image_type) + pimage.save(scrubbed_image_buf, image_format) pimage.close() scrubbed_image_buf.seek(0) image_data = scrubbed_image_buf.read() @@ -130,7 +130,7 @@ def upload_image_to_s3_and_store_in_db(image_buf, user_id, department_id=None): if existing_image: return existing_image try: - new_filename = f"{hash_img}.{image_type}" + new_filename = f"{hash_img}.{image_format}" scrubbed_image_buf.seek(0) url = upload_obj_to_s3(scrubbed_image_buf, new_filename) new_image = Image( diff --git a/OpenOversight/app/utils/general.py b/OpenOversight/app/utils/general.py index 1743ca930..72b222716 100644 --- a/OpenOversight/app/utils/general.py +++ b/OpenOversight/app/utils/general.py @@ -6,12 +6,6 @@ from flask import current_app, url_for -from OpenOversight.app.custom import add_jpeg_patch - - -# Call JPEG patch function -add_jpeg_patch() - def ac_can_edit_officer(officer, ac): if officer.department_id == ac.ac_department_id: diff --git a/OpenOversight/tests/conftest.py b/OpenOversight/tests/conftest.py index 50600fcce..df032f05b 100644 --- a/OpenOversight/tests/conftest.py +++ b/OpenOversight/tests/conftest.py @@ -863,7 +863,7 @@ def browser(app, server_port): # start headless webdriver visual_display = Xvfb() visual_display.start() - driver = webdriver.Firefox(log_path="/tmp/geckodriver.log") + driver = webdriver.Firefox(service_log_path="/tmp/geckodriver.log") # wait for browser to start up time.sleep(3) yield driver diff --git a/OpenOversight/tests/test_utils.py b/OpenOversight/tests/test_utils.py index 48cd82ccf..594b4da00 100644 --- a/OpenOversight/tests/test_utils.py +++ b/OpenOversight/tests/test_utils.py @@ -1,5 +1,6 @@ from io import BytesIO +import PIL import pytest from flask import current_app from flask_login import current_user @@ -264,7 +265,7 @@ def test_upload_image_to_s3_and_store_in_db_saves_filename_in_correct_format( def test_upload_image_to_s3_and_store_in_db_throws_exception_for_unrecognized_format( mockdata, client ): - with pytest.raises(ValueError): + with pytest.raises(PIL.UnidentifiedImageError): upload_image_to_s3_and_store_in_db(BytesIO(b"invalid-image"), 1, 1)