From d3436668d802db889b3d67f390fe925635d2449f Mon Sep 17 00:00:00 2001 From: Pierre Jaury Date: Sun, 2 Oct 2016 14:23:44 +0200 Subject: [PATCH 1/9] Enable Babel --- admin/freeposte/__init__.py | 6 +++++- admin/requirements.txt | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/admin/freeposte/__init__.py b/admin/freeposte/__init__.py index facf4d0a..8d44fa65 100644 --- a/admin/freeposte/__init__.py +++ b/admin/freeposte/__init__.py @@ -4,6 +4,7 @@ import flask_bootstrap import flask_login import flask_script import flask_migrate +import flask_babel import os import docker @@ -23,7 +24,9 @@ default_config = { 'DEBUG': False, 'BOOTSTRAP_SERVE_LOCAL': True, 'DKIM_PATH': '/dkim/{domain}.{selector}.key', - 'DKIM_SELECTOR': 'dkim' + 'DKIM_SELECTOR': 'dkim', + 'BABEL_DEFAULT_LOCALE': 'en', + 'BABEL_DEFAULT_TIMEZONE': 'UTC' } # Load configuration from the environment if available @@ -36,6 +39,7 @@ db = flask_sqlalchemy.SQLAlchemy(app) migrate = flask_migrate.Migrate(app, db) login_manager = flask_login.LoginManager() login_manager.init_app(app) +babel = flask_babel.Babel(app) # Manager commnad manager = flask_script.Manager(app) diff --git a/admin/requirements.txt b/admin/requirements.txt index a7076531..1437717c 100644 --- a/admin/requirements.txt +++ b/admin/requirements.txt @@ -2,9 +2,10 @@ Flask Flask-Login Flask-SQLAlchemy Flask-bootstrap +Flask-Babel Flask-migrate Flask-script -flask_wtf +Flask-wtf WTForms-Components PyOpenSSL passlib From fe035114e9f05259b493b7d74684f5a3074b14dc Mon Sep 17 00:00:00 2001 From: Pierre Jaury Date: Sun, 2 Oct 2016 14:37:06 +0200 Subject: [PATCH 2/9] Enable Babel for forms --- admin/freeposte/admin/forms.py | 98 +++++++++++++++++----------------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/admin/freeposte/admin/forms.py b/admin/freeposte/admin/forms.py index 0aa0ec1f..ad1bc189 100644 --- a/admin/freeposte/admin/forms.py +++ b/admin/freeposte/admin/forms.py @@ -1,5 +1,6 @@ from wtforms import validators, fields, widgets from wtforms_components import fields as fields_ +from flask_babel import lazy_gettext as _ import flask_login import flask_wtf @@ -28,92 +29,93 @@ class DestinationField(fields.SelectMultipleField): def pre_validate(self, form): for item in self.data: if not self.validator.match(item): - raise validators.ValidationError("Invalid email address.") + raise validators.ValidationError(_('Invalid email address.')) class Confirmation(flask_wtf.FlaskForm): - submit = fields.SubmitField('Confirm') + submit = fields.SubmitField(_('Confirm')) class LoginForm(flask_wtf.FlaskForm): - email = fields.StringField('E-mail', [validators.Email()]) - pw = fields.PasswordField('Password', [validators.DataRequired()]) - submit = fields.SubmitField('Sign in') + email = fields.StringField(_('E-mail'), [validators.Email()]) + pw = fields.PasswordField(_('Password'), [validators.DataRequired()]) + submit = fields.SubmitField(_('Sign in')) class DomainForm(flask_wtf.FlaskForm): - name = fields.StringField('Domain name', [validators.DataRequired()]) - max_users = fields_.IntegerField('Maximum user count', default=10) - max_aliases = fields_.IntegerField('Maximum alias count', default=10) - comment = fields.StringField('Comment') - submit = fields.SubmitField('Create') + name = fields.StringField(_('Domain name'), [validators.DataRequired()]) + max_users = fields_.IntegerField(_('Maximum user count'), default=10) + max_aliases = fields_.IntegerField(_('Maximum alias count'), default=10) + comment = fields.StringField(_('Comment')) + submit = fields.SubmitField(_('Create')) class UserForm(flask_wtf.FlaskForm): - localpart = fields.StringField('E-mail', [validators.DataRequired()]) - pw = fields.PasswordField('Password', [validators.DataRequired()]) - pw2 = fields.PasswordField('Confirm password', [validators.EqualTo('pw')]) - quota_bytes = fields_.IntegerSliderField('Quota', default=1000000000) - enable_imap = fields.BooleanField('Allow IMAP access', default=True) - enable_pop = fields.BooleanField('Allow POP3 access', default=True) - comment = fields.StringField('Comment') - submit = fields.SubmitField('Save') + localpart = fields.StringField(_('E-mail'), [validators.DataRequired()]) + pw = fields.PasswordField(_('Password'), [validators.DataRequired()]) + pw2 = fields.PasswordField(_('Confirm password'), [validators.EqualTo('pw')]) + quota_bytes = fields_.IntegerSliderField(_('Quota'), default=1000000000) + enable_imap = fields.BooleanField(_('Allow IMAP access'), default=True) + enable_pop = fields.BooleanField(_('Allow POP3 access'), default=True) + comment = fields.StringField(_('Comment')) + submit = fields.SubmitField(_('Save')) class UserSettingsForm(flask_wtf.FlaskForm): - displayed_name = fields.StringField('Displayed name') - spam_enabled = fields.BooleanField('Enable spam filter') - spam_threshold = fields_.IntegerSliderField('Spam filter threshold') - submit = fields.SubmitField('Save settings') + displayed_name = fields.StringField(_('Displayed name')) + spam_enabled = fields.BooleanField(_('Enable spam filter')) + spam_threshold = fields_.IntegerSliderField(_('Spam filter threshold')) + submit = fields.SubmitField(_('Save settings')) class UserPasswordForm(flask_wtf.FlaskForm): - pw = fields.PasswordField('Password', [validators.DataRequired()]) - pw2 = fields.PasswordField('Password check', [validators.DataRequired()]) - submit = fields.SubmitField('Update password') + pw = fields.PasswordField(_('Password'), [validators.DataRequired()]) + pw2 = fields.PasswordField(_('Password check'), [validators.DataRequired()]) + submit = fields.SubmitField(_('Update password')) class UserForwardForm(flask_wtf.FlaskForm): - forward_enabled = fields.BooleanField('Enable forwarding') + forward_enabled = fields.BooleanField(_('Enable forwarding')) forward_destination = fields.StringField( - 'Destination', [validators.Optional(), validators.Email()] + _('Destination'), [validators.Optional(), validators.Email()] ) - submit = fields.SubmitField('Update') + submit = fields.SubmitField(_('Update')) class UserReplyForm(flask_wtf.FlaskForm): - reply_enabled = fields.BooleanField('Enable automatic reply') - reply_subject = fields.StringField('Reply subject') - reply_body = fields.StringField('Reply body', widget=widgets.TextArea()) - submit = fields.SubmitField('Update') + reply_enabled = fields.BooleanField(_('Enable automatic reply')) + reply_subject = fields.StringField(_('Reply subject')) + reply_body = fields.StringField(_('Reply body'), + widget=widgets.TextArea()) + submit = fields.SubmitField(_('Update')) class AliasForm(flask_wtf.FlaskForm): - localpart = fields.StringField('Alias', [validators.DataRequired()]) + localpart = fields.StringField(_('Alias'), [validators.DataRequired()]) wildcard = fields.BooleanField( - 'Use SQL Like Syntax (e.g. for catch-all aliases, admin-%@domain.com)') - destination = DestinationField('Destination') - comment = fields.StringField('Comment') - submit = fields.SubmitField('Create') + _('Use SQL LIKE Syntax (e.g. for catch-all aliases)')) + destination = DestinationField(_('Destination')) + comment = fields.StringField(_('Comment')) + submit = fields.SubmitField(_('Create')) class AdminForm(flask_wtf.FlaskForm): - admin = fields.SelectField('Admin email', choices=[]) - submit = fields.SubmitField('Submit') + admin = fields.SelectField(_('Admin email'), choices=[]) + submit = fields.SubmitField(_('Submit')) class ManagerForm(flask_wtf.FlaskForm): - manager = fields.SelectField('Manager email') - submit = fields.SubmitField('Submit') + manager = fields.SelectField(_('Manager email')) + submit = fields.SubmitField(_('Submit')) class FetchForm(flask_wtf.FlaskForm): - protocol = fields.SelectField('Protocol', choices=[ + protocol = fields.SelectField(_('Protocol'), choices=[ ('imap', 'IMAP'), ('pop3', 'POP3') ]) - host = fields.StringField('Hostname or IP') - port = fields.IntegerField('TCP port') - tls = fields.BooleanField('Enable TLS') - username = fields.StringField('Username') - password = fields.StringField('Password') - submit = fields.SubmitField('Submit') + host = fields.StringField(_('Hostname or IP')) + port = fields.IntegerField(_('TCP port')) + tls = fields.BooleanField(_('Enable TLS')) + username = fields.StringField(_('Username')) + password = fields.StringField(_('Password')) + submit = fields.SubmitField(_('Submit')) From a3ad45c8ac8c0d4f2c3e8604dd19e73ca962e6a8 Mon Sep 17 00:00:00 2001 From: Pierre Jaury Date: Sun, 2 Oct 2016 14:43:48 +0200 Subject: [PATCH 3/9] Use babel for base views --- admin/freeposte/admin/templates/confirm.html | 4 ++-- admin/freeposte/admin/templates/login.html | 8 +++---- admin/freeposte/admin/templates/services.html | 14 +++++------ admin/freeposte/admin/templates/sidebar.html | 24 +++++++++---------- admin/freeposte/admin/templates/working.html | 2 +- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/admin/freeposte/admin/templates/confirm.html b/admin/freeposte/admin/templates/confirm.html index c95db696..36ecd7f5 100644 --- a/admin/freeposte/admin/templates/confirm.html +++ b/admin/freeposte/admin/templates/confirm.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% block title %} -Confirm action +{% trans %}Confirm action{% endtrans %} {% endblock %} {% block subtitle %} @@ -9,6 +9,6 @@ Confirm action {% endblock %} {% block box_content %} -

You are about to {{ action }}. Please confirm your action.

+

{% trans action %}You are about to {{ action }}. Please confirm your action.{% endtrans %}

{{ macros.form(form) }} {% endblock %} diff --git a/admin/freeposte/admin/templates/login.html b/admin/freeposte/admin/templates/login.html index 3a217046..27b63d43 100644 --- a/admin/freeposte/admin/templates/login.html +++ b/admin/freeposte/admin/templates/login.html @@ -3,10 +3,10 @@ {% block sidebar %}