Implement asset rules as Asset Group children objects
This commit is contained in:
@@ -1,22 +1,15 @@
|
||||
import json
|
||||
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.db import IntegrityError
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
from django.views import View
|
||||
from mixins.views import (
|
||||
ObjectCreate,
|
||||
ObjectDelete,
|
||||
ObjectList,
|
||||
ObjectNameMixin,
|
||||
ObjectUpdate,
|
||||
)
|
||||
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.forms import AssetGroupForm, AssetRuleForm
|
||||
from core.models import AssetGroup, AssetRule
|
||||
from core.trading import assetfilter
|
||||
from core.util import logs
|
||||
|
||||
@@ -55,73 +48,69 @@ class AssetGroupDelete(LoginRequiredMixin, ObjectDelete):
|
||||
model = AssetGroup
|
||||
|
||||
|
||||
# Asset Restrictions
|
||||
# Asset Rules
|
||||
|
||||
|
||||
# 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 AssetRulesPermissionMixin:
|
||||
# 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."
|
||||
# )
|
||||
class AssetRuleList(LoginRequiredMixin, AssetRulesPermissionMixin, ObjectList):
|
||||
list_template = "partials/assetrule-list.html"
|
||||
model = AssetRule
|
||||
page_title = "List of asset rules"
|
||||
|
||||
# list_url_name = "assetrestrictions"
|
||||
# list_url_args = ["type", "group"]
|
||||
list_url_name = "assetrules"
|
||||
list_url_args = ["type", "group"]
|
||||
|
||||
# submit_url_name = "assetrestriction_create"
|
||||
# submit_url_args = ["type", "group"]
|
||||
submit_url_name = "assetrule_create"
|
||||
submit_url_args = ["type", "group"]
|
||||
|
||||
|
||||
# class AssetRestrictionCreate(
|
||||
# LoginRequiredMixin, AssetRestrictionsPermissionMixin, ObjectCreate
|
||||
# ):
|
||||
# model = AssetRestriction
|
||||
# form_class = AssetRestrictionForm
|
||||
class AssetRuleCreate(LoginRequiredMixin, AssetRulesPermissionMixin, ObjectCreate):
|
||||
model = AssetRule
|
||||
form_class = AssetRuleForm
|
||||
|
||||
# submit_url_name = "assetrestriction_create"
|
||||
# submit_url_args = ["type", "group"]
|
||||
submit_url_name = "assetrule_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 form_valid(self, form):
|
||||
"""If the form is invalid, render the invalid form."""
|
||||
try:
|
||||
return super().form_valid(form)
|
||||
except IntegrityError as e:
|
||||
if "UNIQUE constraint failed" in str(e):
|
||||
form.add_error("asset", "Asset rule already exists")
|
||||
return self.form_invalid(form)
|
||||
else:
|
||||
raise e
|
||||
|
||||
# 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")
|
||||
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
|
||||
class AssetRuleUpdate(LoginRequiredMixin, AssetRulesPermissionMixin, ObjectUpdate):
|
||||
model = AssetRule
|
||||
form_class = AssetRuleForm
|
||||
|
||||
# submit_url_name = "assetrestriction_update"
|
||||
# submit_url_args = ["type", "pk", "group"]
|
||||
submit_url_name = "assetrule_update"
|
||||
submit_url_args = ["type", "pk", "group"]
|
||||
|
||||
|
||||
# class AssetRestrictionDelete(
|
||||
# LoginRequiredMixin, AssetRestrictionsPermissionMixin, ObjectDelete
|
||||
# ):
|
||||
# model = AssetRestriction
|
||||
class AssetRuleDelete(LoginRequiredMixin, AssetRulesPermissionMixin, ObjectDelete):
|
||||
model = AssetRule
|
||||
|
||||
|
||||
class AssetGroupAPI(APIView):
|
||||
@@ -164,7 +153,6 @@ class AssetGroupAPI(APIView):
|
||||
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
topic = request.data["topic"]
|
||||
print("YES TOPIC", topic)
|
||||
new_assets = []
|
||||
assets_split = topic.split(",")
|
||||
if not assets_split:
|
||||
@@ -176,88 +164,46 @@ class AssetGroupAPI(APIView):
|
||||
else:
|
||||
log.error(f"Asset API {webhook_id} asset {asset} is not an asset")
|
||||
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
|
||||
print("YES PAIRS", new_assets)
|
||||
|
||||
aggregation = "none"
|
||||
value = None
|
||||
# Check if we have lower/upper bounds
|
||||
if group.aggregation != "none":
|
||||
if "aggs" in request.data["meta"]:
|
||||
aggs = request.data["meta"]["aggs"]
|
||||
if group.aggregation in aggs:
|
||||
if "value" in aggs[group.aggregation]:
|
||||
value = aggs[group.aggregation]["value"]
|
||||
print("YES AVG", value)
|
||||
is_match = assetfilter.check_asset_aggregation(
|
||||
value, group.trigger_above, group.trigger_below
|
||||
)
|
||||
print("YES AVG IS MATCH", is_match)
|
||||
if "aggs" in request.data["meta"]:
|
||||
aggs = request.data["meta"]["aggs"]
|
||||
# TODO: support more aggregations
|
||||
if len(aggs) != 1:
|
||||
log.error(
|
||||
f"Asset API {webhook_id} has an invalid number of aggregations"
|
||||
)
|
||||
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
|
||||
first_agg_key = list(aggs.keys())[0]
|
||||
if "value" in aggs[first_agg_key]:
|
||||
aggregation = first_agg_key
|
||||
value = aggs[first_agg_key]["value"]
|
||||
|
||||
for asset in new_assets:
|
||||
group.allowed[asset] = is_match is True or None
|
||||
group.save()
|
||||
asset_rule, _ = AssetRule.objects.get_or_create(
|
||||
group=group, user=group.user, asset=asset
|
||||
)
|
||||
if is_match:
|
||||
# Make our own is_match based on the aggregations
|
||||
is_match = assetfilter.check_asset_aggregation(
|
||||
value, asset_rule.trigger_above, asset_rule.trigger_below
|
||||
)
|
||||
else:
|
||||
# No matches
|
||||
is_match = None
|
||||
asset_rule.aggregation = aggregation
|
||||
if value:
|
||||
asset_rule.value = value
|
||||
if is_match is not None:
|
||||
our_status = is_match
|
||||
else:
|
||||
our_status = 1
|
||||
asset_rule.original_status = our_status
|
||||
asset_rule.status = assetfilter.update_status_from_mappings(
|
||||
our_status, group
|
||||
)
|
||||
asset_rule.save()
|
||||
|
||||
return HttpResponse(status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
# Asset group allowed field
|
||||
class AssetFilterList(LoginRequiredMixin, ObjectList):
|
||||
list_template = "partials/asset-filter-list.html"
|
||||
page_title = "List of asset filters."
|
||||
page_subtitle = None
|
||||
|
||||
context_object_name_singular = "asset filter"
|
||||
context_object_name = "asset filters"
|
||||
|
||||
list_url_name = "assetfilters"
|
||||
list_url_args = ["type", "group_id"]
|
||||
|
||||
def get_queryset(self, **kwargs):
|
||||
group_id = kwargs.get("group_id", None)
|
||||
self.extra_context = {"group_id": group_id}
|
||||
try:
|
||||
group = AssetGroup.objects.get(id=group_id, user=self.request.user)
|
||||
except AssetGroup.DoesNotExist:
|
||||
context = {"message": "Asset group does not exist", "class": "danger"}
|
||||
return self.render_to_response(context)
|
||||
return group.allowed
|
||||
|
||||
|
||||
class AssetFilterFlip(LoginRequiredMixin, ObjectNameMixin, View):
|
||||
template_name = "mixins/partials/notify.html"
|
||||
model = AssetGroup
|
||||
|
||||
def get(self, request, group_id, symbol):
|
||||
try:
|
||||
group = AssetGroup.objects.get(id=group_id, user=request.user)
|
||||
except AssetGroup.DoesNotExist:
|
||||
context = {"message": "Asset group does not exist", "class": "danger"}
|
||||
return render(request, self.template_name, context)
|
||||
if symbol not in group.allowed:
|
||||
context = {"message": "Asset filter does not exist", "class": "danger"}
|
||||
return render(request, self.template_name, context)
|
||||
group.allowed[symbol] = not group.allowed[symbol]
|
||||
group.save()
|
||||
context = {"message": "Asset filter updated", "class": "success"}
|
||||
response = render(request, self.template_name, context)
|
||||
response["HX-Trigger"] = "assetgroupEvent"
|
||||
return response
|
||||
|
||||
|
||||
class AssetFilterDelete(LoginRequiredMixin, ObjectNameMixin, View):
|
||||
template_name = "mixins/partials/notify.html"
|
||||
model = AssetGroup
|
||||
|
||||
def delete(self, request, group_id, symbol):
|
||||
try:
|
||||
group = AssetGroup.objects.get(id=group_id, user=request.user)
|
||||
except AssetGroup.DoesNotExist:
|
||||
context = {"message": "Asset group does not exist", "class": "danger"}
|
||||
return render(request, self.template_name, context)
|
||||
if symbol not in group.allowed:
|
||||
context = {"message": "Asset filter does not exist", "class": "danger"}
|
||||
return render(request, self.template_name, context)
|
||||
del group.allowed[symbol]
|
||||
group.save()
|
||||
context = {"message": "Asset filter deleted", "class": "success"}
|
||||
response = render(request, self.template_name, context)
|
||||
response["HX-Trigger"] = "assetgroupEvent"
|
||||
return response
|
||||
|
||||
Reference in New Issue
Block a user