[damned-lies] Set custom header to some mail sent by the application



commit fa8e7ab38445bd86ec31ee876fb56e460cd262e2
Author: Claude Paroz <claude 2xlibre net>
Date:   Thu Apr 20 12:19:17 2017 +0200

    Set custom header to some mail sent by the application
    
    Fixes bug #781498. Thanks Tobias Mueller for the initial patch.

 common/utils.py         |   12 +++++++++++-
 damnedlies/settings.py  |    1 +
 people/forms.py         |    8 +++-----
 people/tests.py         |    4 ++++
 stats/tests/tests.py    |    3 ++-
 stats/utils.py          |   12 +++++++-----
 teams/forms.py          |   11 ++++-------
 teams/models.py         |   15 +++++++--------
 teams/tests.py          |    9 +++++++--
 vertimus/models.py      |    7 +++++--
 vertimus/tests/tests.py |    5 ++++-
 11 files changed, 55 insertions(+), 32 deletions(-)
---
diff --git a/common/utils.py b/common/utils.py
index 7c75383..a1f2ec9 100644
--- a/common/utils.py
+++ b/common/utils.py
@@ -1,6 +1,7 @@
 from django.conf import settings
+from django.core.mail import EmailMessage
 from django.utils.translation import ugettext as _, get_language
-from languages.models import Language
+
 try:
     import icu
     pyicu_present = True
@@ -35,7 +36,16 @@ def is_site_admin(user):
 
 
 def get_user_locale(request):
+    from languages.models import Language  # Import here to prevent loop
+
     curlang = Language.get_language_from_ianacode(request.LANGUAGE_CODE)
     if curlang and curlang.locale == 'en':
         curlang = None
     return curlang
+
+
+def send_mail(subject, message, **kwargs):
+    """Wrapper to Django's send_mail allowing all EmailMessage init arguments."""
+    if not subject.startswith(settings.EMAIL_SUBJECT_PREFIX):
+        subject = '%s %s' % (settings.EMAIL_SUBJECT_PREFIX, subject)
+    EmailMessage(subject, message, **kwargs).send()
diff --git a/damnedlies/settings.py b/damnedlies/settings.py
index 8abf61c..f07ef87 100644
--- a/damnedlies/settings.py
+++ b/damnedlies/settings.py
@@ -28,6 +28,7 @@ EMAIL_HOST = 'localhost'
 EMAIL_HOST_USER = ''
 EMAIL_HOST_PASSWORD = ''
 EMAIL_SUBJECT_PREFIX = '[Damned Lies]'
+EMAIL_HEADER_NAME= 'X-Vertimus'
 DEFAULT_FROM_EMAIL = 'gnomeweb gnome org'
 SERVER_EMAIL = 'gnomeweb gnome org'
 # When in STRINGFREEZE, where to send notifications (gnome-i18n gnome org) on any POT changes
diff --git a/people/forms.py b/people/forms.py
index 06f1f4b..56b7565 100644
--- a/people/forms.py
+++ b/people/forms.py
@@ -6,14 +6,15 @@ from django import forms
 from django.conf import settings
 from django.contrib.sites.shortcuts import get_current_site
 from django.core.exceptions import ValidationError
-from django.core.mail import send_mail
 from django.core.urlresolvers import reverse
 from django.utils.encoding import force_bytes
 from django.utils.translation import ugettext_lazy, ugettext as _
 
+from common.utils import send_mail
 from teams.models import Team
 from people.models import Person
 
+
 class RegistrationForm(forms.Form):
     """ Form for user registration """
     username = forms.RegexField(max_length=30, regex=r'^\w+$',
@@ -80,14 +81,11 @@ class RegistrationForm(forms.Form):
         new_user.save()
         # Send activation email
         current_site = get_current_site(request)
-        subject = settings.EMAIL_SUBJECT_PREFIX + _('Account activation')
         message = _("This is a confirmation that your registration on %s succeeded. To activate your 
account, please click on the link below or copy and paste it in a browser.") % current_site.name
         message += "\n\nhttps://%s%s\n\n"; % (current_site.domain, str(reverse("register_activation", 
kwargs={'key': activation_key})))
         message += _("Administrators of %s" % current_site.name)
 
-        send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
-                  (email,), fail_silently=False)
-
+        send_mail(_('Account activation'), message, to=[email])
         return new_user
 
 class DetailForm(forms.ModelForm):
diff --git a/people/tests.py b/people/tests.py
index 2dd3b0a..265e17a 100644
--- a/people/tests.py
+++ b/people/tests.py
@@ -2,9 +2,11 @@ import datetime
 from unittest import skipUnless
 
 from django.test import TestCase
+from django.core import mail
 from django.core.exceptions import ValidationError
 from django.core.urlresolvers import reverse
 from django.utils.safestring import SafeData
+from django.utils.translation import ugettext as _
 
 from common.utils import pyicu_present
 from people.models import Person, obfuscate_email
@@ -31,6 +33,8 @@ class PeopleTestCase(TestCase):
         )
         self.assertRedirects(response, reverse('register_success'))
         self.assertEqual(Person.objects.filter(username=username).count(), 1)
+        self.assertEqual(len(mail.outbox), 1);
+        self.assertIn(_('Account activation'), mail.outbox[0].subject)
 
     def test_person_list(self):
         self.pn = self._create_person()
diff --git a/stats/tests/tests.py b/stats/tests/tests.py
index 4d7ceec..88beaab 100644
--- a/stats/tests/tests.py
+++ b/stats/tests/tests.py
@@ -220,7 +220,8 @@ class ModuleTestCase(TestCase):
         self.branch.update_stats(force=False, checkout=False)
         # Assertions
         self.assertEqual(len(mail.outbox), 1);
-        self.assertEqual(mail.outbox[0].subject, "String additions to 'gnome-hello.master'")
+        self.assertEqual(mail.outbox[0].subject, "[Damned Lies] String additions to 'gnome-hello.master'")
+        self.assertEqual(mail.outbox[0].extra_headers, {settings.EMAIL_HEADER_NAME: 'stringchange'})
         self.assertIn('"%s"' % new_string, mail.outbox[0].body)
 
     @test_scratchdir
diff --git a/stats/utils.py b/stats/utils.py
index cc7e5b9..babecf6 100644
--- a/stats/utils.py
+++ b/stats/utils.py
@@ -17,11 +17,11 @@ except ImportError:
 from django.conf import settings
 from django.contrib.sites.models import Site
 from django.core.files.base import File
-from django.core.mail import send_mail
 from django.template.loader import get_template
 from django.utils.encoding import force_text
 from django.utils.translation import ugettext_noop
 
+from common.utils import send_mail
 from . import potdiff
 
 STATUS_OK = 0
@@ -572,10 +572,12 @@ def notify_list(branch, diff):
         'potdiff': force_text("\n    ".join(diff)),
         'commit_log': branch.get_vcs_web_log_url(),
     })
-    send_mail(subject="String additions to '%s.%s'" % (branch.module.name, branch.name),
-              message=text,
-              from_email="GNOME Status Pages <%s>" % (settings.DEFAULT_FROM_EMAIL),
-              recipient_list=settings.NOTIFICATIONS_TO)
+    send_mail("String additions to '%s.%s'" % (branch.module.name, branch.name),
+              text,
+              from_email="GNOME Status Pages <%s>" % settings.DEFAULT_FROM_EMAIL,
+              to=settings.NOTIFICATIONS_TO,
+              headers={settings.EMAIL_HEADER_NAME: "stringchange"})
+
 
 def url_join(base, *args):
     """ Create an url in joining base with arguments. A lot nicer than urlparse.urljoin! """
diff --git a/teams/forms.py b/teams/forms.py
index 69d3204..46c3df8 100644
--- a/teams/forms.py
+++ b/teams/forms.py
@@ -1,12 +1,12 @@
 from django import forms
 from django.conf import settings
 from django.contrib.sites.shortcuts import get_current_site
-from django.core.mail import send_mail
 from django.utils.translation import ugettext as _
 
-from common.utils import is_site_admin
+from common.utils import is_site_admin, send_mail
 from teams.models import Team, Role, ROLE_CHOICES
 
+
 class EditTeamDetailsForm(forms.ModelForm):
     class Meta:
         model = Team
@@ -81,26 +81,23 @@ class EditMemberRoleForm(forms.Form):
                 role = Role.objects.get(pk=key)
                 if form_value == "remove":
                     team = role.team.description
-                    email = role.person.email
                     role.delete()
-                    subject = settings.EMAIL_SUBJECT_PREFIX + ' ' + _('Removed from team')
                     message = _("You have been removed from the %(team)s team on %(site)s") % {
                         'team': team,
                         'site': current_site,
                     }
                     message += "\n\n" + _("This is an automatic message sent from %(site)s. Please do not 
answer.") % {'site': current_site}
-                    send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [email])
+                    send_mail(_('Removed from team'), message, to=[role.person.email])
                 elif form_value == "inactivate":
                     role.is_active = False
                     role.save()
                 else:
                     role.role = form_value
                     role.save()
-                    subject = settings.EMAIL_SUBJECT_PREFIX + ' ' + _('Role changed')
                     message = _("Your role in the %(team)s team on %(site)s has been set to ā€œ%(role)sā€") % {
                         'team': role.team.description,
                         'site': current_site,
                         'role': role.get_role_display(),
                     }
                     message += "\n\n" + _("This is an automatic message sent from %(site)s. Please do not 
answer.") % {'site': current_site}
-                    send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [role.person.email])
+                    send_mail(_('Role changed'), message, to=[role.person.email])
diff --git a/teams/models.py b/teams/models.py
index 5e7804d..f58484a 100644
--- a/teams/models.py
+++ b/teams/models.py
@@ -1,15 +1,16 @@
 from datetime import datetime, timedelta
 
 from django.db import models
-from django.core import mail
 from django.core.urlresolvers import reverse
 from django.utils import translation
-from django.utils.encoding import force_text
 from django.utils.translation import ugettext_lazy, ugettext as _
 from django.conf import settings
 from django.contrib.sites.models import Site
+
+from common.utils import send_mail
 from people.models import Person
 
+
 class TeamManager(models.Manager):
 
     def all_with_coordinator(self):
@@ -177,14 +178,12 @@ class Team(models.Model):
         recipients = [pers.email for pers in self.get_coordinators() if pers.email]
         if not recipients:
             return
-        with translation.override(self.language_set.all()[0].locale):
+        with translation.override(self.language_set.first().locale):
             message = "%s\n--\n" % (message % messagekw,)
             message += _("This is an automated message sent from %s.") % Site.objects.get_current()
-            mail.send_mail(
-                force_text(subject),
-                message,
-                settings.DEFAULT_FROM_EMAIL,
-                recipients
+            send_mail(
+                str(subject), message, to=recipients,
+                headers={settings.EMAIL_HEADER_NAME: "coordinator-mail"}
             )
 
 
diff --git a/teams/tests.py b/teams/tests.py
index 14f38d5..2a42c82 100644
--- a/teams/tests.py
+++ b/teams/tests.py
@@ -1,5 +1,6 @@
 from datetime import datetime, timedelta
 
+from django.conf import settings
 from django.core.urlresolvers import reverse
 from django.core import mail
 from django.test import TestCase
@@ -196,11 +197,15 @@ class TeamTest(TeamsAndRolesTests):
     def test_send_mail_to_coordinator(self):
         self.t.send_mail_to_coordinator(subject="foo", message="bar")
         self.assertEqual(len(mail.outbox), 1)
-        self.assertEqual(mail.outbox[0].subject, "foo")
+        self.assertEqual(mail.outbox[0].subject, "%s foo" % settings.EMAIL_SUBJECT_PREFIX)
+        self.assertEqual(mail.outbox[0].extra_headers, {settings.EMAIL_HEADER_NAME: 'coordinator-mail'})
         # the message is sent in the language of the team
         self.t.send_mail_to_coordinator(subject=ugettext_lazy("About Damned Lies"), message="...")
         self.assertEqual(len(mail.outbox), 2)
-        self.assertEqual(mail.outbox[1].subject, "ƀ propos de Damned Lies")
+        self.assertEqual(
+            mail.outbox[1].subject,
+            "%s ƀ propos de Damned Lies" % settings.EMAIL_SUBJECT_PREFIX
+        )
 
 
 class JSONTeamsTest(TeamsAndRolesTests):
diff --git a/vertimus/models.py b/vertimus/models.py
index 397afc2..cbb0ae0 100644
--- a/vertimus/models.py
+++ b/vertimus/models.py
@@ -4,7 +4,6 @@ from datetime import datetime, timedelta
 
 from django.conf import settings
 from django.contrib.sites.models import Site
-from django.core import mail
 from django.core.urlresolvers import reverse
 from django.db import models
 from django.db.models import Max
@@ -12,6 +11,7 @@ from django.db.models.signals import post_save, pre_delete
 from django.dispatch import receiver
 from django.utils.translation import override, ugettext, ugettext_noop, ugettext_lazy as _
 
+from common.utils import send_mail
 from stats.models import Branch, Domain, Statistics, PoFile
 from stats.signals import pot_has_changed
 from stats.utils import run_shell_command, is_po_reduced, po_grep
@@ -528,7 +528,10 @@ class Action(ActionAbstract):
             message += "\n\n" + self.person.name
             message += "\n--\n" + ugettext("This is an automated message sent from %s.") % 
current_site.domain
         try:
-            mail.send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, recipient_list)
+            send_mail(
+                subject, message, to=recipient_list,
+                headers={settings.EMAIL_HEADER_NAME: state.description}
+            )
         except Exception as exc:
             raise SendMailFailed("Sending message failed: %r" % exc)
 
diff --git a/vertimus/tests/tests.py b/vertimus/tests/tests.py
index 4ef6964..3e78079 100644
--- a/vertimus/tests/tests.py
+++ b/vertimus/tests/tests.py
@@ -246,6 +246,7 @@ class VertimusTest(TeamsAndRolesTests):
         action.apply_on(state, {'send_to_ml': action.send_mail_to_ml, 'comment': "Hi!"})
         self.assertEqual(len(mail.outbox), 1)
         self.assertEqual(mail.outbox[0].recipients(), [self.l.team.get_coordinators()[0].email])
+        self.assertEqual(mail.outbox[0].extra_headers, {settings.EMAIL_HEADER_NAME: 'Inactive'})
         # Second comment by someone else, mail sent to the other person
         action = Action.new_by_name('WC', person=self.pr)
         action.apply_on(state, {'send_to_ml': action.send_mail_to_ml, 'comment': "Great!"})
@@ -264,6 +265,7 @@ class VertimusTest(TeamsAndRolesTests):
         self.assertEqual(len(mail.outbox), 1)
         self.assertEqual(mail.outbox[0].recipients(), [self.l.team.mailing_list])
         self.assertIn("Hi again!", mail.outbox[0].body)
+        self.assertEqual(mail.outbox[0].extra_headers, {settings.EMAIL_HEADER_NAME: 'Inactive'})
 
     def test_action_rt(self):
         state = StateNone(branch=self.b, domain=self.d, language=self.l)
@@ -297,7 +299,8 @@ class VertimusTest(TeamsAndRolesTests):
         # Mail sent to mailing list
         self.assertEqual(len(mail.outbox), 1)
         self.assertEqual(mail.outbox[0].recipients(), [self.l.team.mailing_list])
-        self.assertEqual(mail.outbox[0].subject, "gedit - gnome-2-24")
+        self.assertEqual(mail.outbox[0].subject, "%s gedit - gnome-2-24" % settings.EMAIL_SUBJECT_PREFIX)
+        self.assertEqual(mail.outbox[0].extra_headers, {settings.EMAIL_HEADER_NAME: 'Translated'})
 
         # Testing if the role was activated
         role = Role.objects.get(person=self.pt, team=self.l.team)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]