from datetime import date from django.contrib.auth import get_user_model from django.contrib.messages.views import SuccessMessageMixin from django.core.mail import EmailMessage from django.http import Http404 from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.views.generic import CreateView, DetailView, FormView, ListView, UpdateView from django.views.generic.edit import SingleObjectMixin from shared.utils import full_url from shared.views import BackgroundUpdateView from .forms import DeleteForm, PetitionForm, SignatureForm, ValidateForm from .mixins import AdminOnlyMixin, CreatorOnlyMixin from .models import Petition, Signature from .staticdefs import MAIL_SIGNATURE_DELETED, MAIL_SIGNATURE_VERIFICATION User = get_user_model() # ############################################################################# # Administration views # ############################################################################# class PetitionCreateView(AdminOnlyMixin, CreateView): model = Petition form_class = PetitionForm success_message = _("Pétition créée avec succès") template_name = "petitions/petition_create.html" def get_success_url(self): return reverse("petition.admin", args=[self.object.pk]) def form_valid(self, form): form.instance.created_by = self.request.user return super().form_valid(form) class PetitionAdminView(CreatorOnlyMixin, DetailView): model = Petition template_name = "petitions/petition_admin.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["d_form"] = DeleteForm() context["v_form"] = ValidateForm() context["today"] = date.today() return context class PetitionUpdateView(CreatorOnlyMixin, SuccessMessageMixin, UpdateView): model = Petition form_class = PetitionForm success_message = _("Pétition modifiée avec succès !") template_name = "petitions/petition_update.html" def get_success_url(self): return reverse("election.admin", args=[self.object.pk]) def get_queryset(self): return ( super().get_queryset().filter(launch_date__gt=date.today(), archived=False) ) class PetitionArchiveView(CreatorOnlyMixin, SingleObjectMixin, BackgroundUpdateView): model = Petition pattern_name = "petition.admin" success_message = _("Élection archivée avec succès !") def get_queryset(self): return super().get_queryset().filter(archived=False) def get(self, request, *args, **kwargs): petition = self.get_object() petition.archived = True petition.save() return super().get(request, *args, **kwargs) class DeleteSignatureView(CreatorOnlyMixin, SingleObjectMixin, FormView): model = Petition template_name = "petitions/delete_signature.html" form_class = DeleteForm def get_success_url(self): return reverse("petition.admin", args=[self.object.pk]) + "#s_{anchor}".format( **self.kwargs ) def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs["signature"] = self.signature return kwargs def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["anchor"] = self.kwargs["anchor"] return context def get_queryset(self): return super().get_queryset().filter(archived=False) def get(self, request, *args, **kwargs): self.object = super().get_object() self.signature = self.object.signatures.get(pk=self.kwargs["signature_pk"]) return super().get(request, *args, **kwargs) def post(self, request, *args, **kwargs): self.object = super().get_object() self.signature = self.object.signatures.get(pk=self.kwargs["signature_pk"]) return super().post(request, *args, **kwargs) def form_valid(self, form): if form.cleaned_data["delete"] == "oui": # On envoie un mail à la personne lui indiquant que la signature est supprimée # si l'adresse mail est validée if self.signature.verified: EmailMessage( subject="Signature removed", body=MAIL_SIGNATURE_DELETED.format( full_name=self.signature.full_name, petition_name_fr=self.object.title_fr, petition_name_en=self.object.title_en, ), to=[self.signature.email], ).send() # On supprime la signature self.signature.delete() return super().form_valid(form) class ValidateSignatureView(CreatorOnlyMixin, SingleObjectMixin, FormView): model = Petition template_name = "petitions/validate_signature.html" form_class = ValidateForm def get_success_url(self): return reverse("petition.admin", args=[self.object.pk]) + "#s_{anchor}".format( **self.kwargs ) def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs["signature"] = self.signature return kwargs def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["anchor"] = self.kwargs["anchor"] return context def get_queryset(self): return super().get_queryset().filter(archived=False) def get(self, request, *args, **kwargs): self.object = super().get_object() self.signature = self.object.signatures.get(pk=self.kwargs["signature_pk"]) return super().get(request, *args, **kwargs) def post(self, request, *args, **kwargs): self.object = super().get_object() self.signature = self.object.signatures.get(pk=self.kwargs["signature_pk"]) return super().post(request, *args, **kwargs) def form_valid(self, form): if form.cleaned_data["validate"] == "oui": # On valide la signature self.signature.valid = True self.signature.save() return super().form_valid(form) # ############################################################################# # Email validation Views # ############################################################################# class EmailValidationView(SingleObjectMixin, BackgroundUpdateView): model = Signature slug_url_kwarg = "token" slug_field = "token" success_message = _("Adresse email vérifiée avec succès") def get_queryset(self): return super().get_queryset().filter(verified=False) def get_redirect_url(self, *args, **kwargs): return reverse("petition.view", args=[self.object.petition.pk]) def get(self, request, *args, **kwargs): self.object = self.get_object() self.object.verified = True self.object.save() return super().get(request, *args, **kwargs) # ############################################################################# # Public Views # ############################################################################# class PetitionListView(ListView): model = Petition template_name = "petitions/petition_list.html" class PetitionView(DetailView): model = Petition template_name = "petitions/petition.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["today"] = date.today() context["signatures"] = self.object.signatures.filter(verified=True) return context def get_queryset(self): return super().get_queryset().select_related("created_by") class PetitionSignView(CreateView): model = Signature form_class = SignatureForm template_name = "petitions/petition_sign.html" def get_success_url(self): return reverse("petition.view", args=[self.petition.pk]) def dispatch(self, request, *args, **kwargs): self.petition = Petition.objects.get(pk=self.kwargs["pk"]) if self.petition.launch_date > date.today(): raise Http404 return super().dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["petition"] = self.petition return context def get_form(self, form_class=None): form = super().get_form(form_class) form.instance.petition = self.petition return form def form_valid(self, form): self.object = form.save(commit=False) # On envoie un mail à l'adresse indiquée EmailMessage( subject="Confirmation de la signature", body=MAIL_SIGNATURE_VERIFICATION.format( full_name=self.object.full_name, petition_name_fr=self.object.petition.title_fr, petition_name_en=self.object.petition.title_en, confirm_url=full_url("petition.confirm-email", self.object.token), ), to=[self.object.email], ).send() return super().form_valid(form)