footer in mail notifications

This commit is contained in:
Élie Bouttier 2017-08-11 23:25:42 +02:00
parent 5f8b92c0aa
commit 2452a3497c
7 changed files with 81 additions and 48 deletions

View File

@ -101,7 +101,7 @@ class UsersWidget(ModelSelect2MultipleWidget):
class ConferenceForm(forms.ModelForm): class ConferenceForm(forms.ModelForm):
class Meta: class Meta:
model = Conference model = Conference
fields = ['name', 'home', 'venue', 'city', 'contact_email', 'reply_email', 'staff',] fields = ['name', 'home', 'venue', 'city', 'contact_email', 'reply_email', 'secure_domain', 'staff',]
widgets = { widgets = {
'staff': UsersWidget(), 'staff': UsersWidget(),
} }

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.3 on 2017-08-11 21:18
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cfp', '0006_auto_20170811_1457'),
]
operations = [
migrations.AddField(
model_name='conference',
name='secure_domain',
field=models.BooleanField(default=True, verbose_name='Secure domain'),
),
]

View File

@ -30,6 +30,7 @@ class Conference(models.Model):
contact_email = models.CharField(max_length=100, blank=True, verbose_name=_('Contact email')) contact_email = models.CharField(max_length=100, blank=True, verbose_name=_('Contact email'))
reply_email = models.CharField(max_length=100, blank=True, verbose_name=_('Reply email')) reply_email = models.CharField(max_length=100, blank=True, verbose_name=_('Reply email'))
staff = models.ManyToManyField(User, blank=True, verbose_name=_('Staff members')) staff = models.ManyToManyField(User, blank=True, verbose_name=_('Staff members'))
secure_domain = models.BooleanField(default=True, verbose_name=_('Secure domain (HTTPS)'))
custom_css = models.TextField(blank=True) custom_css = models.TextField(blank=True)
external_css_link = models.URLField(blank=True) external_css_link = models.URLField(blank=True)

View File

@ -4,6 +4,7 @@ from django.contrib.sites.models import Site
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from ponyconf.decorators import disable_for_loaddata from ponyconf.decorators import disable_for_loaddata
from mailing.models import MessageThread, Message from mailing.models import MessageThread, Message
@ -77,6 +78,8 @@ def send_message_notifications(sender, instance, **kwargs):
participant_dests = [ (participant.name, participant.email) ] participant_dests = [ (participant.name, participant.email) ]
participant_subject = _('[%(prefix)s] Message from the staff') % {'prefix': conf.name} participant_subject = _('[%(prefix)s] Message from the staff') % {'prefix': conf.name}
staff_subject = _('[%(prefix)s] Conversation with %(dest)s') % {'prefix': conf.name, 'dest': participant.name} staff_subject = _('[%(prefix)s] Conversation with %(dest)s') % {'prefix': conf.name, 'dest': participant.name}
proto = 'https' if conf.secure_domain else 'http'
footer = '\n\n--\n%s://' % proto + conf.site.domain + reverse('participant-details', args=[participant.token])
if message.from_email == conf.contact_email: # this is a talk notification message if message.from_email == conf.contact_email: # this is a talk notification message
# send it only to the participant # send it only to the participant
message.send_notification(subject=subject_prefix+participant_subject, sender=sender, dests=participant_dests, message.send_notification(subject=subject_prefix+participant_subject, sender=sender, dests=participant_dests,
@ -84,15 +87,17 @@ def send_message_notifications(sender, instance, **kwargs):
else: else:
# this is a message between the staff and the participant # this is a message between the staff and the participant
message.send_notification(subject=subject_prefix+staff_subject, sender=sender, dests=staff_dests, message.send_notification(subject=subject_prefix+staff_subject, sender=sender, dests=staff_dests,
reply_to=reply_to, message_id=message_id, reference=reference) reply_to=reply_to, message_id=message_id, reference=reference, footer=footer)
if message.from_email != thread.participant.email: # message from staff: sent it to the participant too if message.from_email != thread.participant.email: # message from staff: sent it to the participant too
message.send_notification(subject=subject_prefix+participant_subject, sender=sender, dests=participant_dests, message.send_notification(subject=subject_prefix+participant_subject, sender=sender, dests=participant_dests,
reply_to=reply_to, message_id=message_id, reference=reference) reply_to=reply_to, message_id=message_id, reference=reference)
elif hasattr(thread, 'talk'): elif hasattr(thread, 'talk'):
conf = thread.talk.site.conference conf = thread.talk.site.conference
subject = _('[%(prefix)s] Talk: %(talk)s') % {'prefix': conf.name, 'talk': thread.talk.title} subject = _('[%(prefix)s] Talk: %(talk)s') % {'prefix': conf.name, 'talk': thread.talk.title}
proto = 'https' if conf.secure_domain else 'http'
footer = '\n\n--\n%s://' % proto + conf.site.domain + reverse('talk-details', args=[thread.talk.token])
message.send_notification(subject=subject_prefix+subject, sender=sender, dests=staff_dests, message.send_notification(subject=subject_prefix+subject, sender=sender, dests=staff_dests,
reply_to=reply_to, message_id=message_id, reference=reference) reply_to=reply_to, message_id=message_id, reference=reference, footer=footer)
# connected in apps.py # connected in apps.py

Binary file not shown.

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-08-02 18:25+0000\n" "POT-Creation-Date: 2017-08-11 21:21+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -24,31 +24,31 @@ msgstr ""
"Par exemple, vous devez rentrer le samedi soir, vous ne pouvez pas manger de " "Par exemple, vous devez rentrer le samedi soir, vous ne pouvez pas manger de "
"viande, etc." "viande, etc."
#: accounts/models.py:18 cfp/models.py:83 #: accounts/models.py:18 cfp/models.py:96
msgid "Phone number" msgid "Phone number"
msgstr "Numéro de téléphone" msgstr "Numéro de téléphone"
#: accounts/models.py:20 cfp/models.py:76 #: accounts/models.py:20 cfp/models.py:89
msgid "Twitter" msgid "Twitter"
msgstr "" msgstr ""
#: accounts/models.py:21 cfp/models.py:77 #: accounts/models.py:21 cfp/models.py:90
msgid "LinkedIn" msgid "LinkedIn"
msgstr "" msgstr ""
#: accounts/models.py:22 cfp/models.py:78 #: accounts/models.py:22 cfp/models.py:91
msgid "Github" msgid "Github"
msgstr "" msgstr ""
#: accounts/models.py:23 cfp/models.py:79 #: accounts/models.py:23 cfp/models.py:92
msgid "Website" msgid "Website"
msgstr "" msgstr ""
#: accounts/models.py:24 cfp/models.py:80 #: accounts/models.py:24 cfp/models.py:93
msgid "Facebook" msgid "Facebook"
msgstr "" msgstr ""
#: accounts/models.py:25 cfp/models.py:81 #: accounts/models.py:25 cfp/models.py:94
msgid "Mastodon" msgid "Mastodon"
msgstr "" msgstr ""
@ -100,7 +100,7 @@ msgstr "Contacter"
msgid "Edit" msgid "Edit"
msgstr "Éditer" msgstr "Éditer"
#: accounts/templates/accounts/participant_details.html:20 cfp/models.py:73 #: accounts/templates/accounts/participant_details.html:20 cfp/models.py:86
#: cfp/templates/cfp/staff/participant_details.html:10 #: cfp/templates/cfp/staff/participant_details.html:10
msgid "Biography" msgid "Biography"
msgstr "Biographie" msgstr "Biographie"
@ -174,7 +174,7 @@ msgid "Constraints"
msgstr "Contraintes" msgstr "Contraintes"
#: accounts/templates/accounts/participant_details.html:71 cfp/forms.py:53 #: accounts/templates/accounts/participant_details.html:71 cfp/forms.py:53
#: cfp/models.py:87 cfp/templates/cfp/staff/participant_details.html:14 #: cfp/models.py:100 cfp/templates/cfp/staff/participant_details.html:14
#: cfp/templates/cfp/staff/talk_details.html:92 proposals/models.py:161 #: cfp/templates/cfp/staff/talk_details.html:92 proposals/models.py:161
#: proposals/templates/proposals/talk_detail.html:102 #: proposals/templates/proposals/talk_detail.html:102
msgid "Notes" msgid "Notes"
@ -312,7 +312,7 @@ msgstr "Catégorie"
msgid "Title" msgid "Title"
msgstr "Titre" msgstr "Titre"
#: cfp/forms.py:52 cfp/models.py:141 #: cfp/forms.py:52 cfp/models.py:156
#: cfp/templates/cfp/staff/talk_details.html:71 proposals/models.py:54 #: cfp/templates/cfp/staff/talk_details.html:71 proposals/models.py:54
#: proposals/models.py:77 proposals/models.py:158 #: proposals/models.py:77 proposals/models.py:158
#: proposals/templates/proposals/talk_detail.html:72 volunteers/models.py:14 #: proposals/templates/proposals/talk_detail.html:72 volunteers/models.py:14
@ -330,7 +330,7 @@ msgstr "Visible par les orateurs"
msgid "Status" msgid "Status"
msgstr "Statut" msgstr "Statut"
#: cfp/forms.py:74 cfp/models.py:243 #: cfp/forms.py:74 cfp/models.py:258
#: cfp/templates/cfp/staff/talk_details.html:85 #: cfp/templates/cfp/staff/talk_details.html:85
#: cfp/templates/cfp/staff/talk_list.html:41 #: cfp/templates/cfp/staff/talk_list.html:41
#: cfp/templates/cfp/staff/track_form.html:14 proposals/models.py:160 #: cfp/templates/cfp/staff/track_form.html:14 proposals/models.py:160
@ -370,35 +370,39 @@ msgstr "Un utilisateur avec ce prénom et ce nom existe déjà."
msgid "A user with that email already exists." msgid "A user with that email already exists."
msgstr "Un utilisateur avec cet email existe déjà." msgstr "Un utilisateur avec cet email existe déjà."
#: cfp/models.py:25 #: cfp/models.py:26
msgid "Conference name" msgid "Conference name"
msgstr "Nom de la conférence" msgstr "Nom de la conférence"
#: cfp/models.py:26 #: cfp/models.py:27
msgid "Homepage (markdown)" msgid "Homepage (markdown)"
msgstr "Page daccueil (markdown)" msgstr "Page daccueil (markdown)"
#: cfp/models.py:27 #: cfp/models.py:28
msgid "Venue information" msgid "Venue information"
msgstr "Informations sur le lieu" msgstr "Informations sur le lieu"
#: cfp/models.py:28 #: cfp/models.py:29
msgid "City" msgid "City"
msgstr "Ville" msgstr "Ville"
#: cfp/models.py:29 #: cfp/models.py:30
msgid "Contact email" msgid "Contact email"
msgstr "Email de contact" msgstr "Email de contact"
#: cfp/models.py:30 #: cfp/models.py:31
msgid "Reply email" msgid "Reply email"
msgstr "Adresse de réponse" msgstr "Adresse de réponse"
#: cfp/models.py:31 #: cfp/models.py:32
msgid "Staff members" msgid "Staff members"
msgstr "Membres du staff" msgstr "Membres du staff"
#: cfp/models.py:59 #: cfp/models.py:33
msgid "Secure domain (HTTPS)"
msgstr "Domaine sécurisé (HTTPS)"
#: cfp/models.py:61
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"The reply email should be a formatable string accepting a token argument (e." "The reply email should be a formatable string accepting a token argument (e."
@ -407,33 +411,33 @@ msgstr ""
"Ladresse de réponse doit être une chaine de texte formatable avec un " "Ladresse de réponse doit être une chaine de texte formatable avec un "
"argument « token » (e.g. ponyconf+{token}@exemple.com)." "argument « token » (e.g. ponyconf+{token}@exemple.com)."
#: cfp/models.py:70 #: cfp/models.py:83
msgid "Your Name" msgid "Your Name"
msgstr "Votre Nom" msgstr "Votre Nom"
#: cfp/models.py:87 #: cfp/models.py:100
msgid "This field is only visible by organizers." msgid "This field is only visible by organizers."
msgstr "Ce champs est uniquement visible par les organisateurs." msgstr "Ce champs est uniquement visible par les organisateurs."
#: cfp/models.py:139 cfp/templates/cfp/staff/participant_list.html:49 #: cfp/models.py:154 cfp/templates/cfp/staff/participant_list.html:49
#: proposals/models.py:52 proposals/models.py:75 proposals/models.py:132 #: proposals/models.py:52 proposals/models.py:75 proposals/models.py:132
#: volunteers/models.py:12 #: volunteers/models.py:12
msgid "Name" msgid "Name"
msgstr "Nom" msgstr "Nom"
#: cfp/models.py:162 proposals/models.py:96 #: cfp/models.py:177 proposals/models.py:96
msgid "Default duration (min)" msgid "Default duration (min)"
msgstr "Durée par défaut (min)" msgstr "Durée par défaut (min)"
#: cfp/models.py:163 proposals/models.py:97 #: cfp/models.py:178 proposals/models.py:97
msgid "Color on program" msgid "Color on program"
msgstr "Couleur sur le programme" msgstr "Couleur sur le programme"
#: cfp/models.py:164 proposals/models.py:98 #: cfp/models.py:179 proposals/models.py:98
msgid "Label on program" msgid "Label on program"
msgstr "Label dans le xml du programme" msgstr "Label dans le xml du programme"
#: cfp/models.py:238 cfp/templates/cfp/staff/base.html:19 #: cfp/models.py:253 cfp/templates/cfp/staff/base.html:19
#: cfp/templates/cfp/staff/participant_list.html:8 #: cfp/templates/cfp/staff/participant_list.html:8
#: cfp/templates/cfp/staff/talk_details.html:75 #: cfp/templates/cfp/staff/talk_details.html:75
#: cfp/templates/cfp/staff/talk_list.html:40 proposals/models.py:154 #: cfp/templates/cfp/staff/talk_list.html:40 proposals/models.py:154
@ -443,19 +447,19 @@ msgstr "Label dans le xml du programme"
msgid "Speakers" msgid "Speakers"
msgstr "Orateurs" msgstr "Orateurs"
#: cfp/models.py:239 #: cfp/models.py:254
msgid "Talk Title" msgid "Talk Title"
msgstr "Titre de votre proposition:" msgstr "Titre de votre proposition:"
#: cfp/models.py:242 #: cfp/models.py:257
msgid "Description of your talk" msgid "Description of your talk"
msgstr "Description de votre proposition" msgstr "Description de votre proposition"
#: cfp/models.py:244 #: cfp/models.py:259
msgid "Message to organizers" msgid "Message to organizers"
msgstr "Message aux organisateurs" msgstr "Message aux organisateurs"
#: cfp/models.py:244 #: cfp/models.py:259
msgid "" msgid ""
"If you have any constraint or if you have anything that may help you to " "If you have any constraint or if you have anything that may help you to "
"select your talk, like a video or slides of your talk, please write it down " "select your talk, like a video or slides of your talk, please write it down "
@ -465,37 +469,37 @@ msgstr ""
"votre proposition, comme une vidéo, des slides, n'hésitez pas à les ajouter " "votre proposition, comme une vidéo, des slides, n'hésitez pas à les ajouter "
"ici." "ici."
#: cfp/models.py:245 #: cfp/models.py:260
msgid "Talk Category" msgid "Talk Category"
msgstr "Catégorie de proposition" msgstr "Catégorie de proposition"
#: cfp/models.py:246 #: cfp/models.py:261
msgid "I'm ok to be recorded on video" msgid "I'm ok to be recorded on video"
msgstr "Jaccepte dêtre enregistré en vidéo" msgstr "Jaccepte dêtre enregistré en vidéo"
#: cfp/models.py:247 #: cfp/models.py:262
msgid "Video licence" msgid "Video licence"
msgstr "Licence vidéo" msgstr "Licence vidéo"
#: cfp/models.py:248 #: cfp/models.py:263
msgid "I need sound" msgid "I need sound"
msgstr "Jai besoin de son" msgstr "Jai besoin de son"
#: cfp/models.py:251 proposals/models.py:165 #: cfp/models.py:266 proposals/models.py:165
msgid "Duration (min)" msgid "Duration (min)"
msgstr "Durée (min)" msgstr "Durée (min)"
#: cfp/signals.py:78 #: cfp/signals.py:79
#, python-format #, python-format
msgid "[%(prefix)s] Message from the staff" msgid "[%(prefix)s] Message from the staff"
msgstr "[%(prefix)s] Message du staff" msgstr "[%(prefix)s] Message du staff"
#: cfp/signals.py:79 #: cfp/signals.py:80
#, python-format #, python-format
msgid "[%(prefix)s] Conversation with %(dest)s" msgid "[%(prefix)s] Conversation with %(dest)s"
msgstr "[%(prefix)s] Conversation avec %(dest)s" msgstr "[%(prefix)s] Conversation avec %(dest)s"
#: cfp/signals.py:93 #: cfp/signals.py:96
#, python-format #, python-format
msgid "[%(prefix)s] Talk: %(talk)s" msgid "[%(prefix)s] Talk: %(talk)s"
msgstr "[%(prefix)s] Talk: %(talk)s" msgstr "[%(prefix)s] Talk: %(talk)s"
@ -959,7 +963,7 @@ msgid "You can use this page to communicate with the staff."
msgstr "" msgstr ""
"Vous pouvez utiliser cette page pour communiquer avec léquipe organisatrice." "Vous pouvez utiliser cette page pour communiquer avec léquipe organisatrice."
#: mailing/models.py:90 #: mailing/models.py:93
#, python-format #, python-format
msgid "Message from %(author)s" msgid "Message from %(author)s"
msgstr "Message de %(author)s" msgstr "Message de %(author)s"
@ -1011,11 +1015,11 @@ msgstr "Certains exposés ne sont pas encore planifiés."
msgid "No rooms." msgid "No rooms."
msgstr "Aucune salle." msgstr "Aucune salle."
#: ponyconf/settings.py:147 #: ponyconf/settings.py:146
msgid "English" msgid "English"
msgstr "Anglais" msgstr "Anglais"
#: ponyconf/settings.py:148 #: ponyconf/settings.py:147
msgid "French" msgid "French"
msgstr "Français" msgstr "Français"
@ -1059,7 +1063,7 @@ msgstr "Mot de passe oublié ?"
msgid "Password Change" msgid "Password Change"
msgstr "Changement de mot de passe" msgstr "Changement de mot de passe"
#: ponyconf/urls.py:26 #: ponyconf/urls.py:27
msgid "Email address" msgid "Email address"
msgstr "" msgstr ""

View File

@ -45,7 +45,7 @@ class Message(models.Model):
class Meta: class Meta:
ordering = ['created'] ordering = ['created']
def send_notification(self, subject, sender, dests, reply_to=None, message_id=None, reference=None): def send_notification(self, subject, sender, dests, reply_to=None, message_id=None, reference=None, footer=None):
messages = [] messages = []
for dest_name, dest_email in dests: for dest_name, dest_email in dests:
correspondent, created = MessageCorrespondent.objects.get_or_create(email=dest_email) correspondent, created = MessageCorrespondent.objects.get_or_create(email=dest_email)
@ -64,9 +64,12 @@ class Message(models.Model):
headers.update({ headers.update({
'References': message_id.format(id=reference), 'References': message_id.format(id=reference),
}) })
body = self.content
if footer is not None:
body += footer
messages.append(EmailMessage( messages.append(EmailMessage(
subject=subject, subject=subject,
body=self.content, body=body,
from_email='%s <%s>' % sender, from_email='%s <%s>' % sender,
to=['%s <%s>' % (dest_name, dest_email)], to=['%s <%s>' % (dest_name, dest_email)],
reply_to=reply_to_list, reply_to=reply_to_list,