From f875e317efea1743553b38c548185b1242bd5a4e Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Tue, 21 Apr 2020 16:47:09 +0200 Subject: [PATCH 01/11] Handle empty emails --- users/forms.py | 60 ++++++++++++++++++++++++++++++++++++++++++------- users/models.py | 2 -- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/users/forms.py b/users/forms.py index 3440f2f9..2f3c2e86 100644 --- a/users/forms.py +++ b/users/forms.py @@ -147,10 +147,15 @@ class UserCreationForm(FormRevMixin, forms.ModelForm): super(UserCreationForm, self).__init__(*args, prefix=prefix, **kwargs) def clean_email(self): - if not OptionalUser.objects.first().local_email_domain in self.cleaned_data.get( - "email" - ): - return self.cleaned_data.get("email").lower() + new_email = self.cleaned_data.get("email") + + if not new_email or len(new_email) == 0: + raise forms.ValidationError( + _("Email field cannot be empty.") + ) + + if not OptionalUser.objects.first().local_email_domain in new_email: + return new_email.lower() else: raise forms.ValidationError( _("You can't use an internal address as your external address.") @@ -481,6 +486,17 @@ class AdherentCreationForm(AdherentForm): self.fields.pop("password1") self.fields.pop("password2") + def clean_email(self): + """Forbid empty email""" + new_email = self.cleaned_data.get("email") + + if not new_email or len(new_email) == 0: + raise forms.ValidationError( + _("Email field cannot be empty.") + ) + + return new_email + def clean_password2(self): """Verifie que password1 et 2 sont identiques (si nécessaire)""" send_email = self.cleaned_data.get("init_password_by_mail") @@ -520,6 +536,7 @@ class AdherentEditForm(AdherentForm): self.fields["gpg_fingerprint"].widget.attrs["placeholder"] = _( "Leave empty if you don't have any GPG key." ) + self.user = kwargs["instance"] if "shell" in self.fields: self.fields["shell"].empty_label = _("Default shell") @@ -539,6 +556,22 @@ class AdherentEditForm(AdherentForm): "shortcuts_enabled", ] + def clean_email(self): + """Forbid empty email""" + original_email = self.user.email + new_email = self.cleaned_data.get("email") + + # Allow empty emails if the user had an empty email before + if original_email is None or len(original_email) == 0: + return new_email + + if new_email is None or len(new_email) == 0: + raise forms.ValidationError( + _("Email field cannot be empty.") + ) + + return new_email + class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): """Formulaire de base d'edition d'un user. Formulaire de base, utilisé @@ -832,6 +865,7 @@ class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(EmailSettingsForm, self).__init__(*args, prefix=prefix, **kwargs) + self.user = kwargs["instance"] self.fields["email"].label = _("Main email address") if "local_email_redirect" in self.fields: self.fields["local_email_redirect"].label = _("Redirect local emails") @@ -839,10 +873,20 @@ class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): self.fields["local_email_enabled"].label = _("Use local emails") def clean_email(self): - if not OptionalUser.objects.first().local_email_domain in self.cleaned_data.get( - "email" - ): - return self.cleaned_data.get("email").lower() + original_email = self.user.email + new_email = self.cleaned_data.get("email") + + # Allow empty emails if the user had an empty email before + if original_email is None or len(original_email) == 0: + return new_email + + if new_email is None or len(new_email) == 0: + raise forms.ValidationError( + _("Email field cannot be empty.") + ) + + if not OptionalUser.objects.first().local_email_domain in new_email: + return new_email.lower() else: raise forms.ValidationError( _("You can't use a {} address.").format( diff --git a/users/models.py b/users/models.py index 42df3f5a..8958a95d 100755 --- a/users/models.py +++ b/users/models.py @@ -205,8 +205,6 @@ class User( validators=[linux_user_validator], ) email = models.EmailField( - blank=True, - null=True, help_text=_("External email address allowing us to contact you."), ) local_email_redirect = models.BooleanField( From 42c15c1f5d1936fb76636b918675ccc91b4a057c Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Tue, 21 Apr 2020 15:01:03 +0000 Subject: [PATCH 02/11] Leave user email blank / null for compatilibity --- users/models.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/users/models.py b/users/models.py index 8958a95d..42df3f5a 100755 --- a/users/models.py +++ b/users/models.py @@ -205,6 +205,8 @@ class User( validators=[linux_user_validator], ) email = models.EmailField( + blank=True, + null=True, help_text=_("External email address allowing us to contact you."), ) local_email_redirect = models.BooleanField( From 99cd24cec0952d8738521a9dddac0c75e1158c8a Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Tue, 21 Apr 2020 17:07:09 +0200 Subject: [PATCH 03/11] Add required for email field when necessary --- users/forms.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/users/forms.py b/users/forms.py index 2f3c2e86..01820286 100644 --- a/users/forms.py +++ b/users/forms.py @@ -145,6 +145,7 @@ class UserCreationForm(FormRevMixin, forms.ModelForm): def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(UserCreationForm, self).__init__(*args, prefix=prefix, **kwargs) + self.fields["email"].required = True def clean_email(self): new_email = self.cleaned_data.get("email") @@ -471,6 +472,7 @@ class AdherentCreationForm(AdherentForm): def __init__(self, *args, **kwargs): super(AdherentCreationForm, self).__init__(*args, **kwargs) gtu_file = GeneralOption.get_cached_value("GTU") + self.fields["email"].required = True self.fields["gtu_check"].label = mark_safe( "%s %s." % ( @@ -537,6 +539,7 @@ class AdherentEditForm(AdherentForm): "Leave empty if you don't have any GPG key." ) self.user = kwargs["instance"] + self.fields["email"].required = self.user.email and len(self.user.email) if "shell" in self.fields: self.fields["shell"].empty_label = _("Default shell") @@ -867,6 +870,7 @@ class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): super(EmailSettingsForm, self).__init__(*args, prefix=prefix, **kwargs) self.user = kwargs["instance"] self.fields["email"].label = _("Main email address") + self.fields["email"].required = self.user.email and len(self.user.email) if "local_email_redirect" in self.fields: self.fields["local_email_redirect"].label = _("Redirect local emails") if "local_email_enabled" in self.fields: From ba05a682f47adb3845780ac8fe33afdbb367e43d Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Tue, 21 Apr 2020 16:47:09 +0200 Subject: [PATCH 04/11] Handle empty emails --- users/models.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/users/models.py b/users/models.py index 42df3f5a..8958a95d 100755 --- a/users/models.py +++ b/users/models.py @@ -205,8 +205,6 @@ class User( validators=[linux_user_validator], ) email = models.EmailField( - blank=True, - null=True, help_text=_("External email address allowing us to contact you."), ) local_email_redirect = models.BooleanField( From 51b3c52181a8886f0869fb929c26261499af4ad6 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Tue, 21 Apr 2020 15:01:03 +0000 Subject: [PATCH 05/11] Leave user email blank / null for compatilibity --- users/models.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/users/models.py b/users/models.py index 8958a95d..42df3f5a 100755 --- a/users/models.py +++ b/users/models.py @@ -205,6 +205,8 @@ class User( validators=[linux_user_validator], ) email = models.EmailField( + blank=True, + null=True, help_text=_("External email address allowing us to contact you."), ) local_email_redirect = models.BooleanField( From eb4dd7ebe3e593efe2e226569cefb937dac7010c Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Tue, 21 Apr 2020 18:19:03 +0200 Subject: [PATCH 06/11] Make email check more pythonic --- users/forms.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/users/forms.py b/users/forms.py index 01820286..92d46898 100644 --- a/users/forms.py +++ b/users/forms.py @@ -150,7 +150,7 @@ class UserCreationForm(FormRevMixin, forms.ModelForm): def clean_email(self): new_email = self.cleaned_data.get("email") - if not new_email or len(new_email) == 0: + if not new_email: raise forms.ValidationError( _("Email field cannot be empty.") ) @@ -492,7 +492,7 @@ class AdherentCreationForm(AdherentForm): """Forbid empty email""" new_email = self.cleaned_data.get("email") - if not new_email or len(new_email) == 0: + if not new_email: raise forms.ValidationError( _("Email field cannot be empty.") ) @@ -539,7 +539,7 @@ class AdherentEditForm(AdherentForm): "Leave empty if you don't have any GPG key." ) self.user = kwargs["instance"] - self.fields["email"].required = self.user.email and len(self.user.email) + self.fields["email"].required = bool(self.user.email) if "shell" in self.fields: self.fields["shell"].empty_label = _("Default shell") @@ -565,10 +565,10 @@ class AdherentEditForm(AdherentForm): new_email = self.cleaned_data.get("email") # Allow empty emails if the user had an empty email before - if original_email is None or len(original_email) == 0: + if not original_email: return new_email - if new_email is None or len(new_email) == 0: + if not new_email: raise forms.ValidationError( _("Email field cannot be empty.") ) @@ -870,7 +870,7 @@ class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): super(EmailSettingsForm, self).__init__(*args, prefix=prefix, **kwargs) self.user = kwargs["instance"] self.fields["email"].label = _("Main email address") - self.fields["email"].required = self.user.email and len(self.user.email) + self.fields["email"].required = bool(self.user.email) if "local_email_redirect" in self.fields: self.fields["local_email_redirect"].label = _("Redirect local emails") if "local_email_enabled" in self.fields: @@ -881,10 +881,10 @@ class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): new_email = self.cleaned_data.get("email") # Allow empty emails if the user had an empty email before - if original_email is None or len(original_email) == 0: + if not original_email: return new_email - if new_email is None or len(new_email) == 0: + if not new_email: raise forms.ValidationError( _("Email field cannot be empty.") ) From b119bfeb652484d12255041928c6ec434ca58427 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Tue, 21 Apr 2020 16:31:26 +0000 Subject: [PATCH 07/11] Prevent user email from being null --- users/migrations/0090_auto_20200421_1825.py | 20 ++++++++++++++++++++ users/models.py | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 users/migrations/0090_auto_20200421_1825.py diff --git a/users/migrations/0090_auto_20200421_1825.py b/users/migrations/0090_auto_20200421_1825.py new file mode 100644 index 00000000..3a659d46 --- /dev/null +++ b/users/migrations/0090_auto_20200421_1825.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.28 on 2020-04-21 16:25 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0089_auto_20200418_0112'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='email', + field=models.EmailField(blank=True, default='', help_text='External email address allowing us to contact you.', max_length=254), + ), + ] diff --git a/users/models.py b/users/models.py index 42df3f5a..805e8b69 100755 --- a/users/models.py +++ b/users/models.py @@ -206,7 +206,7 @@ class User( ) email = models.EmailField( blank=True, - null=True, + default="", help_text=_("External email address allowing us to contact you."), ) local_email_redirect = models.BooleanField( From 24abff41064418b02809fb73ebc6ae719a266d6b Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Tue, 21 Apr 2020 18:40:19 +0200 Subject: [PATCH 08/11] Fix some email checks being bypassed for legacy users --- users/forms.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/users/forms.py b/users/forms.py index 92d46898..34d5bfa9 100644 --- a/users/forms.py +++ b/users/forms.py @@ -564,11 +564,8 @@ class AdherentEditForm(AdherentForm): original_email = self.user.email new_email = self.cleaned_data.get("email") - # Allow empty emails if the user had an empty email before - if not original_email: - return new_email - - if not new_email: + # Allow empty emails only if the user had an empty email before + if original_email and not new_email: raise forms.ValidationError( _("Email field cannot be empty.") ) @@ -880,11 +877,8 @@ class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): original_email = self.user.email new_email = self.cleaned_data.get("email") - # Allow empty emails if the user had an empty email before - if not original_email: - return new_email - - if not new_email: + # Allow empty emails only if the user had an empty email before + if original_email and not new_email: raise forms.ValidationError( _("Email field cannot be empty.") ) From e47b555343284a0a269845bf147daa954acc7e31 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Tue, 21 Apr 2020 19:27:12 +0200 Subject: [PATCH 09/11] Check email in user clean (factorise code) --- users/forms.py | 70 ------------------------------------------------- users/models.py | 41 +++++++++++++++-------------- 2 files changed, 22 insertions(+), 89 deletions(-) diff --git a/users/forms.py b/users/forms.py index 34d5bfa9..d9d68c88 100644 --- a/users/forms.py +++ b/users/forms.py @@ -147,21 +147,6 @@ class UserCreationForm(FormRevMixin, forms.ModelForm): super(UserCreationForm, self).__init__(*args, prefix=prefix, **kwargs) self.fields["email"].required = True - def clean_email(self): - new_email = self.cleaned_data.get("email") - - if not new_email: - raise forms.ValidationError( - _("Email field cannot be empty.") - ) - - if not OptionalUser.objects.first().local_email_domain in new_email: - return new_email.lower() - else: - raise forms.ValidationError( - _("You can't use an internal address as your external address.") - ) - class Meta: model = Adherent fields = ("pseudo", "surname", "email") @@ -358,18 +343,6 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): label=_("Force the move?"), initial=False, required=False ) - def clean_email(self): - if not OptionalUser.objects.first().local_email_domain in self.cleaned_data.get( - "email" - ): - return self.cleaned_data.get("email").lower() - else: - raise forms.ValidationError( - _("You can't use a {} address.").format( - OptionalUser.objects.first().local_email_domain - ) - ) - def clean_telephone(self): """Verifie que le tel est présent si 'option est validée dans preferences""" @@ -488,17 +461,6 @@ class AdherentCreationForm(AdherentForm): self.fields.pop("password1") self.fields.pop("password2") - def clean_email(self): - """Forbid empty email""" - new_email = self.cleaned_data.get("email") - - if not new_email: - raise forms.ValidationError( - _("Email field cannot be empty.") - ) - - return new_email - def clean_password2(self): """Verifie que password1 et 2 sont identiques (si nécessaire)""" send_email = self.cleaned_data.get("init_password_by_mail") @@ -559,19 +521,6 @@ class AdherentEditForm(AdherentForm): "shortcuts_enabled", ] - def clean_email(self): - """Forbid empty email""" - original_email = self.user.email - new_email = self.cleaned_data.get("email") - - # Allow empty emails only if the user had an empty email before - if original_email and not new_email: - raise forms.ValidationError( - _("Email field cannot be empty.") - ) - - return new_email - class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): """Formulaire de base d'edition d'un user. Formulaire de base, utilisé @@ -873,25 +822,6 @@ class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): if "local_email_enabled" in self.fields: self.fields["local_email_enabled"].label = _("Use local emails") - def clean_email(self): - original_email = self.user.email - new_email = self.cleaned_data.get("email") - - # Allow empty emails only if the user had an empty email before - if original_email and not new_email: - raise forms.ValidationError( - _("Email field cannot be empty.") - ) - - if not OptionalUser.objects.first().local_email_domain in new_email: - return new_email.lower() - else: - raise forms.ValidationError( - _("You can't use a {} address.").format( - OptionalUser.objects.first().local_email_domain - ) - ) - class Meta: model = User fields = ["email", "local_email_enabled", "local_email_redirect"] diff --git a/users/models.py b/users/models.py index 805e8b69..86d2cb5f 100755 --- a/users/models.py +++ b/users/models.py @@ -1323,32 +1323,35 @@ class User( self.__original_state = self.state self.__original_email = self.email - def clean(self, *args, **kwargs): - """Check if this pseudo is already used by any mailalias. - Better than raising an error in post-save and catching it""" + def clean_pseudo(self, *args, **kwargs): if EMailAddress.objects.filter(local_part=self.pseudo.lower()).exclude( user_id=self.id ): raise ValidationError(_("This username is already used.")) - if ( - not self.local_email_enabled - and not self.email - and not (self.state == self.STATE_FULL_ARCHIVE) - ): - raise ValidationError( - _( - "There is neither a local email address nor an external" - " email address for this user." - ) - ) - if self.local_email_redirect and not self.email: - raise ValidationError( - _( - "You can't redirect your local emails if no external email" - " address has been set." + + def clean_email(self, *args, **kwargs): + # Allow empty emails if the user had an empty email before + if not self.email and (self.__original_email or not self.pk): + raise forms.ValidationError( + _("Email field cannot be empty.") + ) + + self.email = self.email.lower() + + if OptionalUser.get_cached_value("local_email_domain") in self.email: + raise forms.ValidationError( + _("You can't use a {} address as an external contact address.").format( + OptionalUser.get_cached_value("local_email_domain") ) ) + def clean(self, *args, **kwargs): + super(User, self).clean(*args, **kwargs) + """Check if this pseudo is already used by any mailalias. + Better than raising an error in post-save and catching it""" + self.clean_pseudo(*args, **kwargs) + self.clean_email(*args, **kwargs) + def __str__(self): return self.pseudo From 91a4c35d3b3c47900ba90d1c5e0912e8bdb04a13 Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Tue, 21 Apr 2020 21:38:31 +0200 Subject: [PATCH 10/11] Improve comments for User clean methods --- users/models.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/users/models.py b/users/models.py index 86d2cb5f..4d9e1f20 100755 --- a/users/models.py +++ b/users/models.py @@ -1330,8 +1330,9 @@ class User( raise ValidationError(_("This username is already used.")) def clean_email(self, *args, **kwargs): - # Allow empty emails if the user had an empty email before - if not self.email and (self.__original_email or not self.pk): + # Allow empty emails only if the user had an empty email before + is_created = not self.pk + if not self.email and (self.__original_email or is_created): raise forms.ValidationError( _("Email field cannot be empty.") ) @@ -1346,9 +1347,9 @@ class User( ) def clean(self, *args, **kwargs): - super(User, self).clean(*args, **kwargs) """Check if this pseudo is already used by any mailalias. Better than raising an error in post-save and catching it""" + super(User, self).clean(*args, **kwargs) self.clean_pseudo(*args, **kwargs) self.clean_email(*args, **kwargs) From 5107a34a6e95576bdb7373852a7517a8ce22bf8b Mon Sep 17 00:00:00 2001 From: Jean-Romain Garnier Date: Tue, 21 Apr 2020 19:48:59 +0000 Subject: [PATCH 11/11] Add missing translations --- api/locale/fr/LC_MESSAGES/django.po | 2 +- cotisations/locale/fr/LC_MESSAGES/django.po | 149 ++++---- logs/locale/fr/LC_MESSAGES/django.po | 2 +- machines/locale/fr/LC_MESSAGES/django.po | 192 +++++----- multi_op/locale/fr/LC_MESSAGES/django.po | 2 +- preferences/locale/fr/LC_MESSAGES/django.po | 7 +- re2o/locale/fr/LC_MESSAGES/django.po | 4 +- search/locale/fr/LC_MESSAGES/django.po | 2 +- templates/locale/fr/LC_MESSAGES/django.po | 76 ++-- tickets/locale/fr/LC_MESSAGES/django.po | 2 +- topologie/locale/fr/LC_MESSAGES/django.po | 2 +- users/locale/fr/LC_MESSAGES/django.po | 388 ++++++++++---------- 12 files changed, 411 insertions(+), 417 deletions(-) diff --git a/api/locale/fr/LC_MESSAGES/django.po b/api/locale/fr/LC_MESSAGES/django.po index fb747f3e..8040325f 100644 --- a/api/locale/fr/LC_MESSAGES/django.po +++ b/api/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2019-01-07 01:37+0100\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/cotisations/locale/fr/LC_MESSAGES/django.po b/cotisations/locale/fr/LC_MESSAGES/django.po index ec0098c2..ef9b3fa5 100644 --- a/cotisations/locale/fr/LC_MESSAGES/django.po +++ b/cotisations/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n" "Last-Translator: Laouen Fernet \n" "Language: fr_FR\n" @@ -37,7 +37,7 @@ msgstr "Vous n'avez pas le droit de voir cette application." msgid "Select a payment method" msgstr "Sélectionnez un moyen de paiement" -#: cotisations/forms.py:73 cotisations/models.py:687 +#: cotisations/forms.py:73 cotisations/models.py:688 msgid "Member" msgstr "Adhérent" @@ -154,7 +154,7 @@ msgstr "Peut voir un objet facture" msgid "Can edit all the previous invoices" msgstr "Peut modifier toutes les factures précédentes" -#: cotisations/models.py:145 cotisations/models.py:461 cotisations/views.py:376 +#: cotisations/models.py:145 cotisations/models.py:462 cotisations/views.py:376 #: cotisations/views.py:571 msgid "invoice" msgstr "facture" @@ -217,115 +217,115 @@ msgstr "Il n'y a pas de moyens de paiement que vous puissiez utiliser." msgid "There are no articles that you can buy." msgstr "Il n'y a pas d'articles que vous puissiez acheter." -#: cotisations/models.py:377 +#: cotisations/models.py:378 msgid "Can view a custom invoice object" msgstr "Peut voir un objet facture personnalisée" -#: cotisations/models.py:379 +#: cotisations/models.py:380 msgid "recipient" msgstr "destinataire" -#: cotisations/models.py:380 +#: cotisations/models.py:381 msgid "payment type" msgstr "type de paiement" -#: cotisations/models.py:381 +#: cotisations/models.py:382 msgid "address" msgstr "adresse" -#: cotisations/models.py:382 +#: cotisations/models.py:383 msgid "paid" msgstr "payé" -#: cotisations/models.py:383 +#: cotisations/models.py:384 msgid "remark" msgstr "remarque" -#: cotisations/models.py:388 +#: cotisations/models.py:389 msgid "Can view a cost estimate object" msgstr "Peut voir un objet devis" -#: cotisations/models.py:391 +#: cotisations/models.py:392 msgid "period of validity" msgstr "période de validité" -#: cotisations/models.py:426 +#: cotisations/models.py:427 msgid "You don't have the right to delete a cost estimate." msgstr "Vous n'avez pas le droit de supprimer un devis." -#: cotisations/models.py:432 +#: cotisations/models.py:433 msgid "The cost estimate has an invoice and can't be deleted." msgstr "Le devis a une facture et ne peut pas être supprimé." -#: cotisations/models.py:454 cotisations/models.py:693 -#: cotisations/models.py:951 +#: cotisations/models.py:455 cotisations/models.py:694 +#: cotisations/models.py:952 msgid "Connection" msgstr "Connexion" -#: cotisations/models.py:455 cotisations/models.py:694 -#: cotisations/models.py:952 +#: cotisations/models.py:456 cotisations/models.py:695 +#: cotisations/models.py:953 msgid "Membership" msgstr "Adhésion" -#: cotisations/models.py:456 cotisations/models.py:689 -#: cotisations/models.py:695 cotisations/models.py:953 +#: cotisations/models.py:457 cotisations/models.py:690 +#: cotisations/models.py:696 cotisations/models.py:954 msgid "Both of them" msgstr "Les deux" -#: cotisations/models.py:465 +#: cotisations/models.py:466 msgid "amount" msgstr "montant" -#: cotisations/models.py:468 +#: cotisations/models.py:469 msgid "article" msgstr "article" -#: cotisations/models.py:471 +#: cotisations/models.py:472 msgid "price" msgstr "prix" -#: cotisations/models.py:474 cotisations/models.py:707 +#: cotisations/models.py:475 cotisations/models.py:708 msgid "duration (in months)" msgstr "durée (en mois)" -#: cotisations/models.py:480 cotisations/models.py:713 +#: cotisations/models.py:481 cotisations/models.py:714 msgid "duration (in days, will be added to duration in months)" msgstr "durée (en jours, sera ajoutée à la durée en mois)" -#: cotisations/models.py:488 cotisations/models.py:727 -#: cotisations/models.py:964 +#: cotisations/models.py:489 cotisations/models.py:728 +#: cotisations/models.py:965 msgid "subscription type" msgstr "type de cotisation" -#: cotisations/models.py:493 +#: cotisations/models.py:494 msgid "Can view a purchase object" msgstr "Peut voir un objet achat" -#: cotisations/models.py:494 +#: cotisations/models.py:495 msgid "Can edit all the previous purchases" msgstr "Peut modifier tous les achats précédents" -#: cotisations/models.py:496 cotisations/models.py:958 +#: cotisations/models.py:497 cotisations/models.py:959 msgid "purchase" msgstr "achat" -#: cotisations/models.py:497 +#: cotisations/models.py:498 msgid "purchases" msgstr "achats" -#: cotisations/models.py:550 cotisations/models.py:747 +#: cotisations/models.py:551 cotisations/models.py:748 msgid "Duration must be specified for a subscription." msgstr "La durée doit être renseignée pour une cotisation." -#: cotisations/models.py:561 +#: cotisations/models.py:562 msgid "You don't have the right to edit a purchase." msgstr "Vous n'avez pas le droit de modifier un achat." -#: cotisations/models.py:567 +#: cotisations/models.py:568 msgid "You don't have the right to edit this user's purchases." msgstr "Vous n'avez pas le droit de modifier les achats de cet utilisateur." -#: cotisations/models.py:576 +#: cotisations/models.py:577 msgid "" "You don't have the right to edit a purchase already controlled or " "invalidated." @@ -333,15 +333,15 @@ msgstr "" "Vous n'avez pas le droit de modifier un achat précédemment contrôlé ou " "invalidé." -#: cotisations/models.py:591 +#: cotisations/models.py:592 msgid "You don't have the right to delete a purchase." msgstr "Vous n'avez pas le droit de supprimer un achat." -#: cotisations/models.py:597 +#: cotisations/models.py:598 msgid "You don't have the right to delete this user's purchases." msgstr "Vous n'avez pas le droit de supprimer les achats de cet utilisateur." -#: cotisations/models.py:604 +#: cotisations/models.py:605 msgid "" "You don't have the right to delete a purchase already controlled or " "invalidated." @@ -349,134 +349,134 @@ msgstr "" "Vous n'avez pas le droit de supprimer un achat précédemment contrôlé ou " "invalidé." -#: cotisations/models.py:620 +#: cotisations/models.py:621 msgid "You don't have the right to view someone else's purchase history." msgstr "" "Vous n'avez pas le droit de voir l'historique des achats d'un autre " "utilisateur." -#: cotisations/models.py:688 +#: cotisations/models.py:689 msgid "Club" msgstr "Club" -#: cotisations/models.py:698 +#: cotisations/models.py:699 msgid "designation" msgstr "désignation" -#: cotisations/models.py:701 +#: cotisations/models.py:702 msgid "unit price" msgstr "prix unitaire" -#: cotisations/models.py:719 +#: cotisations/models.py:720 msgid "type of users concerned" msgstr "type d'utilisateurs concernés" -#: cotisations/models.py:730 cotisations/models.py:831 +#: cotisations/models.py:731 cotisations/models.py:832 msgid "is available for every user" msgstr "est disponible pour chaque utilisateur" -#: cotisations/models.py:737 +#: cotisations/models.py:738 msgid "Can view an article object" msgstr "Peut voir un objet article" -#: cotisations/models.py:738 +#: cotisations/models.py:739 msgid "Can buy every article" msgstr "Peut acheter chaque article" -#: cotisations/models.py:745 +#: cotisations/models.py:746 msgid "Solde is a reserved article name." msgstr "Solde est un nom d'article réservé." -#: cotisations/models.py:770 +#: cotisations/models.py:771 msgid "You can't buy this article." msgstr "Vous ne pouvez pas acheter cet article." -#: cotisations/models.py:811 +#: cotisations/models.py:812 msgid "Can view a bank object" msgstr "Peut voir un objet banque" -#: cotisations/models.py:812 +#: cotisations/models.py:813 msgid "bank" msgstr "banque" -#: cotisations/models.py:813 +#: cotisations/models.py:814 msgid "banks" msgstr "banques" -#: cotisations/models.py:829 +#: cotisations/models.py:830 msgid "method" msgstr "moyen" -#: cotisations/models.py:836 +#: cotisations/models.py:837 msgid "is user balance" msgstr "est solde utilisateur" -#: cotisations/models.py:837 +#: cotisations/models.py:838 msgid "There should be only one balance payment method." msgstr "Il ne devrait y avoir qu'un moyen de paiement solde." -#: cotisations/models.py:843 +#: cotisations/models.py:844 msgid "Can view a payment method object" msgstr "Peut voir un objet moyen de paiement" -#: cotisations/models.py:844 +#: cotisations/models.py:845 msgid "Can use every payment method" msgstr "Peut utiliser chaque moyen de paiement" -#: cotisations/models.py:846 +#: cotisations/models.py:847 msgid "payment method" msgstr "moyen de paiement" -#: cotisations/models.py:847 +#: cotisations/models.py:848 msgid "payment methods" msgstr "moyens de paiement" -#: cotisations/models.py:886 cotisations/payment_methods/comnpay/views.py:62 +#: cotisations/models.py:887 cotisations/payment_methods/comnpay/views.py:62 #, python-format msgid "The subscription of %(member_name)s was extended to %(end_date)s." msgstr "La cotisation de %(member_name)s a été étendue au %(end_date)s." -#: cotisations/models.py:896 +#: cotisations/models.py:897 msgid "The invoice was created." msgstr "La facture a été créée." -#: cotisations/models.py:916 +#: cotisations/models.py:917 msgid "You can't use this payment method." msgstr "Vous ne pouvez pas utiliser ce moyen de paiement." -#: cotisations/models.py:935 +#: cotisations/models.py:936 msgid "No custom payment methods." msgstr "Pas de moyens de paiement personnalisés." -#: cotisations/models.py:966 +#: cotisations/models.py:967 msgid "start date" msgstr "date de début" -#: cotisations/models.py:967 +#: cotisations/models.py:968 msgid "end date" msgstr "date de fin" -#: cotisations/models.py:971 +#: cotisations/models.py:972 msgid "Can view a subscription object" msgstr "Peut voir un objet cotisation" -#: cotisations/models.py:972 +#: cotisations/models.py:973 msgid "Can edit the previous subscriptions" msgstr "Peut modifier les cotisations précédentes" -#: cotisations/models.py:974 +#: cotisations/models.py:975 msgid "subscription" msgstr "cotisation" -#: cotisations/models.py:975 +#: cotisations/models.py:976 msgid "subscriptions" msgstr "cotisations" -#: cotisations/models.py:981 +#: cotisations/models.py:982 msgid "You don't have the right to edit a subscription." msgstr "Vous n'avez pas le droit de modifier une cotisation." -#: cotisations/models.py:990 +#: cotisations/models.py:991 msgid "" "You don't have the right to edit a subscription already controlled or " "invalidated." @@ -484,11 +484,11 @@ msgstr "" "Vous n'avez pas le droit de modifier une cotisation précédemment contrôlée " "ou invalidée." -#: cotisations/models.py:1002 +#: cotisations/models.py:1003 msgid "You don't have the right to delete a subscription." msgstr "Vous n'avez pas le droit de supprimer une cotisation." -#: cotisations/models.py:1009 +#: cotisations/models.py:1010 msgid "" "You don't have the right to delete a subscription already controlled or " "invalidated." @@ -496,7 +496,7 @@ msgstr "" "Vous n'avez pas le droit de supprimer une cotisation précédemment contrôlée " "ou invalidée." -#: cotisations/models.py:1025 +#: cotisations/models.py:1026 msgid "You don't have the right to view someone else's subscription history." msgstr "" "Vous n'avez pas le droit de voir l'historique des cotisations d'un autre " @@ -933,11 +933,6 @@ msgstr "Créer une facture" msgid "Control the invoices" msgstr "Contrôler les factures" -#: cotisations/utils.py:57 -#, python-format -msgid "Failed to send email: %(error)s." -msgstr "" - #: cotisations/views.py:157 msgid "You need to choose at least one article." msgstr "Vous devez choisir au moins un article." diff --git a/logs/locale/fr/LC_MESSAGES/django.po b/logs/locale/fr/LC_MESSAGES/django.po index 22de19e5..88f515fd 100644 --- a/logs/locale/fr/LC_MESSAGES/django.po +++ b/logs/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2018-06-23 16:01+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/machines/locale/fr/LC_MESSAGES/django.po b/machines/locale/fr/LC_MESSAGES/django.po index 5ec18685..36fd7335 100644 --- a/machines/locale/fr/LC_MESSAGES/django.po +++ b/machines/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2018-06-23 16:35+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -155,7 +155,7 @@ msgstr "Peut voir un objet machine" msgid "Can change the user of a machine" msgstr "Peut changer l'utilisateur d'une machine" -#: machines/models.py:80 machines/views.py:317 +#: machines/models.py:80 machines/views.py:306 msgid "machine" msgstr "machine" @@ -521,7 +521,7 @@ msgid "Can view an SSHFP record object" msgstr "Peut voir un objet enregistrement SSHFP" #: machines/models.py:1057 machines/templates/machines/machine.html:144 -#: machines/views.py:485 +#: machines/views.py:474 msgid "SSHFP record" msgstr "enregistrement SSHFP" @@ -537,7 +537,7 @@ msgstr "Peut voir un objet interface" msgid "Can change the owner of an interface" msgstr "Peut changer l'utilisateur d'une interface" -#: machines/models.py:1096 machines/views.py:369 +#: machines/models.py:1096 machines/views.py:358 msgid "interface" msgstr "interface" @@ -596,7 +596,7 @@ msgstr "Peut voir un objet list d'adresses IPv6" msgid "Can change the SLAAC value of an IPv6 addresses list" msgstr "Peut modifier la valeur SLAAC d'une liste d'adresses IPv6" -#: machines/models.py:1423 machines/views.py:429 +#: machines/models.py:1423 machines/views.py:418 msgid "IPv6 addresses list" msgstr "Liste d'adresses IPv6" @@ -951,13 +951,13 @@ msgstr "Afficher le constructeur" msgid "Display the IPv6 address" msgstr "Afficher les adresses IPv6" -#: machines/templates/machines/aff_machines.html:126 machines/views.py:299 -#: machines/views.py:413 machines/views.py:469 machines/views.py:520 -#: machines/views.py:583 machines/views.py:646 machines/views.py:708 -#: machines/views.py:760 machines/views.py:812 machines/views.py:864 -#: machines/views.py:919 machines/views.py:971 machines/views.py:1033 -#: machines/views.py:1089 machines/views.py:1141 machines/views.py:1207 -#: machines/views.py:1259 machines/views.py:1575 +#: machines/templates/machines/aff_machines.html:126 machines/views.py:288 +#: machines/views.py:402 machines/views.py:458 machines/views.py:509 +#: machines/views.py:572 machines/views.py:635 machines/views.py:697 +#: machines/views.py:749 machines/views.py:801 machines/views.py:853 +#: machines/views.py:908 machines/views.py:960 machines/views.py:1022 +#: machines/views.py:1078 machines/views.py:1130 machines/views.py:1196 +#: machines/views.py:1248 machines/views.py:1564 msgid "Edit" msgstr "Modifier" @@ -1432,76 +1432,76 @@ msgstr "Rôles de serveur" msgid "Ports openings" msgstr "Ouvertures de ports" -#: machines/views.py:153 +#: machines/views.py:142 msgid "Select a machine type first." msgstr "Sélectionnez un type de machine d'abord." -#: machines/views.py:244 +#: machines/views.py:233 msgid "The machine was created." msgstr "La machine a été créée." -#: machines/views.py:253 machines/views.py:348 machines/views.py:389 -#: machines/views.py:447 machines/views.py:501 machines/views.py:566 -#: machines/views.py:629 machines/views.py:691 machines/views.py:743 -#: machines/views.py:795 machines/views.py:847 machines/views.py:902 -#: machines/views.py:954 machines/views.py:1011 machines/views.py:1072 -#: machines/views.py:1124 machines/views.py:1190 machines/views.py:1242 +#: machines/views.py:242 machines/views.py:337 machines/views.py:378 +#: machines/views.py:436 machines/views.py:490 machines/views.py:555 +#: machines/views.py:618 machines/views.py:680 machines/views.py:732 +#: machines/views.py:784 machines/views.py:836 machines/views.py:891 +#: machines/views.py:943 machines/views.py:1000 machines/views.py:1061 +#: machines/views.py:1113 machines/views.py:1179 machines/views.py:1231 msgid "Add" msgstr "Ajouter" -#: machines/views.py:285 +#: machines/views.py:274 msgid "The machine was edited." msgstr "La machine a été modifiée." -#: machines/views.py:312 +#: machines/views.py:301 msgid "The machine was deleted." msgstr "La machine a été supprimée." -#: machines/views.py:338 +#: machines/views.py:327 msgid "The interface was created." msgstr "L'interface a été créée." -#: machines/views.py:364 +#: machines/views.py:353 msgid "The interface was deleted." msgstr "L'interface a été supprimée." -#: machines/views.py:384 +#: machines/views.py:373 msgid "The IPv6 addresses list was created." msgstr "La liste d'adresses IPv6 a été créée." -#: machines/views.py:405 +#: machines/views.py:394 msgid "The IPv6 addresses list was edited." msgstr "La liste d'adresses IPv6 a été modifiée." -#: machines/views.py:424 +#: machines/views.py:413 msgid "The IPv6 addresses list was deleted." msgstr "La liste d'adresses IPv6 a été supprimée." -#: machines/views.py:442 +#: machines/views.py:431 msgid "The SSHFP record was created." msgstr "L'enregistrement SSHFP a été créé." -#: machines/views.py:461 +#: machines/views.py:450 msgid "The SSHFP record was edited." msgstr "L'enregistrement SSHFP a été modifié." -#: machines/views.py:480 +#: machines/views.py:469 msgid "The SSHFP record was deleted." msgstr "L'enregistrement SSHFP a été supprimé." -#: machines/views.py:498 +#: machines/views.py:487 msgid "The IP type was created." msgstr "Le type d'IP a été créé." -#: machines/views.py:517 +#: machines/views.py:506 msgid "The IP type was edited." msgstr "Le type d'IP a été modifié." -#: machines/views.py:536 +#: machines/views.py:525 msgid "The IP type was deleted." msgstr "Le type d'IP a été supprimé." -#: machines/views.py:542 +#: machines/views.py:531 #, python-format msgid "" "The IP type %s is assigned to at least one machine, you can't delete it." @@ -1509,27 +1509,27 @@ msgstr "" "Le type d'IP %s est assigné à au moins une machine, vous ne pouvez pas le " "supprimer." -#: machines/views.py:550 machines/views.py:613 machines/views.py:675 -#: machines/views.py:729 machines/views.py:781 machines/views.py:833 -#: machines/views.py:886 machines/views.py:940 machines/views.py:992 -#: machines/views.py:1056 machines/views.py:1110 machines/views.py:1165 -#: machines/views.py:1228 machines/views.py:1280 +#: machines/views.py:539 machines/views.py:602 machines/views.py:664 +#: machines/views.py:718 machines/views.py:770 machines/views.py:822 +#: machines/views.py:875 machines/views.py:929 machines/views.py:981 +#: machines/views.py:1045 machines/views.py:1099 machines/views.py:1154 +#: machines/views.py:1217 machines/views.py:1269 msgid "Delete" msgstr "Supprimer" -#: machines/views.py:563 +#: machines/views.py:552 msgid "The machine type was created." msgstr "Le type de machine a été créé." -#: machines/views.py:580 +#: machines/views.py:569 msgid "The machine type was edited." msgstr "Le type de machine a été modifié." -#: machines/views.py:599 +#: machines/views.py:588 msgid "The machine type was deleted." msgstr "Le type de machine a été supprimé." -#: machines/views.py:605 +#: machines/views.py:594 #, python-format msgid "" "The machine type %s is assigned to at least one machine, you can't delete it." @@ -1537,19 +1537,19 @@ msgstr "" "Le type de machine %s est assigné à au moins un machine, vous ne pouvez pas " "le supprimer." -#: machines/views.py:626 +#: machines/views.py:615 msgid "The extension was created." msgstr "L'extension a été créée." -#: machines/views.py:643 +#: machines/views.py:632 msgid "The extension was edited." msgstr "L'extension a été modifiée." -#: machines/views.py:662 +#: machines/views.py:651 msgid "The extension was deleted." msgstr "L'extension a été supprimée." -#: machines/views.py:668 +#: machines/views.py:657 #, python-format msgid "" "The extension %s is assigned to at least one machine type, you can't delete " @@ -1558,207 +1558,207 @@ msgstr "" "L'extension %s est assignée à au moins un type de machine, vous ne pouvez " "pas le supprimer." -#: machines/views.py:688 +#: machines/views.py:677 msgid "The SOA record was created." msgstr "L'enregistrement SOA a été créé." -#: machines/views.py:705 +#: machines/views.py:694 msgid "The SOA record was edited." msgstr "L'enregistrement SOA a été modifié." -#: machines/views.py:722 +#: machines/views.py:711 msgid "The SOA record was deleted." msgstr "L'enregistrement SOA a été supprimé." -#: machines/views.py:725 +#: machines/views.py:714 #, python-format msgid "Error: the SOA record %s can't be deleted." msgstr "Erreur : l'enregistrement SOA %s ne peut pas être supprimé." -#: machines/views.py:740 +#: machines/views.py:729 msgid "The MX record was created." msgstr "L'enregistrement MX a été créé." -#: machines/views.py:757 +#: machines/views.py:746 msgid "The MX record was edited." msgstr "L'enregistrement MX a été modifié." -#: machines/views.py:774 +#: machines/views.py:763 msgid "The MX record was deleted." msgstr "L'enregistrement MX a été supprimé." -#: machines/views.py:777 +#: machines/views.py:766 #, python-format msgid "Error: the MX record %s can't be deleted." msgstr "Erreur : l'enregistrement MX %s ne peut pas être supprimé." -#: machines/views.py:792 +#: machines/views.py:781 msgid "The NS record was created." msgstr "L'enregistrement NS a été créé." -#: machines/views.py:809 +#: machines/views.py:798 msgid "The NS record was edited." msgstr "L'enregistrement NS a été modifié." -#: machines/views.py:826 +#: machines/views.py:815 msgid "The NS record was deleted." msgstr "L'enregistrement NS a été supprimé." -#: machines/views.py:829 +#: machines/views.py:818 #, python-format msgid "Error: the NS record %s can't be deleted." msgstr "Erreur : l'enregistrement NS %s ne peut pas être supprimé." -#: machines/views.py:844 +#: machines/views.py:833 msgid "The DNAME record was created." msgstr "L'enregistrement DNAME a été créé." -#: machines/views.py:861 +#: machines/views.py:850 msgid "The DNAME record was edited." msgstr "L'enregistrement DNAME a été modifié." -#: machines/views.py:878 +#: machines/views.py:867 msgid "The DNAME record was deleted." msgstr "L'enregistrement DNAME a été supprimé." -#: machines/views.py:882 +#: machines/views.py:871 #, python-format msgid "Error: the DNAME record %s can't be deleted." msgstr "Erreur : l'enregistrement DNAME %s ne peut pas être supprimé." -#: machines/views.py:899 +#: machines/views.py:888 msgid "The TXT record was created." msgstr "L'enregistrement TXT a été créé." -#: machines/views.py:916 +#: machines/views.py:905 msgid "The TXT record was edited." msgstr "L'enregistrement TXT a été modifié." -#: machines/views.py:933 +#: machines/views.py:922 msgid "The TXT record was deleted." msgstr "L'enregistrement TXT a été supprimé." -#: machines/views.py:936 +#: machines/views.py:925 #, python-format msgid "Error: the TXT record %s can't be deleted." msgstr "Erreur : l'enregistrement %s ne peut pas être supprimé." -#: machines/views.py:951 +#: machines/views.py:940 msgid "The SRV record was created." msgstr "L'enregistrement SRV a été créé." -#: machines/views.py:968 +#: machines/views.py:957 msgid "The SRV record was edited." msgstr "L'enregistrement SRV a été modifié." -#: machines/views.py:985 +#: machines/views.py:974 msgid "The SRV record was deleted." msgstr "L'enregistrement SRV a été supprimé." -#: machines/views.py:988 +#: machines/views.py:977 #, python-format msgid "Error: the SRV record %s can't be deleted." msgstr "Erreur : l'enregistrement SRV %s ne peut pas être supprimé." -#: machines/views.py:1006 +#: machines/views.py:995 msgid "The alias was created." msgstr "L'alias a été créé." -#: machines/views.py:1025 +#: machines/views.py:1014 msgid "The alias was edited." msgstr "L'alias a été modifié." -#: machines/views.py:1047 +#: machines/views.py:1036 #, python-format msgid "The alias %s was deleted." msgstr "L'alias %s a été supprimé." -#: machines/views.py:1050 +#: machines/views.py:1039 #, python-format msgid "Error: the alias %s can't be deleted." msgstr "Erreur : l'alias %s ne peut pas être supprimé." -#: machines/views.py:1069 +#: machines/views.py:1058 msgid "The role was created." msgstr "Le rôle a été créé." -#: machines/views.py:1086 +#: machines/views.py:1075 msgid "The role was edited." msgstr "Le rôle a été modifié." -#: machines/views.py:1103 +#: machines/views.py:1092 msgid "The role was deleted." msgstr "Le rôle a été supprimé." -#: machines/views.py:1106 +#: machines/views.py:1095 #, python-format msgid "Error: the role %s can't be deleted." msgstr "Erreur : le rôle %s ne peut pas être supprimé." -#: machines/views.py:1121 +#: machines/views.py:1110 msgid "The service was created." msgstr "Le service a été créé." -#: machines/views.py:1138 +#: machines/views.py:1127 msgid "The service was edited." msgstr "Le service a été modifié." -#: machines/views.py:1157 +#: machines/views.py:1146 msgid "The service was deleted." msgstr "Le service a été supprimé." -#: machines/views.py:1161 +#: machines/views.py:1150 #, python-format msgid "Error: the service %s can't be deleted." msgstr "Erreur : le service %s ne peut pas être supprimé." -#: machines/views.py:1187 +#: machines/views.py:1176 msgid "The VLAN was created." msgstr "Le VLAN a été créé." -#: machines/views.py:1204 +#: machines/views.py:1193 msgid "The VLAN was edited." msgstr "Le VLAN a été modifié." -#: machines/views.py:1221 +#: machines/views.py:1210 msgid "The VLAN was deleted." msgstr "Le VLAN a été supprimé." -#: machines/views.py:1224 +#: machines/views.py:1213 #, python-format msgid "Error: the VLAN %s can't be deleted." msgstr "Erreur : le VLAN %s ne peut pas être supprimé." -#: machines/views.py:1239 +#: machines/views.py:1228 msgid "The NAS device was created." msgstr "Le dispositif NAS a été créé." -#: machines/views.py:1256 +#: machines/views.py:1245 msgid "The NAS device was edited." msgstr "Le dispositif NAS a été modifié." -#: machines/views.py:1273 +#: machines/views.py:1262 msgid "The NAS device was deleted." msgstr "Le dispositif NAS a été supprimé." -#: machines/views.py:1276 +#: machines/views.py:1265 #, python-format msgid "Error: the NAS device %s can't be deleted." msgstr "Erreur : le dispositif NAS %s ne peut pas être supprimé." -#: machines/views.py:1502 +#: machines/views.py:1491 msgid "The ports list was edited." msgstr "La liste de ports a été modifiée." -#: machines/views.py:1516 +#: machines/views.py:1505 msgid "The ports list was deleted." msgstr "La liste de ports a été supprimée." -#: machines/views.py:1541 +#: machines/views.py:1530 msgid "The ports list was created." msgstr "La liste de ports a été créée." -#: machines/views.py:1561 +#: machines/views.py:1550 msgid "" "Warning: the IP address is not public, the opening won't have any effect in " "v4." @@ -1766,6 +1766,6 @@ msgstr "" "Attention : l'adresse IP n'est pas publique, l'ouverture n'aura pas d'effet " "en v4." -#: machines/views.py:1572 +#: machines/views.py:1561 msgid "The ports configuration was edited." msgstr "La configuration de ports a été modifiée." diff --git a/multi_op/locale/fr/LC_MESSAGES/django.po b/multi_op/locale/fr/LC_MESSAGES/django.po index 31245d63..e60cb464 100644 --- a/multi_op/locale/fr/LC_MESSAGES/django.po +++ b/multi_op/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2019-11-16 00:22+0100\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/preferences/locale/fr/LC_MESSAGES/django.po b/preferences/locale/fr/LC_MESSAGES/django.po index 84d7b67c..e90c1e2a 100644 --- a/preferences/locale/fr/LC_MESSAGES/django.po +++ b/preferences/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2018-06-24 15:54+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -1110,10 +1110,9 @@ msgstr "" "compte" #: preferences/templates/preferences/display_preferences.html:136 -#, fuzzy, python-format -#| msgid "%(delete_notyetactive)s days" +#, python-format msgid "%(disable_emailnotyetconfirmed)s days" -msgstr "%(delete_notyetactive)s jours" +msgstr "%(disable_emailnotyetconfirmed)s jours" #: preferences/templates/preferences/display_preferences.html:140 msgid "Users general permissions" diff --git a/re2o/locale/fr/LC_MESSAGES/django.po b/re2o/locale/fr/LC_MESSAGES/django.po index 1c408790..84b4bd34 100644 --- a/re2o/locale/fr/LC_MESSAGES/django.po +++ b/re2o/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -74,7 +74,7 @@ msgstr "Format : {main} {more}" msgid "Format: {main}" msgstr "Format : {main}" -#: re2o/mail_utils.py:42 +#: re2o/mail_utils.py:42 re2o/mail_utils.py:56 #, python-format msgid "Failed to send email: %(error)s." msgstr "Échec de l'envoi du mail : %(error)s." diff --git a/search/locale/fr/LC_MESSAGES/django.po b/search/locale/fr/LC_MESSAGES/django.po index bf54fb7d..2e18a0a2 100644 --- a/search/locale/fr/LC_MESSAGES/django.po +++ b/search/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2018-06-24 20:10+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/templates/locale/fr/LC_MESSAGES/django.po b/templates/locale/fr/LC_MESSAGES/django.po index 3935e92a..ad8e9968 100644 --- a/templates/locale/fr/LC_MESSAGES/django.po +++ b/templates/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -30,11 +30,11 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: templates/admin/base_site.html:65 templates/base.html:288 +#: templates/admin/base_site.html:65 templates/base.html:290 msgid "powered by" msgstr "propulsé par" -#: templates/admin/base_site.html:69 templates/base.html:296 +#: templates/admin/base_site.html:69 templates/base.html:298 msgid "" "This software is under the terms of the GPLv2 License." @@ -80,7 +80,7 @@ msgstr "" msgid "Unknown content" msgstr "" -#: templates/base.html:70 templates/registration/logged_out.html:11 +#: templates/base.html:72 templates/registration/logged_out.html:11 #: templates/registration/password_change_done.html:11 #: templates/registration/password_change_form.html:11 #: templates/registration/password_reset_complete.html:11 @@ -90,145 +90,145 @@ msgstr "" msgid "Home" msgstr "" -#: templates/base.html:91 +#: templates/base.html:93 msgid "Users" msgstr "Utilisateurs" -#: templates/base.html:94 +#: templates/base.html:96 msgid "Manage the users" msgstr "Gérer les utilisateurs" -#: templates/base.html:95 +#: templates/base.html:97 msgid "Manage the clubs" msgstr "Gérer les clubs" -#: templates/base.html:98 +#: templates/base.html:100 msgid "Manage the machines" msgstr "Gérer les machines" -#: templates/base.html:101 +#: templates/base.html:103 msgid "Manage the subscriptions" msgstr "Gérer les cotisations" -#: templates/base.html:114 +#: templates/base.html:116 msgid "Topology" msgstr "Topologie" -#: templates/base.html:116 +#: templates/base.html:118 msgid "Switches" msgstr "Commutateurs réseau" -#: templates/base.html:117 +#: templates/base.html:119 msgid "Access points" msgstr "Points d'accès sans fil" -#: templates/base.html:118 +#: templates/base.html:120 msgid "Rooms" msgstr "Chambres" -#: templates/base.html:128 +#: templates/base.html:130 msgid "Statistics" msgstr "Statistiques" -#: templates/base.html:133 +#: templates/base.html:135 msgid "Administration" msgstr "" -#: templates/base.html:140 +#: templates/base.html:142 msgid "Information and contact" msgstr "Informations et contact" -#: templates/base.html:142 +#: templates/base.html:144 msgid "About" msgstr "À propos" -#: templates/base.html:143 +#: templates/base.html:145 msgid "Contact" msgstr "Contact" -#: templates/base.html:157 +#: templates/base.html:159 msgid "Sign up" msgstr "S'inscrire" -#: templates/base.html:163 templates/registration/login.html:29 +#: templates/base.html:165 templates/registration/login.html:29 #: templates/registration/login.html:36 msgid "Log in" msgstr "" -#: templates/base.html:171 +#: templates/base.html:173 msgid "Search" msgstr "" -#: templates/base.html:185 +#: templates/base.html:187 msgid "My profile" msgstr "Mon profil" -#: templates/base.html:186 +#: templates/base.html:188 msgid "Log out" msgstr "" -#: templates/base.html:221 +#: templates/base.html:223 msgid "Username" msgstr "Pseudo" -#: templates/base.html:225 +#: templates/base.html:227 msgid "Room" msgstr "Chambre" -#: templates/base.html:229 +#: templates/base.html:231 msgid "Internet access" msgstr "Accès Internet" -#: templates/base.html:232 +#: templates/base.html:234 #, python-format msgid "Until %(end_access_date)s" msgstr "Jusqu'au %(end_access_date)s" -#: templates/base.html:234 +#: templates/base.html:236 msgid "Disabled" msgstr "Désactivé" -#: templates/base.html:239 +#: templates/base.html:241 msgid "Membership" msgstr "Adhésion" -#: templates/base.html:242 +#: templates/base.html:244 #, python-format msgid "Until %(end_adhesion_date)s" msgstr "Jusqu'au %(end_adhesion_date)s" -#: templates/base.html:244 +#: templates/base.html:246 msgid "Non member" msgstr "Non adhérent" -#: templates/base.html:252 +#: templates/base.html:254 msgid "View my profile" msgstr "Voir mon profil" -#: templates/base.html:257 +#: templates/base.html:259 msgid "You are not logged in." msgstr "Vous n'êtes pas connecté." -#: templates/base.html:264 +#: templates/base.html:266 #, python-format msgid "%(nb)s active machine" msgid_plural "%(nb)s active machines" msgstr[0] "%(nb)s machine active" msgstr[1] "%(nb)s machines actives" -#: templates/base.html:273 +#: templates/base.html:275 msgid "View my machines" msgstr "Voir mes machines" -#: templates/base.html:286 +#: templates/base.html:288 msgid "Back to top" msgstr "Retour en haut" -#: templates/base.html:290 +#: templates/base.html:292 msgid "Brought to you with ." msgstr "Codé avec ." -#: templates/base.html:293 +#: templates/base.html:295 msgid "About this website" msgstr "À propos de ce site" diff --git a/tickets/locale/fr/LC_MESSAGES/django.po b/tickets/locale/fr/LC_MESSAGES/django.po index 166576ba..df651ec7 100644 --- a/tickets/locale/fr/LC_MESSAGES/django.po +++ b/tickets/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2019-11-16 00:35+0100\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/topologie/locale/fr/LC_MESSAGES/django.po b/topologie/locale/fr/LC_MESSAGES/django.po index 37a56a9d..b5f45bff 100644 --- a/topologie/locale/fr/LC_MESSAGES/django.po +++ b/topologie/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2018-06-25 14:53+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" diff --git a/users/locale/fr/LC_MESSAGES/django.po b/users/locale/fr/LC_MESSAGES/django.po index 35774bd3..edae2c02 100644 --- a/users/locale/fr/LC_MESSAGES/django.po +++ b/users/locale/fr/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: 2.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-04-19 20:16+0200\n" +"POT-Creation-Date: 2020-04-21 21:38+0200\n" "PO-Revision-Date: 2018-06-27 23:35+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -35,15 +35,15 @@ msgstr "" msgid "You don't have the right to view this application." msgstr "Vous n'avez pas le droit de voir cette application." -#: users/forms.py:80 +#: users/forms.py:81 msgid "Current password" msgstr "Mot de passe actuel" -#: users/forms.py:83 users/forms.py:628 users/forms.py:656 +#: users/forms.py:84 users/forms.py:598 users/forms.py:626 msgid "New password" msgstr "Nouveau mot de passe" -#: users/forms.py:89 +#: users/forms.py:90 msgid "New password confirmation" msgstr "Confirmation du nouveau mot de passe" @@ -51,38 +51,33 @@ msgstr "Confirmation du nouveau mot de passe" msgid "The new passwords don't match." msgstr "Les nouveaux mots de passe ne correspondent pas." -#: users/forms.py:111 +#: users/forms.py:112 msgid "The current password is incorrect." msgstr "Le mot de passe actuel est incorrect." -#: users/forms.py:132 users/forms.py:189 users/forms.py:425 -#: users/models.py:1908 +#: users/forms.py:133 users/forms.py:181 users/forms.py:405 +#: users/models.py:1912 msgid "Password" msgstr "Mot de passe" -#: users/forms.py:138 users/forms.py:192 users/forms.py:432 +#: users/forms.py:139 users/forms.py:184 users/forms.py:412 msgid "Password confirmation" msgstr "Confirmation du mot de passe" -#: users/forms.py:143 users/forms.py:232 +#: users/forms.py:143 users/forms.py:224 msgid "Is admin" msgstr "Est admin" -#: users/forms.py:156 -msgid "You can't use an internal address as your external address." -msgstr "" -"Vous ne pouvez pas utiliser une adresse interne pour votre adresse externe." - -#: users/forms.py:169 users/forms.py:212 users/forms.py:506 +#: users/forms.py:160 users/forms.py:204 users/forms.py:474 msgid "The passwords don't match." msgstr "Les mots de passe ne correspondent pas." -#: users/forms.py:241 +#: users/forms.py:233 #, python-format msgid "User is admin: %s" msgstr "L'utilisateur est admin : %s" -#: users/forms.py:287 users/templates/users/aff_clubs.html:38 +#: users/forms.py:279 users/templates/users/aff_clubs.html:38 #: users/templates/users/aff_listright.html:63 #: users/templates/users/aff_listright.html:168 #: users/templates/users/aff_users.html:39 @@ -91,75 +86,71 @@ msgstr "L'utilisateur est admin : %s" msgid "Username" msgstr "Pseudo" -#: users/forms.py:299 +#: users/forms.py:291 msgid "Fully archive users? WARNING: CRITICAL OPERATION IF TRUE" msgstr "" "Complètement archiver les utilisateurs ? ATTENTION: OPÉRATION CRITIQUE SI OUI" -#: users/forms.py:312 +#: users/forms.py:304 msgid "Impossible to archive users whose end access date is in the future." msgstr "" "Impossible d'archiver des utilisateurs dont la date de fin de connexion est " "dans le futur." -#: users/forms.py:327 users/templates/users/aff_users.html:35 +#: users/forms.py:319 users/templates/users/aff_users.html:35 #: users/templates/users/profil.html:193 users/templates/users/profil.html:367 #: users/templates/users/profil.html:386 msgid "First name" msgstr "Prénom" -#: users/forms.py:328 users/templates/users/aff_users.html:37 +#: users/forms.py:320 users/templates/users/aff_users.html:37 #: users/templates/users/profil.html:199 users/templates/users/profil.html:366 #: users/templates/users/profil.html:385 msgid "Surname" msgstr "Nom" -#: users/forms.py:329 users/forms.py:566 users/models.py:1908 +#: users/forms.py:321 users/forms.py:536 users/models.py:1912 #: users/templates/users/aff_emailaddress.html:36 #: users/templates/users/profil.html:209 msgid "Email address" msgstr "Adresse mail" -#: users/forms.py:330 users/forms.py:564 users/forms.py:709 +#: users/forms.py:322 users/forms.py:534 users/forms.py:679 #: users/templates/users/aff_schools.html:37 #: users/templates/users/profil.html:230 msgid "School" msgstr "Établissement" -#: users/forms.py:331 users/forms.py:565 +#: users/forms.py:323 users/forms.py:535 #: users/templates/users/aff_serviceusers.html:34 #: users/templates/users/profil.html:235 msgid "Comment" msgstr "Commentaire" -#: users/forms.py:333 users/forms.py:568 +#: users/forms.py:325 users/forms.py:538 #: users/templates/users/aff_clubs.html:40 #: users/templates/users/aff_users.html:41 #: users/templates/users/profil.html:214 msgid "Room" msgstr "Chambre" -#: users/forms.py:334 users/forms.py:569 +#: users/forms.py:326 users/forms.py:539 msgid "No room" msgstr "Pas de chambre" -#: users/forms.py:335 users/forms.py:570 +#: users/forms.py:327 users/forms.py:540 msgid "Select a school" msgstr "Sélectionnez un établissement" -#: users/forms.py:351 +#: users/forms.py:343 msgid "Force the move?" msgstr "Forcer le déménagement ?" -#: users/forms.py:361 users/forms.py:860 -msgid "You can't use a {} address." -msgstr "Vous ne pouvez pas utiliser une adresse {}." - -#: users/forms.py:371 users/forms.py:593 +#: users/forms.py:351 users/forms.py:563 msgid "A valid telephone number is required." msgstr "Un numéro de téléphone valide est requis." -#: users/forms.py:405 +#: users/forms.py:385 msgid "" "If this options is set, you will receive a link to set your initial password " "by email. If you do not have any means of accessing your emails, you can " @@ -174,11 +165,11 @@ msgstr "" "votre adresse dans les délais impartis, votre connexion sera automatiquement " "suspendue." -#: users/forms.py:419 +#: users/forms.py:399 msgid "Send password reset link by email." msgstr "Envoyer le lien de modification du mot de passe par mail." -#: users/forms.py:440 +#: users/forms.py:419 msgid "" "If you already have an account, please use it. If your lost access to it, " "please consider using the forgotten password button on the login page or " @@ -189,101 +180,97 @@ msgstr "" "passe oublié est à votre disposition. Si vous avez oublié votre login, " "contactez le support." -#: users/forms.py:447 +#: users/forms.py:426 msgid "I certify that I have not had an account before." msgstr "Je certifie sur l'honneur ne pas déjà avoir de compte." -#: users/forms.py:472 +#: users/forms.py:452 msgid "I commit to accept the" msgstr "J'accepte les" -#: users/forms.py:474 +#: users/forms.py:454 msgid "General Terms of Use" msgstr "Conditions Générales d'Utilisation" -#: users/forms.py:492 -msgid "Password must contain at least 8 characters." -msgstr "Le mot de passe doit contenir au moins 8 caractères." - -#: users/forms.py:533 +#: users/forms.py:501 msgid "Leave empty if you don't have any GPG key." msgstr "Laissez vide si vous n'avez pas de clé GPG." -#: users/forms.py:536 +#: users/forms.py:506 msgid "Default shell" msgstr "Interface en ligne de commande par défaut" -#: users/forms.py:563 users/templates/users/aff_clubs.html:36 +#: users/forms.py:533 users/templates/users/aff_clubs.html:36 #: users/templates/users/aff_serviceusers.html:32 msgid "Name" msgstr "Nom" -#: users/forms.py:571 +#: users/forms.py:541 msgid "Use a mailing list" msgstr "Utiliser une liste de diffusion" -#: users/forms.py:677 users/templates/users/profil.html:277 +#: users/forms.py:647 users/templates/users/profil.html:277 msgid "State" msgstr "État" -#: users/forms.py:678 +#: users/forms.py:648 msgid "Email state" msgstr "État du mail" -#: users/forms.py:696 users/templates/users/aff_listright.html:38 +#: users/forms.py:666 users/templates/users/aff_listright.html:38 msgid "Superuser" msgstr "Superutilisateur" -#: users/forms.py:722 +#: users/forms.py:692 msgid "Shell name" msgstr "Nom de l'interface en ligne de commande" -#: users/forms.py:742 +#: users/forms.py:712 msgid "Name of the group of rights" msgstr "Nom du groupe de droits" -#: users/forms.py:754 +#: users/forms.py:724 msgid "GID. Warning: this field must not be edited after creation." msgstr "GID. Attention : ce champ ne doit pas être modifié après création." -#: users/forms.py:763 +#: users/forms.py:733 msgid "Current groups of rights" msgstr "Groupes de droits actuels" -#: users/forms.py:781 +#: users/forms.py:751 msgid "Current schools" msgstr "Établissements actuels" -#: users/forms.py:800 users/forms.py:815 users/templates/users/aff_bans.html:41 +#: users/forms.py:770 users/forms.py:785 users/templates/users/aff_bans.html:41 #: users/templates/users/aff_whitelists.html:41 msgid "End date" msgstr "Date de fin" -#: users/forms.py:830 +#: users/forms.py:800 msgid "Local part of the email address" msgstr "Partie locale de l'adresse mail" -#: users/forms.py:831 +#: users/forms.py:801 msgid "Can't contain @." msgstr "Ne peut pas contenir @." -#: users/forms.py:847 +#: users/forms.py:818 msgid "Main email address" msgstr "Adresse mail principale" -#: users/forms.py:849 +#: users/forms.py:821 msgid "Redirect local emails" msgstr "Rediriger les mails locaux" -#: users/forms.py:851 +#: users/forms.py:823 msgid "Use local emails" msgstr "Utiliser les mails locaux" -#: users/forms.py:903 +#: users/forms.py:863 msgid "This room is my room" msgstr "Il s'agit bien de ma chambre" -#: users/forms.py:908 +#: users/forms.py:868 msgid "This new connected device is mine" msgstr "Ce nouvel appareil connecté m'appartient" @@ -336,7 +323,7 @@ msgstr "Non confirmé" msgid "Waiting for email confirmation" msgstr "En attente de confirmation" -#: users/models.py:204 users/models.py:1561 +#: users/models.py:204 users/models.py:1565 msgid "Must only contain letters, numerals or dashes." msgstr "Doit seulement contenir des lettres, chiffres ou tirets." @@ -487,7 +474,7 @@ msgstr "Vous n'avez pas le droit de voir ce club." msgid "You don't have the right to view another user." msgstr "Vous n'avez pas le droit de voir un autre utilisateur." -#: users/models.py:1292 users/models.py:1497 +#: users/models.py:1292 users/models.py:1501 msgid "You don't have the right to view the list of users." msgstr "Vous n'avez pas le droit de voir la liste des utilisateurs." @@ -495,215 +482,208 @@ msgstr "Vous n'avez pas le droit de voir la liste des utilisateurs." msgid "You don't have the right to delete this user." msgstr "Vous n'avez pas le droit de supprimer cet utilisateur." -#: users/models.py:1332 +#: users/models.py:1330 msgid "This username is already used." msgstr "Ce pseudo est déjà utilisé." -#: users/models.py:1340 -msgid "" -"There is neither a local email address nor an external email address for " -"this user." -msgstr "" -"Il n'y a pas d'adresse mail locale ni d'adresse mail externe pour cet " -"utilisateur." +#: users/models.py:1337 +msgid "Email field cannot be empty." +msgstr "Le champ mail ne peut pas ^êêtre vide" -#: users/models.py:1347 -msgid "" -"You can't redirect your local emails if no external email address has been " -"set." +#: users/models.py:1344 +msgid "You can't use a {} address as an external contact address." msgstr "" -"Vous ne pouvez pas rediriger vos mails locaux si aucune adresse mail externe " -"n'a été définie." +"Vous ne pouvez pas utiliser une adresse {} pour votre adresse externe." -#: users/models.py:1367 +#: users/models.py:1371 msgid "member" msgstr "adhérent" -#: users/models.py:1368 +#: users/models.py:1372 msgid "members" msgstr "adhérents" -#: users/models.py:1385 +#: users/models.py:1389 msgid "A GPG fingerprint must contain 40 hexadecimal characters." msgstr "Une empreinte GPG doit contenir 40 caractères hexadécimaux." -#: users/models.py:1410 +#: users/models.py:1414 msgid "Self registration is disabled." msgstr "L'auto inscription est désactivée." -#: users/models.py:1420 +#: users/models.py:1424 msgid "You don't have the right to create a user." msgstr "Vous n'avez pas le droit de créer un utilisateur." -#: users/models.py:1450 +#: users/models.py:1454 msgid "club" msgstr "club" -#: users/models.py:1451 +#: users/models.py:1455 msgid "clubs" msgstr "clubs" -#: users/models.py:1462 +#: users/models.py:1466 msgid "You must be authenticated." msgstr "Vous devez être authentifié." -#: users/models.py:1470 +#: users/models.py:1474 msgid "You don't have the right to create a club." msgstr "Vous n'avez pas le droit de créer un club." -#: users/models.py:1565 +#: users/models.py:1569 msgid "Comment." msgstr "Commentaire." -#: users/models.py:1571 +#: users/models.py:1575 msgid "Can view a service user object" msgstr "Peut voir un objet utilisateur service" -#: users/models.py:1572 users/views.py:360 +#: users/models.py:1576 users/views.py:349 msgid "service user" msgstr "utilisateur service" -#: users/models.py:1573 +#: users/models.py:1577 msgid "service users" msgstr "utilisateurs service" -#: users/models.py:1577 +#: users/models.py:1581 #, python-brace-format msgid "Service user <{name}>" msgstr "Utilisateur service <{name}>" -#: users/models.py:1644 +#: users/models.py:1648 msgid "Can view a school object" msgstr "Peut voir un objet établissement" -#: users/models.py:1645 +#: users/models.py:1649 msgid "school" msgstr "établissement" -#: users/models.py:1646 +#: users/models.py:1650 msgid "schools" msgstr "établissements" -#: users/models.py:1665 +#: users/models.py:1669 msgid "UNIX group names can only contain lower case letters." msgstr "" "Les noms de groupe UNIX peuvent seulement contenir des lettres minuscules." -#: users/models.py:1671 +#: users/models.py:1675 msgid "Description." msgstr "Description." -#: users/models.py:1674 +#: users/models.py:1678 msgid "Can view a group of rights object" msgstr "Peut voir un objet groupe de droits" -#: users/models.py:1675 +#: users/models.py:1679 msgid "group of rights" msgstr "groupe de droits" -#: users/models.py:1676 +#: users/models.py:1680 msgid "groups of rights" msgstr "groupes de droits" -#: users/models.py:1721 +#: users/models.py:1725 msgid "Can view a shell object" msgstr "Peut voir un objet interface en ligne de commande" -#: users/models.py:1722 users/views.py:679 +#: users/models.py:1726 users/views.py:649 msgid "shell" msgstr "interface en ligne de commande" -#: users/models.py:1723 +#: users/models.py:1727 msgid "shells" msgstr "interfaces en ligne de commande" -#: users/models.py:1741 +#: users/models.py:1745 msgid "HARD (no access)" msgstr "HARD (pas d'accès)" -#: users/models.py:1742 +#: users/models.py:1746 msgid "SOFT (local access only)" msgstr "SOFT (accès local uniquement)" -#: users/models.py:1743 +#: users/models.py:1747 msgid "RESTRICTED (speed limitation)" msgstr "RESTRICTED (limitation de vitesse)" -#: users/models.py:1754 +#: users/models.py:1758 msgid "Can view a ban object" msgstr "Peut voir un objet bannissement" -#: users/models.py:1755 users/views.py:415 +#: users/models.py:1759 users/views.py:400 msgid "ban" msgstr "bannissement" -#: users/models.py:1756 +#: users/models.py:1760 msgid "bans" msgstr "bannissements" -#: users/models.py:1793 +#: users/models.py:1797 msgid "You don't have the right to view other bans than yours." msgstr "" "Vous n'avez pas le droit de voir d'autres bannissements que les vôtres." -#: users/models.py:1841 +#: users/models.py:1845 msgid "Can view a whitelist object" msgstr "Peut voir un objet accès gracieux" -#: users/models.py:1842 +#: users/models.py:1846 msgid "whitelist (free of charge access)" msgstr "Accès gracieux" -#: users/models.py:1843 +#: users/models.py:1847 msgid "whitelists (free of charge access)" msgstr "Accès gracieux" -#: users/models.py:1863 +#: users/models.py:1867 msgid "You don't have the right to view other whitelists than yours." msgstr "" "Vous n'avez pas le droit de voir d'autres accès gracieux que les vôtres." -#: users/models.py:2061 +#: users/models.py:2065 msgid "User of the local email account." msgstr "Utilisateur du compte mail local." -#: users/models.py:2064 +#: users/models.py:2068 msgid "Local part of the email address." msgstr "Partie locale de l'adresse mail." -#: users/models.py:2069 +#: users/models.py:2073 msgid "Can view a local email account object" msgstr "Peut voir un objet compte mail local" -#: users/models.py:2071 +#: users/models.py:2075 msgid "local email account" msgstr "compte mail local" -#: users/models.py:2072 +#: users/models.py:2076 msgid "local email accounts" msgstr "comptes mail locaux" -#: users/models.py:2100 users/models.py:2135 users/models.py:2169 -#: users/models.py:2203 +#: users/models.py:2104 users/models.py:2139 users/models.py:2173 +#: users/models.py:2207 msgid "The local email accounts are not enabled." msgstr "Les comptes mail locaux ne sont pas activés." -#: users/models.py:2105 +#: users/models.py:2109 msgid "You don't have the right to add a local email account to another user." msgstr "" "Vous n'avez pas le droit d'ajouter un compte mail local à un autre " "utilisateur." -#: users/models.py:2115 +#: users/models.py:2119 msgid "You reached the limit of {} local email accounts." msgstr "Vous avez atteint la limite de {} comptes mail locaux." -#: users/models.py:2141 +#: users/models.py:2145 msgid "You don't have the right to view another user's local email account." msgstr "" "Vous n'avez pas le droit de voir le compte mail local d'un autre utilisateur." -#: users/models.py:2161 +#: users/models.py:2165 msgid "" "You can't delete a local email account whose local part is the same as the " "username." @@ -711,13 +691,13 @@ msgstr "" "Vous ne pouvez pas supprimer un compte mail local dont la partie locale est " "la même que le pseudo." -#: users/models.py:2175 +#: users/models.py:2179 msgid "You don't have the right to delete another user's local email account." msgstr "" "Vous n'avez pas le droit de supprimer le compte mail local d'un autre " "utilisateur." -#: users/models.py:2195 +#: users/models.py:2199 msgid "" "You can't edit a local email account whose local part is the same as the " "username." @@ -725,13 +705,13 @@ msgstr "" "Vous ne pouvez pas modifier un compte mail local dont la partie locale est " "la même que le pseudo." -#: users/models.py:2209 +#: users/models.py:2213 msgid "You don't have the right to edit another user's local email account." msgstr "" "Vous n'avez pas le droit de modifier le compte mail local d'un autre " "utilisateur." -#: users/models.py:2218 +#: users/models.py:2222 msgid "The local part must not contain @ or +." msgstr "La partie locale ne doit pas contenir @ ou +." @@ -840,6 +820,7 @@ msgstr[0] "Total: %(perm_count)s permission" msgstr[1] "Total: %(perm_count)s permissions" #: users/templates/users/aff_listright.html:150 +#: users/templates/users/edit_listright.html:29 #: users/templates/users/index.html:29 users/templates/users/index.html:32 #: users/templates/users/index_ban.html:29 #: users/templates/users/index_clubs.html:29 @@ -888,8 +869,8 @@ msgstr "pour %(name)s." #: users/templates/users/confirm_email.html:39 #: users/templates/users/delete.html:36 #: users/templates/users/mass_archive.html:36 -#: users/templates/users/resend_confirmation_email.html:35 users/views.py:636 -#: users/views.py:740 +#: users/templates/users/resend_confirmation_email.html:35 users/views.py:607 +#: users/views.py:716 msgid "Confirm" msgstr "Confirmer" @@ -1086,14 +1067,14 @@ msgstr "Pas de machine" msgid "Detailed information" msgstr "Informations détaillées" -#: users/templates/users/profil.html:161 users/views.py:206 users/views.py:237 -#: users/views.py:256 users/views.py:273 users/views.py:345 users/views.py:403 -#: users/views.py:457 users/views.py:522 users/views.py:569 users/views.py:605 -#: users/views.py:665 users/views.py:711 +#: users/templates/users/profil.html:161 users/views.py:204 users/views.py:234 +#: users/views.py:253 users/views.py:268 users/views.py:336 users/views.py:389 +#: users/views.py:440 users/views.py:496 users/views.py:544 users/views.py:578 +#: users/views.py:636 users/views.py:684 msgid "Edit" msgstr "Modifier" -#: users/templates/users/profil.html:165 users/views.py:292 users/views.py:1043 +#: users/templates/users/profil.html:165 users/views.py:285 users/views.py:1019 msgid "Change the password" msgstr "Changer le mot de passe" @@ -1333,160 +1314,160 @@ msgstr "Connecté avec l'appareil :" msgid "MAC address %(mac)s" msgstr "Adresse MAC %(mac)s" -#: users/views.py:135 +#: users/views.py:136 #, python-format msgid "The user %s was created, a confirmation email was sent." msgstr "L'utilisateur %s a été créé, un mail de confirmation a été envoyé." -#: users/views.py:142 +#: users/views.py:143 #, python-format msgid "The user %s was created, an email to set the password was sent." msgstr "" "L'utilisateur %s a été créé, un mail pour initialiser le mot de passe a été " "envoyé." -#: users/views.py:155 +#: users/views.py:156 msgid "Commit" msgstr "Valider" -#: users/views.py:178 +#: users/views.py:179 #, python-format msgid "The club %s was created, an email to set the password was sent." msgstr "" "Le club %s a été créé, un mail pour initialiser le mot de passe a été envoyé." -#: users/views.py:183 +#: users/views.py:184 msgid "Create a club" msgstr "Créer un club" -#: users/views.py:198 +#: users/views.py:199 msgid "The club was edited." msgstr "Le club a été modifié." -#: users/views.py:230 +#: users/views.py:227 msgid "The user was edited." msgstr "L'utilisateur a été modifié." -#: users/views.py:233 +#: users/views.py:230 msgid "Sent a new confirmation email." msgstr "Un nouveau mail de confirmation a été envoyé." -#: users/views.py:251 +#: users/views.py:246 msgid "The states were edited." msgstr "Les états ont été modifié." -#: users/views.py:253 +#: users/views.py:249 msgid "An email to confirm the address was sent." msgstr "Un mail pour confirmer l'adresse a été envoyé." -#: users/views.py:270 +#: users/views.py:265 msgid "The groups were edited." msgstr "Les groupes ont été modifiés." -#: users/views.py:289 users/views.py:1040 +#: users/views.py:282 users/views.py:1016 msgid "The password was changed." msgstr "Le mot de passe a été changé." -#: users/views.py:304 +#: users/views.py:297 #, python-format msgid "%s was removed from the group." msgstr "%s a été retiré du groupe." -#: users/views.py:314 +#: users/views.py:307 #, python-format msgid "%s is no longer superuser." msgstr "%s n'est plus superutilisateur." -#: users/views.py:325 +#: users/views.py:318 msgid "The service user was created." msgstr "L'utilisateur service a été créé." -#: users/views.py:328 users/views.py:384 users/views.py:437 users/views.py:495 -#: users/views.py:587 users/views.py:650 users/views.py:693 +#: users/views.py:321 users/views.py:372 users/views.py:422 users/views.py:473 +#: users/views.py:562 users/views.py:621 users/views.py:664 msgid "Add" msgstr "Ajouter" -#: users/views.py:342 +#: users/views.py:333 msgid "The service user was edited." msgstr "L'utilisateur service a été modifié." -#: users/views.py:357 +#: users/views.py:346 msgid "The service user was deleted." msgstr "L'utilisateur service a été supprimé." -#: users/views.py:379 +#: users/views.py:368 msgid "The ban was added." msgstr "Le bannissement a été ajouté." -#: users/views.py:382 +#: users/views.py:371 msgid "Warning: this user already has an active ban." msgstr "Attention : cet utilisateur a déjà un bannissement actif." -#: users/views.py:400 +#: users/views.py:387 msgid "The ban was edited." msgstr "Le bannissement a été modifié." -#: users/views.py:413 +#: users/views.py:398 msgid "The ban was deleted." msgstr "Le bannissement a été supprimé." -#: users/views.py:430 +#: users/views.py:415 msgid "The whitelist was added." msgstr "L'accès gracieux a été ajouté." -#: users/views.py:434 +#: users/views.py:419 msgid "Warning: this user already has an active whitelist." msgstr "Attention : cet utilisateur a déjà un accès gracieux actif." -#: users/views.py:454 +#: users/views.py:437 msgid "The whitelist was edited." msgstr "L'accès gracieux a été ajouté." -#: users/views.py:469 +#: users/views.py:450 msgid "The whitelist was deleted." msgstr "L'accès gracieux a été supprimé." -#: users/views.py:474 +#: users/views.py:455 msgid "whitelist" msgstr "accès gracieux" -#: users/views.py:489 +#: users/views.py:470 msgid "The local email account was created." msgstr "Le compte mail local a été créé." -#: users/views.py:512 +#: users/views.py:489 msgid "The local email account was edited." msgstr "Le compte mail local a été modifié." -#: users/views.py:535 +#: users/views.py:508 msgid "The local email account was deleted." msgstr "Le compte mail local a été supprimé." -#: users/views.py:540 +#: users/views.py:513 msgid "email address" msgstr "adresse mail" -#: users/views.py:556 +#: users/views.py:529 msgid "The email settings were edited." msgstr "Les paramètres mail ont été modifiés." -#: users/views.py:559 users/views.py:1085 +#: users/views.py:533 users/views.py:1061 msgid "An email to confirm your address was sent." msgstr "Un mail pour confirmer votre adresse a été envoyé." -#: users/views.py:584 +#: users/views.py:559 msgid "The school was added." msgstr "L'établissement a été ajouté." -#: users/views.py:602 +#: users/views.py:575 msgid "The school was edited." msgstr "L'établissement a été modifié." -#: users/views.py:624 +#: users/views.py:595 msgid "The school was deleted." msgstr "L'établissement a été supprimé." -#: users/views.py:629 +#: users/views.py:600 #, python-format msgid "" "The school %s is assigned to at least one user, impossible to delete it." @@ -1494,31 +1475,31 @@ msgstr "" "L'établissement %s est assigné à au moins un utilisateur, impossible de le " "supprimer." -#: users/views.py:647 +#: users/views.py:618 msgid "The shell was added." msgstr "L'interface en ligne de commande a été ajoutée." -#: users/views.py:662 +#: users/views.py:633 msgid "The shell was edited." msgstr "L'interface en ligne de commande a été modifiée." -#: users/views.py:677 +#: users/views.py:646 msgid "The shell was deleted." msgstr "L'interface en ligne de commande a été supprimée." -#: users/views.py:690 +#: users/views.py:661 msgid "The group of rights was added." msgstr "Le groupe de droits a été ajouté." -#: users/views.py:708 +#: users/views.py:679 msgid "The group of rights was edited." msgstr "Le groupe de droits a été modifié." -#: users/views.py:728 +#: users/views.py:704 msgid "The group of rights was deleted." msgstr "Le groupe de droits a été supprimé." -#: users/views.py:733 +#: users/views.py:709 #, python-format msgid "" "The group of rights %s is assigned to at least one user, impossible to " @@ -1527,37 +1508,37 @@ msgstr "" "Le groupe de droits %s est assigné à au moins un utilisateur, impossible de " "le supprimer." -#: users/views.py:769 +#: users/views.py:745 #, python-format msgid "%s users were archived." msgstr "%s utilisateurs ont été archivés." -#: users/views.py:998 users/views.py:1081 +#: users/views.py:974 users/views.py:1057 msgid "The user doesn't exist." msgstr "L'utilisateur n'existe pas." -#: users/views.py:1000 users/views.py:1008 +#: users/views.py:976 users/views.py:984 msgid "Reset" msgstr "Réinitialiser" -#: users/views.py:1005 +#: users/views.py:981 msgid "An email to reset the password was sent." msgstr "Un mail pour réinitialiser le mot de passe a été envoyé." -#: users/views.py:1023 +#: users/views.py:999 msgid "Error: please contact an admin." msgstr "Erreur : veuillez contacter un admin." -#: users/views.py:1061 +#: users/views.py:1037 #, python-format msgid "The %s address was confirmed." msgstr "L'adresse mail %s a été confirmée." -#: users/views.py:1108 +#: users/views.py:1080 msgid "Incorrect URL, or already registered device." msgstr "URL incorrect, ou appareil déjà enregistré." -#: users/views.py:1120 +#: users/views.py:1092 msgid "" "Successful registration! Please disconnect and reconnect your Ethernet cable " "to get Internet access." @@ -1565,10 +1546,6 @@ msgstr "" "Enregistrement réussi ! Veuillez débrancher et rebrancher votre câble " "Ethernet pour avoir accès à Internet." -#: users/views.py:1160 users/views.py:1184 users/views.py:1199 -msgid "The mailing list doesn't exist." -msgstr "La liste de diffusion n'existe pas." - #: users/widgets.py:39 msgid "Today" msgstr "Aujourd'hui" @@ -1584,3 +1561,26 @@ msgstr "Précédent" #: users/widgets.py:61 msgid "Wk" msgstr "Sem" + +#~ msgid "You can't use a {} address." +#~ msgstr "Vous ne pouvez pas utiliser une adresse {}." + +#~ msgid "Password must contain at least 8 characters." +#~ msgstr "Le mot de passe doit contenir au moins 8 caractères." + +#~ msgid "" +#~ "There is neither a local email address nor an external email address for " +#~ "this user." +#~ msgstr "" +#~ "Il n'y a pas d'adresse mail locale ni d'adresse mail externe pour cet " +#~ "utilisateur." + +#~ msgid "" +#~ "You can't redirect your local emails if no external email address has " +#~ "been set." +#~ msgstr "" +#~ "Vous ne pouvez pas rediriger vos mails locaux si aucune adresse mail " +#~ "externe n'a été définie." + +#~ msgid "The mailing list doesn't exist." +#~ msgstr "La liste de diffusion n'existe pas."