aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps/api/viewsets
diff options
context:
space:
mode:
authorGravatar Johannes Christ <[email protected]>2023-12-13 09:07:08 +0100
committerGravatar Johannes Christ <[email protected]>2023-12-17 14:34:07 +0100
commita908b9aa3a18222f296c0e4bd67d815f48ada5af (patch)
treef89afe69e35694ca740f5921627ff91a76f272d3 /pydis_site/apps/api/viewsets
parentMerge 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__.py7
-rw-r--r--pydis_site/apps/api/viewsets/bot/__init__.py10
-rw-r--r--pydis_site/apps/api/viewsets/bot/mailing_list.py97
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)