Skip to content

Commit

Permalink
Merge pull request #269 from UnitapApp/fix/prizetap-contribution-hub
Browse files Browse the repository at this point in the history
Move constraint validations and their stuff into core
  • Loading branch information
ShayanShiravani authored Jan 20, 2024
2 parents 9b03551 + 1a9a327 commit 1a85648
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 59 deletions.
80 changes: 80 additions & 0 deletions core/serializers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import base64
import json

from django.core.validators import FileExtensionValidator
from rest_framework import serializers

from core.constraints import ConstraintVerification, get_constraint

from .models import Chain, UserConstraint
from .utils import UploadFileStorage


class ChainSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -65,3 +70,78 @@ class Meta:
def get_params(self, constraint: UserConstraint):
c_class: ConstraintVerification = get_constraint(constraint.name)
return [p.name for p in c_class.param_keys()]


class ConstraintProviderSerializer(serializers.Serializer):
constraint_files = serializers.ListField(
required=False,
child=serializers.FileField(
allow_empty_file=False, validators=[FileExtensionValidator(["csv"])]
),
)

class Meta:
abstract = True

def validate(self, data):
constraints = data["constraints"]
if "constraint_params" in data:
data["constraint_params"] = base64.b64decode(
data["constraint_params"]
).decode("utf-8")
else:
data["constraint_params"] = "{}"
constraint_params = json.loads(data["constraint_params"])
reversed_constraints = []
if "reversed_constraints" in data:
reversed_constraints = str(data["reversed_constraints"]).split(",")
if len(constraints) != 0:
for c in constraints:
constraint_class: ConstraintVerification = get_constraint(c.name)
try:
if len(constraint_class.param_keys()) != 0:
constraint_class.is_valid_param_keys(constraint_params[c.name])
except KeyError as e:
# TODO: revise errors
raise serializers.ValidationError(
{"constraint_params": [{f"{c.name}": str(e)}]}
)
valid_constraints = [str(c.pk) for c in constraints]
for c in reversed_constraints:
if c not in valid_constraints:
raise serializers.ValidationError(
{"reversed_constraints": [{f"{c}": "Invalid constraint pk"}]}
)
if "constraint_files" in data:
file_names = [file.name for file in data["constraint_files"]]
if len(file_names) != len(set(file_names)):
raise serializers.ValidationError(
{"constraint_files": "The name of files should be unique"}
)
return data

def save_constraint_files(self, validated_data):
if "constraint_files" in validated_data:
constraint_files = validated_data.pop("constraint_files")
constraint_params = json.loads(validated_data.get("constraint_params"))
file_storage = UploadFileStorage()
for ـ, constraint in constraint_params.items():
if "CSV_FILE" not in constraint:
continue
file_exist = False
for file in constraint_files:
if constraint["CSV_FILE"] == file.name:
path = file_storage.save(file)
constraint["CSV_FILE"] = path
file_exist = True
break
if not file_exist:
raise serializers.ValidationError(
{
"constraint_files": (
f'File {constraint["CSV_FILE"]} is not exist'
)
}
)
validated_data["constraint_params"] = json.dumps(constraint_params)
return validated_data
67 changes: 8 additions & 59 deletions prizetap/serializers.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import base64
import json

from django.core.validators import FileExtensionValidator
from rest_framework import serializers

from authentication.serializers import SimpleProfilerSerializer
from core.constraints import ConstraintVerification, get_constraint
from core.serializers import ChainSerializer, UserConstraintBaseSerializer
from core.utils import UploadFileStorage
from core.serializers import (
ChainSerializer,
ConstraintProviderSerializer,
UserConstraintBaseSerializer,
)

from .constants import CONTRACT_ADDRESSES
from .models import Constraint, LineaRaffleEntries, Raffle, RaffleEntry, UserConstraint
Expand Down Expand Up @@ -95,14 +94,7 @@ class Meta:
]


class CreateRaffleSerializer(serializers.ModelSerializer):
constraint_files = serializers.ListField(
required=False,
child=serializers.FileField(
allow_empty_file=False, validators=[FileExtensionValidator(["csv"])]
),
)

class CreateRaffleSerializer(serializers.ModelSerializer, ConstraintProviderSerializer):
class Meta:
model = Raffle
fields = "__all__"
Expand All @@ -118,38 +110,7 @@ class Meta:
]

def validate(self, data):
constraints = data["constraints"]
constraint_params = json.loads(base64.b64decode(data["constraint_params"]))
data["constraint_params"] = base64.b64decode(data["constraint_params"]).decode(
"utf-8"
)
reversed_constraints = []
if "reversed_constraints" in data:
reversed_constraints = str(data["reversed_constraints"]).split(",")
if len(constraints) != 0:
for c in constraints:
constraint_class: ConstraintVerification = get_constraint(c.name)
try:
if len(constraint_class.param_keys()) != 0:
constraint_class.is_valid_param_keys(constraint_params[c.name])
except KeyError as e:
# TODO: revise errors
raise serializers.ValidationError(
{"constraint_params": [{f"{c.name}": str(e)}]}
)
valid_constraints = [str(c.pk) for c in constraints]
if len(reversed_constraints) > 0:
for c in reversed_constraints:
if c not in valid_constraints:
raise serializers.ValidationError(
{"reversed_constraints": [{f"{c}": "Invalid constraint pk"}]}
)
if "constraint_files" in data:
file_names = [file.name for file in data["constraint_files"]]
if len(file_names) != len(set(file_names)):
raise serializers.ValidationError(
{"constraint_files": "The name of files should be unique"}
)
data = super().validate(data)
if (
"winners_count" in data
and data["winners_count"] > data["max_number_of_entries"]
Expand All @@ -173,19 +134,7 @@ def validate(self, data):
return data

def create(self, validated_data):
if "constraint_files" in validated_data:
constraint_files = validated_data.pop("constraint_files")
constraint_params = json.loads(validated_data.get("constraint_params"))
file_storage = UploadFileStorage()
for key, constraint in constraint_params.items():
if "CSV_FILE" not in constraint:
continue
for file in constraint_files:
if constraint["CSV_FILE"] == file.name:
path = file_storage.save(file)
constraint["CSV_FILE"] = path
break
validated_data["constraint_params"] = json.dumps(constraint_params)
validated_data = self.save_constraint_files(validated_data)
return super().create(validated_data)


Expand Down

0 comments on commit 1a85648

Please sign in to comment.