diff options
author | 2023-12-13 09:07:08 +0100 | |
---|---|---|
committer | 2023-12-17 14:34:07 +0100 | |
commit | a908b9aa3a18222f296c0e4bd67d815f48ada5af (patch) | |
tree | f89afe69e35694ca740f5921627ff91a76f272d3 /pydis_site/apps/api/viewsets | |
parent | Merge pull request #1175 from python-discord/dependabot/pip/ruff-0.1.8 (diff) |
Migrate mailing lists to their own API endpoints
Add a new model for the bot to store its mailing list state in, as
opposed to the current JSON blob in the BotSetting table. Migrate the
existing settings from the BotSetting table into the new model.
Diffstat (limited to 'pydis_site/apps/api/viewsets')
-rw-r--r-- | pydis_site/apps/api/viewsets/__init__.py | 7 | ||||
-rw-r--r-- | pydis_site/apps/api/viewsets/bot/__init__.py | 10 | ||||
-rw-r--r-- | pydis_site/apps/api/viewsets/bot/mailing_list.py | 97 |
3 files changed, 105 insertions, 9 deletions
diff --git a/pydis_site/apps/api/viewsets/__init__.py b/pydis_site/apps/api/viewsets/__init__.py index 1dae9be1..a28fa8e3 100644 --- a/pydis_site/apps/api/viewsets/__init__.py +++ b/pydis_site/apps/api/viewsets/__init__.py @@ -1,17 +1,18 @@ # flake8: noqa from .bot import ( + AocAccountLinkViewSet, + AocCompletionistBlockViewSet, BotSettingViewSet, BumpedThreadViewSet, DeletedMessageViewSet, DocumentationLinkViewSet, FilterListViewSet, - InfractionViewSet, FilterListViewSet, FilterViewSet, + InfractionViewSet, + MailingListViewSet, NominationViewSet, OffensiveMessageViewSet, - AocAccountLinkViewSet, - AocCompletionistBlockViewSet, OffTopicChannelNameViewSet, ReminderViewSet, RoleViewSet, diff --git a/pydis_site/apps/api/viewsets/bot/__init__.py b/pydis_site/apps/api/viewsets/bot/__init__.py index 33b65009..bb26cb11 100644 --- a/pydis_site/apps/api/viewsets/bot/__init__.py +++ b/pydis_site/apps/api/viewsets/bot/__init__.py @@ -1,18 +1,16 @@ # flake8: noqa -from .filters import ( - FilterListViewSet, - FilterViewSet -) +from .aoc_completionist_block import AocCompletionistBlockViewSet +from .aoc_link import AocAccountLinkViewSet from .bot_setting import BotSettingViewSet from .bumped_thread import BumpedThreadViewSet from .deleted_message import DeletedMessageViewSet from .documentation_link import DocumentationLinkViewSet +from .filters import FilterListViewSet, FilterViewSet from .infraction import InfractionViewSet +from .mailing_list import MailingListViewSet from .nomination import NominationViewSet from .off_topic_channel_name import OffTopicChannelNameViewSet from .offensive_message import OffensiveMessageViewSet -from .aoc_link import AocAccountLinkViewSet -from .aoc_completionist_block import AocCompletionistBlockViewSet from .reminder import ReminderViewSet from .role import RoleViewSet from .user import UserViewSet diff --git a/pydis_site/apps/api/viewsets/bot/mailing_list.py b/pydis_site/apps/api/viewsets/bot/mailing_list.py new file mode 100644 index 00000000..e46dfd4c --- /dev/null +++ b/pydis_site/apps/api/viewsets/bot/mailing_list.py @@ -0,0 +1,97 @@ +from django.db import IntegrityError +from rest_framework import status +from rest_framework.decorators import action +from rest_framework.exceptions import ParseError +from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin +from rest_framework.request import Request +from rest_framework.response import Response +from rest_framework.viewsets import GenericViewSet + +from pydis_site.apps.api.serializers import MailingListSerializer +from pydis_site.apps.api.models import MailingList, MailingListSeenItem + + +class MailingListViewSet(GenericViewSet, CreateModelMixin, ListModelMixin, RetrieveModelMixin): + """ + View providing management and updates of mailing lists and their seen items. + + ## Routes + + ### GET /bot/mailing-lists + Returns all the mailing lists and their seen items. + + #### Response format + >>> [ + ... { + ... 'id': 1, + ... 'name': 'python-dev', + ... 'seen_items': [ + ... 'd81gg90290la8', + ... ... + ... ] + ... }, + ... ... + ... ] + + ### POST /bot/mailing-lists + Create a new mailing list. + + #### Request format + >>> { + ... 'name': str + ... } + + #### Status codes + - 201: when the mailing list was created successfully + - 400: if the request data was invalid + + ### GET /bot/mailing-lists/<name:str> + Retrieve a single mailing list and its seen items. + + #### Response format + >>> { + ... 'id': 1, + ... 'name': 'python-dev', + ... 'seen_items': [ + ... 'd81gg90290la8', + ... ... + ... ] + ... } + + ### POST /bot/mailing-lists/<name:str>/seen-items + Add a single seen item to the given mailing list. The request body should + be the hash of the seen item to add, as a plain string. + + #### Request body + >>> str + + #### Response format + Empty response. + + #### Status codes + - 204: on successful creation of the seen item + - 400: if the request data was invalid + - 404: when the mailing list with the given name could not be found + """ + + lookup_field = 'name' + serializer_class = MailingListSerializer + queryset = MailingList.objects.prefetch_related('seen_items') + + @action(detail=True, methods=["POST"], + name="Add a seen item for a mailing list", url_name='seen-items', url_path='seen-items') + def add_seen_item(self, request: Request, name: str) -> Response: + """Add a single seen item to the given mailing list.""" + if not isinstance(request.data, str): + raise ParseError(detail={'non_field_errors': ["The request body must be a string"]}) + + list_ = self.get_object() + seen_item = MailingListSeenItem(list=list_, hash=request.data) + try: + seen_item.save() + except IntegrityError as err: + if err.__cause__.diag.constraint_name == 'unique_list_and_hash': + raise ParseError(detail={'non_field_errors': ["Seen item already known."]}) + raise # pragma: no cover + + return Response(status=status.HTTP_204_NO_CONTENT) |