mirror of https://github.com/cocosolos/ixion.git
113 lines
4.0 KiB
Python
113 lines
4.0 KiB
Python
from django.http import Http404
|
|
from rest_framework import viewsets, mixins
|
|
from rest_framework.response import Response
|
|
from django.db.models.fields.json import KT
|
|
from v1.serializers.server import ServerDetailsSerializer, ServerSerializer
|
|
from v1.models.server import Server
|
|
from rest_framework import status
|
|
from django.core.exceptions import ValidationError
|
|
|
|
|
|
class ServerViewSet(
|
|
mixins.CreateModelMixin,
|
|
mixins.RetrieveModelMixin,
|
|
mixins.ListModelMixin,
|
|
viewsets.GenericViewSet,
|
|
):
|
|
queryset = Server.objects.all()
|
|
serializer_class = ServerSerializer
|
|
|
|
CONFIG_MAPPING = {
|
|
"name": {
|
|
"annotate_field": "settings__MAIN.SERVER_NAME",
|
|
"filter_type": "startswith",
|
|
},
|
|
}
|
|
|
|
def get_queryset(self):
|
|
queryset = self.queryset
|
|
|
|
# Iterate through the configuration mapping and apply dynamic annotation and filtering
|
|
for param, config in self.CONFIG_MAPPING.items():
|
|
value = self.request.query_params.get(param)
|
|
if value:
|
|
annotate_field = config["annotate_field"]
|
|
filter_type = config["filter_type"]
|
|
annotate_name = f"{param}_annotated"
|
|
|
|
# Annotate the queryset with the specified annotation field and filter type
|
|
queryset = queryset.annotate(
|
|
**{annotate_name: KT(annotate_field)}
|
|
).filter(**{f"{annotate_name}__{filter_type}": value})
|
|
|
|
# Clear the result cache to ensure fresh data
|
|
queryset._result_cache = None
|
|
|
|
return queryset
|
|
|
|
|
|
class ServerDetailsViewSet(
|
|
mixins.CreateModelMixin,
|
|
mixins.RetrieveModelMixin,
|
|
mixins.ListModelMixin,
|
|
viewsets.GenericViewSet,
|
|
):
|
|
queryset = Server.objects.all()
|
|
serializer_class = ServerDetailsSerializer
|
|
|
|
def get_object(self):
|
|
"""
|
|
Override get_object to retrieve server by URL query parameter.
|
|
"""
|
|
queryset = self.filter_queryset(self.get_queryset())
|
|
url_param = self.request.query_params.get("url")
|
|
if url_param:
|
|
url_param = url_param.lower()
|
|
try:
|
|
return queryset.get(url=url_param)
|
|
except Server.DoesNotExist:
|
|
raise Http404("Server not found with the provided URL.")
|
|
return super().get_object()
|
|
|
|
def handle_server_by_url(self, url_param):
|
|
"""
|
|
Check for existing server or create a new one if not found.
|
|
"""
|
|
url_param = url_param.lower()
|
|
try:
|
|
server = Server.objects.get(url=url_param)
|
|
serializer = self.get_serializer(server)
|
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
|
except Server.DoesNotExist:
|
|
serializer = self.get_serializer(data={"url": url_param})
|
|
serializer.is_valid(raise_exception=True)
|
|
self.perform_create(serializer)
|
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
|
except ValidationError as e:
|
|
return Response({"url": e.messages}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
"""
|
|
Handle POST request to retrieve or create server.
|
|
"""
|
|
url_param = request.data.get("url")
|
|
if url_param:
|
|
return self.handle_server_by_url(url_param)
|
|
return Response(
|
|
{"detail": "URL parameter is required."}, status=status.HTTP_400_BAD_REQUEST
|
|
)
|
|
|
|
def list(self, request, *args, **kwargs):
|
|
"""
|
|
Handle GET request to retrieve or create server.
|
|
"""
|
|
queryset = self.filter_queryset(self.get_queryset())
|
|
url_param = self.request.query_params.get("url")
|
|
if url_param:
|
|
url_param = url_param.lower()
|
|
queryset = queryset.filter(url=url_param)
|
|
if not queryset.exists():
|
|
return self.handle_server_by_url(url_param)
|
|
return self.retrieve(request, *args, **kwargs)
|
|
raise Http404("No URL provided.")
|