diff --git a/src/iiif/image_handling.py b/src/iiif/image_handling.py index 709aed4..38a17fb 100644 --- a/src/iiif/image_handling.py +++ b/src/iiif/image_handling.py @@ -103,17 +103,16 @@ def content_type_to_format(content_type): return content_type.split("/")[1] -def scale_image(source_file, content_type, scaling, content): +def scale_image(content_type, scaling, content): """ Scale the image to the desired size. Never scale up. :param content: The image data - :param source_file: Bool whether the raw source file should be returned without any scaling :param scaling: The scaling string from the url :param content_type: The content type of the image :return: The scaled image data """ - if source_file or scaling.lower() == "full": + if scaling.lower() == "full": return content desired_width, desired_height = parse_scaling_string(scaling) @@ -194,7 +193,7 @@ def clamp(n, minn, maxn): # TODO: Extract sub functions to own functions for: # - asserting the region is valid # - return original when no crop was applied -def crop_image(source_file, content_type, region, content): +def crop_image(content_type, region, content): """ Crop the image to the desired size. Never crop outside the image. @@ -204,9 +203,6 @@ def crop_image(source_file, content_type, region, content): :param content_type: The content type of the image :return: The cropped image data """ - if source_file: - return content - img = Image.open(BytesIO(content)) match region.lower(): diff --git a/src/iiif/parsing.py b/src/iiif/parsing.py index 809a1a7..85fe77b 100644 --- a/src/iiif/parsing.py +++ b/src/iiif/parsing.py @@ -97,7 +97,6 @@ def get_info_from_iiif_url(iiif_url, source_file): "formatting": formatting, "region": region, "scaling": scaling, - "source_file": source_file, # Bool whether the file should be served without image processing (pdf/xls) "source_filename": source_filename, # The filename on the source system "filename": relevant_url_part, # The filename if this file needs to be stored on disc "info_json": info_json, # Whether the info.json is requested instead of the image itself @@ -115,7 +114,6 @@ def get_info_from_iiif_url(iiif_url, source_file): "formatting": formatting, "region": region, "scaling": scaling, - "source_file": source_file, # Bool whether the file should be served without image processing (pdf/xls) "source_filename": source_filename, # The filename on the source system "filename": relevant_url_part, # The filename if this file needs to be stored on disc "info_json": info_json, diff --git a/src/iiif/views.py b/src/iiif/views.py index cc2ded3..8bf1dcd 100644 --- a/src/iiif/views.py +++ b/src/iiif/views.py @@ -27,9 +27,9 @@ def index(request, iiif_url): authentication.check_auth_availability(request) mail_jwt_token, is_mail_login = authentication.read_out_mail_jwt_token(request) scope = authentication.get_max_scope(request, mail_jwt_token) - url_info = parsing.get_url_info( - iiif_url, utils.str_to_bool(request.GET.get("source_file")) - ) + + is_source_file_requested = utils.str_to_bool(request.GET.get("source_file")) + url_info = parsing.get_url_info(iiif_url, is_source_file_requested) authentication.check_wabo_for_mail_login(is_mail_login, url_info) metadata, _ = get_metadata(url_info, iiif_url, {}) @@ -42,16 +42,12 @@ def index(request, iiif_url): file_content = file_response.content file_type = file_response.headers.get("Content-Type") - if url_info["info_json"]: - response_content = generate_info_json( - request.build_absolute_uri().split("/info.json")[0], + + if is_source_file_requested: + return HttpResponse( file_content, file_type, ) - return HttpResponse( - response_content, - content_type="application/json", - ) if not is_image_content_type(file_type): raise utils.ImmediateHttpResponse( @@ -60,15 +56,24 @@ def index(request, iiif_url): ) ) + if url_info["info_json"]: + response_content = generate_info_json( + request.build_absolute_uri().split("/info.json")[0], + file_content, + file_type, + ) + return HttpResponse( + response_content, + content_type="application/json", + ) + crop = partial( crop_image, - url_info["source_file"], file_type, url_info["region"], ) scale = partial( scale_image, - url_info["source_file"], file_type, url_info["scaling"], ) diff --git a/tests/test_iiif.py b/tests/test_iiif.py index f9d32d3..8c8ea04 100644 --- a/tests/test_iiif.py +++ b/tests/test_iiif.py @@ -23,6 +23,7 @@ from tests.test_settings import ( IMAGE_BINARY_DATA, PRE_WABO_IMG_URL_NO_SCALING, + PRE_WABO_IMG_URL_SOURCE_FILE, PRE_WABO_IMG_URL_WITH_EMPTY_SCALING, PRE_WABO_IMG_URL_WITH_EXTRA_REFERENCE, PRE_WABO_IMG_URL_WITH_REGION, @@ -147,6 +148,27 @@ def test_get_image_when_image_server_gives_ConnectTimeout( == RESPONSE_CONTENT_ERROR_RESPONSE_FROM_IMAGE_SERVER + " ConnectTimeout" ) + @patch("iiif.image_server.get_image_from_server") + @patch("iiif.metadata.do_metadata_request") + def test_get_info_json_non_image_raises( + self, mock_do_metadata_request, mock_get_image_from_server, client + ): + mock_do_metadata_request.return_value = MockResponse( + 200, + json_content=PRE_WABO_METADATA_CONTENT, + ) + mock_get_image_from_server.return_value = MockResponse( + 200, content=b"b", headers={"Content-Type": "text/xml"} + ) + + header = { + "HTTP_AUTHORIZATION": "Bearer " + + create_authz_token(settings.BOUWDOSSIER_READ_SCOPE) + } + + response = client.get(self.url + PRE_WABO_INFO_JSON_URL, **header) + assert response.status_code == 400 + @patch("iiif.image_server.get_image_from_server") @patch("iiif.metadata.do_metadata_request") def test_get_info_json( @@ -453,6 +475,28 @@ def test_get_restricted_image_with_only_extended_scope_and_no_read_scope( assert response.status_code == 200 assert response.content == IMAGE_BINARY_DATA + @patch("iiif.image_server.get_image_from_server") + @patch("iiif.metadata.do_metadata_request") + def test_get_source_image( + self, mock_do_metadata_request, mock_get_image_from_server, client + ): + mock_do_metadata_request.return_value = MockResponse( + 200, + json_content=PRE_WABO_METADATA_CONTENT, + ) + mock_get_image_from_server.return_value = MockResponse( + 200, content=IMAGE_BINARY_DATA, headers={"Content-Type": "image/jpeg"} + ) + + header = { + "HTTP_AUTHORIZATION": "Bearer " + + create_authz_token(settings.BOUWDOSSIER_READ_SCOPE) + } + + response = client.get(self.url + PRE_WABO_IMG_URL_SOURCE_FILE, **header) + assert response.status_code == 200 + assert response.content == IMAGE_BINARY_DATA + @patch("iiif.image_server.get_image_from_server") @patch("iiif.metadata.do_metadata_request") def test_get_resized_image( diff --git a/tests/test_image_handling.py b/tests/test_image_handling.py index 7d8bca1..2e09c00 100644 --- a/tests/test_image_handling.py +++ b/tests/test_image_handling.py @@ -40,30 +40,14 @@ def test_parse_scaling_string(self): assert parse_scaling_string("100,100") == (100, 100) def test_scale_image(self): - assert ( - scale_image(False, "image/jpeg", "full", self.img_96x85) == self.img_96x85 - ) - assert ( - scale_image(False, "image/jpeg", "100,100", self.img_96x85) - == self.img_96x85 - ) - assert ( - scale_image(False, "image/jpeg", "100,", self.img_96x85) == self.img_96x85 - ) - assert ( - scale_image(False, "image/jpeg", ",100", self.img_96x85) == self.img_96x85 - ) - assert ( - scale_image(True, "image/jpeg", "20,20", self.img_96x85) == self.img_96x85 - ) - assert ( - scale_image(False, "image/jpeg", "50,50", self.img_96x85) == self.img_50x44 - ) - assert scale_image(False, "image/jpeg", "50,", self.img_96x85) == self.img_50x44 - assert ( - scale_image(False, "image/jpeg", "60,44", self.img_96x85) == self.img_49x44 - ) - assert scale_image(False, "image/jpeg", ",44", self.img_96x85) == self.img_49x44 + assert scale_image("image/jpeg", "full", self.img_96x85) == self.img_96x85 + assert scale_image("image/jpeg", "100,100", self.img_96x85) == self.img_96x85 + assert scale_image("image/jpeg", "100,", self.img_96x85) == self.img_96x85 + assert scale_image("image/jpeg", ",100", self.img_96x85) == self.img_96x85 + assert scale_image("image/jpeg", "50,50", self.img_96x85) == self.img_50x44 + assert scale_image("image/jpeg", "50,", self.img_96x85) == self.img_50x44 + assert scale_image("image/jpeg", "60,44", self.img_96x85) == self.img_49x44 + assert scale_image("image/jpeg", ",44", self.img_96x85) == self.img_49x44 @pytest.mark.parametrize("param", [None, "", ",,,", "x,y,w,h", "50,50,,"]) def test_parse_invalid_region_string_raises(self, param): @@ -75,43 +59,33 @@ def test_parse_region_string(self): assert parse_region_string("0,0,50,44") == (0, 0, 50, 44) def test_crop_image(self): - assert crop_image(False, "image/jpeg", "full", self.img_96x85) == self.img_96x85 - assert ( - crop_image(False, "image/jpeg", "square", self.img_96x85) == self.img_85x85 - ) + assert crop_image("image/jpeg", "full", self.img_96x85) == self.img_96x85 + assert crop_image("image/jpeg", "square", self.img_96x85) == self.img_85x85 + assert crop_image("image/jpeg", "0,0,100,100", self.img_96x85) == self.img_96x85 assert ( - crop_image(False, "image/jpeg", "0,0,100,100", self.img_96x85) - == self.img_96x85 - ) - assert ( - crop_image(True, "image/jpeg", "0,0,50,44", self.img_96x85) - == self.img_96x85 - ) - assert ( - crop_image(False, "image/jpeg", "0,0,50,44", self.img_96x85) - == self.img_0x0x50x44 + crop_image("image/jpeg", "0,0,50,44", self.img_96x85) == self.img_0x0x50x44 ) assert ( - crop_image(False, "image/jpeg", "24,24,48,48", self.img_96x85) + crop_image("image/jpeg", "24,24,48,48", self.img_96x85) == self.img_24x24x72x72 ) assert ( - crop_image(False, "image/jpeg", "0,41,96,85", self.img_96x85) + crop_image("image/jpeg", "0,41,96,85", self.img_96x85) == self.img_0x41x96x44 ) assert ( - crop_image(False, "image/jpeg", "48,0,96,85", self.img_96x85) + crop_image("image/jpeg", "48,0,96,85", self.img_96x85) == self.img_48x0x48x85 ) assert ( - crop_image(False, "image/jpeg", "-50,-56,100,100", self.img_96x85) + crop_image("image/jpeg", "-50,-56,100,100", self.img_96x85) == self.img_0x0x50x44 ) def test_crop_image_no_size(self): with pytest.raises(ImmediateHttpResponse): - crop_image(False, "image/jpeg", "0,0,0,0", self.img_96x85) + crop_image("image/jpeg", "0,0,0,0", self.img_96x85) def test_crop_outside_image(self): with pytest.raises(ImmediateHttpResponse): - crop_image(False, "image/jpeg", "100,100,50,50", self.img_96x85) + crop_image("image/jpeg", "100,100,50,50", self.img_96x85) diff --git a/tests/test_settings.py b/tests/test_settings.py index ee4f7c9..d4f176c 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -18,6 +18,10 @@ def filename_from_url(url): PRE_WABO_IMG_URL_BASE + "10000,10000,48,48/full/0/default.jpg" ) + +PRE_WABO_IMG_URL_SOURCE_FILE = ( + "2/edepot:ST-00015-ST00000126_00001.jpg/?source_file=true&" +) PRE_WABO_IMG_URL_NO_SCALING = ( "2/edepot:ST-00015-ST00000126_00001.jpg/full/full/0/default.jpg" ) diff --git a/tests/test_utils.py b/tests/test_utils.py index 001d9ee..6fb771e 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -44,7 +44,6 @@ def test_get_info_json_from_pre_wabo_url(self): assert url_info["file"] == "00001" assert url_info["region"] is None assert url_info["scaling"] is None - assert url_info["source_file"] is False assert url_info["source_filename"] == "ST/00015/ST00000126_00001.jpg" assert url_info["filename"] == "ST-00015-ST00000126_00001.jpg" assert url_info["formatting"] is None @@ -59,7 +58,6 @@ def test_get_info_from_pre_wabo_url_vanilla(self): assert url_info["file"] == "00001" assert url_info["region"] == "full" assert url_info["scaling"] == "50,50" - assert url_info["source_file"] is False assert url_info["source_filename"] == "ST/00015/ST00000126_00001.jpg" assert url_info["filename"] == "ST-00015-ST00000126_00001.jpg" assert url_info["formatting"] == "full/50,50/0/default.jpg" @@ -74,7 +72,6 @@ def test_get_info_from_pre_wabo_url_with_source_file(self): assert url_info["file"] == "00001" assert url_info["region"] == "full" assert url_info["scaling"] == "50,50" - assert url_info["source_file"] is True assert url_info["source_filename"] == "ST/00015/ST00000126_00001.jpg" assert url_info["filename"] == "ST-00015-ST00000126_00001.jpg" assert url_info["formatting"] == "full/50,50/0/default.jpg" @@ -89,7 +86,6 @@ def test_get_info_from_pre_wabo_url_with_no_scaling(self): assert url_info["file"] == "00001" assert url_info["region"] == "full" assert url_info["scaling"] == "full" - assert url_info["source_file"] is True assert url_info["source_filename"] == "ST/00015/ST00000126_00001.jpg" assert url_info["filename"] == "ST-00015-ST00000126_00001.jpg" assert url_info["formatting"] == "full/full/0/default.jpg" @@ -104,7 +100,6 @@ def test_get_info_from_pre_wabo_url_with_cropping(self): assert url_info["file"] == "00001" assert url_info["region"] == "24,24,48,48" assert url_info["scaling"] == "full" - assert url_info["source_file"] is True assert url_info["source_filename"] == "ST/00015/ST00000126_00001.jpg" assert url_info["filename"] == "ST-00015-ST00000126_00001.jpg" assert url_info["formatting"] == "24,24,48,48/full/0/default.jpg" @@ -123,7 +118,6 @@ def test_get_info_from_wabo_url_vanilla(self): assert url_info["document_barcode"] == "628547" assert url_info["region"] == "full" assert url_info["scaling"] == "1000,900" - assert url_info["source_file"] is False assert url_info["source_filename"] == "SDZ/38657/4900487_628547" assert url_info["filename"] == "SDZ-38657-4900487_628547" assert url_info["formatting"] == "full/1000,900/0/default.jpg" @@ -138,7 +132,6 @@ def test_get_info_from_wabo_url_with_source_file(self): assert url_info["document_barcode"] == "628547" assert url_info["region"] == "full" assert url_info["scaling"] == "1000,900" - assert url_info["source_file"] is True assert url_info["source_filename"] == "SDZ/38657/4900487_628547" assert url_info["filename"] == "SDZ-38657-4900487_628547" assert url_info["formatting"] == "full/1000,900/0/default.jpg" @@ -155,7 +148,6 @@ def test_get_info_from_wabo_url_with_underscores_in_barcode(self): assert url_info["document_barcode"] == "ECS0000004420_000_000" assert url_info["region"] is None assert url_info["scaling"] is None - assert url_info["source_file"] is False assert url_info["source_filename"] == "SDO/10316333/3304_ECS0000004420_000_000" assert url_info["filename"] == "SDO-10316333-3304_ECS0000004420_000_000" assert url_info["formatting"] is None @@ -172,7 +164,6 @@ def test_get_info_from_wabo_url_with_underscores_and_hyphens_in_barcode(self): assert url_info["document_barcode"] == "ECS0000004420-000_00-00" assert url_info["region"] is None assert url_info["scaling"] is None - assert url_info["source_file"] is False assert ( url_info["source_filename"] == "SDO/10316333/3304_ECS0000004420-000_00-00" ) @@ -226,7 +217,6 @@ def test_create_file_url_and_headers(self): url, headers = create_file_url_and_headers( { "source": "edepot", - "source_file": False, "source_filename": source_filename_from_url( PRE_WABO_IMG_URL_WITH_SCALING ), @@ -245,7 +235,6 @@ def test_create_file_url_and_headers(self): url, headers = create_file_url_and_headers( { "source": "edepot", - "source_file": True, "source_filename": source_filename_from_url( PRE_WABO_IMG_URL_WITH_SCALING ), @@ -263,7 +252,6 @@ def test_create_file_url_and_headers(self): url, headers = create_file_url_and_headers( { "source": "edepot", - "source_file": False, "source_filename": source_filename_from_url( PRE_WABO_IMG_URL_WITH_EXTRA_REFERENCE ), @@ -281,7 +269,6 @@ def test_create_file_url_and_headers(self): url, headers = create_file_url_and_headers( { "source": "edepot", - "source_file": False, "source_filename": source_filename_from_url(PRE_WABO_INFO_JSON_URL), "filename": filename_from_url(PRE_WABO_INFO_JSON_URL), }, @@ -298,7 +285,6 @@ def test_create_file_url_and_headers(self): "source": "wabo", "document_barcode": "628547", "formatting": "full/1000,1000/0/default.jpg", - "source_file": False, }, metadata, ) @@ -310,7 +296,6 @@ def test_create_file_url_and_headers(self): "source": "wabo", "document_barcode": "628547", "formatting": "full/1000,1000/0/default.jpg", - "source_file": False, }, metadata, ) @@ -322,7 +307,6 @@ def test_create_file_url_and_headers(self): "source": "wabo", "document_barcode": "628547", "formatting": "full/1000,1000/0/default.jpg", - "source_file": True, }, metadata, )