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,
|
TransactFromAdminView,
|
||||||
TransactToUserView,
|
TransactToUserView,
|
||||||
TransactToAdminView,
|
TransactToAdminView,
|
||||||
GetMoneyApi, TransactionHistoryApi,
|
GetMoneyApi,
|
||||||
|
TransactionHistoryApi,
|
||||||
)
|
)
|
||||||
from events.api.views import (
|
from events.api.views import (
|
||||||
ListCreateEventApi,
|
ListCreateEventApi,
|
||||||
|
@ -15,7 +16,7 @@ from events.api.views import (
|
||||||
ListAttendedWorkersApi,
|
ListAttendedWorkersApi,
|
||||||
SubmitWorkerAttendedEvent,
|
SubmitWorkerAttendedEvent,
|
||||||
)
|
)
|
||||||
from marketplace.api.views import ListCreateProductApi, RetrieveUpdateDestroyProductApi
|
from marketplace.api.views import ListCreateProductApi, RetrieveUpdateDestroyProductApi, BuyProductApi
|
||||||
from users.api.views import (
|
from users.api.views import (
|
||||||
ListCreateUserApi,
|
ListCreateUserApi,
|
||||||
RetrieveUpdateDeleteUserApi,
|
RetrieveUpdateDeleteUserApi,
|
||||||
|
@ -27,6 +28,7 @@ from users.api.views import (
|
||||||
RetrieveUpdateDeleteCommandApi,
|
RetrieveUpdateDeleteCommandApi,
|
||||||
CreateSeasonApi,
|
CreateSeasonApi,
|
||||||
ListClansApiView,
|
ListClansApiView,
|
||||||
|
GetSelfUserApi,
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
@ -118,6 +120,11 @@ urlpatterns = [
|
||||||
RetrieveUpdateDestroyProductApi.as_view(),
|
RetrieveUpdateDestroyProductApi.as_view(),
|
||||||
name="get_update_destroy_product",
|
name="get_update_destroy_product",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"product/<str:slug>/buy",
|
||||||
|
BuyProductApi.as_view(),
|
||||||
|
name="bui_product",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -126,6 +133,7 @@ urlpatterns = [
|
||||||
include(
|
include(
|
||||||
[
|
[
|
||||||
path("", ListCreateUserApi.as_view(), name="list_create_user"),
|
path("", ListCreateUserApi.as_view(), name="list_create_user"),
|
||||||
|
path("self/", GetSelfUserApi.as_view(), name="get_self_user_api"),
|
||||||
path(
|
path(
|
||||||
"<str:username>",
|
"<str:username>",
|
||||||
RetrieveUpdateDeleteUserApi.as_view(),
|
RetrieveUpdateDeleteUserApi.as_view(),
|
||||||
|
|
|
@ -12,13 +12,11 @@ class ProductSerializer(serializers.ModelSerializer):
|
||||||
"description",
|
"description",
|
||||||
"image",
|
"image",
|
||||||
"image_cropped",
|
"image_cropped",
|
||||||
"nft",
|
|
||||||
"price",
|
"price",
|
||||||
"creator",
|
"creator",
|
||||||
]
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
"image": {"write_only": True},
|
"image": {"write_only": True},
|
||||||
"nft": {"read_only": True},
|
|
||||||
"slug": {"read_only": True},
|
"slug": {"read_only": True},
|
||||||
"image_cropped": {"read_only": True},
|
"image_cropped": {"read_only": True},
|
||||||
"creator": {"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.generics import get_object_or_404
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from rest_framework.parsers import FormParser, MultiPartParser
|
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.api.serializers import ProductSerializer
|
||||||
from marketplace.models import Product
|
from marketplace.models import Product
|
||||||
from common.permissions import IsManager
|
from common.permissions import IsManager
|
||||||
|
from utils.blockchain import transfer_nft
|
||||||
|
|
||||||
|
|
||||||
class ListCreateProductApi(generics.ListCreateAPIView):
|
class ListCreateProductApi(generics.ListCreateAPIView):
|
||||||
|
@ -27,3 +31,16 @@ class RetrieveUpdateDestroyProductApi(generics.RetrieveUpdateDestroyAPIView):
|
||||||
slug=self.request.parser_context["kwargs"]["slug"],
|
slug=self.request.parser_context["kwargs"]["slug"],
|
||||||
)
|
)
|
||||||
return product
|
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 = models.ImageField(upload_to="uploads/")
|
||||||
image_cropped = models.ImageField(upload_to="cropped/", blank=True)
|
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)])
|
price = models.IntegerField(validators=[MinValueValidator(0)])
|
||||||
creator = models.ForeignKey(User, related_name="products", on_delete=models.CASCADE)
|
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.file import crop_image
|
||||||
from utils.generators import generate_charset
|
from utils.generators import generate_charset
|
||||||
from .models import Product
|
from .models import Product
|
||||||
|
from .tasks import await_nft
|
||||||
|
|
||||||
|
|
||||||
@receiver(pre_save, sender=Product)
|
@receiver(pre_save, sender=Product)
|
||||||
|
@ -17,9 +18,12 @@ def create_product(sender, instance, **kwargs):
|
||||||
|
|
||||||
@receiver(post_save, sender=Product)
|
@receiver(post_save, sender=Product)
|
||||||
def process_product(sender, instance, created, **kwargs):
|
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(
|
instance.image_cropped = File(
|
||||||
crop_image(instance.image.path, cut_to=(250, 250)),
|
crop_image(instance.image.path, cut_to=(250, 250)),
|
||||||
name=instance.image.path.split(".")[0].split("/")[-1] + ".png",
|
name=instance.image.path.split(".")[0].split("/")[-1] + ".png",
|
||||||
)
|
)
|
||||||
instance.save(update_fields=["image_cropped"])
|
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
|
serializer_class = ClanSerializer
|
||||||
queryset = Clan.objects.all()
|
queryset = Clan.objects.all()
|
||||||
permission_classes = [IsAuthenticated, IsAdmin]
|
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]:
|
def get_nfts(wallet_public_key: str) -> List[NftInfo]:
|
||||||
res = r.get(URL + f"/v1/wallets/{wallet_public_key}/nft/balance")
|
res = r.get(URL + f"/v1/wallets/{wallet_public_key}/nft/balance")
|
||||||
print(res.json())
|
|
||||||
return list(
|
return list(
|
||||||
map(
|
map(
|
||||||
lambda res: NftInfo(uri=res["uri"], tokens=res["tokens"]),
|
lambda res: NftInfo(uri=res["uri"], tokens=res["tokens"]),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user