Coverage for website/facedetection/views.py: 46.43%
78 statements
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
1from django.conf import settings
2from django.contrib import messages
3from django.contrib.auth.mixins import LoginRequiredMixin
4from django.core.exceptions import ValidationError
5from django.http import HttpResponseRedirect
6from django.shortcuts import redirect
7from django.urls import reverse_lazy
8from django.utils import timezone
9from django.utils.translation import gettext_lazy as _
10from django.views.generic import DeleteView, FormView, ListView
12from photos.models import Photo
13from thaliawebsite.views import PagedView
15from .forms import ReferenceFaceUploadForm
16from .models import ReferenceFace
17from .services import get_user_photos
20class YourPhotosView(LoginRequiredMixin, PagedView):
21 model = Photo
22 paginate_by = 50
23 template_name = "facedetection/your-photos.html"
24 context_object_name = "photos"
26 def get(self, request, *args, **kwargs):
27 if not request.member or not request.member.has_active_membership():
28 messages.error(request, _("You need to be a member to use this feature."))
29 return redirect("index")
31 return super().get(request, *args, **kwargs)
33 def get_queryset(self):
34 return get_user_photos(self.request.member)
36 def get_context_data(self, **kwargs):
37 context = super().get_context_data(**kwargs)
39 context["has_processing_reference_faces"] = (
40 self.request.member.reference_faces.filter(
41 status=ReferenceFace.Status.PROCESSING,
42 marked_for_deletion_at__isnull=True,
43 ).exists()
44 )
46 context["has_rejected_reference_faces"] = (
47 self.request.member.reference_faces.filter(
48 status=ReferenceFace.Status.REJECTED,
49 marked_for_deletion_at__isnull=True,
50 ).exists()
51 )
53 context["has_reference_faces"] = self.request.member.reference_faces.filter(
54 marked_for_deletion_at__isnull=True
55 ).exists()
57 return context
60class ReferenceFaceView(LoginRequiredMixin, ListView):
61 template_name = "facedetection/reference-faces.html"
63 def get_context_data(self, **kwargs):
64 context = super().get_context_data(**kwargs)
65 context["reference_faces_limit"] = (
66 settings.FACEDETECTION_MAX_NUM_REFERENCE_FACES
67 )
68 context["storage_period_after_delete"] = (
69 settings.FACEDETECTION_REFERENCE_FACE_STORAGE_PERIOD_AFTER_DELETE_DAYS
70 )
71 context["reference_faces_limit_reached"] = bool(
72 self.request.member.reference_faces.filter(
73 marked_for_deletion_at__isnull=True
74 ).count()
75 >= settings.FACEDETECTION_MAX_NUM_REFERENCE_FACES
76 )
77 context["has_rejected_reference_faces"] = (
78 self.request.member.reference_faces.filter(
79 status=ReferenceFace.Status.REJECTED,
80 marked_for_deletion_at__isnull=True,
81 ).exists()
82 )
83 return context
85 def get_queryset(self):
86 return self.request.member.reference_faces.filter(
87 marked_for_deletion_at__isnull=True
88 ).all()
91class ReferenceFaceUploadView(LoginRequiredMixin, FormView):
92 template_name = "facedetection/reference-face-upload.html"
93 form_class = ReferenceFaceUploadForm
94 success_url = reverse_lazy("facedetection:reference-faces")
96 def dispatch(self, request, *args, **kwargs):
97 if not request.member or not request.member.has_active_membership():
98 messages.error(request, "You need to be a member to use this feature.")
99 return redirect("index")
100 return super().dispatch(request, *args, **kwargs)
102 def form_valid(self, form):
103 try:
104 form.save(user=self.request.member)
105 except ValidationError as e:
106 for error in e:
107 messages.error(self.request, error)
108 return self.form_invalid(form)
109 messages.success(self.request, "Your reference face has been uploaded.")
110 return super().form_valid(form)
113class ReferenceFaceDeleteView(LoginRequiredMixin, DeleteView):
114 model = ReferenceFace
115 success_url = reverse_lazy("facedetection:reference-faces")
117 def get_context_data(self, **kwargs):
118 context = super().get_context_data(**kwargs)
119 context["storage_period_after_delete"] = (
120 settings.FACEDETECTION_REFERENCE_FACE_STORAGE_PERIOD_AFTER_DELETE_DAYS
121 )
122 return context
124 def get_queryset(self):
125 return self.request.member.reference_faces.filter(
126 marked_for_deletion_at__isnull=True
127 ).all()
129 def form_valid(self, form):
130 success_url = self.get_success_url()
132 instance = self.get_object()
133 instance.marked_for_deletion_at = timezone.now()
134 instance.save()
135 messages.success(self.request, "Your reference face has been deleted.")
137 return HttpResponseRedirect(success_url)