From 383d256ea9518780a00075cf31c2c698fada25f6 Mon Sep 17 00:00:00 2001 From: Kaladaran Date: Sat, 28 Oct 2023 18:34:33 +0200 Subject: [PATCH] search & eval reprocess --- api/serializers.py | 6 ++-- api/urls.py | 6 ++++ api/views.py | 77 +++++++++++++++++++++++++++++++++++++++++++--- mabras/settings.py | 4 ++- mabras/urls.py | 12 +++----- sde/models.py | 3 ++ sde/serializers.py | 2 +- sde/urls.py | 4 +++ 8 files changed, 97 insertions(+), 17 deletions(-) diff --git a/api/serializers.py b/api/serializers.py index 466c3f6..b6bf275 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -1,15 +1,15 @@ from django.contrib.auth.models import User, Group from rest_framework import serializers +from sde.models import SDEType -class UserSerializer(serializers.HyperlinkedModelSerializer): +class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['url', 'username', 'email', 'groups'] -class GroupSerializer(serializers.HyperlinkedModelSerializer): +class GroupSerializer(serializers.ModelSerializer): class Meta: model = Group fields = ['url', 'name'] - diff --git a/api/urls.py b/api/urls.py index c8711f0..cfcc4ef 100644 --- a/api/urls.py +++ b/api/urls.py @@ -5,3 +5,9 @@ from rest_framework import routers router = routers.DefaultRouter() router.register(r'users', views.UserViewSet) router.register(r'groups', views.GroupViewSet) + +urlpatterns = [ + path('', include(router.urls)), + path('types/search', views.custom_types_search, name='custom_types_search'), + path('reprocess/eval', views.reprocess_eval, name='custom_types_search'), +] diff --git a/api/views.py b/api/views.py index 4f59f72..74c0361 100644 --- a/api/views.py +++ b/api/views.py @@ -1,8 +1,14 @@ from django.shortcuts import render from django.contrib.auth.models import User, Group -from rest_framework import viewsets -from rest_framework import permissions -from api.serializers import UserSerializer, GroupSerializer +from rest_framework import viewsets, permissions, settings +from rest_framework.decorators import api_view +from rest_framework.response import Response +from api import serializers +from sde import serializers as sde_serializers +from django.http import JsonResponse +from django.db.models import Q + +from sde.models import SDEType class UserViewSet(viewsets.ModelViewSet): @@ -10,7 +16,7 @@ class UserViewSet(viewsets.ModelViewSet): API endpoint that allows users to be viewed or edited. """ queryset = User.objects.all().order_by('-date_joined') - serializer_class = UserSerializer + serializer_class = serializers.UserSerializer permission_classes = [permissions.IsAuthenticated] @@ -19,6 +25,67 @@ class GroupViewSet(viewsets.ModelViewSet): API endpoint that allows groups to be viewed or edited. """ queryset = Group.objects.all() - serializer_class = GroupSerializer + serializer_class = serializers.GroupSerializer permission_classes = [permissions.IsAuthenticated] + +@api_view(['POST']) +def custom_types_search(request): + items = [] + + for q in request.data: + condition = Q() + for k in q.keys(): + value = q[k] + + token = k.split('___') + key, mods = token[0], token[1:] + + if "i" in mods: + condition = condition & Q(**{key + '__icontains': value}) + elif "in" in mods: + condition = condition & Q(**{key + '__in': value}) + else: + condition = condition & Q(**{key: value}) + + if "not" in mods: + condition = ~condition + + items.extend(SDEType.objects.filter(condition)) + + paginator = settings.api_settings.DEFAULT_PAGINATION_CLASS() + result_page = paginator.paginate_queryset(items, request) + serializer = sde_serializers.SDETypeSerializer(result_page, many=True) + return paginator.get_paginated_response(serializer.data) + + +@api_view(['POST']) +def reprocess_eval(request): + ep_mat = request.data.get("ep_mat") + ep_items = request.data.get("ep_items") + efficiency = request.data.get("efficiency", 0.55) + + matprices = {item["typeID"]: {'sell': item["prices"]["sell"]["min"], 'buy': item["prices"]["buy"]["max"]} for item in ep_mat['items']} + + item_reprocess = [] + for rawitem in ep_items["items"]: + item = SDEType.objects.get(id=rawitem["typeID"]) + buy_reprocess = sell_reprocess = 0.0 + for mat in item.typematerials.all(): + try: + buy_reprocess += matprices[mat.material_type_id]['buy'] * mat.quantity/item.portionSize * efficiency + sell_reprocess += matprices[mat.material_type_id]['sell'] * mat.quantity/item.portionSize * efficiency + except KeyError as e: + JsonResponse({"error": f"No price for material {e}"}) + item_reprocess.append({ + "typeID": item.id, + "name": item.name, + "buy": rawitem["prices"]['buy']["max"], + "sell": rawitem["prices"]['sell']["min"], + "buy_reprocess": buy_reprocess, + "sell_reprocess": sell_reprocess, + }) + + paginator = settings.api_settings.DEFAULT_PAGINATION_CLASS() + result_page = paginator.paginate_queryset(item_reprocess, request) + return paginator.get_paginated_response(result_page) diff --git a/mabras/settings.py b/mabras/settings.py index 4437214..fe1f0f5 100644 --- a/mabras/settings.py +++ b/mabras/settings.py @@ -33,13 +33,14 @@ ALLOWED_HOSTS = [] REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', - 'PAGE_SIZE': 10, + 'PAGE_SIZE': 25, 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', ], 'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', ], + 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], } INSTALLED_APPS = [ @@ -51,6 +52,7 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'django_filters', 'rest_framework' ] diff --git a/mabras/urls.py b/mabras/urls.py index e89d4e4..4fe342a 100644 --- a/mabras/urls.py +++ b/mabras/urls.py @@ -15,17 +15,15 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.urls import include, path -from rest_framework import routers from rest_framework.schemas import get_schema_view from django.views.generic import TemplateView -from sde.urls import router as sde_router -from api.urls import router as api_router +from sde.urls import urlpatterns as sde_urls +from api.urls import urlpatterns as api_urls + -# Wire up our API using automatic URL routing. -# Additionally, we include login URLs for the browsable API. urlpatterns = [ - path('', include(api_router.urls)), - path('sde/', include(sde_router.urls)), + path('api/', include(api_urls)), + path('sde/', include(sde_urls)), path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), path('openapi/', get_schema_view( title="Mabras", diff --git a/sde/models.py b/sde/models.py index 2b38ec7..0d0ef09 100644 --- a/sde/models.py +++ b/sde/models.py @@ -56,6 +56,9 @@ class SDEType(models.Model): portionSize = models.IntegerField() materials = models.ManyToManyField("self", through="SDETypeMaterial", symmetrical=False, related_name="material_of") + def __str__(self): + return self.name + class SDETypeMaterial(models.Model): type = models.ForeignKey(SDEType, on_delete=models.CASCADE, related_name="typematerials") diff --git a/sde/serializers.py b/sde/serializers.py index d0563b7..7f57f3f 100644 --- a/sde/serializers.py +++ b/sde/serializers.py @@ -46,7 +46,7 @@ class SDETypeMaterialSerializer(serializers.ModelSerializer): class SDETypeSerializer(serializers.ModelSerializer): - typematerials = SDETypeMaterialSerializer(many=True, read_only=True) + # typematerials = SDETypeMaterialSerializer(many=True, read_only=True) class Meta: model = SDEType # fields = ['id', 'group', 'marketgroup', 'metagroup', 'name', 'description', 'published', 'basePrice', 'icon', 'volume', 'portionSize', 'materials'] diff --git a/sde/urls.py b/sde/urls.py index 905d28b..152956e 100644 --- a/sde/urls.py +++ b/sde/urls.py @@ -10,3 +10,7 @@ router.register(r'marketgroups', views.SDEMarketGroupViewSet) router.register(r'metagroups', views.SDEMetaGroupViewSet) router.register(r'types', views.SDETypeViewSet) router.register(r'typematerials', views.SDETypeMaterialViewSet) + +urlpatterns = [ + path('', include(router.urls)), +]