diff --git a/swh/web/api/views/identifiers.py b/swh/web/api/views/identifiers.py --- a/swh/web/api/views/identifiers.py +++ b/swh/web/api/views/identifiers.py @@ -1,4 +1,4 @@ -# Copyright (C) 2018-2020 The Software Heritage developers +# Copyright (C) 2018-2021 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -54,14 +54,14 @@ # object is present in the archive, NotFoundExc # will be raised otherwise swhid_parsed = swhid_resolved["swhid_parsed"] - object_type = swhid_parsed.object_type.name.lower() + object_type = swhid_parsed.object_type object_id = hash_to_hex(swhid_parsed.object_id) - archive.lookup_object(object_type, object_id) + archive.lookup_object(swhid_parsed.object_type, object_id) # id is well-formed and the pointed object exists return { "namespace": swhid_parsed.namespace, "scheme_version": swhid_parsed.scheme_version, - "object_type": object_type, + "object_type": object_type.name.lower(), "object_id": object_id, "metadata": swhid_parsed.qualifiers(), "browse_url": request.build_absolute_uri(swhid_resolved["browse_url"]), diff --git a/swh/web/browse/snapshot_context.py b/swh/web/browse/snapshot_context.py --- a/swh/web/browse/snapshot_context.py +++ b/swh/web/browse/snapshot_context.py @@ -13,15 +13,7 @@ from django.utils.html import escape from swh.model.hashutil import hash_to_bytes -from swh.model.identifiers import ( - CONTENT, - DIRECTORY, - RELEASE, - REVISION, - SNAPSHOT, - CoreSWHID, - ObjectType, -) +from swh.model.identifiers import CoreSWHID, ObjectType from swh.model.model import Snapshot from swh.web.browse.utils import ( content_display_max_size, @@ -806,16 +798,22 @@ revision_found = False if sha1_git is not None: - swh_objects.append(SWHObjectInfo(object_type=DIRECTORY, object_id=sha1_git)) + swh_objects.append( + SWHObjectInfo(object_type=ObjectType.DIRECTORY, object_id=sha1_git) + ) vault_cooking.update( {"directory_context": True, "directory_swhid": f"swh:1:dir:{sha1_git}",} ) if revision_found: - swh_objects.append(SWHObjectInfo(object_type=REVISION, object_id=revision_id)) + swh_objects.append( + SWHObjectInfo(object_type=ObjectType.REVISION, object_id=revision_id) + ) vault_cooking.update( {"revision_context": True, "revision_swhid": f"swh:1:rev:{revision_id}",} ) - swh_objects.append(SWHObjectInfo(object_type=SNAPSHOT, object_id=snapshot_id)) + swh_objects.append( + SWHObjectInfo(object_type=ObjectType.SNAPSHOT, object_id=snapshot_id) + ) visit_date = None visit_type = None @@ -825,10 +823,12 @@ release_id = snapshot_context["release_id"] if release_id: - swh_objects.append(SWHObjectInfo(object_type=RELEASE, object_id=release_id)) + swh_objects.append( + SWHObjectInfo(object_type=ObjectType.RELEASE, object_id=release_id) + ) dir_metadata = DirectoryMetadata( - object_type=DIRECTORY, + object_type=ObjectType.DIRECTORY, object_id=sha1_git, directory=sha1_git, nb_files=nb_files, @@ -984,10 +984,12 @@ content_checksums = content_data.get("checksums", {}) swh_objects = [ - SWHObjectInfo(object_type=CONTENT, object_id=content_checksums.get("sha1_git")), - SWHObjectInfo(object_type=DIRECTORY, object_id=directory_id), - SWHObjectInfo(object_type=REVISION, object_id=revision_id), - SWHObjectInfo(object_type=SNAPSHOT, object_id=snapshot_id), + SWHObjectInfo( + object_type=ObjectType.CONTENT, object_id=content_checksums.get("sha1_git") + ), + SWHObjectInfo(object_type=ObjectType.DIRECTORY, object_id=directory_id), + SWHObjectInfo(object_type=ObjectType.REVISION, object_id=revision_id), + SWHObjectInfo(object_type=ObjectType.SNAPSHOT, object_id=snapshot_id), ] visit_date = None @@ -998,10 +1000,12 @@ release_id = snapshot_context["release_id"] if release_id: - swh_objects.append(SWHObjectInfo(object_type=RELEASE, object_id=release_id)) + swh_objects.append( + SWHObjectInfo(object_type=ObjectType.RELEASE, object_id=release_id) + ) content_metadata = ContentMetadata( - object_type=CONTENT, + object_type=ObjectType.CONTENT, object_id=content_checksums.get("sha1_git"), sha1=content_checksums.get("sha1"), sha1_git=content_checksums.get("sha1_git"), @@ -1175,13 +1179,15 @@ revision_metadata["origin visit type"] = visit_info["type"] swh_objects = [ - SWHObjectInfo(object_type=REVISION, object_id=revision_id), - SWHObjectInfo(object_type=SNAPSHOT, object_id=snapshot_id), + SWHObjectInfo(object_type=ObjectType.REVISION, object_id=revision_id), + SWHObjectInfo(object_type=ObjectType.SNAPSHOT, object_id=snapshot_id), ] release_id = snapshot_context["release_id"] if release_id: - swh_objects.append(SWHObjectInfo(object_type=RELEASE, object_id=release_id)) + swh_objects.append( + SWHObjectInfo(object_type=ObjectType.RELEASE, object_id=release_id) + ) browse_rel_link = gen_release_link(release_id) revision_metadata["release"] = release_id revision_metadata["context-independent release"] = browse_rel_link diff --git a/swh/web/browse/views/content.py b/swh/web/browse/views/content.py --- a/swh/web/browse/views/content.py +++ b/swh/web/browse/views/content.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2020 The Software Heritage developers +# Copyright (C) 2017-2021 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -12,7 +12,7 @@ from django.shortcuts import render from swh.model.hashutil import hash_to_hex -from swh.model.identifiers import CONTENT, DIRECTORY, RELEASE, REVISION, SNAPSHOT +from swh.model.identifiers import ObjectType from swh.web.browse.browseurls import browse_route from swh.web.browse.snapshot_context import get_snapshot_context from swh.web.browse.utils import ( @@ -208,7 +208,7 @@ release_name=request.GET.get("release"), revision_id=request.GET.get("revision"), path=path, - browse_context=CONTENT, + browse_context="content", ) except NotFoundExc as e: if str(e).startswith("Origin"): @@ -305,7 +305,7 @@ ) content_metadata = ContentMetadata( - object_type=CONTENT, + object_type=ObjectType.CONTENT, object_id=content_checksums.get("sha1_git"), sha1=content_checksums.get("sha1"), sha1_git=content_checksums.get("sha1_git"), @@ -327,27 +327,34 @@ ) swh_objects = [ - SWHObjectInfo(object_type=CONTENT, object_id=content_checksums.get("sha1_git")) + SWHObjectInfo( + object_type=ObjectType.CONTENT, object_id=content_checksums.get("sha1_git") + ) ] if directory_id: - swh_objects.append(SWHObjectInfo(object_type=DIRECTORY, object_id=directory_id)) + swh_objects.append( + SWHObjectInfo(object_type=ObjectType.DIRECTORY, object_id=directory_id) + ) if snapshot_context: swh_objects.append( SWHObjectInfo( - object_type=REVISION, object_id=snapshot_context["revision_id"] + object_type=ObjectType.REVISION, + object_id=snapshot_context["revision_id"], ) ) swh_objects.append( SWHObjectInfo( - object_type=SNAPSHOT, object_id=snapshot_context["snapshot_id"] + object_type=ObjectType.SNAPSHOT, + object_id=snapshot_context["snapshot_id"], ) ) if snapshot_context["release_id"]: swh_objects.append( SWHObjectInfo( - object_type=RELEASE, object_id=snapshot_context["release_id"] + object_type=ObjectType.RELEASE, + object_id=snapshot_context["release_id"], ) ) diff --git a/swh/web/browse/views/directory.py b/swh/web/browse/views/directory.py --- a/swh/web/browse/views/directory.py +++ b/swh/web/browse/views/directory.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2020 The Software Heritage developers +# Copyright (C) 2017-2021 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -10,7 +10,7 @@ from django.http import HttpResponse from django.shortcuts import redirect, render -from swh.model.identifiers import DIRECTORY, RELEASE, REVISION, SNAPSHOT +from swh.model.identifiers import ObjectType from swh.web.browse.browseurls import browse_route from swh.web.browse.snapshot_context import get_snapshot_context from swh.web.browse.utils import gen_link, get_directory_entries, get_readme_to_display @@ -135,7 +135,7 @@ readme_name, readme_url, readme_html = get_readme_to_display(readmes) dir_metadata = DirectoryMetadata( - object_type=DIRECTORY, + object_type=ObjectType.DIRECTORY, object_id=sha1_git, directory=root_sha1_git, nb_files=len(files), @@ -156,23 +156,26 @@ "revision_swhid": None, } - swh_objects = [SWHObjectInfo(object_type=DIRECTORY, object_id=sha1_git)] + swh_objects = [SWHObjectInfo(object_type=ObjectType.DIRECTORY, object_id=sha1_git)] if snapshot_context: swh_objects.append( SWHObjectInfo( - object_type=REVISION, object_id=snapshot_context["revision_id"] + object_type=ObjectType.REVISION, + object_id=snapshot_context["revision_id"], ) ) swh_objects.append( SWHObjectInfo( - object_type=SNAPSHOT, object_id=snapshot_context["snapshot_id"] + object_type=ObjectType.SNAPSHOT, + object_id=snapshot_context["snapshot_id"], ) ) if snapshot_context["release_id"]: swh_objects.append( SWHObjectInfo( - object_type=RELEASE, object_id=snapshot_context["release_id"] + object_type=ObjectType.RELEASE, + object_id=snapshot_context["release_id"], ) ) diff --git a/swh/web/browse/views/release.py b/swh/web/browse/views/release.py --- a/swh/web/browse/views/release.py +++ b/swh/web/browse/views/release.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2020 The Software Heritage developers +# Copyright (C) 2017-2021 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -7,7 +7,7 @@ from django.shortcuts import render -from swh.model.identifiers import CONTENT, DIRECTORY, RELEASE, REVISION, SNAPSHOT +from swh.model.identifiers import ObjectType from swh.web.browse.browseurls import browse_route from swh.web.browse.snapshot_context import get_snapshot_context from swh.web.browse.utils import ( @@ -81,7 +81,7 @@ snapshot_id = snapshot_context.get("snapshot_id", None) release_metadata = ReleaseMetadata( - object_type=RELEASE, + object_type=ObjectType.RELEASE, object_id=sha1_git, release=sha1_git, author=release["author"]["fullname"] if release["author"] else "None", @@ -101,13 +101,13 @@ if release["message"]: release_note_lines = release["message"].split("\n") - swh_objects = [SWHObjectInfo(object_type=RELEASE, object_id=sha1_git)] + swh_objects = [SWHObjectInfo(object_type=ObjectType.RELEASE, object_id=sha1_git)] vault_cooking = None rev_directory = None target_link = None - if release["target_type"] == REVISION: + if release["target_type"] == ObjectType.REVISION.name.lower(): target_link = gen_revision_link( release["target"], snapshot_context=snapshot_context, @@ -124,14 +124,16 @@ "revision_swhid": f"swh:1:rev:{release['target']}", } swh_objects.append( - SWHObjectInfo(object_type=REVISION, object_id=release["target"]) + SWHObjectInfo( + object_type=ObjectType.REVISION, object_id=release["target"] + ) ) swh_objects.append( - SWHObjectInfo(object_type=DIRECTORY, object_id=rev_directory) + SWHObjectInfo(object_type=ObjectType.DIRECTORY, object_id=rev_directory) ) except Exception as exc: sentry_sdk.capture_exception(exc) - elif release["target_type"] == DIRECTORY: + elif release["target_type"] == ObjectType.DIRECTORY.name.lower(): target_link = gen_directory_link( release["target"], snapshot_context=snapshot_context, @@ -148,11 +150,13 @@ "revision_swhid": None, } swh_objects.append( - SWHObjectInfo(object_type=DIRECTORY, object_id=release["target"]) + SWHObjectInfo( + object_type=ObjectType.DIRECTORY, object_id=release["target"] + ) ) except Exception as exc: sentry_sdk.capture_exception(exc) - elif release["target_type"] == CONTENT: + elif release["target_type"] == ObjectType.CONTENT.name.lower(): target_link = gen_content_link( release["target"], snapshot_context=snapshot_context, @@ -160,9 +164,9 @@ link_attrs=None, ) swh_objects.append( - SWHObjectInfo(object_type=CONTENT, object_id=release["target"]) + SWHObjectInfo(object_type=ObjectType.CONTENT, object_id=release["target"]) ) - elif release["target_type"] == RELEASE: + elif release["target_type"] == ObjectType.RELEASE.name.lower(): target_link = gen_release_link( release["target"], snapshot_context=snapshot_context, @@ -202,7 +206,9 @@ snapshot_id = snapshot_context["snapshot_id"] if snapshot_id: - swh_objects.append(SWHObjectInfo(object_type=SNAPSHOT, object_id=snapshot_id)) + swh_objects.append( + SWHObjectInfo(object_type=ObjectType.SNAPSHOT, object_id=snapshot_id) + ) swhids_info = get_swhids_info(swh_objects, snapshot_context) diff --git a/swh/web/browse/views/revision.py b/swh/web/browse/views/revision.py --- a/swh/web/browse/views/revision.py +++ b/swh/web/browse/views/revision.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2020 The Software Heritage developers +# Copyright (C) 2017-2021 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -12,14 +12,7 @@ from django.utils.safestring import mark_safe from swh.model.hashutil import hash_to_bytes -from swh.model.identifiers import ( - CONTENT, - DIRECTORY, - REVISION, - SNAPSHOT, - CoreSWHID, - ObjectType, -) +from swh.model.identifiers import CoreSWHID, ObjectType from swh.web.browse.browseurls import browse_route from swh.web.browse.snapshot_context import get_snapshot_context from swh.web.browse.utils import ( @@ -377,7 +370,7 @@ dirs, files = get_directory_entries(dir_id) revision_metadata = RevisionMetadata( - object_type=REVISION, + object_type=ObjectType.REVISION, object_id=sha1_git, revision=sha1_git, author=revision["author"]["fullname"] if revision["author"] else "None", @@ -448,7 +441,7 @@ "revision_swhid": f"swh:1:rev:{sha1_git}", } - swh_objects = [SWHObjectInfo(object_type=REVISION, object_id=sha1_git)] + swh_objects = [SWHObjectInfo(object_type=ObjectType.REVISION, object_id=sha1_git)] content = None content_size = None @@ -492,7 +485,7 @@ } swh_objects.append( - SWHObjectInfo(object_type=CONTENT, object_id=file_info["target"]) + SWHObjectInfo(object_type=ObjectType.CONTENT, object_id=file_info["target"]) ) else: for d in dirs: @@ -528,7 +521,9 @@ vault_cooking["directory_context"] = True vault_cooking["directory_swhid"] = f"swh:1:dir:{dir_id}" - swh_objects.append(SWHObjectInfo(object_type=DIRECTORY, object_id=dir_id)) + swh_objects.append( + SWHObjectInfo(object_type=ObjectType.DIRECTORY, object_id=dir_id) + ) query_params.pop("path", None) @@ -537,7 +532,9 @@ ) if snapshot_id: - swh_objects.append(SWHObjectInfo(object_type=SNAPSHOT, object_id=snapshot_id)) + swh_objects.append( + SWHObjectInfo(object_type=ObjectType.SNAPSHOT, object_id=snapshot_id) + ) swhids_info = get_swhids_info(swh_objects, snapshot_context, extra_context) diff --git a/swh/web/common/archive.py b/swh/web/common/archive.py --- a/swh/web/common/archive.py +++ b/swh/web/common/archive.py @@ -11,14 +11,7 @@ from urllib.parse import urlparse from swh.model import hashutil -from swh.model.identifiers import ( - CONTENT, - DIRECTORY, - RELEASE, - REVISION, - SNAPSHOT, - CoreSWHID, -) +from swh.model.identifiers import ObjectType, CoreSWHID from swh.model.model import OriginVisit, Revision from swh.storage.algos import diff, revisions_walker from swh.storage.algos.origin import origin_get_latest_visit_status @@ -26,7 +19,7 @@ from swh.vault.exc import NotFoundExc as VaultNotFoundExc from swh.web import config from swh.web.common import converters, query -from swh.web.common.exc import BadInputExc, NotFoundExc +from swh.web.common.exc import NotFoundExc from swh.web.common.typing import ( OriginInfo, OriginMetadataInfo, @@ -1331,7 +1324,7 @@ return _RevisionsWalkerProxy(rev_walker_type, rev_start, *args, **kwargs) -def lookup_object(object_type: str, object_id: str) -> Dict[str, Any]: +def lookup_object(object_type: ObjectType, object_id: str) -> Dict[str, Any]: """ Utility function for looking up an object in the archive by its type and id. @@ -1351,24 +1344,18 @@ the archive BadInputExc: if the object identifier is invalid """ - if object_type == CONTENT: + if object_type == ObjectType.CONTENT: return lookup_content(f"sha1_git:{object_id}") - elif object_type == DIRECTORY: + elif object_type == ObjectType.DIRECTORY: return {"id": object_id, "content": list(lookup_directory(object_id))} - elif object_type == RELEASE: + elif object_type == ObjectType.RELEASE: return lookup_release(object_id) - elif object_type == REVISION: + elif object_type == ObjectType.REVISION: return lookup_revision(object_id) - elif object_type == SNAPSHOT: + elif object_type == ObjectType.SNAPSHOT: return lookup_snapshot(object_id) - - raise BadInputExc( - ( - "Invalid swh object type! Valid types are " - f"{CONTENT}, {DIRECTORY}, {RELEASE} " - f"{REVISION} or {SNAPSHOT}." - ) - ) + else: + raise ValueError(f"Unexpected object type variant: {object_type}") def lookup_missing_hashes(grouped_swhids: Dict[str, List[bytes]]) -> Set[str]: @@ -1385,15 +1372,15 @@ missing_hashes = [] for obj_type, obj_ids in grouped_swhids.items(): - if obj_type == CONTENT: + if obj_type == ObjectType.CONTENT: missing_hashes.append(storage.content_missing_per_sha1_git(obj_ids)) - elif obj_type == DIRECTORY: + elif obj_type == ObjectType.DIRECTORY: missing_hashes.append(storage.directory_missing(obj_ids)) - elif obj_type == REVISION: + elif obj_type == ObjectType.REVISION: missing_hashes.append(storage.revision_missing(obj_ids)) - elif obj_type == RELEASE: + elif obj_type == ObjectType.RELEASE: missing_hashes.append(storage.release_missing(obj_ids)) - elif obj_type == SNAPSHOT: + elif obj_type == ObjectType.SNAPSHOT: missing_hashes.append(storage.snapshot_missing(obj_ids)) missing = set( diff --git a/swh/web/common/converters.py b/swh/web/common/converters.py --- a/swh/web/common/converters.py +++ b/swh/web/common/converters.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015-2020 The Software Heritage developers +# Copyright (C) 2015-2021 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -7,8 +7,11 @@ import json from typing import Any, Dict, Union +from django.core.serializers.json import DjangoJSONEncoder + from swh.core.utils import decode_with_escape from swh.model import hashutil +from swh.model.identifiers import ObjectType from swh.model.model import RawExtrinsicMetadata, Release, Revision from swh.storage.interface import PartialBranches from swh.web.common.typing import OriginInfo, OriginVisitInfo @@ -229,6 +232,17 @@ ) +class SWHDjangoJSONEncoder(DjangoJSONEncoder): + """Wrapper around DjangoJSONEncoder to serialize SWH-specific types + found in :class:`swh.web.common.typing.SWHObjectInfo`.""" + + def default(self, o): + if isinstance(o, ObjectType): + return o.name.lower() + else: + super().default(o) + + class SWHMetadataEncoder(json.JSONEncoder): """Special json encoder for metadata field which can contain bytes encoded value. diff --git a/swh/web/common/identifiers.py b/swh/web/common/identifiers.py --- a/swh/web/common/identifiers.py +++ b/swh/web/common/identifiers.py @@ -1,4 +1,4 @@ -# Copyright (C) 2020 The Software Heritage developers +# Copyright (C) 2020-2021 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -12,15 +12,7 @@ from swh.model.exceptions import ValidationError from swh.model.hashutil import hash_to_bytes, hash_to_hex -from swh.model.identifiers import ( - CONTENT, - DIRECTORY, - RELEASE, - REVISION, - SNAPSHOT, - ObjectType, - QualifiedSWHID, -) +from swh.model.identifiers import ObjectType, QualifiedSWHID from swh.web.common import archive from swh.web.common.exc import BadInputExc from swh.web.common.typing import ( @@ -33,8 +25,18 @@ from swh.web.common.utils import reverse +def parse_object_type(object_type: str) -> ObjectType: + try: + return ObjectType[object_type.upper()] + except KeyError: + valid_types = ", ".join(variant.name.lower() for variant in ObjectType) + raise BadInputExc( + f"Invalid swh object type! Valid types are {valid_types}; not {object_type}" + ) + + def gen_swhid( - object_type: str, + object_type: ObjectType, object_id: str, scheme_version: int = 1, metadata: SWHIDContext = {}, @@ -61,11 +63,10 @@ generate a valid identifier """ try: - decoded_object_type = ObjectType[object_type.upper()] decoded_object_id = hash_to_bytes(object_id) obj_swhid = str( QualifiedSWHID( - object_type=decoded_object_type, + object_type=object_type, object_id=decoded_object_id, scheme_version=scheme_version, **metadata, @@ -136,7 +137,7 @@ release = archive.lookup_release( hash_to_hex(swhid_parsed.anchor.object_id) ) - if release["target_type"] == REVISION: + if release["target_type"] == ObjectType.REVISION.name.lower(): revision = archive.lookup_revision(release["target"]) directory = revision["directory"] if object_type == ObjectType.CONTENT: @@ -241,7 +242,7 @@ raise BadInputExc("Error when parsing identifier: %s" % " ".join(ve.messages)) -def group_swhids(swhids: Iterable[QualifiedSWHID],) -> Dict[str, List[bytes]]: +def group_swhids(swhids: Iterable[QualifiedSWHID],) -> Dict[ObjectType, List[bytes]]: """ Groups many SoftWare Heritage persistent IDentifiers into a dictionary depending on their type. @@ -255,18 +256,18 @@ keys: object types values: object hashes """ - swhids_by_type: Dict[str, List[bytes]] = { - CONTENT: [], - DIRECTORY: [], - REVISION: [], - RELEASE: [], - SNAPSHOT: [], + swhids_by_type: Dict[ObjectType, List[bytes]] = { + ObjectType.CONTENT: [], + ObjectType.DIRECTORY: [], + ObjectType.REVISION: [], + ObjectType.RELEASE: [], + ObjectType.SNAPSHOT: [], } for obj_swhid in swhids: obj_id = obj_swhid.object_id obj_type = obj_swhid.object_type - swhids_by_type[obj_type.name.lower()].append(hash_to_bytes(obj_id)) + swhids_by_type[obj_type].append(hash_to_bytes(obj_id)) return swhids_by_type @@ -313,47 +314,49 @@ swhid_context["origin"] = quote( snapshot_context["origin_info"]["url"], safe="/?:@&" ) - if object_type != SNAPSHOT: + if object_type != ObjectType.SNAPSHOT: swhid_context["visit"] = gen_swhid( - SNAPSHOT, snapshot_context["snapshot_id"] + ObjectType.SNAPSHOT, snapshot_context["snapshot_id"] ) - if object_type in (CONTENT, DIRECTORY): + if object_type in (ObjectType.CONTENT, ObjectType.DIRECTORY): if snapshot_context["release_id"] is not None: swhid_context["anchor"] = gen_swhid( - RELEASE, snapshot_context["release_id"] + ObjectType.RELEASE, snapshot_context["release_id"] ) elif snapshot_context["revision_id"] is not None: swhid_context["anchor"] = gen_swhid( - REVISION, snapshot_context["revision_id"] + ObjectType.REVISION, snapshot_context["revision_id"] ) - if object_type in (CONTENT, DIRECTORY): + if object_type in (ObjectType.CONTENT, ObjectType.DIRECTORY): if ( extra_context and "revision" in extra_context and extra_context["revision"] and "anchor" not in swhid_context ): - swhid_context["anchor"] = gen_swhid(REVISION, extra_context["revision"]) + swhid_context["anchor"] = gen_swhid( + ObjectType.REVISION, extra_context["revision"] + ) elif ( extra_context and "root_directory" in extra_context and extra_context["root_directory"] and "anchor" not in swhid_context and ( - object_type != DIRECTORY + object_type != ObjectType.DIRECTORY or extra_context["root_directory"] != object_id ) ): swhid_context["anchor"] = gen_swhid( - DIRECTORY, extra_context["root_directory"] + ObjectType.DIRECTORY, extra_context["root_directory"] ) path = None if extra_context and "path" in extra_context: path = extra_context["path"] or "/" - if "filename" in extra_context and object_type == CONTENT: + if "filename" in extra_context and object_type == ObjectType.CONTENT: path += extra_context["filename"] - if object_type == DIRECTORY and path == "/": + if object_type == ObjectType.DIRECTORY and path == "/": path = None if path: swhid_context["path"] = quote(path, safe="/?:@&") diff --git a/swh/web/common/swh_templatetags.py b/swh/web/common/swh_templatetags.py --- a/swh/web/common/swh_templatetags.py +++ b/swh/web/common/swh_templatetags.py @@ -7,9 +7,9 @@ import re from django import template -from django.core.serializers.json import DjangoJSONEncoder from django.utils.safestring import mark_safe +from swh.web.common.converters import SWHDjangoJSONEncoder from swh.web.common.origin_save import get_savable_visit_types from swh.web.common.utils import rst_to_html @@ -79,7 +79,7 @@ JSON representation of the variable. """ - return mark_safe(json.dumps(obj, cls=DjangoJSONEncoder)) + return mark_safe(json.dumps(obj, cls=SWHDjangoJSONEncoder)) @register.filter diff --git a/swh/web/common/typing.py b/swh/web/common/typing.py --- a/swh/web/common/typing.py +++ b/swh/web/common/typing.py @@ -10,6 +10,7 @@ from django.http import QueryDict from swh.core.api.classes import PagedResult as CorePagedResult +from swh.model.identifiers import ObjectType QueryParameters = Union[Dict[str, Any], QueryDict] @@ -133,7 +134,7 @@ class SWHObjectInfo(TypedDict): - object_type: str + object_type: ObjectType object_id: str diff --git a/swh/web/misc/badges.py b/swh/web/misc/badges.py --- a/swh/web/misc/badges.py +++ b/swh/web/misc/badges.py @@ -1,4 +1,4 @@ -# Copyright (C) 2019-2020 The Software Heritage developers +# Copyright (C) 2019-2021 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -14,10 +14,10 @@ from swh.model.exceptions import ValidationError from swh.model.hashutil import hash_to_bytes, hash_to_hex -from swh.model.identifiers import RELEASE, CoreSWHID, ObjectType, QualifiedSWHID +from swh.model.identifiers import CoreSWHID, ObjectType, QualifiedSWHID from swh.web.common import archive from swh.web.common.exc import BadInputExc, NotFoundExc -from swh.web.common.identifiers import resolve_swhid +from swh.web.common.identifiers import parse_object_type, resolve_swhid from swh.web.common.utils import reverse _orange = "#f36a24" @@ -92,9 +92,9 @@ # from it if object_swhid: parsed_swhid = QualifiedSWHID.from_string(object_swhid) - object_type = parsed_swhid.object_type.name.lower() + parsed_object_type = parsed_swhid.object_type object_id = hash_to_hex(parsed_swhid.object_id) - swh_object = archive.lookup_object(object_type, object_id) + swh_object = archive.lookup_object(parsed_swhid.object_type, object_id) # remove SWHID qualified if any for badge text right_text = str( CoreSWHID( @@ -102,18 +102,20 @@ object_id=parsed_swhid.object_id, ) ) + object_type = parsed_swhid.object_type.name.lower() else: + parsed_object_type = parse_object_type(object_type) right_text = str( CoreSWHID( - object_type=ObjectType[object_type.upper()], + object_type=parsed_object_type, object_id=hash_to_bytes(object_id), ) ) - swh_object = archive.lookup_object(object_type, object_id) + swh_object = archive.lookup_object(parsed_object_type, object_id) whole_link = resolve_swhid(str(right_text))["browse_url"] # use release name for badge text - if object_type == RELEASE: + if parsed_object_type == ObjectType.RELEASE: right_text = "release %s" % swh_object["name"] left_text = "archived" except (BadInputExc, ValidationError): 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 @@ -10,14 +10,7 @@ from django.views.decorators.clickjacking import xframe_options_exempt from swh.model.hashutil import hash_to_bytes -from swh.model.identifiers import ( - CONTENT, - DIRECTORY, - REVISION, - SNAPSHOT, - ObjectType, - QualifiedSWHID, -) +from swh.model.identifiers import ObjectType, QualifiedSWHID from swh.web.browse.snapshot_context import get_snapshot_context from swh.web.browse.utils import ( content_display_max_size, @@ -220,7 +213,8 @@ view_data = _get_content_rendering_data(parsed_swhid, path) swh_objects.append( SWHObjectInfo( - object_type=CONTENT, object_id=parsed_swhid.object_id.hex() + object_type=ObjectType.CONTENT, + object_id=parsed_swhid.object_id.hex(), ) ) @@ -230,7 +224,8 @@ ) swh_objects.append( SWHObjectInfo( - object_type=DIRECTORY, object_id=parsed_swhid.object_id.hex() + object_type=ObjectType.DIRECTORY, + object_id=parsed_swhid.object_id.hex(), ) ) @@ -251,7 +246,8 @@ if parsed_swhid.object_type == ObjectType.CONTENT and len(breadcrumbs) > 1: swh_objects.append( SWHObjectInfo( - object_type=DIRECTORY, object_id=breadcrumbs[-2]["object_id"] + object_type=ObjectType.DIRECTORY, + object_id=breadcrumbs[-2]["object_id"], ) ) swhids_info_extra_context["path"] = breadcrumbs[-2]["path"] @@ -260,13 +256,13 @@ if snapshot_context: swh_objects.append( SWHObjectInfo( - object_type=REVISION, + object_type=ObjectType.REVISION, object_id=snapshot_context["revision_id"] or "", ) ) swh_objects.append( SWHObjectInfo( - object_type=SNAPSHOT, + object_type=ObjectType.SNAPSHOT, object_id=snapshot_context["snapshot_id"] or "", ) ) diff --git a/swh/web/templates/includes/show-metadata.html b/swh/web/templates/includes/show-metadata.html --- a/swh/web/templates/includes/show-metadata.html +++ b/swh/web/templates/includes/show-metadata.html @@ -1,5 +1,5 @@ {% comment %} -Copyright (C) 2017-2020 The Software Heritage developers +Copyright (C) 2017-2021 The Software Heritage developers See the AUTHORS file at the top-level directory of this distribution License: GNU Affero General Public License version 3, or any later version See top-level LICENSE file for more information @@ -38,7 +38,7 @@