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