import json from cachalot.api import invalidate from django.contrib.auth.mixins import LoginRequiredMixin from django.http import HttpResponse from mixins.views import AbortSave, ObjectCreate, ObjectDelete, ObjectList, ObjectUpdate from rest_framework import status from rest_framework.parsers import JSONParser from rest_framework.views import APIView from core.forms import AssetGroupForm, AssetRestrictionForm from core.models import AssetGroup, AssetRestriction from core.util import logs log = logs.get_logger(__name__) # Asset Groups class AssetGroupList(LoginRequiredMixin, ObjectList): list_template = "partials/assetgroup-list.html" model = AssetGroup page_title = "List of asset groups for restrictions. Linked to strategies." page_subtitle = "Asset groups are collections of asset restrictions." list_url_name = "assetgroups" list_url_args = ["type"] submit_url_name = "assetgroup_create" class AssetGroupCreate(LoginRequiredMixin, ObjectCreate): model = AssetGroup form_class = AssetGroupForm submit_url_name = "assetgroup_create" class AssetGroupUpdate(LoginRequiredMixin, ObjectUpdate): model = AssetGroup form_class = AssetGroupForm submit_url_name = "assetgroup_update" class AssetGroupDelete(LoginRequiredMixin, ObjectDelete): model = AssetGroup # Asset Restrictions class AssetRestrictionsPermissionMixin: # Check the user has permission to view the asset group # We have a user check on the AssetRestriction, but we need to check the # AssetGroup as well def set_extra_args(self, user): self.extra_permission_args = { "group__user": user, "group__pk": self.kwargs["group"], } class AssetRestrictionList( LoginRequiredMixin, AssetRestrictionsPermissionMixin, ObjectList ): list_template = "partials/assetrestriction-list.html" model = AssetRestriction page_title = "List of asset restrictions. Linked to asset groups." page_subtitle = ( "Allows API calls to permit or prohibit trading on defined currency pairs." ) list_url_name = "assetrestrictions" list_url_args = ["type", "group"] submit_url_name = "assetrestriction_create" submit_url_args = ["type", "group"] class AssetRestrictionCreate( LoginRequiredMixin, AssetRestrictionsPermissionMixin, ObjectCreate ): model = AssetRestriction form_class = AssetRestrictionForm submit_url_name = "assetrestriction_create" submit_url_args = ["type", "group"] def form_invalid(self, form): """If the form is invalid, render the invalid form.""" return self.get(self.request, **self.kwargs, form=form) def pre_save_mutate(self, user, obj): try: assetgroup = AssetGroup.objects.get(pk=self.kwargs["group"], user=user) obj.group = assetgroup except AssetGroup.DoesNotExist: log.error(f"Asset Group {self.kwargs['group']} does not exist") raise AbortSave("asset group does not exist or you don't have access") class AssetRestrictionUpdate( LoginRequiredMixin, AssetRestrictionsPermissionMixin, ObjectUpdate ): model = AssetRestriction form_class = AssetRestrictionForm submit_url_name = "assetrestriction_update" submit_url_args = ["type", "pk", "group"] class AssetRestrictionDelete( LoginRequiredMixin, AssetRestrictionsPermissionMixin, ObjectDelete ): model = AssetRestriction class AssetRestrictionAPI(APIView): parser_classes = [JSONParser] def post(self, request, webhook_id): # log.debug(f"AssetAPI POST {webhook_id}: {request.data}") print(json.dumps(request.data, indent=2)) try: restriction = AssetRestriction.objects.get(webhook_id=webhook_id) except AssetRestriction.DoesNotExist: log.error(f"Asset restriction {webhook_id} does not exist") return HttpResponse(status=status.HTTP_404_NOT_FOUND) if restriction.group is not None: group = restriction.group else: log.error(f"Asset restriction {restriction} has no group") return HttpResponse(status=status.HTTP_404_NOT_FOUND) # if group.strategy_set.exists() is not None: # strategies = group.strategy_set.all() # else: # log.error(f"Asset group {group} has no strategy") # return HttpResponse(status=status.HTTP_404_NOT_FOUND) # log.debug(f"Asset API {webhook_id} matched to strategies {strategies}") if "meta" in request.data: if "is_match" in request.data["meta"]: is_match = request.data["meta"]["is_match"] if isinstance(restriction.pairs_parsed, list): for pair in restriction.pairs_parsed: group.allowed[pair] = is_match group.save() invalidate(restriction) invalidate(group) return HttpResponse(status=status.HTTP_200_OK) return HttpResponse(status=status.HTTP_400_BAD_REQUEST)