Source code for swh.web.utils.urlsindex
# Copyright (C) 2017-2022  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
from typing import Callable, List
from django.http.response import HttpResponseBase
from django.shortcuts import redirect
from django.urls import URLPattern, path, re_path
[docs]
class UrlsIndex:
    """Simple helper class for centralizing URL patterns of a Django web application."""
    def __init__(self):
        self.urlpatterns: List[URLPattern] = []
[docs]
    def add_url_pattern(
        self,
        url_pattern: str,
        view: Callable[..., HttpResponseBase],
        view_name: str = "",
    ) -> None:
        """
        Adds an URL pattern.
        Args:
            url_pattern: string or regex describing a Django URL
            view: function implementing the Django view
            view_name: name of the view used to reverse the URL
        """
        if "(?P<" in url_pattern:
            url = re_path
            assert not url_pattern.startswith("^")
            assert not url_pattern.endswith("$")
            pattern = "^" + url_pattern + "$"
        else:
            url = path
            pattern = url_pattern
        if view_name:
            self.urlpatterns.append(url(pattern, view, name=view_name))
        else:
            self.urlpatterns.append(url(pattern, view)) 
[docs]
    def add_redirect_for_checksum_args(
        self, view_name: str, url_patterns: List[str], checksum_args: List[str]
    ) -> None:
        """
        Adds redirection to view with lowercase checksums when upper/mixed case
        checksums are passed as url arguments.
        Args:
            view_name: name of the view to redirect requests
            url_patterns: regexps describing the view URLs
            checksum_args: url argument names corresponding to checksum values
        """
        new_view_name = view_name + "-uppercase-checksum"
        for url_pattern in url_patterns:
            url_pattern_upper = url_pattern.replace("[0-9a-f]", "[0-9a-fA-F]")
            def view_redirect(request, *args, **kwargs):
                for checksum_arg in checksum_args:
                    checksum_upper = kwargs[checksum_arg]
                    kwargs[checksum_arg] = checksum_upper.lower()
                return redirect(view_name, *args, **kwargs)
            self.add_url_pattern(url_pattern_upper, view_redirect, new_view_name) 
[docs]
    def get_url_patterns(self) -> List[URLPattern]:
        """
        Returns the list of registered URL patterns.
        """
        return self.urlpatterns