Changeset View
Changeset View
Standalone View
Standalone View
swh/web/common/utils.py
# Copyright (C) 2017-2020 The Software Heritage developers | # Copyright (C) 2017-2020 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 docutils.parsers.rst | |||||
import docutils.utils | |||||
import re | import re | ||||
from datetime import datetime, timezone | from datetime import datetime, timezone | ||||
from dateutil import parser as date_parser | from dateutil import parser as date_parser | ||||
from dateutil import tz | from dateutil import tz | ||||
from typing import Optional, Dict, Any | from typing import Optional, Dict, Any | ||||
import docutils.parsers.rst | |||||
import docutils.utils | |||||
from docutils.core import publish_parts | |||||
from docutils.writers.html5_polyglot import Writer, HTMLTranslator | |||||
from django.urls import reverse as django_reverse | from django.urls import reverse as django_reverse | ||||
from django.http import QueryDict, HttpRequest | from django.http import QueryDict, HttpRequest | ||||
from prometheus_client.registry import CollectorRegistry | from prometheus_client.registry import CollectorRegistry | ||||
from rest_framework.authentication import SessionAuthentication | from rest_framework.authentication import SessionAuthentication | ||||
from swh.model.exceptions import ValidationError | from swh.model.exceptions import ValidationError | ||||
▲ Show 20 Lines • Show All 320 Lines • ▼ Show 20 Lines | def context_processor(request): | ||||
} | } | ||||
class EnforceCSRFAuthentication(SessionAuthentication): | class EnforceCSRFAuthentication(SessionAuthentication): | ||||
""" | """ | ||||
Helper class to enforce CSRF validation on a DRF view | Helper class to enforce CSRF validation on a DRF view | ||||
when a user is not authenticated. | when a user is not authenticated. | ||||
""" | """ | ||||
def authenticate(self, request): | def authenticate(self, request): | ||||
user = getattr(request._request, 'user', None) | user = getattr(request._request, 'user', None) | ||||
self.enforce_csrf(request) | self.enforce_csrf(request) | ||||
return (user, None) | return (user, None) | ||||
def resolve_branch_alias(snapshot: Dict[str, Any], | def resolve_branch_alias(snapshot: Dict[str, Any], | ||||
branch: Optional[Dict[str, Any]] | branch: Optional[Dict[str, Any]] | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | Returns: | ||||
keys: persistent identifier types | keys: persistent identifier types | ||||
values: list(bytes) persistent identifiers id | values: list(bytes) persistent identifiers id | ||||
Raises: | Raises: | ||||
BadInputExc: if one of the provided persistent identifier can | BadInputExc: if one of the provided persistent identifier can | ||||
not be parsed. | not be parsed. | ||||
""" | """ | ||||
pids_by_type = { | pids_by_type = { | ||||
CONTENT: [], | CONTENT: [], | ||||
DIRECTORY: [], | DIRECTORY: [], | ||||
REVISION: [], | REVISION: [], | ||||
RELEASE: [], | RELEASE: [], | ||||
SNAPSHOT: [] | SNAPSHOT: [] | ||||
} | } | ||||
for pid in persistent_ids: | for pid in persistent_ids: | ||||
obj_id = pid.object_id | obj_id = pid.object_id | ||||
obj_type = pid.object_type | obj_type = pid.object_type | ||||
pids_by_type[obj_type].append(hash_to_bytes(obj_id)) | pids_by_type[obj_type].append(hash_to_bytes(obj_id)) | ||||
return pids_by_type | return pids_by_type | ||||
class _NoHeaderHTMLTranslator(HTMLTranslator): | |||||
""" | |||||
Docutils translator subclass to customize the generation of HTML | |||||
from reST-formatted docstrings | |||||
""" | |||||
def __init__(self, document): | |||||
super().__init__(document) | |||||
self.body_prefix = [] | |||||
self.body_suffix = [] | |||||
_HTML_WRITER = Writer() | |||||
_HTML_WRITER.translator_class = _NoHeaderHTMLTranslator | |||||
def rst_to_html(rst: str) -> str: | |||||
""" | |||||
Convert reStructuredText document into HTML. | |||||
Args: | |||||
rst: A string containing a reStructuredText document | |||||
Returns: | |||||
Body content of the produced HTML conversion. | |||||
""" | |||||
settings = { | |||||
'initial_header_level': 2, | |||||
} | |||||
pp = publish_parts(rst, writer=_HTML_WRITER, | |||||
settings_overrides=settings) | |||||
return f'<div class="swh-rst">{pp["html_body"]}</div>' |