Changeset View
Changeset View
Standalone View
Standalone View
swh/web/common/utils.py
# Copyright (C) 2017-2022 The Software Heritage developers | # Copyright (C) 2017-2022 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 datetime import datetime, timezone | from datetime import datetime, timezone | ||||
import functools | import functools | ||||
import os | import os | ||||
import re | import re | ||||
from typing import Any, Callable, Dict, List, Optional | from typing import Any, Callable, Dict, List, Mapping, Optional | ||||
import urllib.parse | import urllib.parse | ||||
from bs4 import BeautifulSoup | from bs4 import BeautifulSoup | ||||
from docutils.core import publish_parts | from docutils.core import publish_parts | ||||
import docutils.parsers.rst | import docutils.parsers.rst | ||||
import docutils.utils | import docutils.utils | ||||
from docutils.writers.html5_polyglot import HTMLTranslator, Writer | from docutils.writers.html5_polyglot import HTMLTranslator, Writer | ||||
from iso8601 import ParseError, parse_date | from iso8601 import ParseError, parse_date | ||||
Show All 10 Lines | |||||
from django.urls import reverse as django_reverse | from django.urls import reverse as django_reverse | ||||
from swh.web.auth.utils import ( | from swh.web.auth.utils import ( | ||||
ADD_FORGE_MODERATOR_PERMISSION, | ADD_FORGE_MODERATOR_PERMISSION, | ||||
ADMIN_LIST_DEPOSIT_PERMISSION, | ADMIN_LIST_DEPOSIT_PERMISSION, | ||||
MAILMAP_ADMIN_PERMISSION, | MAILMAP_ADMIN_PERMISSION, | ||||
) | ) | ||||
from swh.web.common.exc import BadInputExc, sentry_capture_exception | from swh.web.common.exc import BadInputExc, sentry_capture_exception | ||||
from swh.web.common.typing import QueryParameters | |||||
from swh.web.config import SWH_WEB_SERVER_NAME, get_config, search | from swh.web.config import SWH_WEB_SERVER_NAME, get_config, search | ||||
SWH_WEB_METRICS_REGISTRY = CollectorRegistry(auto_describe=True) | SWH_WEB_METRICS_REGISTRY = CollectorRegistry(auto_describe=True) | ||||
SWHID_RE = "swh:1:[a-z]{3}:[0-9a-z]{40}" | SWHID_RE = "swh:1:[a-z]{3}:[0-9a-z]{40}" | ||||
swh_object_icons = { | swh_object_icons = { | ||||
"alias": "mdi mdi-star", | "alias": "mdi mdi-star", | ||||
Show All 16 Lines | swh_object_icons = { | ||||
"snp": "mdi mdi-camera", | "snp": "mdi mdi-camera", | ||||
"visits": "mdi mdi-calendar-month", | "visits": "mdi mdi-calendar-month", | ||||
} | } | ||||
def reverse( | def reverse( | ||||
viewname: str, | viewname: str, | ||||
url_args: Optional[Dict[str, Any]] = None, | url_args: Optional[Dict[str, Any]] = None, | ||||
query_params: Optional[QueryParameters] = None, | query_params: Optional[Mapping[str, Optional[str]]] = None, | ||||
current_app: Optional[str] = None, | current_app: Optional[str] = None, | ||||
urlconf: Optional[str] = None, | urlconf: Optional[str] = None, | ||||
request: Optional[HttpRequest] = None, | request: Optional[HttpRequest] = None, | ||||
) -> str: | ) -> str: | ||||
"""An override of django reverse function supporting query parameters. | """An override of django reverse function supporting query parameters. | ||||
Args: | Args: | ||||
viewname: the name of the django view from which to compute a url | viewname: the name of the django view from which to compute a url | ||||
Show All 11 Lines | ) -> str: | ||||
if url_args: | if url_args: | ||||
url_args = {k: v for k, v in url_args.items() if v is not None} | url_args = {k: v for k, v in url_args.items() if v is not None} | ||||
url = django_reverse( | url = django_reverse( | ||||
viewname, urlconf=urlconf, kwargs=url_args, current_app=current_app | viewname, urlconf=urlconf, kwargs=url_args, current_app=current_app | ||||
) | ) | ||||
params: Dict[str, str] = {} | |||||
if query_params: | if query_params: | ||||
query_params = {k: v for k, v in query_params.items() if v is not None} | params = {k: v for k, v in query_params.items() if v is not None} | ||||
if query_params and len(query_params) > 0: | if params: | ||||
query_dict = QueryDict("", mutable=True) | query_dict = QueryDict("", mutable=True) | ||||
for k in sorted(query_params.keys()): | query_dict.update(dict(sorted(params.items()))) | ||||
query_dict[k] = str(query_params[k]) | |||||
url += "?" + query_dict.urlencode(safe="/;:") | url += "?" + query_dict.urlencode(safe="/;:") | ||||
vlorentz: ditto | |||||
Done Inline Actionssame as above plus here we ensure parameters are sorted by their names. anlambert: same as above plus here we ensure parameters are sorted by their names. | |||||
Not Done Inline Actionsyou can do the same here: query_dict.update(sorted(params.items())) or even query_dict = dict(sorted(params.items()) vlorentz: you can do the same here: `query_dict.update(sorted(params.items()))` or even `query_dict =… | |||||
if request is not None: | if request is not None: | ||||
url = request.build_absolute_uri(url) | url = request.build_absolute_uri(url) | ||||
return url | return url | ||||
def datetime_to_utc(date): | def datetime_to_utc(date): | ||||
▲ Show 20 Lines • Show All 407 Lines • Show Last 20 Lines |
ditto