aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps/api/viewsets
diff options
context:
space:
mode:
authorGravatar Rohan Reddy Alleti <[email protected]>2021-06-10 02:32:50 +0530
committerGravatar GitHub <[email protected]>2021-06-10 02:32:50 +0530
commitc444b82e20bda8b3ba27ca31ecab3135edc4f289 (patch)
tree8933c7928e19b8923d5c78e8022e7df3666e9650 /pydis_site/apps/api/viewsets
parentUse assertListEqual where applicable instead of assertEqual. (diff)
parentMerge pull request #524 from python-discord/swfarnsworth/resource_suggestion_... (diff)
Merge branch 'main' into otn_softdel
Diffstat (limited to 'pydis_site/apps/api/viewsets')
-rw-r--r--pydis_site/apps/api/viewsets/bot/infraction.py73
1 files changed, 73 insertions, 0 deletions
diff --git a/pydis_site/apps/api/viewsets/bot/infraction.py b/pydis_site/apps/api/viewsets/bot/infraction.py
index bd512ddd..f8b0cb9d 100644
--- a/pydis_site/apps/api/viewsets/bot/infraction.py
+++ b/pydis_site/apps/api/viewsets/bot/infraction.py
@@ -1,3 +1,6 @@
+from datetime import datetime
+
+from django.db.models import QuerySet
from django.http.request import HttpRequest
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.decorators import action
@@ -43,10 +46,17 @@ class InfractionViewSet(
- **offset** `int`: the initial index from which to return the results (default 0)
- **search** `str`: regular expression applied to the infraction's reason
- **type** `str`: the type of the infraction
+ - **types** `str`: comma separated sequence of types to filter for
- **user__id** `int`: snowflake of the user to which the infraction was applied
- **ordering** `str`: comma-separated sequence of fields to order the returned results
+ - **permanent** `bool`: whether or not to retrieve permanent infractions (default True)
+ - **expires_after** `isodatetime`: the earliest expires_at time to return infractions for
+ - **expires_before** `isodatetime`: the latest expires_at time to return infractions for
Invalid query parameters are ignored.
+ Only one of `type` and `types` may be provided. If both `expires_before` and `expires_after`
+ are provided, `expires_after` must come after `expires_before`.
+ If `permanent` is provided and true, `expires_before` and `expires_after` must not be provided.
#### Response format
Response is paginated but the result is returned without any pagination metadata.
@@ -156,6 +166,69 @@ class InfractionViewSet(
return Response(serializer.data)
+ def get_queryset(self) -> QuerySet:
+ """
+ Called to fetch the initial queryset, used to implement some of the more complex filters.
+
+ This provides the `permanent` and the `expires_gte` and `expires_lte` options.
+ """
+ filter_permanent = self.request.query_params.get('permanent')
+ additional_filters = {}
+ if filter_permanent is not None:
+ additional_filters['expires_at__isnull'] = filter_permanent.lower() == 'true'
+
+ filter_expires_after = self.request.query_params.get('expires_after')
+ if filter_expires_after:
+ try:
+ additional_filters['expires_at__gte'] = datetime.fromisoformat(
+ filter_expires_after
+ )
+ except ValueError:
+ raise ValidationError({'expires_after': ['failed to convert to datetime']})
+
+ filter_expires_before = self.request.query_params.get('expires_before')
+ if filter_expires_before:
+ try:
+ additional_filters['expires_at__lte'] = datetime.fromisoformat(
+ filter_expires_before
+ )
+ except ValueError:
+ raise ValidationError({'expires_before': ['failed to convert to datetime']})
+
+ if 'expires_at__lte' in additional_filters and 'expires_at__gte' in additional_filters:
+ if additional_filters['expires_at__gte'] > additional_filters['expires_at__lte']:
+ raise ValidationError({
+ 'expires_before': ['cannot be after expires_after'],
+ 'expires_after': ['cannot be before expires_before'],
+ })
+
+ if (
+ ('expires_at__lte' in additional_filters or 'expires_at__gte' in additional_filters)
+ and 'expires_at__isnull' in additional_filters
+ and additional_filters['expires_at__isnull']
+ ):
+ raise ValidationError({
+ 'permanent': [
+ 'cannot filter for permanent infractions at the'
+ ' same time as expires_at or expires_before',
+ ]
+ })
+
+ if filter_expires_before:
+ # Filter out permanent infractions specifically if we want ones that will expire
+ # before a given date
+ additional_filters['expires_at__isnull'] = False
+
+ filter_types = self.request.query_params.get('types')
+ if filter_types:
+ if self.request.query_params.get('type'):
+ raise ValidationError({
+ 'types': ['you must provide only one of "type" or "types"'],
+ })
+ additional_filters['type__in'] = [i.strip() for i in filter_types.split(",")]
+
+ return self.queryset.filter(**additional_filters)
+
@action(url_path='expanded', detail=False)
def list_expanded(self, *args, **kwargs) -> Response:
"""