Source code for web.mixins.CustomActionMixin

# SPDX-License-Identifier: AGPL-3.0-or-later
#
# Eonvelope - a open-source self-hostable email archiving server
# Copyright (C) 2024 David Aderbauer & The Eonvelope Contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

"""Module with :class:`web.mixins.CustomActionMixin`."""

from typing import Final

from django.core.exceptions import ImproperlyConfigured
from django.http import HttpRequest, HttpResponse
from rest_framework import status


[docs] class CustomActionMixin: """Mixin to provide action button handling for views. To register handlers for the different actions define a viewclass method `handle_action` that creates the appropriate response to a `action` post request. """ _handler_method_prefix: Final[str] = "handle_" """The name prefix of methods considered request handlers."""
[docs] def post(self, request: HttpRequest) -> HttpResponse: """Creates response to a post request. If no action matches the existing handlers, responds with Http204. Should be executed last in a custom view post method. Args: request: The post request to handle. Returns: The handlers response to the request. If no matching handler is found Http204. Raises: ImproperlyConfigured: If the called handler method does not return a :class:`django.http.HttpResponse`.> """ for attr in dir(self): if ( attr.startswith(self._handler_method_prefix) and attr.removeprefix(self._handler_method_prefix) in request.POST ): response = getattr(self, attr)(request) if isinstance(response, HttpResponse): return response raise ImproperlyConfigured( f"The custom action handler {attr} did not return a HttpResponse!" ) return HttpResponse(status=status.HTTP_204_NO_CONTENT)