Removed deprecation

This commit is contained in:
Spitap
2023-05-04 08:17:29 +02:00
parent 041c0d2afe
commit 3ba8c5cdfd
121 changed files with 729 additions and 729 deletions
+7 -7
View File
@@ -6,8 +6,8 @@ from django.conf import settings
from django.contrib.auth import password_validation
from django.core.exceptions import ValidationError
from django.shortcuts import get_object_or_404
from django.utils.encoding import force_text
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.encoding import force_str
from django.utils.translation import gettext as _, gettext_lazy
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import extend_schema_field
@@ -31,14 +31,14 @@ class DomainSerializer(serializers.ModelSerializer):
quota = serializers.CharField(
required=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Quota shared between mailboxes. Can be expressed in KB, "
"MB (default) or GB. A value of 0 means no quota."
)
)
default_mailbox_quota = serializers.CharField(
required=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Default quota in MB applied to mailboxes. A value of 0 means "
"no quota."
)
@@ -140,7 +140,7 @@ class DomainAliasSerializer(serializers.ModelSerializer):
object_type="domain_aliases")
except lib_exceptions.ModoboaException as inst:
raise serializers.ValidationError({
"domain": force_text(inst)})
"domain": force_str(inst)})
domain_alias.save(creator=creator)
return domain_alias
@@ -331,7 +331,7 @@ class WritableAccountSerializer(AccountSerializer):
object_type="mailboxes")
except lib_exceptions.ModoboaException as inst:
raise serializers.ValidationError({
"mailbox": force_text(inst)})
"mailbox": force_str(inst)})
condition = (
not data.get("random_password") and (
data.get("password") or
@@ -447,7 +447,7 @@ class AliasSerializer(serializers.ModelSerializer):
recipients = serializers.ListField(
child=lib_fields.DRFEmailFieldUTF8AndEmptyUser(),
allow_empty=False,
help_text=ugettext_lazy("A list of recipient")
help_text=gettext_lazy("A list of recipient")
)
class Meta:
+1 -1
View File
@@ -2,7 +2,7 @@
from django import http
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django_filters import rest_framework as dj_filters
from drf_spectacular.utils import extend_schema, extend_schema_view
+1 -1
View File
@@ -8,7 +8,7 @@ from django.conf import settings
from django.core.exceptions import ValidationError
from django.core import validators as dj_validators
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.contrib.auth import password_validation
+3 -3
View File
@@ -2,7 +2,7 @@
from django.core.files.base import ContentFile
from django.urls import reverse
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from rest_framework.authtoken.models import Token
@@ -165,7 +165,7 @@ domainalias; domalias1.com; domain1.com; True
]
self.assertCountEqual(
expected_response,
force_text(response.content.strip()).split("\r\n")
force_str(response.content.strip()).split("\r\n")
)
@@ -385,7 +385,7 @@ dlist; dlist@test.com; True; user1@test.com; user@extdomain.com
def test_export(self):
response = self.client.get(reverse("v2:identities-export"))
expected_response = "account,admin,,,,True,SuperAdmins,,\r\naccount,admin@test.com,{PLAIN}toto,,,True,DomainAdmins,admin@test.com,10,test.com\r\naccount,admin@test2.com,{PLAIN}toto,,,True,DomainAdmins,admin@test2.com,10,test2.com\r\naccount,user@test.com,{PLAIN}toto,,,True,SimpleUsers,user@test.com,10\r\naccount,user@test2.com,{PLAIN}toto,,,True,SimpleUsers,user@test2.com,10\r\nalias,alias@test.com,True,user@test.com\r\nalias,forward@test.com,True,user@external.com\r\nalias,postmaster@test.com,True,test@truc.fr,toto@titi.com\r\n" # NOQA:E501
received_content = force_text(response.content.strip()).split("\r\n")
received_content = force_str(response.content.strip()).split("\r\n")
# Empty admin password because it is hashed using SHA512-CRYPT
admin_row = received_content[0].split(",")
admin_row[2] = ""
+1 -1
View File
@@ -1,6 +1,6 @@
"""Admin API v2 viewsets."""
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.contrib.contenttypes.models import ContentType
+91 -91
View File
@@ -6,8 +6,8 @@ import os
from django import forms
from django.conf import settings
from django.utils.encoding import force_text
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.encoding import force_str
from django.utils.translation import gettext as _, gettext_lazy
from django.forms.fields import GenericIPAddressField
from modoboa.lib.form_utils import SeparatorField, YesNoField
@@ -20,20 +20,20 @@ from . import constants
class AdminParametersForm(param_forms.AdminParametersForm):
app = "admin"
dom_sep = SeparatorField(label=ugettext_lazy("Domains"))
dom_sep = SeparatorField(label=gettext_lazy("Domains"))
enable_mx_checks = YesNoField(
label=ugettext_lazy("Enable MX checks"),
label=gettext_lazy("Enable MX checks"),
initial=True,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Check that every domain has a valid MX record"
)
)
valid_mxs = forms.CharField(
label=ugettext_lazy("Valid MXs"),
label=gettext_lazy("Valid MXs"),
initial="",
help_text=ugettext_lazy(
help_text=gettext_lazy(
"A list of IP or network address every MX record should match."
" A warning will be sent if a record does not respect it."
),
@@ -42,68 +42,68 @@ class AdminParametersForm(param_forms.AdminParametersForm):
)
domains_must_have_authorized_mx = YesNoField(
label=ugettext_lazy("New domains must use authorized MX(s)"),
label=gettext_lazy("New domains must use authorized MX(s)"),
initial=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Prevent the creation of a new domain if its MX record does "
"not use one of the defined addresses."
)
)
enable_spf_checks = YesNoField(
label=ugettext_lazy("Enable SPF checks"),
label=gettext_lazy("Enable SPF checks"),
initial=True,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Check if every domain has a valid SPF record"
)
)
enable_dkim_checks = YesNoField(
label=ugettext_lazy("Enable DKIM checks"),
label=gettext_lazy("Enable DKIM checks"),
initial=True,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Check if every domain with DKIM signin enabled has a valid DNS "
"record"
)
)
enable_dmarc_checks = YesNoField(
label=ugettext_lazy("Enable DMARC checks"),
label=gettext_lazy("Enable DMARC checks"),
initial=True,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Check if every domain has a valid DMARC record"
)
)
enable_autoconfig_checks = YesNoField(
label=ugettext_lazy("Enable autoconfig checks"),
label=gettext_lazy("Enable autoconfig checks"),
initial=True,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Check if every domain has a valid records for autoconfiguration"
)
)
enable_dnsbl_checks = YesNoField(
label=ugettext_lazy("Enable DNSBL checks"),
label=gettext_lazy("Enable DNSBL checks"),
initial=True,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Check every domain against major DNSBL providers"
)
)
custom_dns_server = GenericIPAddressField(
label=ugettext_lazy("Custom DNS server"),
label=gettext_lazy("Custom DNS server"),
required=False,
initial="",
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Use a custom DNS server instead of local server configuration"
)
)
dkim_keys_storage_dir = forms.CharField(
label=ugettext_lazy("DKIM keys storage directory"),
label=gettext_lazy("DKIM keys storage directory"),
initial="",
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Absolute path of the directory where DKIM private keys will "
"be stored. Make sure this directory belongs to root user "
"and is not readable by the outside world."
@@ -112,81 +112,81 @@ class AdminParametersForm(param_forms.AdminParametersForm):
)
dkim_default_key_length = forms.ChoiceField(
label=ugettext_lazy("Default DKIM key length"),
label=gettext_lazy("Default DKIM key length"),
initial=2048,
choices=constants.DKIM_KEY_LENGTHS,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Default length in bits for newly generated DKIM keys."
)
)
default_domain_quota = forms.IntegerField(
label=ugettext_lazy("Default domain quota"),
label=gettext_lazy("Default domain quota"),
initial=0,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Default quota (in MB) applied to freshly created domains with no "
"value specified. A value of 0 means no quota."
)
)
default_domain_message_limit = forms.IntegerField(
label=ugettext_lazy("Default domain sending limit"),
label=gettext_lazy("Default domain sending limit"),
required=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Number of messages freshly created domains will be "
"allowed to send per day. Leave empty for no limit."
)
)
mbsep = SeparatorField(label=ugettext_lazy("Mailboxes"))
mbsep = SeparatorField(label=gettext_lazy("Mailboxes"))
handle_mailboxes = YesNoField(
label=ugettext_lazy("Handle mailboxes on filesystem"),
label=gettext_lazy("Handle mailboxes on filesystem"),
initial=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Rename or remove mailboxes on the filesystem when they get"
" renamed or removed within Modoboa"
)
)
default_mailbox_quota = forms.IntegerField(
label=ugettext_lazy("Default mailbox quota"),
label=gettext_lazy("Default mailbox quota"),
initial=0,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Default mailbox quota (in MB) applied to freshly created "
"mailboxes with no value specified. A value of 0 means no quota."
)
)
default_mailbox_message_limit = forms.IntegerField(
label=ugettext_lazy("Default mailbox sending limit"),
label=gettext_lazy("Default mailbox sending limit"),
required=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Number of messages freshly created mailboxes will be "
"allowed to send per day. Leave empty for no limit."
)
)
auto_account_removal = YesNoField(
label=ugettext_lazy("Automatic account removal"),
label=gettext_lazy("Automatic account removal"),
initial=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"When a mailbox is removed, also remove the associated account")
)
auto_create_domain_and_mailbox = YesNoField(
label=ugettext_lazy("Automatic domain/mailbox creation"),
label=gettext_lazy("Automatic domain/mailbox creation"),
initial=True,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Create a domain and a mailbox when an account is automatically "
"created."
)
)
create_alias_on_mbox_rename = YesNoField(
label=ugettext_lazy("Create an alias when a mailbox is renamed"),
label=gettext_lazy("Create an alias when a mailbox is renamed"),
initial=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Create an alias using the old address when a mailbox is renamed."
)
)
@@ -207,7 +207,7 @@ class AdminParametersForm(param_forms.AdminParametersForm):
dpath = None
code, output = exec_cmd("which dovecot")
if not code:
dpath = force_text(output).strip()
dpath = force_str(output).strip()
else:
known_paths = getattr(
settings, "DOVECOT_LOOKUP_PATH",
@@ -222,7 +222,7 @@ class AdminParametersForm(param_forms.AdminParametersForm):
except OSError:
hide_fields = True
else:
version = force_text(version)
version = force_str(version)
if code or not version.strip().startswith("2"):
hide_fields = True
else:
@@ -234,7 +234,7 @@ class AdminParametersForm(param_forms.AdminParametersForm):
"""Ensure quota is a positive integer."""
if self.cleaned_data["default_domain_quota"] < 0:
raise forms.ValidationError(
ugettext_lazy("Must be a positive integer")
gettext_lazy("Must be a positive integer")
)
return self.cleaned_data["default_domain_quota"]
@@ -242,7 +242,7 @@ class AdminParametersForm(param_forms.AdminParametersForm):
"""Ensure quota is a positive integer."""
if self.cleaned_data["default_mailbox_quota"] < 0:
raise forms.ValidationError(
ugettext_lazy("Must be a positive integer")
gettext_lazy("Must be a positive integer")
)
return self.cleaned_data["default_mailbox_quota"]
@@ -252,12 +252,12 @@ class AdminParametersForm(param_forms.AdminParametersForm):
if storage_dir:
if not os.path.isdir(storage_dir):
raise forms.ValidationError(
ugettext_lazy("Directory not found.")
gettext_lazy("Directory not found.")
)
code, output = exec_cmd("which openssl")
if code:
raise forms.ValidationError(
ugettext_lazy(
gettext_lazy(
"openssl not found, please make sure it is installed.")
)
return storage_dir
@@ -274,7 +274,7 @@ class AdminParametersForm(param_forms.AdminParametersForm):
]
except ValueError:
raise forms.ValidationError(
ugettext_lazy(
gettext_lazy(
"This field only allows valid IP addresses (or networks)"
)
)
@@ -297,94 +297,94 @@ class AdminParametersForm(param_forms.AdminParametersForm):
GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([
("domains", {
"label": ugettext_lazy("Domains"),
"label": gettext_lazy("Domains"),
"params": collections.OrderedDict([
("enable_mx_checks", {
"label": ugettext_lazy("Enable MX checks"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Enable MX checks"),
"help_text": gettext_lazy(
"Check that every domain has a valid MX record"
)
}),
("valid_mxs", {
"label": ugettext_lazy("Valid MXs"),
"label": gettext_lazy("Valid MXs"),
"display": "enable_mx_checks=true",
"help_text": ugettext_lazy(
"help_text": gettext_lazy(
"A list of IP or network address every MX record should "
"match. A warning will be sent if a record does not "
"respect it."
),
}),
("domains_must_have_authorized_mx", {
"label": ugettext_lazy("New domains must use authorized MX(s)"),
"label": gettext_lazy("New domains must use authorized MX(s)"),
"display": "enable_mx_checks=true",
"help_text": ugettext_lazy(
"help_text": gettext_lazy(
"Prevent the creation of a new domain if its MX record "
"does not use one of the defined addresses."
)
}),
("enable_spf_checks", {
"label": ugettext_lazy("Enable SPF checks"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Enable SPF checks"),
"help_text": gettext_lazy(
"Check if every domain has a valid SPF record"
)
}),
("enable_dkim_checks", {
"label": ugettext_lazy("Enable DKIM checks"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Enable DKIM checks"),
"help_text": gettext_lazy(
"Check if every domain with DKIM signin enabled "
"has a valid DNS record"
)
}),
("enable_dmarc_checks", {
"label": ugettext_lazy("Enable DMARC checks"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Enable DMARC checks"),
"help_text": gettext_lazy(
"Check if every domain has a valid DMARC record"
)
}),
("enable_autoconfig_checks", {
"label": ugettext_lazy("Enable autoconfig checks"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Enable autoconfig checks"),
"help_text": gettext_lazy(
"Check if every domain has a valid records for "
"autoconfiguration"
)
}),
("enable_dnsbl_checks", {
"label": ugettext_lazy("Enable DNSBL checks"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Enable DNSBL checks"),
"help_text": gettext_lazy(
"Check every domain against major DNSBL providers"
)
}),
("custom_dns_server", {
"label": ugettext_lazy("Custom DNS server"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Custom DNS server"),
"help_text": gettext_lazy(
"Use a custom DNS server instead of local server "
"configuration"
)
}),
("dkim_keys_storage_dir", {
"label": ugettext_lazy("DKIM keys storage directory"),
"help_text": ugettext_lazy(
"label": gettext_lazy("DKIM keys storage directory"),
"help_text": gettext_lazy(
"Absolute path of the directory where DKIM private keys "
"will be stored. Make sure this directory belongs to root "
"user and is not readable by the outside world."
),
}),
("dkim_default_key_length", {
"label": ugettext_lazy("Default DKIM key length"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Default DKIM key length"),
"help_text": gettext_lazy(
"Default length in bits for newly generated DKIM keys."
)
}),
("default_domain_quota", {
"label": ugettext_lazy("Default domain quota"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Default domain quota"),
"help_text": gettext_lazy(
"Default quota (in MB) applied to freshly created domains "
"with no value specified. A value of 0 means no quota."
)
}),
("default_domain_message_limit", {
"label": ugettext_lazy("Default domain sending limit"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Default domain sending limit"),
"help_text": gettext_lazy(
"Number of messages freshly created domains will be "
"allowed to send per day. Leave empty for no limit."
)
@@ -392,47 +392,47 @@ GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([
])
}),
("mailboxes", {
"label": ugettext_lazy("Mailboxes"),
"label": gettext_lazy("Mailboxes"),
"params": collections.OrderedDict([
("handle_mailboxes", {
"label": ugettext_lazy("Handle mailboxes on filesystem"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Handle mailboxes on filesystem"),
"help_text": gettext_lazy(
"Rename or remove mailboxes on the filesystem when they get"
" renamed or removed within Modoboa"
)
}),
("default_mailbox_quota", {
"label": ugettext_lazy("Default mailbox quota"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Default mailbox quota"),
"help_text": gettext_lazy(
"Default mailbox quota (in MB) applied to freshly created "
"domains with no value specified. A value of 0 means no "
"quota."
)
}),
("default_mailbox_message_limit", {
"label": ugettext_lazy("Default mailbox sending limit"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Default mailbox sending limit"),
"help_text": gettext_lazy(
"Number of messages freshly created mailboxes will be "
"allowed to send per day. Leave empty for no limit."
)
}),
("auto_account_removal", {
"label": ugettext_lazy("Automatic account removal"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Automatic account removal"),
"help_text": gettext_lazy(
"When a mailbox is removed, also remove the associated "
"account")
}),
("auto_create_domain_and_mailbox", {
"label": ugettext_lazy("Automatic domain/mailbox creation"),
"help_text": ugettext_lazy(
"label": gettext_lazy("Automatic domain/mailbox creation"),
"help_text": gettext_lazy(
"Create a domain and a mailbox when an account is "
"automatically created."
)
}),
("create_alias_on_mbox_rename", {
"label": ugettext_lazy(
"label": gettext_lazy(
"Create an alias when a mailbox is renamed"),
"help_text": ugettext_lazy(
"help_text": gettext_lazy(
"Create an alias using the old address when a mailbox is "
"renamed."
)
@@ -448,8 +448,8 @@ def load_admin_settings():
from .api.v2 import serializers
param_tools.registry.add(
"global", AdminParametersForm, ugettext_lazy("Administration"))
"global", AdminParametersForm, gettext_lazy("Administration"))
param_tools.registry.add2(
"global", "admin", ugettext_lazy("Administration"),
"global", "admin", gettext_lazy("Administration"),
GLOBAL_PARAMETERS_STRUCT,
serializers.AdminGlobalParametersSerializer)
+1 -1
View File
@@ -1,6 +1,6 @@
"""Admin constants."""
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
DNSBL_PROVIDERS = [
"b.barracudacentral.org",
+23 -23
View File
@@ -8,7 +8,7 @@ from django.conf import settings
from django.contrib.auth import password_validation
from django.http import QueryDict
from django.urls import reverse
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.translation import gettext as _, gettext_lazy
from modoboa.core import signals as core_signals
from modoboa.core.models import User
@@ -29,34 +29,34 @@ class AccountFormGeneral(forms.ModelForm):
"""General account form."""
username = forms.CharField(
label=ugettext_lazy("Username"),
help_text=ugettext_lazy(
label=gettext_lazy("Username"),
help_text=gettext_lazy(
"The user's name. Must be a valid e-mail address for simple users "
"or administrators with a mailbox."
)
)
role = forms.ChoiceField(
label=ugettext_lazy("Role"),
choices=[("", ugettext_lazy("Choose"))],
help_text=ugettext_lazy("What level of permission this user will have")
label=gettext_lazy("Role"),
choices=[("", gettext_lazy("Choose"))],
help_text=gettext_lazy("What level of permission this user will have")
)
random_password = forms.BooleanField(
label=ugettext_lazy("Random password"),
help_text=ugettext_lazy(
label=gettext_lazy("Random password"),
help_text=gettext_lazy(
"Generate a random password. If you're updating this account and "
"check this box, a new password will be generated."
),
required=False
)
password1 = forms.CharField(
label=ugettext_lazy("Password"), widget=forms.widgets.PasswordInput,
label=gettext_lazy("Password"), widget=forms.widgets.PasswordInput,
required=False
)
password2 = forms.CharField(
label=ugettext_lazy("Confirmation"),
label=gettext_lazy("Confirmation"),
widget=forms.widgets.PasswordInput,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Enter the same password as above, for verification."
),
required=False
@@ -69,7 +69,7 @@ class AccountFormGeneral(forms.ModelForm):
"master_user",
)
labels = {
"is_active": ugettext_lazy("Enabled")
"is_active": gettext_lazy("Enabled")
}
def __init__(self, user, *args, **kwargs):
@@ -223,14 +223,14 @@ class AccountFormMail(forms.Form, DynamicForm):
"""Form to handle mail part."""
email = lib_fields.UTF8EmailField(
label=ugettext_lazy("E-mail"), required=False)
label=gettext_lazy("E-mail"), required=False)
create_alias_with_old_address = forms.BooleanField(
label=ugettext_lazy("Create an alias using the old address"),
label=gettext_lazy("Create an alias using the old address"),
required=False,
initial=False
)
quota = forms.CharField(
label=ugettext_lazy("Quota"),
label=gettext_lazy("Quota"),
required=False,
help_text=_(
"Quota for this mailbox, can be expressed in KB, MB (default) or "
@@ -243,25 +243,25 @@ class AccountFormMail(forms.Form, DynamicForm):
)
quota_act = forms.BooleanField(required=False)
message_limit = forms.IntegerField(
label=ugettext_lazy("Message sending limit"),
label=gettext_lazy("Message sending limit"),
required=False,
min_value=0,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Number of messages this mailbox can send per day")
)
aliases = lib_fields.UTF8AndEmptyUserEmailField(
label=ugettext_lazy("Alias(es)"),
label=gettext_lazy("Alias(es)"),
required=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Alias(es) of this mailbox. Indicate only one address per input, "
"press ENTER to add a new input. To create a catchall alias, just "
"enter the domain name (@domain.tld)."
)
)
senderaddress = lib_fields.UTF8AndEmptyUserEmailField(
label=ugettext_lazy("Sender addresses"),
label=gettext_lazy("Sender addresses"),
required=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Additional sender address(es) for this account. The user will be "
"allowed to send emails using this address, even if it "
"does not exist locally. Indicate one address per input. Press "
@@ -473,9 +473,9 @@ class AccountPermissionsForm(forms.Form, DynamicForm):
"""A form to assign domain(s) permission."""
domains = lib_fields.DomainNameField(
label=ugettext_lazy("Domain(s)"),
label=gettext_lazy("Domain(s)"),
required=False,
help_text=ugettext_lazy("Domain(s) that user administrates")
help_text=gettext_lazy("Domain(s) that user administrates")
)
def __init__(self, *args, **kwargs):
+7 -7
View File
@@ -4,7 +4,7 @@ from collections import OrderedDict
from django import forms
from django.http import QueryDict
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.translation import gettext as _, gettext_lazy
from modoboa.core import signals as core_signals
from modoboa.lib import exceptions as lib_exceptions, fields as lib_fields
@@ -17,19 +17,19 @@ class AliasForm(forms.ModelForm, DynamicForm):
"""A form to create/modify an alias."""
random_address = forms.BooleanField(
label=ugettext_lazy("Random address"),
label=gettext_lazy("Random address"),
required=False)
address = lib_fields.UTF8AndEmptyUserEmailField(
label=ugettext_lazy("Email address"),
help_text=ugettext_lazy(
label=gettext_lazy("Email address"),
help_text=gettext_lazy(
"The alias address. To create a catchall alias, just enter the "
"domain name (@domain.tld)."
),
widget=forms.TextInput(attrs={"class": "form-control"})
)
recipients = lib_fields.UTF8AndEmptyUserEmailField(
label=ugettext_lazy("Recipients"), required=False,
help_text=ugettext_lazy(
label=gettext_lazy("Recipients"), required=False,
help_text=gettext_lazy(
"Addresses this alias will point to. Indicate only one address "
"per input, press ENTER to add a new input."
),
@@ -40,7 +40,7 @@ class AliasForm(forms.ModelForm, DynamicForm):
model = Alias
fields = ("address", "domain", "enabled", "expire_at", "description")
labels = {
"domain": ugettext_lazy("Domain")
"domain": gettext_lazy("Domain")
}
widgets = {
"domain": forms.widgets.Select(
+22 -22
View File
@@ -5,8 +5,8 @@ from functools import reduce
from django import forms
from django.http import QueryDict
from django.urls import reverse
from django.utils.encoding import force_text
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.encoding import force_str
from django.utils.translation import gettext as _, gettext_lazy
from modoboa.core import signals as core_signals
from modoboa.core.models import User
@@ -25,30 +25,30 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm):
"""A form to create/edit a domain."""
type = forms.ChoiceField( # NOQA:A003
label=ugettext_lazy("Type"),
label=gettext_lazy("Type"),
)
aliases = DomainNameField(
label=ugettext_lazy("Alias(es)"),
label=gettext_lazy("Alias(es)"),
required=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Alias(es) of this domain. Indicate only one name per input, "
"press ENTER to add a new input."
)
)
dkim_key_selector = forms.CharField(
label=ugettext_lazy("Key selector"), initial="modoboa", required=False)
label=gettext_lazy("Key selector"), initial="modoboa", required=False)
quota = forms.CharField(
label=ugettext_lazy("Quota"),
label=gettext_lazy("Quota"),
initial=0,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Quota shared between mailboxes. Can be expressed in KB, "
"MB (default) or GB. A value of 0 means no quota."
)
)
default_mailbox_quota = forms.CharField(
label=ugettext_lazy("Default mailbox quota"),
label=gettext_lazy("Default mailbox quota"),
initial=0,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Default quota applied to mailboxes. Can be expressed in KB, MB "
"(default) or GB. A value of 0 means no quota."
)
@@ -97,7 +97,7 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm):
name, [(DomainAlias, _("domain alias"))])
if label is not None:
raise forms.ValidationError(
_("A %s with this name already exists") % force_text(label))
_("A %s with this name already exists") % force_str(label))
domains_must_have_authorized_mx = (
param_tools.get_global_parameter("domains_must_have_authorized_mx")
@@ -182,7 +182,7 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm):
if label is not None:
self.add_error(
k, _("A %s with this name already exists")
% force_text(label)
% force_str(label)
)
else:
self.aliases.append(cleaned_data[k])
@@ -227,17 +227,17 @@ class DomainFormOptions(forms.Form):
"""A form containing options for domain creation."""
create_dom_admin = YesNoField(
label=ugettext_lazy("Create a domain administrator"),
label=gettext_lazy("Create a domain administrator"),
initial=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Automatically create an administrator for this domain"
)
)
dom_admin_username = forms.CharField(
label=ugettext_lazy("Name"),
label=gettext_lazy("Name"),
initial="admin",
help_text=ugettext_lazy(
help_text=gettext_lazy(
"The administrator's name. Don't include the domain's name here, "
"it will be automatically appended."
),
@@ -245,27 +245,27 @@ class DomainFormOptions(forms.Form):
)
random_password = YesNoField(
label=ugettext_lazy("Random password"),
label=gettext_lazy("Random password"),
initial=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Generate a random password for the administrator."
),
required=False
)
with_mailbox = YesNoField(
label=ugettext_lazy("With a mailbox"),
label=gettext_lazy("With a mailbox"),
initial=True,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Create a mailbox for the administrator."
),
required=False
)
create_aliases = YesNoField(
label=ugettext_lazy("Create aliases"),
label=gettext_lazy("Create aliases"),
initial=True,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Automatically create standard aliases for this domain"
),
required=False
+2 -2
View File
@@ -1,12 +1,12 @@
"""Export related forms."""
from django import forms
from django.utils.translation import ugettext_lazy
from django.utils.translation import gettext_lazy
class ExportDataForm(forms.Form):
sepchar = forms.CharField(
label=ugettext_lazy("Separator"),
label=gettext_lazy("Separator"),
max_length=1,
required=False,
widget=forms.TextInput(attrs={"class": "form-control"})
+5 -5
View File
@@ -2,23 +2,23 @@
from django import forms
from django.core import validators
from django.utils.translation import ugettext_lazy
from django.utils.translation import gettext_lazy
class ForwardForm(forms.Form):
"""Forward definition form."""
dest = forms.CharField(
label=ugettext_lazy("Recipient(s)"),
label=gettext_lazy("Recipient(s)"),
widget=forms.Textarea(attrs={"class": "form-control"}),
required=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Indicate one or more recipients separated by a ','")
)
keepcopies = forms.BooleanField(
label=ugettext_lazy("Keep local copies"),
label=gettext_lazy("Keep local copies"),
required=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Forward messages and store copies into your local mailbox")
)
+7 -7
View File
@@ -1,23 +1,23 @@
"""Forms related to import operations."""
from django import forms
from django.utils.translation import ugettext_lazy
from django.utils.translation import gettext_lazy
class ImportDataForm(forms.Form):
"""Base form to import objects."""
sourcefile = forms.FileField(label=ugettext_lazy("Select a file"))
sourcefile = forms.FileField(label=gettext_lazy("Select a file"))
sepchar = forms.CharField(
label=ugettext_lazy("Separator"),
label=gettext_lazy("Separator"),
max_length=1,
required=False,
widget=forms.TextInput(attrs={"class": "form-control"})
)
continue_if_exists = forms.BooleanField(
label=ugettext_lazy("Continue on error"), required=False,
help_text=ugettext_lazy("Don't treat duplicated objects as error")
label=gettext_lazy("Continue on error"), required=False,
help_text=gettext_lazy("Don't treat duplicated objects as error")
)
def __init__(self, *args, **kwargs):
@@ -35,8 +35,8 @@ class ImportIdentitiesForm(ImportDataForm):
"""A form to import identities."""
crypt_password = forms.BooleanField(
label=ugettext_lazy("Crypt passwords"), required=False,
help_text=ugettext_lazy(
label=gettext_lazy("Crypt passwords"), required=False,
help_text=gettext_lazy(
"Check this option if passwords contained in your file "
"are not crypted"
)
+1 -1
View File
@@ -4,7 +4,7 @@ from django.contrib.contenttypes.models import ContentType
from django.db.models import signals
from django.dispatch import receiver
from django.urls import reverse
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core import models as core_models, signals as core_signals
from modoboa.lib import exceptions, permissions, signals as lib_signals
+5 -5
View File
@@ -15,8 +15,8 @@ from dns.name import IDNA_2008_UTS_46
from django.core.exceptions import ValidationError
from django.db import transaction
from django.db.models import Q
from django.utils.encoding import smart_text
from django.utils.translation import ugettext as _
from django.utils.encoding import smart_str
from django.utils.translation import gettext as _
from django.contrib.auth import password_validation
from django.contrib.contenttypes.models import ContentType
@@ -232,14 +232,14 @@ def get_domain_mx_list(domain):
continue
for ip_answer in ip_answers:
try:
address_smart = smart_text(ip_answer.address)
address_smart = smart_str(ip_answer.address)
mx_ip = ipaddress.ip_address(address_smart)
except ValueError as e:
logger.warning(
_("Invalid IP address format for "
"{domain}; {addr}").format(
domain=mx_domain,
addr=smart_text(ip_answer.address)
addr=smart_str(ip_answer.address)
), exc_info=e)
else:
result.append((mx_domain, mx_ip))
@@ -249,7 +249,7 @@ def get_domain_mx_list(domain):
def domain_has_authorized_mx(name):
"""Check if domain has authorized mx record at least."""
valid_mxs = param_tools.get_global_parameter("valid_mxs")
valid_mxs = [ipaddress.ip_network(smart_text(v.strip()))
valid_mxs = [ipaddress.ip_network(smart_str(v.strip()))
for v in valid_mxs.split() if v.strip()]
domain_mxs = get_domain_mx_list(name)
for _mx_addr, mx_ip_addr in domain_mxs:
@@ -3,7 +3,7 @@
import csv
from django.core.management.base import BaseCommand
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str
from modoboa.core.extensions import exts_pool
from modoboa.core.models import User
@@ -56,5 +56,5 @@ class ExportCommand(BaseCommand):
def handle(self, *args, **options):
exts_pool.load_all()
self.csvwriter = csv.writer(
self.stdout, delimiter=smart_text(options["sepchar"]))
self.stdout, delimiter=smart_str(options["sepchar"]))
getattr(self, "export_{}".format(options["objtype"]))()
@@ -9,7 +9,7 @@ from chardet.universaldetector import UniversalDetector
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core import models as core_models
from modoboa.core.extensions import exts_pool
@@ -3,8 +3,8 @@
import os
from django.core.management.base import BaseCommand
from django.utils.encoding import smart_text
from django.utils.translation import ugettext as _
from django.utils.encoding import smart_str
from django.utils.translation import gettext as _
from modoboa.lib import sysutils
from modoboa.parameters import tools as param_tools
@@ -41,15 +41,15 @@ class ManageDKIMKeys(BaseCommand):
"openssl genrsa -out {} {}".format(pkey_path, key_size))
if code:
print("Failed to generate DKIM private key for domain {}: {}"
.format(domain.name, smart_text(output)))
.format(domain.name, smart_str(output)))
domain.dkim_private_key_path = pkey_path
code, output = sysutils.exec_cmd(
"openssl rsa -in {} -pubout".format(pkey_path))
if code:
print("Failed to generate DKIM public key for domain {}: {}"
.format(domain.name, smart_text(output)))
.format(domain.name, smart_str(output)))
public_key = ""
for cpt, line in enumerate(smart_text(output).splitlines()):
for cpt, line in enumerate(smart_str(output).splitlines()):
if cpt == 0 or line.startswith("-----"):
continue
public_key += line
@@ -10,9 +10,9 @@ from django.core.mail import EmailMessage
from django.core.management.base import BaseCommand
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str
from django.utils.functional import cached_property
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.admin import constants, models
from modoboa.dnstools import models as dns_models
@@ -40,7 +40,7 @@ class CheckMXRecords(BaseCommand):
def valid_mxs(self):
"""Return valid MXs set in admin."""
valid_mxs = param_tools.get_global_parameter("valid_mxs")
return [ipaddress.ip_network(smart_text(v.strip()))
return [ipaddress.ip_network(smart_str(v.strip()))
for v in valid_mxs.split() if v.strip()]
def add_arguments(self, parser):
@@ -70,7 +70,7 @@ class CheckMXRecords(BaseCommand):
results = {}
for ip, mxs in mx_list.items():
try:
ip = ipaddress.ip_address(smart_text(ip))
ip = ipaddress.ip_address(smart_str(ip))
except ValueError:
continue
else:
+9 -9
View File
@@ -7,9 +7,9 @@ from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse
from django.utils.encoding import (
force_bytes, force_str, smart_text
force_bytes, force_str, smart_str
)
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.translation import gettext as _, gettext_lazy
from reversion import revisions as reversion
@@ -68,22 +68,22 @@ class Alias(AdminObject):
"""Mailbox alias."""
address = models.CharField(
ugettext_lazy("address"), max_length=254,
help_text=ugettext_lazy(
gettext_lazy("address"), max_length=254,
help_text=gettext_lazy(
"The alias address."
)
)
domain = models.ForeignKey(Domain, null=True, on_delete=models.CASCADE)
enabled = models.BooleanField(
ugettext_lazy("enabled"),
help_text=ugettext_lazy("Check to activate this alias"),
gettext_lazy("enabled"),
help_text=gettext_lazy("Check to activate this alias"),
default=True
)
internal = models.BooleanField(default=False)
description = models.TextField(
ugettext_lazy("Description"), blank=True)
gettext_lazy("Description"), blank=True)
expire_at = models.DateTimeField(
ugettext_lazy("Expire at"), blank=True, null=True)
gettext_lazy("Expire at"), blank=True, null=True)
_objectname = "MailboxAlias"
objects = AliasManager()
@@ -258,6 +258,6 @@ class AliasRecipient(models.Model):
def __str__(self):
"""Return alias and recipient."""
return smart_text(
return smart_str(
"{} -> {}".format(self.alias.address, self.address)
)
+16 -16
View File
@@ -6,9 +6,9 @@ from reversion import revisions as reversion
from django.db import models
from django.utils import timezone
from django.utils.encoding import force_text, smart_text
from django.utils.encoding import force_str, smart_str
from django.utils.functional import cached_property
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.translation import gettext as _, gettext_lazy
from modoboa.core import signals as core_signals
from modoboa.core.models import User
@@ -23,46 +23,46 @@ from . import mixins
class Domain(mixins.MessageLimitMixin, AdminObject):
"""Mail domain."""
name = models.CharField(ugettext_lazy("name"), max_length=253, unique=True,
help_text=ugettext_lazy("The domain name"))
name = models.CharField(gettext_lazy("name"), max_length=253, unique=True,
help_text=gettext_lazy("The domain name"))
quota = models.PositiveIntegerField(
default=0,
)
default_mailbox_quota = models.PositiveIntegerField(
verbose_name=ugettext_lazy("Default mailbox quota"),
verbose_name=gettext_lazy("Default mailbox quota"),
default=0
)
message_limit = models.PositiveIntegerField(
ugettext_lazy("Message sending limit"),
gettext_lazy("Message sending limit"),
null=True, blank=True,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Number of messages this domain can send per day"
)
)
enabled = models.BooleanField(
ugettext_lazy("enabled"),
help_text=ugettext_lazy("Check to activate this domain"),
gettext_lazy("enabled"),
help_text=gettext_lazy("Check to activate this domain"),
default=True
)
type = models.CharField(default="domain", max_length=20) # NOQA:A003
enable_dns_checks = models.BooleanField(
ugettext_lazy("Enable DNS checks"), default=True,
help_text=ugettext_lazy("Check to enable DNS checks for this domain")
gettext_lazy("Enable DNS checks"), default=True,
help_text=gettext_lazy("Check to enable DNS checks for this domain")
)
transport = models.OneToOneField(
"transport.Transport", null=True, on_delete=models.SET_NULL)
enable_dkim = models.BooleanField(
ugettext_lazy("Enable DKIM signing"),
help_text=ugettext_lazy(
gettext_lazy("Enable DKIM signing"),
help_text=gettext_lazy(
"If you activate this feature, a DKIM key will be "
"generated for this domain."),
default=False
)
dkim_key_selector = models.CharField(max_length=30, default="modoboa")
dkim_key_length = models.PositiveIntegerField(
ugettext_lazy("Key length"), choices=constants.DKIM_KEY_LENGTHS,
gettext_lazy("Key length"), choices=constants.DKIM_KEY_LENGTHS,
blank=True, null=True
)
dkim_public_key = models.TextField(blank=True)
@@ -339,7 +339,7 @@ class Domain(mixins.MessageLimitMixin, AdminObject):
super().delete()
def __str__(self):
return smart_text(self.name)
return smart_str(self.name)
def from_csv(self, user, row):
"""Create a new domain from a CSV entry.
@@ -397,7 +397,7 @@ class Domain(mixins.MessageLimitMixin, AdminObject):
result = [
[
"domain",
force_text(self.name),
force_str(self.name),
self.quota,
self.default_mailbox_quota,
self.enabled
+9 -9
View File
@@ -4,8 +4,8 @@ from reversion import revisions as reversion
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from django.utils.encoding import smart_text
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.encoding import smart_str
from django.utils.translation import gettext as _, gettext_lazy
from modoboa.core import models as core_models, signals as core_signals
from modoboa.lib.exceptions import BadRequest, Conflict
@@ -30,16 +30,16 @@ class DomainAlias(AdminObject):
"""Domain aliases."""
name = models.CharField(ugettext_lazy("name"), max_length=100, unique=True,
help_text=ugettext_lazy("The alias name"))
name = models.CharField(gettext_lazy("name"), max_length=100, unique=True,
help_text=gettext_lazy("The alias name"))
target = models.ForeignKey(
Domain, verbose_name=ugettext_lazy("target"),
help_text=ugettext_lazy("The domain this alias points to"),
Domain, verbose_name=gettext_lazy("target"),
help_text=gettext_lazy("The domain this alias points to"),
on_delete=models.CASCADE
)
enabled = models.BooleanField(
ugettext_lazy("enabled"),
help_text=ugettext_lazy("Check to activate this alias"),
gettext_lazy("enabled"),
help_text=gettext_lazy("Check to activate this alias"),
default=True
)
@@ -51,7 +51,7 @@ class DomainAlias(AdminObject):
app_label = "admin"
def __str__(self):
return smart_text(self.name)
return smart_str(self.name)
def from_csv(self, user, row):
"""Create a domain alias from a CSV row
+9 -9
View File
@@ -6,8 +6,8 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models import Q
from django.db.models.manager import Manager
from django.utils.encoding import smart_text, force_text
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.encoding import smart_str, force_str
from django.utils.translation import gettext as _, gettext_lazy
from modoboa.core.models import User
from modoboa.lib import exceptions as lib_exceptions
@@ -89,15 +89,15 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject):
"""User mailbox."""
address = models.CharField(
ugettext_lazy("address"), max_length=252,
help_text=ugettext_lazy(
gettext_lazy("address"), max_length=252,
help_text=gettext_lazy(
"Mailbox address (without the @domain.tld part)")
)
quota = models.PositiveIntegerField(default=0)
use_domain_quota = models.BooleanField(default=False)
message_limit = models.PositiveIntegerField(
ugettext_lazy("Message sending limit"), null=True, blank=True,
help_text=ugettext_lazy(
gettext_lazy("Message sending limit"), null=True, blank=True,
help_text=gettext_lazy(
"Number of messages this mailbox can send per day")
)
domain = models.ForeignKey(Domain, on_delete=models.CASCADE)
@@ -115,7 +115,7 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject):
self.old_message_limit = self.message_limit
def __str__(self):
return smart_text(self.full_address)
return smart_str(self.full_address)
def __full_address(self, localpart):
return "%s@%s" % (localpart, self.domain.name)
@@ -154,7 +154,7 @@ class Mailbox(mixins.MessageLimitMixin, AdminObject):
if code:
raise lib_exceptions.InternalError(
_("Failed to retrieve mailbox location (%s)") % output)
self.__mail_home = force_text(output.strip())
self.__mail_home = force_str(output.strip())
return self.__mail_home
@property
@@ -363,7 +363,7 @@ class SenderAddress(models.Model):
def __str__(self):
"""Return address."""
return smart_text(self.address)
return smart_str(self.address)
reversion.register(SenderAddress)
+15 -24
View File
@@ -2,31 +2,22 @@
import django.dispatch
check_extra_account_form = django.dispatch.Signal(
providing_args=["account", "form"])
extra_account_dashboard_widgets = django.dispatch.Signal(
providing_args=["user", "account"])
extra_account_forms = django.dispatch.Signal(
providing_args=["user", "account"])
extra_admin_content = django.dispatch.Signal(
providing_args=["user", "location", "currentpage"])
extra_domain_actions = django.dispatch.Signal(
providing_args=["user", "domain"])
extra_domain_dashboard_widgets = django.dispatch.Signal(
providing_args=["user", "domain"])
check_extra_account_form = django.dispatch.Signal() # Provides account, form
extra_account_dashboard_widgets = django.dispatch.Signal() # Provides user, account
extra_account_forms = django.dispatch.Signal() # Provides user, account
extra_admin_content = django.dispatch.Signal() # Provides user, location, currentpage
extra_domain_actions = django.dispatch.Signal() # Provides user, domain
extra_domain_dashboard_widgets = django.dispatch.Signal() # Provides user, domain
extra_domain_filters = django.dispatch.Signal()
extra_domain_forms = django.dispatch.Signal(providing_args=["user", "domain"])
extra_domain_menu_entries = django.dispatch.Signal(providing_args=["user"])
extra_domain_qset_filters = django.dispatch.Signal(
providing_args=["domfilter", "extrafilters"])
extra_domain_forms = django.dispatch.Signal() # Provides user, domain
extra_domain_menu_entries = django.dispatch.Signal() # Provides user
extra_domain_qset_filters = django.dispatch.Signal() # Provides domfilter, extrafilters
# extra_domain_types = django.dispatch.Signal()
extra_domain_wizard_steps = django.dispatch.Signal()
get_account_form_instances = django.dispatch.Signal(
providing_args=["user", "account"])
get_domain_form_instances = django.dispatch.Signal(
providing_args=["user", "domain"])
get_account_form_instances = django.dispatch.Signal() # Provides user, account
get_domain_form_instances = django.dispatch.Signal() # Provides user, domain
# get_domain_tags = django.dispatch.Signal(providing_args=["domain"])
import_object = django.dispatch.Signal(providing_args=["objtype"])
use_external_recipients = django.dispatch.Signal(providing_args=["recipients"])
new_dkim_keys = django.dispatch.Signal(providing_args=["domains"])
extra_account_identities_actions = django.dispatch.Signal(providing_args=["account"])
import_object = django.dispatch.Signal() # Provides objtype
use_external_recipients = django.dispatch.Signal() # Provides recipients
new_dkim_keys = django.dispatch.Signal() # Provides domain
extra_account_identities_actions = django.dispatch.Signal() # Provides account
+2 -2
View File
@@ -6,7 +6,7 @@ from django import template
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.translation import gettext as _, gettext_lazy
from modoboa.core import signals as core_signals
from modoboa.lib.templatetags.lib_tags import render_link
@@ -16,7 +16,7 @@ from .. import signals
register = template.Library()
genders = {
"Enabled": (ugettext_lazy("enabled_m"), ugettext_lazy("enabled_f"))
"Enabled": (gettext_lazy("enabled_m"), gettext_lazy("enabled_f"))
}
+6 -6
View File
@@ -5,7 +5,7 @@ from io import StringIO
from django.core.management import call_command
from django.urls import reverse
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from modoboa.lib.tests import ModoTestCase
from .. import factories, models
@@ -50,7 +50,7 @@ class ExportTestCase(ModoTestCase):
]
self.assertCountEqual(
expected_response,
force_text(response.content.strip()).split("\r\n")
force_str(response.content.strip()).split("\r\n")
)
# Test management command too.
@@ -59,12 +59,12 @@ class ExportTestCase(ModoTestCase):
response = sys.stdout.getvalue()
sys.stdout = stdout_backup
self.assertCountEqual(
expected_response, force_text(response.strip()).split("\r\n"))
expected_response, force_str(response.strip()).split("\r\n"))
def test_export_identities(self):
response = self.__export_identities()
expected_response = "account;admin;;;;True;SuperAdmins;;\r\naccount;admin@test.com;{PLAIN}toto;;;True;DomainAdmins;admin@test.com;10;test.com\r\naccount;admin@test2.com;{PLAIN}toto;;;True;DomainAdmins;admin@test2.com;10;test2.com\r\naccount;user@test.com;{PLAIN}toto;;;True;SimpleUsers;user@test.com;10\r\naccount;user@test2.com;{PLAIN}toto;;;True;SimpleUsers;user@test2.com;10\r\nalias;alias@test.com;True;user@test.com\r\nalias;forward@test.com;True;user@external.com\r\nalias;postmaster@test.com;True;test@truc.fr;toto@titi.com\r\n" # NOQA:E501
received_content = force_text(response.content.strip()).split("\r\n")
received_content = force_str(response.content.strip()).split("\r\n")
# Empty admin password because it is hashed using SHA512-CRYPT
admin_row = received_content[0].split(";")
admin_row[2] = ""
@@ -86,7 +86,7 @@ class ExportTestCase(ModoTestCase):
expected_response = "account;user@test.com;{PLAIN}toto;;;True;SimpleUsers;user@test.com;10\r\naccount;user@test2.com;{PLAIN}toto;;;True;SimpleUsers;user@test2.com;10\r\naccount;toto@test.com;{PLAIN}toto;Léon;;True;SimpleUsers;toto@test.com;10" # NOQA:E501
self.assertCountEqual(
expected_response.split("\r\n"),
force_text(response.content.strip()).split("\r\n")
force_str(response.content.strip()).split("\r\n")
)
def test_export_superadmins(self):
@@ -111,7 +111,7 @@ class ExportTestCase(ModoTestCase):
expected_response = "account;admin@test.com;{PLAIN}toto;;;True;DomainAdmins;admin@test.com;10;test.com\r\naccount;admin@test2.com;{PLAIN}toto;;;True;DomainAdmins;admin@test2.com;10;test2.com" # NOQA:E501
self.assertCountEqual(
expected_response.split("\r\n"),
force_text(response.content.strip()).split("\r\n")
force_str(response.content.strip()).split("\r\n")
)
def test_export_aliases(self):
+2 -2
View File
@@ -8,7 +8,7 @@ from testfixtures import LogCapture
from django.core import mail, management
from django.test import override_settings
from django.urls import reverse
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core import factories as core_factories
from modoboa.lib.tests import ModoTestCase
@@ -221,7 +221,7 @@ class DNSBLTestCase(ModoTestCase):
management.call_command(
"modo", "check_mx", "--email", "user@example.test")
self.assertEqual(len(mail.outbox), 2)
@mock.patch("gevent.socket.gethostbyname")
@mock.patch("socket.getaddrinfo")
@mock.patch.object(dns.resolver.Resolver, "resolve")
+2 -2
View File
@@ -7,7 +7,7 @@ from django.contrib.auth.decorators import login_required, permission_required
from django.db import IntegrityError
from django.shortcuts import render
from django.urls import reverse
from django.utils.translation import ugettext as _, ungettext
from django.utils.translation import gettext as _, ngettext
from django.views import generic
from django.views.decorators.http import require_http_methods
@@ -102,7 +102,7 @@ def delalias(request):
if not request.user.can_access(alias):
raise PermDeniedException
alias.delete()
msg = ungettext("Alias deleted", "Aliases deleted", len(selection))
msg = ngettext("Alias deleted", "Aliases deleted", len(selection))
return render_to_json_response(msg)
+1 -1
View File
@@ -1,7 +1,7 @@
"""DNSBL related views."""
from django.contrib.auth import mixins as auth_mixins
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.views import generic
from .. import models
+2 -2
View File
@@ -13,7 +13,7 @@ from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils.translation import ugettext as _, ungettext
from django.utils.translation import gettext as _, ngettext
from django.views import generic
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_http_methods
@@ -247,7 +247,7 @@ def deldomain(request, dom_id):
raise PermDeniedException(_("You can't delete your own domain"))
dom.delete(request.user, keepdir)
msg = ungettext("Domain deleted", "Domains deleted", 1)
msg = ngettext("Domain deleted", "Domains deleted", 1)
return render_to_json_response(msg)
+1 -1
View File
@@ -9,7 +9,7 @@ from django.contrib.auth.decorators import (
from django.http import HttpResponse
from django.shortcuts import render
from django.urls import reverse
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from ..forms import ExportDataForm
from ..lib import get_domains, get_identities
+2 -2
View File
@@ -8,7 +8,7 @@ from django.contrib.auth.decorators import (
)
from django.shortcuts import render
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _, ungettext
from django.utils.translation import gettext as _, ngettext
from django.views import generic
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_http_methods
@@ -191,7 +191,7 @@ def editaccount(request, pk):
def delaccount(request, pk):
User.objects.get(pk=pk).delete()
return render_to_json_response(
ungettext("Account deleted", "Accounts deleted", 1)
ngettext("Account deleted", "Accounts deleted", 1)
)
+2 -2
View File
@@ -11,8 +11,8 @@ from django.contrib.auth.decorators import (
from django.db import transaction
from django.shortcuts import render
from django.urls import reverse
from django.utils.encoding import smart_text
from django.utils.translation import ugettext as _
from django.utils.encoding import smart_str
from django.utils.translation import gettext as _
from modoboa.lib.exceptions import Conflict, ModoboaException
from .. import lib
+1 -1
View File
@@ -4,7 +4,7 @@ from reversion import revisions as reversion
from django.contrib.auth.decorators import login_required
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.lib.web_utils import render_to_json_response
from ..forms import ForwardForm
+1 -1
View File
@@ -1,6 +1,6 @@
"""Core API serializers."""
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from rest_framework import serializers
+1 -1
View File
@@ -1,6 +1,6 @@
"""Core API viewsets."""
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
import django_otp
from django_otp.plugins.otp_static.models import StaticDevice, StaticToken
+9 -9
View File
@@ -13,10 +13,10 @@ from django.core.exceptions import ValidationError as djangoValidationError
from django.template import loader
from django.utils import formats
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes
from django.utils.translation import ugettext_lazy, ugettext as _
from django.utils.translation import gettext_lazy, gettext as _
from rest_framework import serializers, status
from rest_framework.exceptions import APIException
@@ -36,7 +36,7 @@ class CustomValidationError(APIException):
if detail is not None:
self.detail = detail
else:
self.detail = {'detail': force_text(self.default_detail)}
self.detail = {'detail': force_str(self.default_detail)}
class NoSMSAvailable(Exception):
@@ -57,7 +57,7 @@ class CoreGlobalParametersSerializer(serializers.Serializer):
# General settings
authentication_type = serializers.ChoiceField(
choices=[("local", ugettext_lazy("Local")),
choices=[("local", gettext_lazy("Local")),
("ldap", "LDAP")],
default="local"
)
@@ -65,11 +65,11 @@ class CoreGlobalParametersSerializer(serializers.Serializer):
choices=[("sha512crypt", "sha512crypt"),
("sha256crypt", "sha256crypt"),
("blfcrypt", "bcrypt"),
("md5crypt", ugettext_lazy("md5crypt (weak)")),
("sha256", ugettext_lazy("sha256 (weak)")),
("md5", ugettext_lazy("md5 (weak)")),
("crypt", ugettext_lazy("crypt (weak)")),
("plain", ugettext_lazy("plain (weak)"))],
("md5crypt", gettext_lazy("md5crypt (weak)")),
("sha256", gettext_lazy("sha256 (weak)")),
("md5", gettext_lazy("md5 (weak)")),
("crypt", gettext_lazy("crypt (weak)")),
("plain", gettext_lazy("plain (weak)"))],
default="sha512crypt"
)
rounds_number = serializers.IntegerField(default=70000)
+1 -1
View File
@@ -3,7 +3,7 @@
import logging
from django.utils.html import escape
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.utils.datastructures import MultiValueDictKeyError
from django.contrib.auth import login
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -2,7 +2,7 @@
from django.apps import AppConfig
from django.db.models import signals
from django.utils.translation import ugettext_lazy
from django.utils.translation import gettext_lazy
def load_core_settings():
@@ -16,9 +16,9 @@ def load_core_settings():
from .api.v2 import serializers
param_tools.registry.add(
"global", app_settings.GeneralParametersForm, ugettext_lazy("General"))
"global", app_settings.GeneralParametersForm, gettext_lazy("General"))
param_tools.registry.add2(
"global", "core", ugettext_lazy("General"),
"global", "core", gettext_lazy("General"),
app_settings.GLOBAL_PARAMETERS_STRUCT,
serializers.CoreGlobalParametersSerializer)
+1 -1
View File
@@ -1,6 +1,6 @@
from django.conf import settings
from django.core.checks import Warning, register
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
W001 = Warning(
_("You have USE_TZ set to False, this may result in issues during "
+10 -10
View File
@@ -1,12 +1,12 @@
"""Core application constants."""
from django.conf import settings
from django.utils.translation import ugettext_lazy
from django.utils.translation import gettext_lazy
SIMPLEUSERS_ROLE = ("SimpleUsers", ugettext_lazy("Simple user"))
DOMAINADMINS_ROLE = ("DomainAdmins", ugettext_lazy("Domain administrator"))
RESELLERS_ROLE = ("Resellers", ugettext_lazy("Reseller"))
SUPERADMINS_ROLE = ("SuperAdmins", ugettext_lazy("Super administrator"))
SIMPLEUSERS_ROLE = ("SimpleUsers", gettext_lazy("Simple user"))
DOMAINADMINS_ROLE = ("DomainAdmins", gettext_lazy("Domain administrator"))
RESELLERS_ROLE = ("Resellers", gettext_lazy("Reseller"))
SUPERADMINS_ROLE = ("SuperAdmins", gettext_lazy("Super administrator"))
ROLES = (
SIMPLEUSERS_ROLE,
@@ -50,14 +50,14 @@ LDAP_GROUP_TYPES = (
)
LDAP_SECURE_MODES = [
("none", ugettext_lazy("No")),
("none", gettext_lazy("No")),
("starttls", "STARTTLS"),
("ssl", "SSL/TLS")
]
LDAP_AUTH_METHODS = [
("searchbind", ugettext_lazy("Search and bind")),
("directbind", ugettext_lazy("Direct bind"))
("searchbind", gettext_lazy("Search and bind")),
("directbind", gettext_lazy("Direct bind"))
]
PERMISSIONS = {
@@ -105,11 +105,11 @@ PERMISSIONS = {
}
SMS_BACKENDS = [
("", ugettext_lazy("Choose a provider")),
("", gettext_lazy("Choose a provider")),
("ovh", "OVH"),
]
if settings.DEBUG:
SMS_BACKENDS.insert(1, ("dummy", ugettext_lazy("Dummy")))
SMS_BACKENDS.insert(1, ("dummy", gettext_lazy("Dummy")))
TFA_DEVICE_TOKEN_KEY = "otp_device_id"
+1 -1
View File
@@ -1,7 +1,7 @@
"""Custom authentication for DRF."""
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django_otp.models import Device
from drf_spectacular.contrib.rest_framework_simplejwt import SimpleJWTScheme
+3 -2
View File
@@ -1,7 +1,8 @@
"""Extension management."""
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls import include
from django.urls import re_path
from django.utils.encoding import smart_str
@@ -111,7 +112,7 @@ class ExtensionsPool(object):
pattern = "{}.urls"
try:
result.append(
url(root, include(pattern.format(ext_name)))
re_path(root, include(pattern.format(ext_name)))
)
except ImportError:
# No urls for this extension
+8 -8
View File
@@ -7,7 +7,7 @@ from django.contrib.auth import (
forms as auth_forms, get_user_model, password_validation
)
from django.db.models import Q
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.translation import gettext as _, gettext_lazy
import django_otp
@@ -20,11 +20,11 @@ class LoginForm(forms.Form):
"""User login form."""
username = forms.CharField(
label=ugettext_lazy("Username"),
label=gettext_lazy("Username"),
widget=forms.TextInput(attrs={"class": "form-control"})
)
password = forms.CharField(
label=ugettext_lazy("Password"),
label=gettext_lazy("Password"),
widget=forms.PasswordInput(attrs={"class": "form-control"})
)
rememberme = forms.BooleanField(
@@ -37,15 +37,15 @@ class ProfileForm(forms.ModelForm):
"""Form to update User profile."""
oldpassword = forms.CharField(
label=ugettext_lazy("Old password"), required=False,
label=gettext_lazy("Old password"), required=False,
widget=forms.PasswordInput(attrs={"class": "form-control"})
)
newpassword = forms.CharField(
label=ugettext_lazy("New password"), required=False,
label=gettext_lazy("New password"), required=False,
widget=forms.PasswordInput(attrs={"class": "form-control"})
)
confirmation = forms.CharField(
label=ugettext_lazy("Confirmation"), required=False,
label=gettext_lazy("Confirmation"), required=False,
widget=forms.PasswordInput(attrs={"class": "form-control"})
)
@@ -115,7 +115,7 @@ class APIAccessForm(forms.Form):
"""Form to control API access."""
enable_api_access = forms.BooleanField(
label=ugettext_lazy("Enable API access"), required=False)
label=gettext_lazy("Enable API access"), required=False)
def __init__(self, *args, **kwargs):
"""Initialize form."""
@@ -149,7 +149,7 @@ class VerifySMSCodeForm(forms.Form):
"""A form to verify a code received by SMS."""
code = forms.CharField(
label=ugettext_lazy("Verification code"),
label=gettext_lazy("Verification code"),
widget=forms.widgets.TextInput(attrs={"class": "form-control"})
)
+4 -4
View File
@@ -9,8 +9,8 @@ from django.contrib.sites import models as sites_models
from django.db.models import signals
from django.dispatch import receiver
from django.urls import reverse
from django.utils.encoding import smart_text
from django.utils.translation import ugettext as _
from django.utils.encoding import smart_str
from django.utils.translation import gettext as _
from modoboa.lib import exceptions, permissions
from modoboa.lib.signals import get_request
@@ -39,7 +39,7 @@ def post_revision_commit(sender, **kwargs):
action = _("modified")
level = "warning"
message = _("%(object)s '%(name)s' %(action)s by user %(user)s") % {
"object": smart_text(version.content_type).capitalize(),
"object": smart_str(version.content_type).capitalize(),
"name": version.object_repr, "action": action,
"user": current_user
}
@@ -61,7 +61,7 @@ def log_object_removal(sender, instance, **kwargs):
return
logger = logging.getLogger("modoboa.admin")
msg = _("%(object)s '%(name)s' %(action)s by ") % {
"object": smart_text(version.content_type).capitalize(),
"object": smart_str(version.content_type).capitalize(),
"name": version.object_repr, "action": _("deleted")
}
request = get_request()
@@ -3,7 +3,7 @@
from django.core.mail import EmailMessage
from django.core.management.base import BaseCommand, CommandError
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.admin import models as admin_models
from modoboa.core.extensions import exts_pool
@@ -0,0 +1,17 @@
# Generated by Django 4.2 on 2023-04-25 12:00
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("core", "0024_alter_user_language"),
]
operations = [
migrations.RenameIndex(
model_name="user",
new_name="core_user_email_c0c03f_idx",
old_fields=("email", "is_active"),
),
]
+19 -21
View File
@@ -6,9 +6,9 @@ from email.header import Header
from django.conf import settings
from django.db import models
from django.urls import reverse
from django.utils.encoding import force_str, smart_bytes, smart_text
from django.utils.encoding import force_str, smart_bytes, smart_str
from django.utils.functional import cached_property
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.translation import gettext as _, gettext_lazy
from django.contrib.auth.models import AbstractUser, Group
from django.contrib.contenttypes.fields import GenericForeignKey
@@ -49,26 +49,26 @@ class User(AbstractUser):
is_active = models.BooleanField(default=True, db_index=True)
is_local = models.BooleanField(default=True, db_index=True)
master_user = models.BooleanField(
ugettext_lazy("Allow mailboxes access"), default=False,
help_text=ugettext_lazy(
gettext_lazy("Allow mailboxes access"), default=False,
help_text=gettext_lazy(
"Allow this administrator to access user mailboxes"
)
)
password = models.CharField(ugettext_lazy("password"), max_length=256)
password = models.CharField(gettext_lazy("password"), max_length=256)
language = models.CharField(
ugettext_lazy("language"),
gettext_lazy("language"),
max_length=10, default="en", choices=constants.LANGUAGES,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Prefered language to display pages."
)
)
phone_number = PhoneNumberField(
ugettext_lazy("Phone number"), blank=True, null=True)
gettext_lazy("Phone number"), blank=True, null=True)
secondary_email = models.EmailField(
ugettext_lazy("Secondary email"), max_length=254,
gettext_lazy("Secondary email"), max_length=254,
blank=True, null=True,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"An alternative e-mail address, can be used for recovery needs.")
)
@@ -78,9 +78,7 @@ class User(AbstractUser):
class Meta(object):
ordering = ["username"]
index_together = [
["email", "is_active"]
]
indexes = [models.Index(fields=["email", "is_active"])]
password_expr = re.compile(r'\{([\w\-]+)\}(.+)')
@@ -144,7 +142,7 @@ class User(AbstractUser):
return hasher().verify(raw_value, val2)
def __str__(self):
return smart_text(self.get_username())
return smart_str(self.get_username())
def get_absolute_url(self):
"""Return detail url for this user."""
@@ -369,13 +367,13 @@ class User(AbstractUser):
"""Return row that can be included in a CSV file."""
row = [
"account",
smart_text(self.username),
smart_text(self.password),
smart_text(self.first_name),
smart_text(self.last_name),
smart_text(self.is_active),
smart_text(self.role),
smart_text(self.email)
smart_str(self.username),
smart_str(self.password),
smart_str(self.first_name),
smart_str(self.last_name),
smart_str(self.is_active),
smart_str(self.role),
smart_str(self.email)
]
results = signals.account_exported.send(
sender=self.__class__, user=self)
+2 -2
View File
@@ -3,7 +3,7 @@ Password hashers for Modoboa.
"""
from django.conf import settings
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str
from modoboa.core.password_hashers.advanced import ( # NOQA:F401
BLFCRYPTHasher, MD5CRYPTHasher, SHA256CRYPTHasher, SHA512CRYPTHasher,
@@ -53,5 +53,5 @@ def get_dovecot_schemes():
if retcode:
schemes = default_schemes
return ["{{{}}}".format(smart_text(scheme))
return ["{{{}}}".format(smart_str(scheme))
for scheme in schemes.split()]
+3 -3
View File
@@ -40,7 +40,7 @@ class BLFCRYPTHasher(PasswordHasher):
# rounds = parameters.get_global_parameter("rounds_number")
# To get around this, I use the default of 12.
rounds = 12
return bcrypt.hash(clearvalue, rounds=rounds)
return bcrypt.hash.using(rounds=rounds).hash(clearvalue)
def verify(self, clearvalue, hashed_value):
return bcrypt.verify(clearvalue, hashed_value)
@@ -85,7 +85,7 @@ class SHA256CRYPTHasher(PasswordHasher):
def _encrypt(self, clearvalue, salt=None):
rounds = param_tools.get_global_parameter("rounds_number")
return sha256_crypt.hash(clearvalue, rounds=rounds)
return sha256_crypt.using(rounds=rounds).hash(clearvalue)
def verify(self, clearvalue, hashed_value):
return sha256_crypt.verify(clearvalue, hashed_value)
@@ -107,7 +107,7 @@ class SHA512CRYPTHasher(PasswordHasher):
def _encrypt(self, clearvalue, salt=None):
rounds = param_tools.get_global_parameter("rounds_number")
return sha512_crypt.hash(clearvalue, rounds=rounds)
return sha512_crypt.using(rounds=rounds).hash(clearvalue)
def verify(self, clearvalue, hashed_value):
return sha512_crypt.verify(clearvalue, hashed_value)
+3 -3
View File
@@ -11,7 +11,7 @@ import string
from random import Random
from django.utils.crypto import constant_time_compare
from django.utils.encoding import force_bytes, force_text
from django.utils.encoding import force_bytes, force_str
class MetaHasher(type):
@@ -65,8 +65,8 @@ class PasswordHasher(metaclass=MetaHasher):
:rtype: str
:return: encrypted password
"""
pwhash = self._b64encode(self._encrypt(force_text(clearvalue)))
return "%s%s" % (self.scheme, force_text(pwhash))
pwhash = self._b64encode(self._encrypt(force_str(clearvalue)))
return "%s%s" % (self.scheme, force_str(pwhash))
def verify(self, clearvalue, hashed_value):
"""Verify a password against a hashed value.
+5 -5
View File
@@ -1,7 +1,7 @@
"""Custom password validators."""
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _, ungettext
from django.utils.translation import gettext as _, ngettext
class ComplexityValidator(object):
@@ -20,7 +20,7 @@ class ComplexityValidator(object):
sum(1 for char in password if char.isdigit()) < self.digits)
if condition:
raise ValidationError(
ungettext(
ngettext(
"Password must contain at least {} digit.",
"Password must contain at least {} digits.",
self.digits
@@ -30,7 +30,7 @@ class ComplexityValidator(object):
sum(1 for char in password if char.islower()) < self.lower)
if condition:
raise ValidationError(
ungettext(
ngettext(
"Password must contain at least {} lowercase letter.",
"Password must contain at least {} lowercase letters.",
self.lower
@@ -41,7 +41,7 @@ class ComplexityValidator(object):
sum(1 for char in password if char.isupper()) < self.upper)
if condition:
raise ValidationError(
ungettext(
ngettext(
"Password must contain at least {} uppercase letter.",
"Password must contain at least {} uppercase letters.",
self.upper
@@ -53,7 +53,7 @@ class ComplexityValidator(object):
self.specials)
if condition:
raise ValidationError(
ungettext(
ngettext(
"Password must contain at least {} special character.",
"Password must contain at least {} special characters.",
self.specials
+19 -30
View File
@@ -2,36 +2,25 @@
import django.dispatch
account_auto_created = django.dispatch.Signal(providing_args=["user"])
account_exported = django.dispatch.Signal(providing_args=["account"])
account_imported = django.dispatch.Signal(
providing_args=["user", "account", "row"])
account_deleted = django.dispatch.Signal(providing_args=["user"])
account_role_changed = django.dispatch.Signal(
providing_args=["account", "role"])
account_password_updated = django.dispatch.Signal(
providing_args=["account", "password", "created"])
allow_password_change = django.dispatch.Signal(providing_args=["user"])
can_create_object = django.dispatch.Signal(
providing_args=["context", "klass", "object_type", "count", "instance"])
extra_account_actions = django.dispatch.Signal(providing_args=["account"])
extra_admin_dashboard_widgets = django.dispatch.Signal(
providing_args=["user"])
extra_admin_menu_entries = django.dispatch.Signal(
providing_args=["location", "user"])
extra_role_permissions = django.dispatch.Signal(providing_args=["role"])
extra_static_content = django.dispatch.Signal(
providing_args=["caller", "st_type", "user"])
account_auto_created = django.dispatch.Signal() # Provides user
account_exported = django.dispatch.Signal() # Provides account
account_imported = django.dispatch.Signal() # Provides user, account, row
account_deleted = django.dispatch.Signal() # Provides user
account_role_changed = django.dispatch.Signal() # Provides account, role
account_password_updated = django.dispatch.Signal() # Provides account password created
allow_password_change = django.dispatch.Signal() # Provides user
can_create_object = django.dispatch.Signal() # Provides context, klass, object_type, count, instance
extra_account_actions = django.dispatch.Signal() # Provides account
extra_admin_dashboard_widgets = django.dispatch.Signal() # Provides user
extra_admin_menu_entries = django.dispatch.Signal() # Provides location, user
extra_role_permissions = django.dispatch.Signal() # Provides role
extra_static_content = django.dispatch.Signal() # Provides caller, st_type, user
extra_uprefs_routes = django.dispatch.Signal()
extra_user_menu_entries = django.dispatch.Signal(
providing_args=["location", "user"])
get_announcements = django.dispatch.Signal(providing_args=["location"])
get_top_notifications = django.dispatch.Signal(
providing_args=["include_all"])
initial_data_loaded = django.dispatch.Signal(providing_args=["extname"])
extra_user_menu_entries = django.dispatch.Signal() # Provides location, user
get_announcements = django.dispatch.Signal() # Provides location
get_top_notifications = django.dispatch.Signal() # Provides include_all
initial_data_loaded = django.dispatch.Signal() # Provides extname
register_postfix_maps = django.dispatch.Signal()
user_can_set_role = django.dispatch.Signal(
providing_args=["user", "role", "account"])
user_login = django.dispatch.Signal(
providing_args=["username", "password"])
user_can_set_role = django.dispatch.Signal() # Provides user, role, account
user_login = django.dispatch.Signal() # Provides username, password
user_logout = django.dispatch.Signal()
+1 -1
View File
@@ -4,7 +4,7 @@ import ovh
from django import forms
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
+3 -3
View File
@@ -12,9 +12,9 @@ from django.contrib.sessions.models import Session
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils import timezone
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str
from django.utils.safestring import mark_safe
from django.utils.translation import get_language, ugettext as _
from django.utils.translation import get_language, gettext as _
from .. import models
from .. import signals
@@ -241,7 +241,7 @@ def display_messages(msgs):
level = "info"
for m in msgs:
level = m.tags
text += smart_text(m) + "\\\n"
text += smart_str(m) + "\\\n"
if level == "info":
level = "success"
@@ -1,9 +1,9 @@
"""Custom urls."""
from django.conf.urls import url
from django.urls import re_path
from . import views
urlpatterns = [
url("^$", views.test_view, name="index")
re_path("^$", views.test_view, name="index")
]
+1 -1
View File
@@ -2,7 +2,7 @@
from pkg_resources import parse_version
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core.extensions import exts_pool
from modoboa.lib.api_client import ModoAPIClient
+1 -1
View File
@@ -5,7 +5,7 @@ from functools import reduce
from django.contrib.auth.decorators import login_required, user_passes_test
from django.shortcuts import render
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core.models import Log
from modoboa.core.utils import check_for_updates
+1 -1
View File
@@ -13,7 +13,7 @@ from django.utils import translation
from django.utils.encoding import force_bytes
from django.utils.html import escape
from django.utils.http import urlsafe_base64_encode
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.views import generic
from django.views.decorators.cache import never_cache
+2 -2
View File
@@ -2,7 +2,7 @@
from django.contrib.auth import mixins as auth_mixins
from django.urls import reverse
from django.utils.http import is_safe_url
from django.utils.http import url_has_allowed_host_and_scheme
from django.views import generic
from ..extensions import exts_pool
@@ -16,7 +16,7 @@ def find_nextlocation(request, user):
nextlocation = request.POST.get("next", request.GET.get("next"))
condition = (
nextlocation and
is_safe_url(nextlocation, request.get_host())
url_has_allowed_host_and_scheme(nextlocation, request.get_host())
)
if condition:
return nextlocation
+3 -3
View File
@@ -9,8 +9,8 @@ from django.conf import settings
from django.shortcuts import render
from django.template.loader import render_to_string
from django.utils import translation
from django.utils.encoding import force_text
from django.utils.translation import ugettext as _
from django.utils.encoding import force_str
from django.utils.translation import gettext as _
from django.contrib.auth.decorators import login_required, user_passes_test
@@ -52,7 +52,7 @@ def profile(request, tplname="core/user_profile.html"):
if form.is_valid():
form.save()
if update_password and form.cleaned_data["confirmation"] != "":
request.session["password"] = force_text(encrypt(
request.session["password"] = force_str(encrypt(
form.cleaned_data["confirmation"]
))
translation.activate(request.user.language)
+1 -1
View File
@@ -4,7 +4,7 @@ import collections
from django import forms
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from modoboa.dmarc.api.v2 import serializers
from modoboa.lib import form_utils
+1 -1
View File
@@ -1,7 +1,7 @@
"""Django signal handlers for modoboa_dmarc."""
from django.urls import reverse
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.dispatch import receiver
from modoboa.admin import signals as admin_signals
+3 -3
View File
@@ -20,8 +20,8 @@ import six
from django.db import transaction
from django.db.models import Q
from django.utils import timezone
from django.utils.encoding import smart_text
from django.utils.translation import ugettext as _
from django.utils.encoding import smart_str
from django.utils.translation import gettext as _
from modoboa.admin import models as admin_models
from modoboa.parameters import tools as param_tools
@@ -57,7 +57,7 @@ def import_record(xml_node, report):
record.spf_result = policy_evaluated.find("spf").text
reason = policy_evaluated.find("reason")
if reason:
record.reason_type = smart_text(reason.find("type").text)[:14]
record.reason_type = smart_str(reason.find("type").text)[:14]
if record.reason_type not in constants.ALLOWED_REASON_TYPES:
record.reason_type = "other"
comment = reason.find("comment").text or ""
+1 -1
View File
@@ -1,7 +1,7 @@
"""DMARC models."""
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from modoboa.admin import models as admin_models
+1 -1
View File
@@ -6,7 +6,7 @@ from collections import OrderedDict
from django import template
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
register = template.Library()
+1 -1
View File
@@ -11,7 +11,7 @@ from django.utils import timezone
from django.views import generic
from django.contrib.auth import mixins as auth_mixins
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from modoboa.admin import models as admin_models
from modoboa.parameters import tools as param_tools
+1 -1
View File
@@ -2,7 +2,7 @@
import ipaddress
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.admin import lib as admin_lib
+1 -1
View File
@@ -4,7 +4,7 @@ import datetime
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from . import constants
from . import lib
+1 -1
View File
@@ -1,6 +1,6 @@
"""App related views."""
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.views import generic
from django.contrib.auth import mixins as auth_mixins
+1 -1
View File
@@ -3,7 +3,7 @@
import collections
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from modoboa.lib import form_utils
from modoboa.parameters import forms as param_forms
+3 -3
View File
@@ -1,7 +1,7 @@
"""AppConfig for IMAP migration."""
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy
from django.utils.translation import gettext_lazy
def load_imapmigration_settings():
@@ -15,9 +15,9 @@ def load_imapmigration_settings():
from .api.v2 import serializers
param_tools.registry.add(
"global", app_settings.ParametersForm, ugettext_lazy("IMAP Migration"))
"global", app_settings.ParametersForm, gettext_lazy("IMAP Migration"))
param_tools.registry.add2(
"global", "imap_migration", ugettext_lazy("IMAP Migration"),
"global", "imap_migration", gettext_lazy("IMAP Migration"),
app_settings.IMAP_MIGRATION_PARAMETERS_STRUCT,
serializers.IMAPMigrationSettingsSerializer,
True)
+1 -1
View File
@@ -5,7 +5,7 @@ import socket
import ssl
from django.utils.encoding import smart_bytes, smart_str
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core import models as core_models
from modoboa.lib import email_utils
+1 -1
View File
@@ -2,7 +2,7 @@
from django.core.checks import Warning, register
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core import models as core_models
+1 -1
View File
@@ -5,7 +5,7 @@ import ldap.modlist as modlist
from django.conf import settings
from django.utils.encoding import force_bytes, force_str
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core import models as core_models
from modoboa.lib.email_utils import split_mailbox
+1 -1
View File
@@ -7,7 +7,7 @@ import pkg_resources
import requests
from requests.exceptions import RequestException
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
logger = logging.getLogger("modoboa.admin")
+3 -3
View File
@@ -11,7 +11,7 @@ from cryptography.hazmat.primitives.hashes import SHA1
from django.conf import settings
from django.utils.crypto import get_random_string
from django.utils.encoding import smart_bytes, smart_text
from django.utils.encoding import smart_bytes, smart_str
def random_key(length=16):
@@ -34,12 +34,12 @@ def _get_fernet():
def encrypt(clear_value):
"""Encrypt a value using secret_key."""
return smart_text(_get_fernet().encrypt(smart_bytes(clear_value)))
return smart_str(_get_fernet().encrypt(smart_bytes(clear_value)))
def decrypt(encrypted_value):
"""Decrypt a value using secret_key."""
return smart_text(_get_fernet().decrypt(smart_bytes(encrypted_value)))
return smart_str(_get_fernet().decrypt(smart_bytes(encrypted_value)))
def get_password(request):
+1 -1
View File
@@ -1,6 +1,6 @@
from django.conf import settings
from django.db import connection
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.lib.exceptions import InternalError
+5 -5
View File
@@ -13,9 +13,9 @@ from lxml.html.clean import Cleaner
from django.core.mail import EmailMessage
from django.template.loader import render_to_string
from django.utils.encoding import smart_str, smart_text
from django.utils.encoding import smart_str, smart_str
from django.utils.html import conditional_escape, escape
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core import models as core_models
from modoboa.lib import u2u_decode
@@ -130,7 +130,7 @@ class Email(object):
if not len(value):
continue
if encoding:
value = smart_text(value, encoding=encoding)
value = smart_str(value, encoding=encoding)
elif isinstance(value, bytes):
# SMTPUTF8 fallback (most of the time)
# Address contains non ASCII chars but is not RFC2047
@@ -229,7 +229,7 @@ class Email(object):
_RE_REMOVE_EXTRA_WHITESPACE.sub("\n\n", content).strip()
)
mail_text = escape(mail_text)
return smart_text(mail_text)
return smart_str(mail_text)
def _post_process_html(self, content):
html = lxml.html.fromstring(content)
@@ -253,7 +253,7 @@ class Email(object):
)
mail_text = lxml.html.tostring(
cleaner.clean_html(html), encoding="unicode")
return smart_text(mail_text)
return smart_str(mail_text)
def _map_cid(self, url):
if url.startswith("cid:"):
+1 -1
View File
@@ -4,7 +4,7 @@
"""
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
class ModoboaException(Exception):
+4 -4
View File
@@ -1,7 +1,7 @@
"""Custom form fields."""
from django import forms
from django.utils.translation import ugettext_lazy
from django.utils.translation import gettext_lazy
from rest_framework import serializers
@@ -12,7 +12,7 @@ class DomainNameField(forms.fields.CharField):
"""A subclass of CharField that only accepts a valid domain name."""
default_error_messages = {
"invalid": ugettext_lazy("Enter a valid domain name")
"invalid": gettext_lazy("Enter a valid domain name")
}
default_validators = [validators.validate_hostname]
@@ -41,7 +41,7 @@ class DRFEmailFieldUTF8(serializers.CharField):
"""Custom DRF email field to support UTF8."""
default_error_messages = {
"invalid": ugettext_lazy("Enter a valid email address.")
"invalid": gettext_lazy("Enter a valid email address.")
}
def __init__(self, **kwargs):
@@ -55,7 +55,7 @@ class DRFEmailFieldUTF8AndEmptyUser(serializers.CharField):
"""Custom DRF email field to support UTF8 and empty local part."""
default_error_messages = {
"invalid": ugettext_lazy("Enter a valid email address.")
"invalid": gettext_lazy("Enter a valid email address.")
}
def __init__(self, **kwargs):
+3 -3
View File
@@ -9,7 +9,7 @@ from django.forms.fields import Field
from django.forms.widgets import RadioSelect
from django.shortcuts import render
from django.utils.encoding import force_str
from django.utils.translation import ugettext as _, ugettext_lazy
from django.utils.translation import gettext as _, gettext_lazy
from modoboa.lib.exceptions import BadRequest
from modoboa.lib.web_utils import render_to_json_response
@@ -393,8 +393,8 @@ class YesNoField(TypedChoiceField):
"""Constructor."""
kwargs.update({
"choices": (
(True, ugettext_lazy("Yes")),
(False, ugettext_lazy("No"))
(True, gettext_lazy("Yes")),
(False, gettext_lazy("No"))
),
"widget": HorizontalRadioSelect(),
"coerce": lambda x: x == "True"
+1 -1
View File
@@ -35,7 +35,7 @@ import ldap
from django.conf import settings
from django.utils.encoding import force_bytes, force_str
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core.password_hashers import get_password_hasher
from modoboa.lib.exceptions import InternalError
+10 -6
View File
@@ -2,7 +2,7 @@
from django.http import HttpResponseRedirect
from django.utils.deprecation import MiddlewareMixin
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str
from modoboa.lib import signals as lib_signals
from modoboa.lib.exceptions import ModoboaException
@@ -11,10 +11,14 @@ from modoboa.lib.web_utils import (
)
def is_ajax(request):
return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
class AjaxLoginRedirect(MiddlewareMixin):
def process_response(self, request, response):
if request.is_ajax():
if is_ajax(request):
if isinstance(response, HttpResponseRedirect):
response.status_code = 278
return response
@@ -27,17 +31,17 @@ class CommonExceptionCatcher(MiddlewareMixin):
if not isinstance(exception, ModoboaException):
return None
if request.is_ajax() or "/api/" in request.path:
if is_ajax(request) or "/api/" in request.path:
if exception.http_code is None:
return ajax_response(
request, status="ko", respmsg=smart_text(exception),
request, status="ko", respmsg=smart_str(exception),
norefresh=True
)
return render_to_json_response(
smart_text(exception), status=exception.http_code
smart_str(exception), status=exception.http_code
)
return _render_error(
request, user_context={"error": smart_text(exception)}
request, user_context={"error": smart_str(exception)}
)
+2 -2
View File
@@ -10,7 +10,7 @@ import re
import subprocess
from django.conf import settings
from django.utils.encoding import force_text
from django.utils.encoding import force_str
def exec_cmd(cmd, sudo_user=None, pinput=None, capture_output=True, **kwargs):
@@ -59,7 +59,7 @@ def doveadm_cmd(params, pinput=None, capture_output=True, **kwargs):
dpath = None
code, output = exec_cmd("which doveadm")
if not code:
dpath = force_text(output).strip()
dpath = force_str(output).strip()
else:
known_paths = getattr(
settings, "DOVEADM_LOOKUP_PATH",
+2 -2
View File
@@ -4,7 +4,7 @@ Form rendering tags.
from django import forms, template
from django.template.loader import render_to_string
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str
from django.utils.safestring import mark_safe
from modoboa.lib.form_utils import SeparatorField
@@ -43,7 +43,7 @@ def render_field(
from modoboa.core.templatetags.core_tags import visirule
if isinstance(field.field, SeparatorField):
return "<h5%s>%s</h5>" % (visirule(field), smart_text(field.label))
return "<h5%s>%s</h5>" % (visirule(field), smart_str(field.label))
configure_field_classes(field)
context = {
"field": field, "help_display_mode": help_display_mode,
+1 -1
View File
@@ -5,7 +5,7 @@ from datetime import datetime
from django import template
from django.template import Context, Template
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core import signals as core_signals
+2 -2
View File
@@ -3,7 +3,7 @@
import os
from django.test import SimpleTestCase
from django.utils.encoding import smart_bytes, smart_text
from django.utils.encoding import smart_bytes, smart_str
from ..email_utils import (
Email, prepare_addresses, split_address, split_local_part
@@ -44,7 +44,7 @@ class EmailTests(SimpleTestCase):
with open(message_path, "rb") as fp:
# output should always be unicode (py2) or str (py3)
mail_text = smart_text(fp.read())
mail_text = smart_str(fp.read())
return mail_text
+2 -2
View File
@@ -9,7 +9,7 @@ import re
from email.header import decode_header, make_header
from email.utils import parseaddr
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str
# check spaces between encoded_words (and strip them)
sre = re.compile(r"\?=[ \t]+=\?")
@@ -40,7 +40,7 @@ def decode_mime(m):
"""Substitute matching encoded_word with unicode equiv."""
h = decode_header(clean_spaces(m))
try:
u = smart_text(make_header(h))
u = smart_str(make_header(h))
except (LookupError, UnicodeDecodeError):
return m.group(0)
return u
+2 -2
View File
@@ -4,14 +4,14 @@ import re
from django.core.exceptions import ValidationError
from django.core.validators import EmailValidator, URLValidator
from django.utils.translation import ugettext_lazy
from django.utils.translation import gettext_lazy
class HostnameValidator(object):
"""Validator for fqdn."""
message = ugettext_lazy("Enter a valid domain name")
message = gettext_lazy("Enter a valid domain name")
code = "invalid"
regex = re.compile(URLValidator.host_re)
+1 -1
View File
@@ -3,7 +3,7 @@
import collections
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from modoboa.lib.form_utils import SeparatorField, YesNoField
from modoboa.parameters import forms as param_forms
+1 -1
View File
@@ -1,7 +1,7 @@
"""App config for limits."""
from django.apps import AppConfig
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
def load_limits_settings():
+1 -1
View File
@@ -2,7 +2,7 @@
import collections
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
DEFAULT_USER_LIMITS = collections.OrderedDict((
("domains", {
+1 -1
View File
@@ -1,7 +1,7 @@
"""Custom forms."""
from django import forms
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.lib.permissions import get_object_owner
from . import utils
+1 -1
View File
@@ -4,7 +4,7 @@ from django.contrib.contenttypes.models import ContentType
from django.db.models import signals
from django.dispatch import receiver
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.admin import models as admin_models, signals as admin_signals
from modoboa.core import models as core_models, signals as core_signals
+1 -1
View File
@@ -4,7 +4,7 @@
"""
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.lib.exceptions import ModoboaException
+1 -1
View File
@@ -3,7 +3,7 @@
from django.conf import settings
from django.db import models
from django.utils.functional import cached_property
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from modoboa.core import models as core_models
from . import lib, utils
+1 -1
View File
@@ -1,6 +1,6 @@
"""App. related serializers."""
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from rest_framework import serializers
+9 -9
View File
@@ -5,7 +5,7 @@ import rrdtool
from pkg_resources import parse_version
from django.conf import settings
from django.utils.translation import ugettext_lazy
from django.utils.translation import gettext_lazy
from django import forms
from modoboa.lib import form_utils
@@ -17,27 +17,27 @@ class ParametersForm(param_forms.AdminParametersForm):
app = "maillog"
general_sep = form_utils.SeparatorField(label=ugettext_lazy("General"))
general_sep = form_utils.SeparatorField(label=gettext_lazy("General"))
logfile = forms.CharField(
label=ugettext_lazy("Path to the log file"),
label=gettext_lazy("Path to the log file"),
initial="/var/log/mail.log",
help_text=ugettext_lazy("Path to log file used to collect statistics"),
help_text=gettext_lazy("Path to log file used to collect statistics"),
widget=forms.TextInput(attrs={"class": "form-control"})
)
rrd_rootdir = forms.CharField(
label=ugettext_lazy("Directory to store RRD files"),
label=gettext_lazy("Directory to store RRD files"),
initial="/tmp/modoboa",
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Path to directory where RRD files are stored"),
widget=forms.TextInput(attrs={"class": "form-control"})
)
greylist = form_utils.YesNoField(
label=ugettext_lazy("Show greylisted messages"),
label=gettext_lazy("Show greylisted messages"),
initial=False,
help_text=ugettext_lazy(
help_text=gettext_lazy(
"Differentiate between hard and soft rejects (greylisting)")
)
@@ -56,4 +56,4 @@ def load_settings():
from modoboa.parameters import tools as param_tools
param_tools.registry.add(
"global", ParametersForm, ugettext_lazy("Statistics"))
"global", ParametersForm, gettext_lazy("Statistics"))

Some files were not shown because too many files have changed in this diff Show More