diff --git a/cads_catalogue/layout_manager.py b/cads_catalogue/layout_manager.py index 449a130..c90ec24 100644 --- a/cads_catalogue/layout_manager.py +++ b/cads_catalogue/layout_manager.py @@ -54,44 +54,55 @@ def manage_image_section( new_section = copy.deepcopy(section) blocks = new_section.get("blocks", []) for i, block in enumerate(copy.deepcopy(blocks)): - image_dict = block.get("image", {}) - image_rel_path = image_dict.get("url") - if block.get("type") == "thumb-markdown" and image_rel_path: - if utils.is_url(image_rel_path): - # nothing to do, the url is already uploaded somewhere - continue - image_abs_path = os.path.join(folder_path, block["image"]["url"]) - if os.path.isfile(image_abs_path): - if image_abs_path not in images_stored and not disable_upload: - # process upload to object storage - subpath = os.path.dirname( - os.path.join( - "resources", resource["resource_uid"], image_rel_path + if "image" not in block: + continue + image_dict_list = block["image"] + if isinstance(image_dict_list, dict): + image_dict_list = [image_dict_list] + for j, image_dict in enumerate(image_dict_list): + # TODO: better to not use relative paths, look only inside local folder + image_rel_path = image_dict.get("url") + if block.get("type") == "thumb-markdown" and image_rel_path: + if utils.is_url(image_rel_path): + # nothing to do, the url is already uploaded somewhere + continue + image_abs_path = os.path.abspath( + os.path.join(folder_path, image_dict["url"]) + ) + if os.path.isfile(image_abs_path): + if image_abs_path not in images_stored and not disable_upload: + # process upload to object storage + subpath = f"resources/{resource['resource_uid']}" + image_rel_url = object_storage.store_file( + image_abs_path, + storage_settings.object_storage_url, + bucket_name=storage_settings.catalogue_bucket, + subpath=subpath, + **storage_settings.storage_kws, ) - ) - image_rel_url = object_storage.store_file( - image_abs_path, - storage_settings.object_storage_url, - bucket_name=storage_settings.catalogue_bucket, - subpath=subpath, - **storage_settings.storage_kws, - ) - # update cache of the upload urls - images_stored[image_abs_path] = urllib.parse.urljoin( - storage_settings.document_storage_url, image_rel_url - ) - blocks[i]["image"]["url"] = images_stored.get(image_abs_path, "") - else: - raise ValueError(f"image {image_rel_path} not found") - elif block.get("type") in ("section", "accordion"): - blocks[i] = manage_image_section( - folder_path, - block, - images_stored, - resource, - storage_settings, - disable_upload=disable_upload, - ) + # update cache of the upload urls + images_stored[image_abs_path] = urllib.parse.urljoin( + storage_settings.document_storage_url, image_rel_url + ) + if isinstance(block["image"], dict): + blocks[i]["image"]["url"] = images_stored.get( + image_abs_path, "" + ) + else: + blocks[i]["image"][j]["url"] = images_stored.get( + image_abs_path, "" + ) + else: + raise ValueError(f"image {image_rel_path} not found") + elif block.get("type") in ("section", "accordion"): + blocks[i] = manage_image_section( + folder_path, + block, + images_stored, + resource, + storage_settings, + disable_upload=disable_upload, + ) return new_section diff --git a/tests/test_30_layout_manager.py b/tests/test_30_layout_manager.py index 7dec86e..b04cf05 100644 --- a/tests/test_30_layout_manager.py +++ b/tests/test_30_layout_manager.py @@ -202,6 +202,21 @@ def test_manage_image_section(tmpdir, mocker: pytest_mock.MockerFixture) -> None "alt": "alternative text", }, } + multi_images_block = { + "id": "abstract", + "type": "thumb-markdown", + "content": "a content", + "image": [ + { + "url": "overview/overview.png", + "alt": "alternative text1", + }, + { + "url": "overview/overview2.png", + "alt": "alternative text2", + }, + ], + } modified_image_block = { "id": "abstract", "type": "thumb-markdown", @@ -211,6 +226,21 @@ def test_manage_image_section(tmpdir, mocker: pytest_mock.MockerFixture) -> None "alt": "alternative text", }, } + multi_images_block_uploaded = { + "id": "abstract", + "type": "thumb-markdown", + "content": "a content", + "image": [ + { + "url": "http://public-storage/an url", + "alt": "alternative text1", + }, + { + "url": "http://public-storage/an url", + "alt": "alternative text2", + }, + ], + } section = {"id": "overview", "blocks": [no_image_block, image_block]} images_stored: dict[str, str] = dict() @@ -219,7 +249,7 @@ def test_manage_image_section(tmpdir, mocker: pytest_mock.MockerFixture) -> None layout_manager.manage_image_section( str(tmpdir), section, images_stored, resource, oss ) - # url is already a link: no change + # url is already uploaded: no change image_block_already_url = { "id": "abstract", "type": "thumb-markdown", @@ -241,7 +271,9 @@ def test_manage_image_section(tmpdir, mocker: pytest_mock.MockerFixture) -> None overview_file_path = os.path.join(overview_path, "overview.png") with open(overview_file_path, "w") as fp: fp.write("hello! I am an image") - + overview2_file_path = os.path.join(overview_path, "overview2.png") + with open(overview2_file_path, "w") as fp: + fp.write("hello! I am an image2") # 1 image block section = {"id": "overview", "blocks": [no_image_block, image_block]} new_section = layout_manager.manage_image_section( @@ -263,7 +295,7 @@ def test_manage_image_section(tmpdir, mocker: pytest_mock.MockerFixture) -> None ) assert new_section == section - # case section with more image_blocks + # case section with more separeted image blocks section = {"id": "overview", "blocks": [image_block, no_image_block, image_block]} new_section = layout_manager.manage_image_section( str(tmpdir), section, images_stored, resource, oss @@ -322,6 +354,15 @@ def test_manage_image_section(tmpdir, mocker: pytest_mock.MockerFixture) -> None no_image_block, ], } + # case section with a block with multiple images + section = {"id": "overview", "blocks": [no_image_block, multi_images_block]} + new_section = layout_manager.manage_image_section( + str(tmpdir), section, images_stored, resource, oss + ) + assert new_section == { + "id": "overview", + "blocks": [no_image_block, multi_images_block_uploaded], + } def test_transform_image_blocks(tmpdir, mocker: pytest_mock.MockerFixture) -> None: