248 lines
8.1 KiB
Python
248 lines
8.1 KiB
Python
# -*- encoding: utf-8 -*-
|
|
|
|
import json
|
|
import logging
|
|
import requests
|
|
|
|
from django.conf import settings
|
|
from django.db.utils import IntegrityError
|
|
from django.core.exceptions import ValidationError
|
|
from django_filters import rest_framework as rest_filters
|
|
from rest_framework import status, permissions, filters, generics
|
|
from rest_framework.response import Response
|
|
from rest_framework.pagination import PageNumberPagination
|
|
from rest_framework.authentication import SessionAuthentication, TokenAuthentication
|
|
from rest_framework.parsers import MultiPartParser, FormParser
|
|
|
|
from apps.home.models import Subscription, SavedGuilds
|
|
from apps.authentication.models import UserServerLink
|
|
from .serializers import (
|
|
SubscriptionSerializer,
|
|
UserServerLinkSerializer,
|
|
SavedGuildSerializer
|
|
)
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class DefaultPagination(PageNumberPagination):
|
|
"""Default class for pagination in API views."""
|
|
|
|
page_size = 10
|
|
page_size_query_param = "page_size"
|
|
max_page_size = 25
|
|
|
|
|
|
# =================================================================================================
|
|
# Subscription Views
|
|
|
|
class Subscription_ListView(generics.ListCreateAPIView):
|
|
"""
|
|
View to provide a list of Subscription model instances.
|
|
Can also be used to create a new instance.
|
|
|
|
Supports: GET, POST
|
|
"""
|
|
|
|
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
|
permission_classes = [permissions.IsAuthenticated]
|
|
|
|
pagination_class = DefaultPagination
|
|
serializer_class = SubscriptionSerializer
|
|
queryset = Subscription.objects.all().order_by("-creation_datetime")
|
|
|
|
filter_backends = [filters.SearchFilter, rest_filters.DjangoFilterBackend, filters.OrderingFilter]
|
|
filterset_fields = ["uuid", "name", "rss_url", "server", "targets", "creation_datetime", "extra_notes", "active"]
|
|
search_fields = ["name", "extra_notes"]
|
|
ordering_fields = ["creation_datetime", "server"]
|
|
|
|
def post(self, request):
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
try:
|
|
self.perform_create(serializer)
|
|
except IntegrityError:
|
|
return Response(
|
|
{"detail": "Duplicate or limit reached"},
|
|
status=status.HTTP_409_CONFLICT,
|
|
exception=True
|
|
)
|
|
|
|
headers = self.get_success_headers(serializer.data)
|
|
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
|
|
|
|
|
|
class Subscription_DetailView(generics.RetrieveUpdateDestroyAPIView):
|
|
"""
|
|
View to provide details on a particular Subscription model instances.
|
|
|
|
Supports: GET, PUT, PATCH, DELETE
|
|
"""
|
|
|
|
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
|
permission_classes = [permissions.IsAuthenticated]
|
|
parser_classes = [MultiPartParser, FormParser]
|
|
|
|
serializer_class = SubscriptionSerializer
|
|
queryset = Subscription.objects.all().order_by("-creation_datetime")
|
|
|
|
# def get_queryset(self):
|
|
# user_servers = self.request.user.servers
|
|
# user_servers = [server.id for server in user_servers]
|
|
# return Subscription.objects \
|
|
# .filter(server__in=user_servers) \
|
|
# .order_by("-creation_datetime")
|
|
|
|
|
|
# =================================================================================================
|
|
# UserServerLinks Views
|
|
|
|
class UserServerLink_Pagination(PageNumberPagination):
|
|
"""
|
|
Pagination for UserServerLink API views.
|
|
Set to 200 as a discord user cannot exceed membership of
|
|
200 discord servers.
|
|
"""
|
|
|
|
page_size = 200
|
|
page_size_query_param = "page_size"
|
|
max_page_size = 200
|
|
|
|
|
|
class UserServerLink_MembershipPermission(permissions.BasePermission):
|
|
"""
|
|
Permission for UserServerLink that requires the current user
|
|
to be equal to the object.user.
|
|
"""
|
|
|
|
def has_object_permission(self, request, view, obj):
|
|
log.debug(f"{obj.name} {obj.user} {request.user}")
|
|
return obj.user == request.user
|
|
|
|
|
|
class UserServerLink_ListView(generics.ListCreateAPIView):
|
|
"""
|
|
View to provide a list of UserServerLink model instances.
|
|
Can also be used to create a new instance.
|
|
|
|
Supports: GET, POST
|
|
"""
|
|
|
|
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
|
permission_classes = [permissions.IsAuthenticated, UserServerLink_MembershipPermission]
|
|
|
|
pagination_class = UserServerLink_Pagination
|
|
serializer_class = UserServerLinkSerializer
|
|
|
|
filter_backends = [filters.SearchFilter, rest_filters.DjangoFilterBackend, filters.OrderingFilter]
|
|
filterset_fields = ["id", "server_id", "user", "name", "permissions"]
|
|
search_fields = ["name"]
|
|
|
|
def get_queryset(self):
|
|
return UserServerLink.objects.filter(user=self.request.user).order_by("id")
|
|
|
|
def post(self, request):
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
try:
|
|
self.perform_create(serializer)
|
|
except IntegrityError:
|
|
return Response(
|
|
{"detail": "UserServerLinks must be unique"},
|
|
status=status.HTTP_409_CONFLICT,
|
|
exception=True
|
|
)
|
|
|
|
headers = self.get_success_headers(serializer.data)
|
|
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
|
|
|
|
|
|
class UserServerLink_DetailView(generics.RetrieveDestroyAPIView):
|
|
"""
|
|
View to provide details on a particular UserServerLink model instances.
|
|
|
|
Supports: GET, DELETE
|
|
"""
|
|
|
|
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
|
permission_classes = [permissions.IsAuthenticated, UserServerLink_MembershipPermission]
|
|
parser_classes = [MultiPartParser, FormParser]
|
|
|
|
serializer_class = UserServerLinkSerializer
|
|
queryset = UserServerLink.objects.all()
|
|
|
|
|
|
# =================================================================================================
|
|
# SavedGuild Views
|
|
|
|
class SavedGuild_ListView(generics.ListCreateAPIView):
|
|
"""
|
|
View to provide a list of SavedGuild model instances.
|
|
Can also be used to create a new instance.
|
|
|
|
Supports: GET, POST
|
|
"""
|
|
|
|
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
|
permission_classes = [permissions.IsAuthenticated]
|
|
|
|
pagination_class = None
|
|
serializer_class = SavedGuildSerializer
|
|
|
|
filter_backends = [filters.SearchFilter, rest_filters.DjangoFilterBackend, filters.OrderingFilter]
|
|
filterset_fields = ["id", "guild_id", "name", "icon", "added_by", "permissions", "owner"]
|
|
search_fields = ["name"]
|
|
|
|
def get_queryset(self):
|
|
return SavedGuilds.objects.filter(added_by=self.request.user)
|
|
|
|
def post(self, request):
|
|
|
|
is_owner = request.data["owner"].lower() == "true"
|
|
|
|
# Check user is admin in server
|
|
if not (self.is_server_admin(request.data["permissions"]) or is_owner):
|
|
return Response(
|
|
{"detail": "You must be a server administrator"},
|
|
status=status.HTTP_403_FORBIDDEN,
|
|
exception=False
|
|
)
|
|
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
try:
|
|
self.perform_create(serializer)
|
|
except IntegrityError as err:
|
|
return Response(
|
|
{"detail": str(err)},
|
|
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
exception=True
|
|
)
|
|
|
|
headers = self.get_success_headers(serializer.data)
|
|
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
|
|
|
|
def is_server_admin(self, permissions) -> bool:
|
|
|
|
return (int(permissions) & 1 << 3) == 1 << 3
|
|
|
|
|
|
class SavedGuild_DetailView(generics.RetrieveDestroyAPIView):
|
|
"""
|
|
View to provide details on a particular UserServerLink model instances.
|
|
|
|
Supports: GET, DELETE
|
|
"""
|
|
|
|
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
|
permission_classes = [permissions.IsAuthenticated]
|
|
parser_classes = [MultiPartParser, FormParser]
|
|
|
|
serializer_class = SavedGuildSerializer
|
|
|
|
def get_queryset(self):
|
|
return SavedGuilds.objects.filter(added_by=self.request.user)
|