i18n in emails

remotes/origin/enhancement/email-actions
David Barragán Merino 2015-03-26 13:42:58 +01:00
parent 027e15475d
commit 2d960c7a5d
12 changed files with 68 additions and 27 deletions

View File

@ -58,7 +58,7 @@ def send_register_email(user) -> bool:
cancel_token = get_token_for_user(user, "cancel_account")
context = {"user": user, "cancel_token": cancel_token}
mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail)
email = mbuilder.registered_user(user.email, context)
email = mbuilder.registered_user(user, context)
return bool(email.send())

View File

@ -16,6 +16,8 @@
import datetime
from optparse import make_option
from django.db.models.loading import get_model
from django.core.management.base import BaseCommand
from django.utils import timezone
@ -30,6 +32,11 @@ from taiga.users.models import User
class Command(BaseCommand):
args = '<email>'
option_list = BaseCommand.option_list + (
make_option('--locale', '-l', default=None, dest='locale',
help='Send emails in an specific language.'),
)
help = 'Send an example of all emails'
def handle(self, *args, **options):
@ -37,12 +44,13 @@ class Command(BaseCommand):
print("Usage: ./manage.py test_emails <email-address>")
return
locale = options.get('locale')
test_email = args[0]
mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail)
# Register email
context = {"user": User.objects.all().order_by("?").first(), "cancel_token": "cancel-token"}
context = {"lang": locale, "user": User.objects.all().order_by("?").first(), "cancel_token": "cancel-token"}
email = mbuilder.registered_user(test_email, context)
email.send()
@ -51,17 +59,18 @@ class Command(BaseCommand):
membership.invited_by = User.objects.all().order_by("?").first()
membership.invitation_extra_text = "Text example, Text example,\nText example,\n\nText example"
context = {"membership": membership}
context = {"lang": locale, "membership": membership}
email = mbuilder.membership_invitation(test_email, context)
email.send()
# Membership notification
context = {"membership": Membership.objects.order_by("?").filter(user__isnull=False).first()}
context = {"lang": locale, "membership": Membership.objects.order_by("?").filter(user__isnull=False).first()}
email = mbuilder.membership_notification(test_email, context)
email.send()
# Feedback
context = {
"lang": locale,
"feedback_entry": {
"full_name": "Test full name",
"email": "test@email.com",
@ -76,17 +85,18 @@ class Command(BaseCommand):
email.send()
# Password recovery
context = {"user": User.objects.all().order_by("?").first()}
context = {"lang": locale, "user": User.objects.all().order_by("?").first()}
email = mbuilder.password_recovery(test_email, context)
email.send()
# Change email
context = {"user": User.objects.all().order_by("?").first()}
context = {"lang": locale, "user": User.objects.all().order_by("?").first()}
email = mbuilder.change_email(test_email, context)
email.send()
# Export/Import emails
context = {
"lang": locale,
"user": User.objects.all().order_by("?").first(),
"project": Project.objects.all().order_by("?").first(),
"error_subject": "Error generating project dump",
@ -95,6 +105,7 @@ class Command(BaseCommand):
email = mbuilder.export_error(test_email, context)
email.send()
context = {
"lang": locale,
"user": User.objects.all().order_by("?").first(),
"error_subject": "Error importing project dump",
"error_message": "Error importing project dump",
@ -104,6 +115,7 @@ class Command(BaseCommand):
deletion_date = timezone.now() + datetime.timedelta(seconds=60*60*24)
context = {
"lang": locale,
"url": "http://dummyurl.com",
"user": User.objects.all().order_by("?").first(),
"project": Project.objects.all().order_by("?").first(),
@ -113,6 +125,7 @@ class Command(BaseCommand):
email.send()
context = {
"lang": locale,
"user": User.objects.all().order_by("?").first(),
"project": Project.objects.all().order_by("?").first(),
}
@ -139,6 +152,7 @@ class Command(BaseCommand):
]
context = {
"lang": locale,
"project": Project.objects.all().order_by("?").first(),
"changer": User.objects.all().order_by("?").first(),
"history_entries": HistoryEntry.objects.all().order_by("?")[0:5],

View File

@ -49,7 +49,7 @@ def dump_project(self, user, project):
"error_message": "Error generating project dump",
"project": project
}
email = mbuilder.export_error(user.email, ctx)
email = mbuilder.export_error(user, ctx)
email.send()
return
@ -60,7 +60,7 @@ def dump_project(self, user, project):
"user": user,
"deletion_date": deletion_date
}
email = mbuilder.dump_project(user.email, ctx)
email = mbuilder.dump_project(user, ctx)
email.send()
@ -81,10 +81,10 @@ def load_project_dump(user, dump):
"error_subject": "Error loading project dump",
"error_message": "Error loading project dump",
}
email = mbuilder.import_error(user.email, ctx)
email = mbuilder.import_error(user, ctx)
email.send()
return
ctx = {"user": user, "project": project}
email = mbuilder.load_dump(user.email, ctx)
email = mbuilder.load_dump(user, ctx)
email.send()

View File

@ -269,6 +269,7 @@ def send_sync_notifications(notification_id):
for user in notification.notify_users.distinct():
context["user"] = user
context["lang"] = user.lang
email.send(user.email, context)
notification.delete()

View File

@ -9,10 +9,11 @@ def send_invitation(invitation):
mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail)
if invitation.user:
template = mbuilder.membership_notification
email = template(invitation.user, {"membership": invitation})
else:
template = mbuilder.membership_invitation
email = template(invitation.email, {"membership": invitation})
email.send()

View File

@ -48,7 +48,7 @@ class UserAdmin(DjangoUserAdmin):
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('full_name', 'email', 'bio', 'photo')}),
(_('Extra info'), {'fields': ('color', 'default_language', 'default_timezone', 'token', 'colorize_tags', 'email_token', 'new_email')}),
(_('Extra info'), {'fields': ('color', 'lang', 'timezone', 'token', 'colorize_tags', 'email_token', 'new_email')}),
(_('Permissions'), {'fields': ('is_active', 'is_superuser',)}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)

View File

@ -97,7 +97,7 @@ class UsersViewSet(ModelCrudViewSet):
user.save(update_fields=["token"])
mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail)
email = mbuilder.password_recovery(user.email, {"user": user})
email = mbuilder.password_recovery(user, {"user": user})
email.send()
return response.Ok({"detail": _("Mail sended successful!"),
@ -231,7 +231,8 @@ class UsersViewSet(ModelCrudViewSet):
request.user.new_email = new_email
request.user.save(update_fields=["email_token", "new_email"])
mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail)
email = mbuilder.change_email(request.user.new_email, {"user": request.user})
email = mbuilder.change_email(request.user.new_email, {"user": request.user,
"lang": request.user.lang})
email.send()
return ret

View File

@ -5,12 +5,12 @@
"username": "admin",
"full_name": "",
"bio": "",
"default_language": "",
"lang": "",
"color": "",
"photo": "",
"is_active": true,
"colorize_tags": false,
"default_timezone": "",
"timezone": "",
"is_superuser": true,
"token": "",
"last_login": "2013-04-04T07:36:09.880Z",

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('users', '0008_auto_20150213_1701'),
]
operations = [
migrations.RenameField(
model_name='user',
old_name='default_language',
new_name='lang',
),
migrations.RenameField(
model_name='user',
old_name='default_timezone',
new_name='timezone',
),
]

View File

@ -116,9 +116,9 @@ class User(AbstractBaseUser, PermissionsMixin):
max_length=500, null=True, blank=True,
verbose_name=_("photo"))
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
default_language = models.CharField(max_length=20, null=False, blank=True, default="",
lang = models.CharField(max_length=20, null=False, blank=True, default="",
verbose_name=_("default language"))
default_timezone = models.CharField(max_length=20, null=False, blank=True, default="",
timezone = models.CharField(max_length=20, null=False, blank=True, default="",
verbose_name=_("default timezone"))
colorize_tags = models.BooleanField(null=False, blank=True, default=False,
verbose_name=_("colorize tags"))
@ -166,8 +166,8 @@ class User(AbstractBaseUser, PermissionsMixin):
self.full_name = "Deleted user"
self.color = ""
self.bio = ""
self.default_language = ""
self.default_timezone = ""
self.lang = ""
self.timezone = ""
self.colorize_tags = True
self.token = None
self.set_unusable_password()

View File

@ -43,8 +43,8 @@ class UserSerializer(ModelSerializer):
# IMPORTANT: Maintain the UserAdminSerializer Meta up to date
# with this info (including there the email)
fields = ("id", "username", "full_name", "full_name_display",
"color", "bio", "default_language",
"default_timezone", "is_active", "photo", "big_photo")
"color", "bio", "lang", "timezone", "is_active",
"photo", "big_photo")
read_only_fields = ("id",)
def validate_username(self, attrs, source):
@ -81,8 +81,8 @@ class UserAdminSerializer(UserSerializer):
# IMPORTANT: Maintain the UserSerializer Meta up to date
# with this info (including here the email)
fields = ("id", "username", "full_name", "full_name_display", "email",
"color", "bio", "default_language",
"default_timezone", "is_active", "photo", "big_photo")
"color", "bio", "lang", "timezone", "is_active", "photo",
"big_photo")
read_only_fields = ("id", "email")

View File

@ -80,7 +80,7 @@ def test_api_create_bulk_members_with_extra_text(client, outbox):
def test_api_resend_invitation(client, outbox):
invitation = f.create_invitation()
invitation = f.create_invitation(user=None)
f.MembershipFactory(project=invitation.project, user=invitation.project.owner, is_owner=True)
url = reverse("memberships-resend-invitation", kwargs={"pk": invitation.pk})