diff --git a/swh/web/misc/iframe.py b/swh/web/misc/iframe.py --- a/swh/web/misc/iframe.py +++ b/swh/web/misc/iframe.py @@ -3,14 +3,14 @@ # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, Optional, Tuple from django.conf.urls import url from django.shortcuts import render from django.views.decorators.clickjacking import xframe_options_exempt from swh.model.hashutil import hash_to_bytes -from swh.model.swhids import ObjectType, QualifiedSWHID +from swh.model.swhids import CoreSWHID, ObjectType, QualifiedSWHID from swh.web.browse.snapshot_context import get_snapshot_context from swh.web.browse.utils import ( content_display_max_size, @@ -96,7 +96,7 @@ focus_swhid: QualifiedSWHID, path: str, snapshot_context: Optional[SnapshotContext] = None, -) -> List[Dict[str, Any]]: +) -> Tuple[List[Dict[str, Any]], Optional[str]]: breadcrumbs = [] filename = None # strip any leading or trailing slash from path qualifier of SWHID @@ -114,6 +114,8 @@ root_dir = None if snapshot_context and snapshot_context["root_directory"]: root_dir = snapshot_context["root_directory"] + elif swhid.anchor and swhid.anchor.object_type == ObjectType.DIRECTORY: + root_dir = swhid.anchor.object_id.hex() elif focus_swhid.object_type == ObjectType.DIRECTORY: root_dir = focus_swhid.object_id.hex() @@ -125,6 +127,7 @@ visit=swhid.visit, anchor=swhid.anchor, ) + breadcrumbs.append( { "name": root_dir[:7], @@ -133,7 +136,11 @@ "url": reverse( "swhid-iframe", url_args={"swhid": str(root_dir_swhid)}, - query_params={"focus_swhid": focus_swhid}, + query_params={ + "focus_swhid": focus_swhid + if focus_swhid != root_dir_swhid + else None + }, ), } ) @@ -170,7 +177,7 @@ } ) - return breadcrumbs + return breadcrumbs, root_dir @xframe_options_exempt @@ -182,10 +189,11 @@ focus_swhid = request.GET.get("focus_swhid", swhid) parsed_swhid = None view_data = {} - breadcrumbs = [] + breadcrumbs: List[Dict[str, Any]] = [] swh_objects = [] snapshot_context = None swhids_info_extra_context = {} + archive_link = None try: parsed_swhid = get_swhid(swhid) parsed_focus_swhid = get_swhid(focus_swhid) @@ -239,7 +247,7 @@ swhids_info_extra_context["path"] = path if parsed_swhid and view_data: - breadcrumbs = _get_breacrumbs_data( + breadcrumbs, root_dir = _get_breacrumbs_data( parsed_swhid, parsed_focus_swhid, path, snapshot_context ) @@ -267,6 +275,28 @@ ) ) + archive_link = reverse("browse-swhid", url_args={"swhid": swhid}) + if ( + parsed_swhid.origin is None + and parsed_swhid.visit is None + and parsed_swhid.anchor is None + and root_dir is not None + ): + # qualifier values cannot be used to get root directory from them, + # we need to add it as anchor in the SWHID argument of the archive link + root_dir_swhid = CoreSWHID( + object_type=ObjectType.DIRECTORY, object_id=hash_to_bytes(root_dir) + ) + archive_swhid = QualifiedSWHID( + object_type=parsed_swhid.object_type, + object_id=parsed_swhid.object_id, + path=parsed_swhid.path, + anchor=root_dir_swhid, + ) + archive_link = reverse( + "browse-swhid", url_args={"swhid": f"{archive_swhid}"}, + ) + except BadInputExc as e: error_info = {"status_code": 400, "description": f"BadInputExc: {str(e)}"} except NotFoundExc as e: @@ -285,6 +315,7 @@ "breadcrumbs": breadcrumbs, "swhid": swhid, "focus_swhid": focus_swhid, + "archive_link": archive_link, "error_code": error_info["status_code"], "error_message": http_status_code_message.get(error_info["status_code"]), "error_description": error_info["description"], diff --git a/swh/web/templates/misc/iframe.html b/swh/web/templates/misc/iframe.html --- a/swh/web/templates/misc/iframe.html +++ b/swh/web/templates/misc/iframe.html @@ -135,12 +135,12 @@ {% endif %} - View in the archive - diff --git a/swh/web/tests/misc/test_iframe.py b/swh/web/tests/misc/test_iframe.py --- a/swh/web/tests/misc/test_iframe.py +++ b/swh/web/tests/misc/test_iframe.py @@ -3,10 +3,12 @@ # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information +import random from swh.model.hashutil import hash_to_bytes -from swh.model.swhids import CoreSWHID, ObjectType +from swh.model.swhids import CoreSWHID, ObjectType, QualifiedSWHID from swh.web.common.utils import reverse +from swh.web.tests.django_asserts import assert_contains from swh.web.tests.utils import check_html_get_response @@ -67,3 +69,38 @@ check_html_get_response( client, url, status_code=500, template_used="misc/iframe.html" ) + + +def test_iframe_directory_no_snapshot_context( + client, archive_data, directory_with_subdirs +): + dir_content = archive_data.directory_ls(directory_with_subdirs) + subdir = random.choice([e for e in dir_content if e["type"] == "dir"]) + path = f"/{subdir['name']}/" + + root_swhid = CoreSWHID( + object_type=ObjectType.DIRECTORY, + object_id=hash_to_bytes(directory_with_subdirs), + ) + swhid = CoreSWHID( + object_type=ObjectType.DIRECTORY, object_id=hash_to_bytes(subdir["target"]) + ) + qualified_swhid = QualifiedSWHID( + object_type=ObjectType.DIRECTORY, + object_id=hash_to_bytes(subdir["target"]), + anchor=root_swhid, + path=path, + ) + + url = reverse( + "swhid-iframe", + url_args={"swhid": f"{str(swhid)};path={path}"}, + query_params={"focus_swhid": str(root_swhid)}, + ) + resp = check_html_get_response( + client, url, status_code=200, template_used="misc/iframe.html" + ) + + archive_url = reverse("browse-swhid", url_args={"swhid": str(qualified_swhid)}) + + assert_contains(resp, archive_url)