feat(emails): envoi de la confirmation de vote
parent
5149ff0799
commit
b3da5a897b
|
@ -103,3 +103,5 @@
|
|||
# Note that it's always disabled in production.
|
||||
#DJANGO_DEBUG=off
|
||||
#DJANGO_DEBUG_TOOLBAR=on
|
||||
#
|
||||
#ASSISTANCE=tech@cliss21.org
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
from django.conf import settings
|
||||
from django.contrib.sites.shortcuts import get_current_site
|
||||
from django.core.mail.message import EmailMultiAlternatives
|
||||
from django.template.exceptions import TemplateDoesNotExist
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
|
||||
def send_templated(request, base_tpl, context, sender, recipients, **kwargs):
|
||||
def render_subject():
|
||||
template = "emails/{}.subject".format(base_tpl)
|
||||
subject = render_to_string(template, context, request=request)
|
||||
# Email subject *must not* contain newlines
|
||||
return ''.join(subject.splitlines())
|
||||
|
||||
def render_message(html=False):
|
||||
if not html:
|
||||
template = "emails/{}.txt".format(base_tpl)
|
||||
else:
|
||||
template = "emails/{}.html".format(base_tpl)
|
||||
return render_to_string(template, context, request=request)
|
||||
|
||||
context.update({
|
||||
'site': get_current_site(request),
|
||||
'settings': {'assistance': settings.ASSISTANCE},
|
||||
})
|
||||
|
||||
subject = render_subject()
|
||||
message = render_message()
|
||||
|
||||
email_message = EmailMultiAlternatives(
|
||||
subject, message, sender, recipients, **kwargs
|
||||
)
|
||||
try:
|
||||
html_message = render_message(html=True)
|
||||
email_message.attach_alternative(html_message, 'text/html')
|
||||
except TemplateDoesNotExist:
|
||||
pass
|
||||
|
||||
email_message.send()
|
|
@ -30,7 +30,7 @@ from wagtail.core.fields import RichTextField, StreamField
|
|||
from wagtail.core.models import Page
|
||||
from wagtail.search import index
|
||||
|
||||
from . import blocks
|
||||
from . import blocks, emails
|
||||
|
||||
|
||||
class SitePage(Page):
|
||||
|
@ -118,7 +118,6 @@ class ClosedScrutin(Exception):
|
|||
|
||||
# TODO: email d'annonce
|
||||
# TODO: email de rappel
|
||||
# TODO: email de confirmation
|
||||
# TODO: afficher ouverture du scrutin dans la liste des scrutins
|
||||
class Scrutin(RoutablePageMixin, AbstractEmailForm):
|
||||
"""
|
||||
|
@ -220,6 +219,7 @@ class Scrutin(RoutablePageMixin, AbstractEmailForm):
|
|||
return super().serve(request, *args, **kwargs)
|
||||
raise Http404
|
||||
|
||||
# FIXME: c'est contreproductif de mettre l'uuid sous le path
|
||||
@route(r'(?P<uuid>' + UUIDConverter.regex + ')')
|
||||
def uuid_way(self, request, uuid, *args, **kwargs):
|
||||
pouvoir = get_object_or_404(Pouvoir, uuid=uuid)
|
||||
|
@ -236,7 +236,9 @@ class Scrutin(RoutablePageMixin, AbstractEmailForm):
|
|||
|
||||
if form.is_valid():
|
||||
try:
|
||||
submission = self.process_form_submission(form, pouvoir)
|
||||
submission = self.process_form_submission(
|
||||
request, form, pouvoir
|
||||
)
|
||||
return self.render_landing_page(
|
||||
request, submission, *args, **kwargs
|
||||
)
|
||||
|
@ -265,7 +267,7 @@ class Scrutin(RoutablePageMixin, AbstractEmailForm):
|
|||
return form_class(*args, initial=initial, **kwargs)
|
||||
return form_class(*args, **kwargs)
|
||||
|
||||
def process_form_submission(self, form, pouvoir):
|
||||
def process_form_submission(self, request, form, pouvoir):
|
||||
# FIXME: documentation :
|
||||
# compte tenu que les types des questions/réponses ne sont pas
|
||||
# nécessairement multipliables, la seule façon de les comptabiliser
|
||||
|
@ -291,6 +293,8 @@ class Scrutin(RoutablePageMixin, AbstractEmailForm):
|
|||
else:
|
||||
# Mise à jour
|
||||
votes.update(form_data=form_data, submit_time=timezone.now())
|
||||
pouvoir.notify_vote(request)
|
||||
|
||||
elif not self.vote_set.exists():
|
||||
# Personne n'a oncore voté ; donc on est en test
|
||||
pass
|
||||
|
@ -298,13 +302,13 @@ class Scrutin(RoutablePageMixin, AbstractEmailForm):
|
|||
# Quelqu'un rejoue un POST alors que l'interface ne le propose pas
|
||||
raise ClosedScrutin
|
||||
|
||||
# TODO: notification au participant
|
||||
|
||||
def get_submission_class(self):
|
||||
return Vote
|
||||
|
||||
|
||||
class Pouvoir(models.Model):
|
||||
# FIXME: le pouvoir devrait fournir lui même son url d'accès
|
||||
# pour limiter le contexte accessible via le backend
|
||||
uuid = models.UUIDField(
|
||||
primary_key=True, default=uuid.uuid4, editable=False
|
||||
)
|
||||
|
@ -335,3 +339,9 @@ class Pouvoir(models.Model):
|
|||
|
||||
def __str__(self):
|
||||
return "{} {} ({})".format(self.prenom, self.nom, self.uuid)
|
||||
|
||||
def notify_vote(self, request):
|
||||
context = {'pouvoir': self}
|
||||
emails.send_templated(
|
||||
request, 'notify_vote', context, None, [self.courriel]
|
||||
)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from . import env
|
||||
|
||||
"""
|
||||
Django specific settings for GvoT project.
|
||||
"""
|
||||
|
@ -15,3 +17,5 @@ WAGTAILEMBEDS_FINDERS = [
|
|||
{'class': 'wagtail.embeds.finders.oembed'},
|
||||
{'class': 'wagtailembedpeertube.finders'},
|
||||
]
|
||||
|
||||
ASSISTANCE = env('ASSISTANCE', default='assistance@localhost')
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<title>
|
||||
Confirmation de votre participation au scrutin « {{ pouvoir.scrutin.title }} »
|
||||
</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Bonjour {{ pouvoir.prenom }} {{ pouvoir.nom }},
|
||||
</p>
|
||||
<p>
|
||||
Nous avons bien enregistré votre vote pour le scrutin
|
||||
« {{ pouvoir.scrutin.title }} ».
|
||||
</p>
|
||||
<p>
|
||||
Vous pouvez à tout moment jusque la fin du scrutin retrouver votre contribution
|
||||
et éventuellement la corriger à cette adresse :<br>
|
||||
<a rel="noreferrer"href="{{ request.scheme }}://{{ request.get_host }}{{ pouvoir.scrutin.url_path }}{{ pouvoir.uuid }}">
|
||||
{{ request.scheme }}://{{ request.get_host }}{{ pouvoir.scrutin.url_path }}{{ pouvoir.uuid }}
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
Merci pour votre participation.
|
||||
</p>
|
||||
<hr>
|
||||
<p>
|
||||
Ce courriel a été envoyé automatiquement ; merci de ne pas y répondre.<br>
|
||||
Pour plus d'informations :
|
||||
<a rel="noreferrer"href="{{ request.scheme }}://{{ request.get_host }}">
|
||||
{{ request.scheme }}://{{ request.get_host }}
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
En cas de difficultés : <a href="mailto:{{ settings.assistance }}">contactez l'assistance</a>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
Confirmation de votre participation au scrutin « {{ pouvoir.scrutin.title | safe }} »
|
|
@ -0,0 +1,20 @@
|
|||
{% autoescape off %}
|
||||
Bonjour {{ pouvoir.prenom }} {{ pouvoir.nom }},
|
||||
|
||||
Nous avons bien enregistré votre vote pour le scrutin
|
||||
« {{ pouvoir.scrutin.title }} ».
|
||||
|
||||
Vous pouvez à tout moment jusque la fin du scrutin retrouver votre contribution
|
||||
et éventuellement la corriger à cette adresse :
|
||||
{{ request.scheme }}://{{ request.get_host }}{{ pouvoir.scrutin.url_path }}{{ pouvoir.uuid }}
|
||||
|
||||
Merci pour votre participation.
|
||||
L'équipe organisatrice
|
||||
---
|
||||
|
||||
Ce courriel a été envoyé automatiquement ; merci de ne pas y répondre.
|
||||
Pour plus d'informations : {{ request.scheme }}://{{ request.get_host }}
|
||||
|
||||
En cas de difficultés : {{ settings.assistance }}
|
||||
|
||||
{% endautoescape %}
|
Loading…
Reference in New Issue