Commit ed790882 authored by Michal Čihař's avatar Michal Čihař

Send all notification mails in single SMTP connection

Opening SMTP connection can be expensive, so let's reuse it as much as
we can.
Signed-off-by: default avatarMichal Čihař <michal@cihar.com>
parent e25aacb3
No related merge requests found
...@@ -31,7 +31,7 @@ from django.utils.translation import ugettext_lazy as _ ...@@ -31,7 +31,7 @@ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import Group, User, Permission from django.contrib.auth.models import Group, User, Permission
from django.utils import translation as django_translation from django.utils import translation as django_translation
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.core.mail import EmailMultiAlternatives from django.core.mail import EmailMultiAlternatives, get_connection
from django.utils.translation import LANGUAGE_SESSION_KEY from django.utils.translation import LANGUAGE_SESSION_KEY
from social.apps.django_app.default.models import UserSocialAuth from social.apps.django_app.default.models import UserSocialAuth
...@@ -43,6 +43,15 @@ import weblate ...@@ -43,6 +43,15 @@ import weblate
from weblate.appsettings import ANONYMOUS_USER_NAME, SITE_TITLE from weblate.appsettings import ANONYMOUS_USER_NAME, SITE_TITLE
def send_mails(mails):
"""Sends multiple mails in single connection."""
try:
connection = get_connection()
connection.send_messages(mails)
except SMTPException as error:
weblate.logger.error('Failed to send email: %s', error)
def notify_merge_failure(subproject, error, status): def notify_merge_failure(subproject, error, status):
''' '''
Notification on merge failure. Notification on merge failure.
...@@ -51,128 +60,168 @@ def notify_merge_failure(subproject, error, status): ...@@ -51,128 +60,168 @@ def notify_merge_failure(subproject, error, status):
subproject.project, subproject.project,
) )
users = set() users = set()
mails = []
for subscription in subscriptions: for subscription in subscriptions:
subscription.notify_merge_failure(subproject, error, status) mails.append(
subscription.notify_merge_failure(subproject, error, status)
)
users.add(subscription.user_id) users.add(subscription.user_id)
if subproject.project.owner and subproject.project.owner_id not in users: if subproject.project.owner and subproject.project.owner_id not in users:
subproject.project.owner.profile.notify_merge_failure( mails.append(
subproject, error, status subproject.project.owner.profile.notify_merge_failure(
subproject, error, status
)
) )
# Notify admins # Notify admins
send_notification_email( mails.append(
'en', get_notification_email(
'ADMINS', 'en',
'merge_failure', 'ADMINS',
subproject, 'merge_failure',
{ subproject,
'subproject': subproject, {
'status': status, 'subproject': subproject,
'error': error, 'status': status,
} 'error': error,
}
)
) )
send_mails(mails)
def notify_new_string(translation): def notify_new_string(translation):
''' '''
Notification on new string to translate. Notification on new string to translate.
''' '''
mails = []
subscriptions = Profile.objects.subscribed_new_string( subscriptions = Profile.objects.subscribed_new_string(
translation.subproject.project, translation.language translation.subproject.project, translation.language
) )
for subscription in subscriptions: for subscription in subscriptions:
subscription.notify_new_string(translation) mails.append(
subscription.notify_new_string(translation)
)
send_mails(mails)
def notify_new_language(subproject, language, user): def notify_new_language(subproject, language, user):
''' '''
Notify subscribed users about new language requests Notify subscribed users about new language requests
''' '''
mails = []
subscriptions = Profile.objects.subscribed_new_language( subscriptions = Profile.objects.subscribed_new_language(
subproject.project, subproject.project,
user user
) )
users = set() users = set()
for subscription in subscriptions: for subscription in subscriptions:
subscription.notify_new_language(subproject, language, user) mails.append(
subscription.notify_new_language(subproject, language, user)
)
users.add(subscription.user_id) users.add(subscription.user_id)
if subproject.project.owner and subproject.project.owner_id not in users: if subproject.project.owner and subproject.project.owner_id not in users:
subproject.project.owner.profile.notify_new_language( mails.append(
subproject, language, user subproject.project.owner.profile.notify_new_language(
subproject, language, user
)
) )
# Notify admins # Notify admins
send_notification_email( mails.append(
'en', get_notification_email(
'ADMINS', 'en',
'new_language', 'ADMINS',
subproject, 'new_language',
{ subproject,
'language': language, {
'user': user, 'language': language,
}, 'user': user,
user=user, },
user=user,
)
) )
send_mails(mails)
def notify_new_translation(unit, oldunit, user): def notify_new_translation(unit, oldunit, user):
''' '''
Notify subscribed users about new translation Notify subscribed users about new translation
''' '''
mails = []
subscriptions = Profile.objects.subscribed_any_translation( subscriptions = Profile.objects.subscribed_any_translation(
unit.translation.subproject.project, unit.translation.subproject.project,
unit.translation.language, unit.translation.language,
user user
) )
for subscription in subscriptions: for subscription in subscriptions:
subscription.notify_any_translation(unit, oldunit) mails.append(
subscription.notify_any_translation(unit, oldunit)
)
send_mails(mails)
def notify_new_contributor(unit, user): def notify_new_contributor(unit, user):
''' '''
Notify about new contributor. Notify about new contributor.
''' '''
mails = []
subscriptions = Profile.objects.subscribed_new_contributor( subscriptions = Profile.objects.subscribed_new_contributor(
unit.translation.subproject.project, unit.translation.subproject.project,
unit.translation.language, unit.translation.language,
user user
) )
for subscription in subscriptions: for subscription in subscriptions:
subscription.notify_new_contributor( mails.append(
unit.translation, user subscription.notify_new_contributor(
unit.translation, user
)
) )
send_mails(mails)
def notify_new_suggestion(unit, suggestion, user): def notify_new_suggestion(unit, suggestion, user):
''' '''
Notify about new suggestion. Notify about new suggestion.
''' '''
mails = []
subscriptions = Profile.objects.subscribed_new_suggestion( subscriptions = Profile.objects.subscribed_new_suggestion(
unit.translation.subproject.project, unit.translation.subproject.project,
unit.translation.language, unit.translation.language,
user user
) )
for subscription in subscriptions: for subscription in subscriptions:
subscription.notify_new_suggestion( mails.append(
unit.translation, subscription.notify_new_suggestion(
suggestion, unit.translation,
unit suggestion,
unit
)
) )
send_mails(mails)
def notify_new_comment(unit, comment, user, report_source_bugs): def notify_new_comment(unit, comment, user, report_source_bugs):
''' '''
Notify about new comment. Notify about new comment.
''' '''
mails = []
subscriptions = Profile.objects.subscribed_new_comment( subscriptions = Profile.objects.subscribed_new_comment(
unit.translation.subproject.project, unit.translation.subproject.project,
comment.language, comment.language,
user user
) )
for subscription in subscriptions: for subscription in subscriptions:
subscription.notify_new_comment(unit, comment, user) mails.append(
subscription.notify_new_comment(unit, comment, user)
)
# Notify upstream # Notify upstream
if comment.language is None and report_source_bugs != '': if comment.language is None and report_source_bugs != '':
...@@ -189,6 +238,8 @@ def notify_new_comment(unit, comment, user, report_source_bugs): ...@@ -189,6 +238,8 @@ def notify_new_comment(unit, comment, user, report_source_bugs):
user=user, user=user,
) )
send_mails(mails)
def get_notification_email(language, email, notification, def get_notification_email(language, email, notification,
translation_obj=None, context=None, headers=None, translation_obj=None, context=None, headers=None,
...@@ -500,7 +551,7 @@ class Profile(models.Model): ...@@ -500,7 +551,7 @@ class Profile(models.Model):
if not translation_obj.has_acl(self.user): if not translation_obj.has_acl(self.user):
return return
# Actually send notification # Actually send notification
send_notification_email( return get_notification_email(
self.language, self.language,
self.user.email, self.user.email,
notification, notification,
...@@ -518,7 +569,7 @@ class Profile(models.Model): ...@@ -518,7 +569,7 @@ class Profile(models.Model):
template = 'changed_translation' template = 'changed_translation'
else: else:
template = 'new_translation' template = 'new_translation'
self.notify_user( return self.notify_user(
template, template,
unit.translation, unit.translation,
{ {
...@@ -531,7 +582,7 @@ class Profile(models.Model): ...@@ -531,7 +582,7 @@ class Profile(models.Model):
''' '''
Sends notification on new language request. Sends notification on new language request.
''' '''
self.notify_user( return self.notify_user(
'new_language', 'new_language',
subproject, subproject,
{ {
...@@ -545,7 +596,7 @@ class Profile(models.Model): ...@@ -545,7 +596,7 @@ class Profile(models.Model):
''' '''
Sends notification on new strings to translate. Sends notification on new strings to translate.
''' '''
self.notify_user( return self.notify_user(
'new_string', 'new_string',
translation, translation,
) )
...@@ -554,7 +605,7 @@ class Profile(models.Model): ...@@ -554,7 +605,7 @@ class Profile(models.Model):
''' '''
Sends notification on new suggestion. Sends notification on new suggestion.
''' '''
self.notify_user( return self.notify_user(
'new_suggestion', 'new_suggestion',
translation, translation,
{ {
...@@ -567,7 +618,7 @@ class Profile(models.Model): ...@@ -567,7 +618,7 @@ class Profile(models.Model):
''' '''
Sends notification on new contributor. Sends notification on new contributor.
''' '''
self.notify_user( return self.notify_user(
'new_contributor', 'new_contributor',
translation, translation,
{ {
...@@ -579,7 +630,7 @@ class Profile(models.Model): ...@@ -579,7 +630,7 @@ class Profile(models.Model):
''' '''
Sends notification about new comment. Sends notification about new comment.
''' '''
self.notify_user( return self.notify_user(
'new_comment', 'new_comment',
unit.translation, unit.translation,
{ {
...@@ -594,7 +645,7 @@ class Profile(models.Model): ...@@ -594,7 +645,7 @@ class Profile(models.Model):
''' '''
Sends notification on merge failure. Sends notification on merge failure.
''' '''
self.notify_user( return self.notify_user(
'merge_failure', 'merge_failure',
subproject, subproject,
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment