Source code for gpf_instance.views

from pathlib import Path
from typing import Any

from datasets_api.permissions import get_instance_timestamp_etag
from django.utils.decorators import method_decorator
from django.views.decorators.http import etag
from query_base.query_base import QueryBaseView
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.request import Request
from rest_framework.response import Response

from dae import __version__ as VERSION  # type: ignore
from gpf_instance.gpf_instance import (
    calc_and_set_cacheable_hash,
    get_cacheable_hash,
)


[docs] @api_view(["GET"]) @etag(get_instance_timestamp_etag) def version(_request: Request) -> Response: """Get GPF version.""" return Response( {"version": VERSION}, status=status.HTTP_200_OK, )
[docs] def get_description_etag( _request: Request, **_kwargs: dict[str, Any], ) -> str | None: return get_cacheable_hash("instance_description")
[docs] def get_about_etag( _request: Request, **_kwargs: dict[str, Any], ) -> str | None: return get_cacheable_hash("instance_about")
[docs] class MarkdownFileView(QueryBaseView): """Provide fetching and editing markdown files.""" CONTENT_ID = "placeholder_id" def __init__(self) -> None: super().__init__() self.filepath: str | None = None
[docs] def get(self, _request: Request) -> Response: # pylint: disable=unused-argument """Collect the application description.""" if self.filepath is None: return Response( {"error": "Route incorrectly configured"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, ) try: content = Path(self.filepath).read_text() except FileNotFoundError: return Response( {"error": "File not found"}, status=status.HTTP_404_NOT_FOUND, ) if get_cacheable_hash(self.CONTENT_ID) is None: calc_and_set_cacheable_hash(self.CONTENT_ID, content) return Response( {"content": content}, status=status.HTTP_200_OK, )
[docs] def post(self, request: Request) -> Response: """Overwrite the application description.""" if self.filepath is None: return Response( {"error": "Route incorrectly configured"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, ) if not request.user.is_staff: return Response( {"error": "You have no permission to edit the content."}, status=status.HTTP_403_FORBIDDEN, ) try: Path(self.filepath).write_text(request.data.get("content")) except PermissionError: return Response( {"error": "Failed to write to file"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, ) calc_and_set_cacheable_hash( self.CONTENT_ID, request.data.get("content"), ) return Response(status=status.HTTP_200_OK)
[docs] class DescriptionView(MarkdownFileView): """Provide fetching and editing the main application description.""" CONTENT_ID = "instance_description" def __init__(self) -> None: super().__init__() self.filepath = self.gpf_instance.get_main_description_path()
[docs] @method_decorator(etag(get_description_etag)) def get(self, _request: Request) -> Response: return super().get(_request)
[docs] class AboutDescriptionView(MarkdownFileView): """Provide fetching and editing the main application description.""" CONTENT_ID = "instance_about" def __init__(self) -> None: super().__init__() self.filepath = self.gpf_instance.get_about_description_path()
[docs] @method_decorator(etag(get_about_etag)) def get(self, _request: Request) -> Response: return super().get(_request)