Files
oxpanel25/app/user/views.py
2025-04-20 03:20:34 +02:00

133 lines
5.0 KiB
Python

from django.contrib.auth.views import LoginView
from django.views.generic import CreateView
from django.contrib.auth import login
from django.urls import reverse_lazy
from django.db.models import Count, Sum, F, IntegerField
from django.db.models.functions import Coalesce
from rest_framework.viewsets import ModelViewSet, GenericViewSet
from rest_framework import mixins
from rest_framework.decorators import action
from rest_framework.response import Response
import shutil
from .models import User, FriendRequest, Invitation
from .forms import RegisterForm
from .serializers import UserSerializer, FriendRequestSerializer, InvitationSerializer
class UserLoginView(LoginView):
template_name = "user/login.html"
fields = "__all__"
redirect_authenticated_user = True
class RegisterView(CreateView):
template_name = "user/register.html"
form_class = RegisterForm
success_url = reverse_lazy("torrent:home")
invitation = None
def get_form(self, form_class=None):
self.invitation = Invitation.objects.get(token=self.kwargs.get("token"), user__isnull=True)
return super().get_form(form_class)
def form_valid(self, form):
r = super().form_valid(form)
self.invitation.user = self.object
self.invitation.save()
login(self.request, self.object)
return r
class UserViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
queryset = User.objects.all().annotate(
count_torrent=Count("torrents") + Count("torrents_shares")
)
serializer_class = UserSerializer
def get_queryset(self):
qs = super().get_queryset()
only_friends = self.request.query_params.get("only_friends", "false") == "true"
if only_friends:
qs = qs.filter(friends=self.request.user)
return qs
@action(methods=["get"], detail=True)
def add_friend_request(self, request, pk):
# receiver = User.objects.get(pk=pk)
if not User.objects.filter(username__iexact=pk).exists():
return Response({"success": False, "message": f"User '{pk}' doesn't exist"})
receiver = User.objects.get(username__iexact=pk)
user: User = self.request.user
if user.friends.filter(id=receiver.id).exists():
# déjà dans les amis
return Response({"success": False, "message": "Already friend"})
elif FriendRequest.objects.filter(sender=user, receiver=receiver).exists():
# déjà une demande en attente
return Response({"success": False, "message": "Friend request Already sent"})
elif FriendRequest.objects.filter(sender=receiver, receiver=user).exists():
# friend request en cours, on accepte
FriendRequest.objects.filter(sender=receiver, receiver=user).delete()
user.friends.add(receiver)
return Response({"success": True, "message": f"{receiver.username} added to your friend list"})
else:
# aucune demande en cours, on créer un friend request
FriendRequest.objects.create(
sender=user,
receiver=receiver
)
return Response({"success": True, "message": "Request sent"})
@action(methods=["get"], detail=True)
def remove_friend(self, request, pk):
friend = User.objects.get(pk=pk)
if self.request.user.friends.filter(pk=friend.pk).exists():
self.request.user.friends.remove(friend)
return Response({"success": True, "message": f"The friend {friend.username} successfully removed"})
return Response({"success": False, "message": f"error"})
@action(methods=["get"], detail=False)
def user_stats(self, request):
stats = User.objects.filter(id=request.user.id).aggregate(
total_size=Coalesce(Sum("torrents__size"), 0),
total_torrent=Coalesce(Count("torrents"), 0),
total_shared_torrent=Coalesce(Count("torrents_shares", distinct=True), 0),
)
disk_usage = shutil.disk_usage("/")
return Response({
"torrents_size": stats["total_size"],
"torrents_len": stats["total_torrent"],
"torrent_len_shared": stats["total_shared_torrent"],
"torrents_total_len": stats["total_torrent"] + stats["total_shared_torrent"],
"user_max_size": request.user.max_size,
"user_usage_percent": (stats["total_size"] / request.user.max_size) * 100,
"disk_total": disk_usage.total,
"disk_used": disk_usage.used,
"disk_free": disk_usage.free,
"disk_usage_percent": (disk_usage.used / disk_usage.total) * 100,
})
class FriendRequestViewSet(mixins.ListModelMixin,
mixins.DestroyModelMixin,
GenericViewSet):
queryset = FriendRequest.objects.all()
serializer_class = FriendRequestSerializer
def get_queryset(self):
qs = super().get_queryset()
qs = qs.filter(receiver=self.request.user)
return qs