Changeset View
Changeset View
Standalone View
Standalone View
swh/web/misc/iframe.py
# Copyright (C) 2021 The Software Heritage developers | # Copyright (C) 2021 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU Affero General Public License version 3, or any later version | # License: GNU Affero General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # 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.conf.urls import url | ||||
from django.shortcuts import render | from django.shortcuts import render | ||||
from django.views.decorators.clickjacking import xframe_options_exempt | from django.views.decorators.clickjacking import xframe_options_exempt | ||||
from swh.model.hashutil import hash_to_bytes | 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.snapshot_context import get_snapshot_context | ||||
from swh.web.browse.utils import ( | from swh.web.browse.utils import ( | ||||
content_display_max_size, | content_display_max_size, | ||||
get_directory_entries, | get_directory_entries, | ||||
prepare_content_for_display, | prepare_content_for_display, | ||||
request_content, | request_content, | ||||
) | ) | ||||
from swh.web.common import archive | from swh.web.common import archive | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | ) -> Dict[str, Any]: | ||||
return {"dirs": dirs, "files": files} | return {"dirs": dirs, "files": files} | ||||
def _get_breacrumbs_data( | def _get_breacrumbs_data( | ||||
swhid: QualifiedSWHID, | swhid: QualifiedSWHID, | ||||
focus_swhid: QualifiedSWHID, | focus_swhid: QualifiedSWHID, | ||||
path: str, | path: str, | ||||
snapshot_context: Optional[SnapshotContext] = None, | snapshot_context: Optional[SnapshotContext] = None, | ||||
) -> List[Dict[str, Any]]: | ) -> Tuple[List[Dict[str, Any]], Optional[str]]: | ||||
breadcrumbs = [] | breadcrumbs = [] | ||||
filename = None | filename = None | ||||
# strip any leading or trailing slash from path qualifier of SWHID | # strip any leading or trailing slash from path qualifier of SWHID | ||||
if path and path[0] == "/": | if path and path[0] == "/": | ||||
path = path[1:] | path = path[1:] | ||||
if path and path[-1] == "/": | if path and path[-1] == "/": | ||||
path = path[:-1] | path = path[:-1] | ||||
if swhid.object_type == ObjectType.CONTENT: | if swhid.object_type == ObjectType.CONTENT: | ||||
split_path = path.split("/") | split_path = path.split("/") | ||||
filename = split_path[-1] | filename = split_path[-1] | ||||
path = path[: -len(filename)] | path = path[: -len(filename)] | ||||
path_info = gen_path_info(path) if path != "/" else [] | path_info = gen_path_info(path) if path != "/" else [] | ||||
root_dir = None | root_dir = None | ||||
if snapshot_context and snapshot_context["root_directory"]: | if snapshot_context and snapshot_context["root_directory"]: | ||||
root_dir = 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: | elif focus_swhid.object_type == ObjectType.DIRECTORY: | ||||
root_dir = focus_swhid.object_id.hex() | root_dir = focus_swhid.object_id.hex() | ||||
if root_dir: | if root_dir: | ||||
root_dir_swhid = QualifiedSWHID( | root_dir_swhid = QualifiedSWHID( | ||||
object_type=ObjectType.DIRECTORY, | object_type=ObjectType.DIRECTORY, | ||||
object_id=hash_to_bytes(root_dir), | object_id=hash_to_bytes(root_dir), | ||||
origin=swhid.origin, | origin=swhid.origin, | ||||
visit=swhid.visit, | visit=swhid.visit, | ||||
anchor=swhid.anchor, | anchor=swhid.anchor, | ||||
) | ) | ||||
breadcrumbs.append( | breadcrumbs.append( | ||||
{ | { | ||||
"name": root_dir[:7], | "name": root_dir[:7], | ||||
"object_id": root_dir_swhid.object_id.hex(), | "object_id": root_dir_swhid.object_id.hex(), | ||||
"path": "/", | "path": "/", | ||||
"url": reverse( | "url": reverse( | ||||
"swhid-iframe", | "swhid-iframe", | ||||
url_args={"swhid": str(root_dir_swhid)}, | 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 | |||||
}, | |||||
), | ), | ||||
} | } | ||||
) | ) | ||||
for pi in path_info: | for pi in path_info: | ||||
dir_info = archive.lookup_directory_with_path(root_dir, pi["path"]) | dir_info = archive.lookup_directory_with_path(root_dir, pi["path"]) | ||||
dir_swhid = QualifiedSWHID( | dir_swhid = QualifiedSWHID( | ||||
object_type=ObjectType.DIRECTORY, | object_type=ObjectType.DIRECTORY, | ||||
Show All 20 Lines | if filename: | ||||
{ | { | ||||
"name": filename, | "name": filename, | ||||
"object_id": swhid.object_id.hex(), | "object_id": swhid.object_id.hex(), | ||||
"path": path, | "path": path, | ||||
"url": "", | "url": "", | ||||
} | } | ||||
) | ) | ||||
return breadcrumbs | return breadcrumbs, root_dir | ||||
@xframe_options_exempt | @xframe_options_exempt | ||||
def swhid_iframe(request, swhid: str): | def swhid_iframe(request, swhid: str): | ||||
"""Django view that can be embedded in an iframe to display objects archived | """Django view that can be embedded in an iframe to display objects archived | ||||
by Software Heritage (currently contents and directories) in a minimalist | by Software Heritage (currently contents and directories) in a minimalist | ||||
Web UI. | Web UI. | ||||
""" | """ | ||||
focus_swhid = request.GET.get("focus_swhid", swhid) | focus_swhid = request.GET.get("focus_swhid", swhid) | ||||
parsed_swhid = None | parsed_swhid = None | ||||
view_data = {} | view_data = {} | ||||
breadcrumbs = [] | breadcrumbs: List[Dict[str, Any]] = [] | ||||
swh_objects = [] | swh_objects = [] | ||||
snapshot_context = None | snapshot_context = None | ||||
swhids_info_extra_context = {} | swhids_info_extra_context = {} | ||||
archive_link = None | |||||
try: | try: | ||||
parsed_swhid = get_swhid(swhid) | parsed_swhid = get_swhid(swhid) | ||||
parsed_focus_swhid = get_swhid(focus_swhid) | parsed_focus_swhid = get_swhid(focus_swhid) | ||||
path = parsed_swhid.path.decode("utf-8") if parsed_swhid.path else "" | path = parsed_swhid.path.decode("utf-8") if parsed_swhid.path else "" | ||||
snapshot_context = None | snapshot_context = None | ||||
revision_id = None | revision_id = None | ||||
if ( | if ( | ||||
Show All 37 Lines | try: | ||||
"status_code": 400, | "status_code": 400, | ||||
"description": ( | "description": ( | ||||
f"Objects of type {parsed_swhid.object_type} are not supported" | f"Objects of type {parsed_swhid.object_type} are not supported" | ||||
), | ), | ||||
} | } | ||||
swhids_info_extra_context["path"] = path | swhids_info_extra_context["path"] = path | ||||
if parsed_swhid and view_data: | if parsed_swhid and view_data: | ||||
breadcrumbs = _get_breacrumbs_data( | breadcrumbs, root_dir = _get_breacrumbs_data( | ||||
parsed_swhid, parsed_focus_swhid, path, snapshot_context | parsed_swhid, parsed_focus_swhid, path, snapshot_context | ||||
) | ) | ||||
if parsed_swhid.object_type == ObjectType.CONTENT and len(breadcrumbs) > 1: | if parsed_swhid.object_type == ObjectType.CONTENT and len(breadcrumbs) > 1: | ||||
swh_objects.append( | swh_objects.append( | ||||
SWHObjectInfo( | SWHObjectInfo( | ||||
object_type=ObjectType.DIRECTORY, | object_type=ObjectType.DIRECTORY, | ||||
object_id=breadcrumbs[-2]["object_id"], | object_id=breadcrumbs[-2]["object_id"], | ||||
Show All 11 Lines | try: | ||||
) | ) | ||||
swh_objects.append( | swh_objects.append( | ||||
SWHObjectInfo( | SWHObjectInfo( | ||||
object_type=ObjectType.SNAPSHOT, | object_type=ObjectType.SNAPSHOT, | ||||
object_id=snapshot_context["snapshot_id"] or "", | object_id=snapshot_context["snapshot_id"] or "", | ||||
) | ) | ||||
) | ) | ||||
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: | except BadInputExc as e: | ||||
error_info = {"status_code": 400, "description": f"BadInputExc: {str(e)}"} | error_info = {"status_code": 400, "description": f"BadInputExc: {str(e)}"} | ||||
except NotFoundExc as e: | except NotFoundExc as e: | ||||
error_info = {"status_code": 404, "description": f"NotFoundExc: {str(e)}"} | error_info = {"status_code": 404, "description": f"NotFoundExc: {str(e)}"} | ||||
except Exception as e: | except Exception as e: | ||||
error_info = {"status_code": 500, "description": str(e)} | error_info = {"status_code": 500, "description": str(e)} | ||||
return render( | return render( | ||||
request, | request, | ||||
"misc/iframe.html", | "misc/iframe.html", | ||||
{ | { | ||||
**view_data, | **view_data, | ||||
"iframe_mode": True, | "iframe_mode": True, | ||||
"object_type": parsed_swhid.object_type.value if parsed_swhid else None, | "object_type": parsed_swhid.object_type.value if parsed_swhid else None, | ||||
"lines": parsed_swhid.lines if parsed_swhid else None, | "lines": parsed_swhid.lines if parsed_swhid else None, | ||||
"breadcrumbs": breadcrumbs, | "breadcrumbs": breadcrumbs, | ||||
"swhid": swhid, | "swhid": swhid, | ||||
"focus_swhid": focus_swhid, | "focus_swhid": focus_swhid, | ||||
"archive_link": archive_link, | |||||
"error_code": error_info["status_code"], | "error_code": error_info["status_code"], | ||||
"error_message": http_status_code_message.get(error_info["status_code"]), | "error_message": http_status_code_message.get(error_info["status_code"]), | ||||
"error_description": error_info["description"], | "error_description": error_info["description"], | ||||
"snapshot_context": None, | "snapshot_context": None, | ||||
"swhids_info": get_swhids_info( | "swhids_info": get_swhids_info( | ||||
swh_objects, snapshot_context, swhids_info_extra_context | swh_objects, snapshot_context, swhids_info_extra_context | ||||
), | ), | ||||
}, | }, | ||||
Show All 11 Lines |