mirror of
https://github.com/more-tech4-magnum-opus/backend.git
synced 2024-11-21 19:16:33 +03:00
added products as NFT
This commit is contained in:
parent
abbd90551a
commit
5c3b109f47
|
@ -5,7 +5,8 @@ from blockchain.api.views import (
|
|||
TransactFromAdminView,
|
||||
TransactToUserView,
|
||||
TransactToAdminView,
|
||||
GetMoneyApi, TransactionHistoryApi,
|
||||
GetMoneyApi,
|
||||
TransactionHistoryApi,
|
||||
)
|
||||
from events.api.views import (
|
||||
ListCreateEventApi,
|
||||
|
@ -15,7 +16,7 @@ from events.api.views import (
|
|||
ListAttendedWorkersApi,
|
||||
SubmitWorkerAttendedEvent,
|
||||
)
|
||||
from marketplace.api.views import ListCreateProductApi, RetrieveUpdateDestroyProductApi
|
||||
from marketplace.api.views import ListCreateProductApi, RetrieveUpdateDestroyProductApi, BuyProductApi
|
||||
from users.api.views import (
|
||||
ListCreateUserApi,
|
||||
RetrieveUpdateDeleteUserApi,
|
||||
|
@ -27,6 +28,7 @@ from users.api.views import (
|
|||
RetrieveUpdateDeleteCommandApi,
|
||||
CreateSeasonApi,
|
||||
ListClansApiView,
|
||||
GetSelfUserApi,
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
|
@ -118,6 +120,11 @@ urlpatterns = [
|
|||
RetrieveUpdateDestroyProductApi.as_view(),
|
||||
name="get_update_destroy_product",
|
||||
),
|
||||
path(
|
||||
"product/<str:slug>/buy",
|
||||
BuyProductApi.as_view(),
|
||||
name="bui_product",
|
||||
),
|
||||
]
|
||||
),
|
||||
),
|
||||
|
@ -126,6 +133,7 @@ urlpatterns = [
|
|||
include(
|
||||
[
|
||||
path("", ListCreateUserApi.as_view(), name="list_create_user"),
|
||||
path("self/", GetSelfUserApi.as_view(), name="get_self_user_api"),
|
||||
path(
|
||||
"<str:username>",
|
||||
RetrieveUpdateDeleteUserApi.as_view(),
|
||||
|
|
|
@ -12,13 +12,11 @@ class ProductSerializer(serializers.ModelSerializer):
|
|||
"description",
|
||||
"image",
|
||||
"image_cropped",
|
||||
"nft",
|
||||
"price",
|
||||
"creator",
|
||||
]
|
||||
extra_kwargs = {
|
||||
"image": {"write_only": True},
|
||||
"nft": {"read_only": True},
|
||||
"slug": {"read_only": True},
|
||||
"image_cropped": {"read_only": True},
|
||||
"creator": {"read_only": True},
|
||||
|
|
|
@ -2,10 +2,14 @@ from rest_framework import generics
|
|||
from rest_framework.generics import get_object_or_404
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.parsers import FormParser, MultiPartParser
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from blockchain.services import transact_to_admin
|
||||
from conf import settings
|
||||
from marketplace.api.serializers import ProductSerializer
|
||||
from marketplace.models import Product
|
||||
from common.permissions import IsManager
|
||||
from utils.blockchain import transfer_nft
|
||||
|
||||
|
||||
class ListCreateProductApi(generics.ListCreateAPIView):
|
||||
|
@ -27,3 +31,16 @@ class RetrieveUpdateDestroyProductApi(generics.RetrieveUpdateDestroyAPIView):
|
|||
slug=self.request.parser_context["kwargs"]["slug"],
|
||||
)
|
||||
return product
|
||||
|
||||
|
||||
class BuyProductApi(generics.DestroyAPIView):
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_object(self):
|
||||
product = get_object_or_404(
|
||||
Product,
|
||||
slug=self.request.parser_context["kwargs"]["slug"],
|
||||
)
|
||||
transact_to_admin(self.request.user, product.price)
|
||||
transfer_nft(settings.MAIN_WALLET, self.request.user.wallet_public_key, product.token)
|
||||
return product
|
||||
|
|
|
@ -11,7 +11,7 @@ class Product(models.Model):
|
|||
|
||||
image = models.ImageField(upload_to="uploads/")
|
||||
image_cropped = models.ImageField(upload_to="cropped/", blank=True)
|
||||
nft = models.CharField(max_length=500, blank=True)
|
||||
token = models.IntegerField(default=0)
|
||||
|
||||
price = models.IntegerField(validators=[MinValueValidator(0)])
|
||||
creator = models.ForeignKey(User, related_name="products", on_delete=models.CASCADE)
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.dispatch import receiver
|
|||
from utils.file import crop_image
|
||||
from utils.generators import generate_charset
|
||||
from .models import Product
|
||||
from .tasks import await_nft
|
||||
|
||||
|
||||
@receiver(pre_save, sender=Product)
|
||||
|
@ -17,9 +18,12 @@ def create_product(sender, instance, **kwargs):
|
|||
|
||||
@receiver(post_save, sender=Product)
|
||||
def process_product(sender, instance, created, **kwargs):
|
||||
if instance.image and kwargs["update_fields"] != frozenset({"image_cropped"}):
|
||||
if instance.image and kwargs["update_fields"] is None:
|
||||
instance.image_cropped = File(
|
||||
crop_image(instance.image.path, cut_to=(250, 250)),
|
||||
name=instance.image.path.split(".")[0].split("/")[-1] + ".png",
|
||||
)
|
||||
instance.save(update_fields=["image_cropped"])
|
||||
|
||||
if created and kwargs["update_fields"] is None:
|
||||
await_nft.apply_async(kwargs={"pk": instance.pk})
|
||||
|
|
35
app/marketplace/tasks.py
Normal file
35
app/marketplace/tasks.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
from time import sleep
|
||||
|
||||
from celery import shared_task
|
||||
|
||||
from conf import settings
|
||||
from marketplace.models import Product
|
||||
from utils.blockchain import check_transaction, get_nfts, create_nft
|
||||
|
||||
|
||||
@shared_task
|
||||
def await_nft(pk: int):
|
||||
product = Product.objects.get(pk=pk)
|
||||
url = product.image.url
|
||||
t = create_nft(settings.PUB_KEY, url)
|
||||
|
||||
status = ""
|
||||
try:
|
||||
status = check_transaction(t.transaction_hash)
|
||||
except KeyError as e:
|
||||
pass
|
||||
|
||||
while status != "Success":
|
||||
sleep(3)
|
||||
try:
|
||||
status = check_transaction(t.transaction_hash)
|
||||
except KeyError as e:
|
||||
pass
|
||||
|
||||
print(status)
|
||||
nfts = get_nfts(settings.PUB_KEY)
|
||||
for nft in nfts:
|
||||
if nft.uri == product.image.url:
|
||||
product.token = nft.tokens[0]
|
||||
product.save(update_fields=["token"])
|
||||
return pk
|
|
@ -75,3 +75,11 @@ class ListClansApiView(generics.ListAPIView):
|
|||
serializer_class = ClanSerializer
|
||||
queryset = Clan.objects.all()
|
||||
permission_classes = [IsAuthenticated, IsAdmin]
|
||||
|
||||
|
||||
class GetSelfUserApi(generics.RetrieveAPIView):
|
||||
def get_object(self):
|
||||
return self.request.user
|
||||
|
||||
permission_classes = [IsAuthenticated]
|
||||
serializer_class = UserSerializer
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
from celery import shared_task
|
||||
|
||||
|
||||
@shared_task
|
||||
def process_dir(path):
|
||||
return path
|
|
@ -81,7 +81,6 @@ def create_nft(wallet_public_key: str, string_url: str) -> TransHash:
|
|||
|
||||
def get_nfts(wallet_public_key: str) -> List[NftInfo]:
|
||||
res = r.get(URL + f"/v1/wallets/{wallet_public_key}/nft/balance")
|
||||
print(res.json())
|
||||
return list(
|
||||
map(
|
||||
lambda res: NftInfo(uri=res["uri"], tokens=res["tokens"]),
|
||||
|
|
Loading…
Reference in New Issue
Block a user