Files
oxpanel25/app/user/views.py
2026-04-11 22:07:59 +02:00

145 lines
5.2 KiB
Python

import shutil
from django.contrib.auth import login
from django.contrib.auth.views import LoginView
from django.db.models import Count, Sum
from django.db.models.functions import Coalesce
from django.urls import reverse_lazy
from django.views.generic import CreateView
from rest_framework import mixins
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from .forms import RegisterForm
from .models import FriendRequest, Invitation, User
from .serializers import FriendRequestSerializer, UserSerializer
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": "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