Changeset View
Changeset View
Standalone View
Standalone View
swh/web/browse/views/content.py
# Copyright (C) 2017-2021 The Software Heritage developers | # Copyright (C) 2017-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 | ||||
import difflib | import difflib | ||||
from distutils.util import strtobool | from distutils.util import strtobool | ||||
import sentry_sdk | import sentry_sdk | ||||
from django.http import HttpResponse, JsonResponse | from django.http import HttpResponse, JsonResponse | ||||
from django.shortcuts import render | from django.shortcuts import redirect, render | ||||
from swh.model.hashutil import hash_to_hex | from swh.model.hashutil import hash_to_hex | ||||
from swh.model.swhids import ObjectType | from swh.model.swhids import ObjectType | ||||
from swh.web.browse.browseurls import browse_route | from swh.web.browse.browseurls import browse_route | ||||
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, | ||||
gen_link, | gen_link, | ||||
prepare_content_for_display, | prepare_content_for_display, | ||||
request_content, | request_content, | ||||
) | ) | ||||
from swh.web.common import archive, highlightjs, query | from swh.web.common import archive, highlightjs, query | ||||
from swh.web.common.exc import NotFoundExc, http_status_code_message | from swh.web.common.exc import BadInputExc, NotFoundExc, http_status_code_message | ||||
from swh.web.common.identifiers import get_swhids_info | from swh.web.common.identifiers import get_swhids_info | ||||
from swh.web.common.typing import ContentMetadata, SWHObjectInfo | from swh.web.common.typing import ContentMetadata, SWHObjectInfo | ||||
from swh.web.common.utils import gen_path_info, reverse, swh_object_icons | from swh.web.common.utils import gen_path_info, reverse, swh_object_icons | ||||
@browse_route( | @browse_route( | ||||
r"content/(?P<query_string>[0-9a-z_:]*[0-9a-f]+.)/raw/", | r"content/(?P<query_string>[0-9a-z_:]*[0-9a-f]+.)/raw/", | ||||
view_name="browse-content-raw", | view_name="browse-content-raw", | ||||
▲ Show 20 Lines • Show All 131 Lines • ▼ Show 20 Lines | else: | ||||
sentry_sdk.capture_exception(exc) | sentry_sdk.capture_exception(exc) | ||||
diff_str = str(exc) | diff_str = str(exc) | ||||
diff_data["diff_str"] = diff_str | diff_data["diff_str"] = diff_str | ||||
diff_data["language"] = language | diff_data["language"] = language | ||||
return JsonResponse(diff_data) | return JsonResponse(diff_data) | ||||
def _get_content_from_request(request): | |||||
path = request.GET.get("path") | |||||
if path is None: | |||||
anlambert: The path query parameter must be provided. | |||||
raise BadInputExc("The path query parameter must be provided.") | |||||
snapshot = request.GET.get("snapshot") | |||||
origin_url = request.GET.get("origin_url") | |||||
if snapshot is None and origin_url is None: | |||||
Done Inline ActionsThe origin_url or snapshot query parameters must be provided. anlambert: The origin_url or snapshot query parameters must be provided. | |||||
raise BadInputExc( | |||||
"The origin_url or snapshot query parameters must be provided." | |||||
) | |||||
snapshot_context = get_snapshot_context( | |||||
snapshot_id=snapshot, | |||||
origin_url=origin_url, | |||||
path=path, | |||||
timestamp=request.GET.get("timestamp"), | |||||
visit_id=request.GET.get("visit_id"), | |||||
branch_name=request.GET.get("branch"), | |||||
release_name=request.GET.get("release"), | |||||
browse_context="content", | |||||
) | |||||
root_directory = snapshot_context["root_directory"] | |||||
return archive.lookup_directory_with_path(root_directory, path) | |||||
@browse_route( | @browse_route( | ||||
r"content/(?P<query_string>[0-9a-z_:]*[0-9a-f]+.)/", | r"content/(?P<query_string>[0-9a-z_:]*[0-9a-f]+.)/", | ||||
r"content/", | |||||
view_name="browse-content", | view_name="browse-content", | ||||
checksum_args=["query_string"], | checksum_args=["query_string"], | ||||
) | ) | ||||
def content_display(request, query_string): | def content_display(request, query_string=None): | ||||
"""Django view that produces an HTML display of a content identified | """Django view that produces an HTML display of a content identified | ||||
by its hash value. | by its hash value. | ||||
The url that points to it is | The URLs that points to it are | ||||
:http:get:`/browse/content/[(algo_hash):](hash)/` | :http:get:`/browse/content/[(algo_hash):](hash)/` | ||||
:http:get:`/browse/content/` | |||||
""" | """ | ||||
if query_string is None: | |||||
# this case happens when redirected from origin/content or snapshot/content | |||||
Done Inline Actionsthis case happens when redirected either from /browse/origin/content or /browse/snapshot/content anlambert: this case happens when redirected either from /browse/origin/content or /browse/snapshot/content | |||||
content = _get_content_from_request(request) | |||||
return redirect( | |||||
reverse( | |||||
"browse-content", | |||||
url_args={"query_string": f"sha1_git:{content['target']}"}, | |||||
query_params=request.GET, | |||||
), | |||||
) | |||||
algo, checksum = query.parse_hash(query_string) | algo, checksum = query.parse_hash(query_string) | ||||
checksum = hash_to_hex(checksum) | checksum = hash_to_hex(checksum) | ||||
origin_url = request.GET.get("origin_url") | origin_url = request.GET.get("origin_url") | ||||
selected_language = request.GET.get("language") | selected_language = request.GET.get("language") | ||||
if not origin_url: | if not origin_url: | ||||
origin_url = request.GET.get("origin") | origin_url = request.GET.get("origin") | ||||
snapshot_id = request.GET.get("snapshot") | snapshot_id = request.GET.get("snapshot") | ||||
path = request.GET.get("path") | path = request.GET.get("path") | ||||
content_data = {} | content_data = {} | ||||
error_info = {"status_code": 200, "description": None} | error_info = {"status_code": 200, "description": None} | ||||
try: | try: | ||||
content_data = request_content(query_string) | content_data = request_content(query_string) | ||||
except NotFoundExc as e: | except NotFoundExc as e: | ||||
error_info["status_code"] = 404 | error_info["status_code"] = 404 | ||||
error_info["description"] = f"NotFoundExc: {str(e)}" | error_info["description"] = f"NotFoundExc: {str(e)}" | ||||
snapshot_context = None | snapshot_context = None | ||||
if origin_url is not None or snapshot_id is not None: | if origin_url is not None or snapshot_id is not None: | ||||
try: | try: | ||||
snapshot_context = get_snapshot_context( | snapshot_context = get_snapshot_context( | ||||
origin_url=origin_url, | origin_url=origin_url, | ||||
snapshot_id=snapshot_id, | snapshot_id=snapshot_id, | ||||
timestamp=request.GET.get("timestamp"), | |||||
visit_id=request.GET.get("visit_id"), | |||||
branch_name=request.GET.get("branch"), | branch_name=request.GET.get("branch"), | ||||
release_name=request.GET.get("release"), | release_name=request.GET.get("release"), | ||||
revision_id=request.GET.get("revision"), | revision_id=request.GET.get("revision"), | ||||
path=path, | path=path, | ||||
browse_context="content", | browse_context="content", | ||||
) | ) | ||||
except NotFoundExc as e: | except NotFoundExc as e: | ||||
if str(e).startswith("Origin"): | if str(e).startswith("Origin"): | ||||
▲ Show 20 Lines • Show All 190 Lines • Show Last 20 Lines |
The path query parameter must be provided.