From e0fc3d384676bc30c16a0fac75b09e880b6d886a Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Fri, 28 Dec 2018 20:32:39 +0100 Subject: [PATCH 01/73] Menage ordre des fonctions du forms de users --- users/forms.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/users/forms.py b/users/forms.py index b5b8b602..ca01c52d 100644 --- a/users/forms.py +++ b/users/forms.py @@ -324,14 +324,6 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): self.fields['room'].empty_label = _("No room") self.fields['school'].empty_label = _("Select a school") - 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)) - class Meta: model = Adherent fields = [ @@ -345,6 +337,19 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): 'room', ] + force = forms.BooleanField( + 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 @@ -356,12 +361,6 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): ) return telephone - force = forms.BooleanField( - label=_("Force the move?"), - initial=False, - required=False - ) - def clean_force(self): """On supprime l'ancien user de la chambre si et seulement si la case est cochée""" From bfd79d44eb20276c4efa9d05e524e4d55279f939 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Fri, 28 Dec 2018 20:58:43 +0100 Subject: [PATCH 02/73] Fix #192 : Gpgfp validation et formatage --- users/forms.py | 7 +----- users/migrations/0079_auto_20181228_2039.py | 20 ++++++++++++++++ users/models.py | 26 ++++++++++++++++----- 3 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 users/migrations/0079_auto_20181228_2039.py diff --git a/users/forms.py b/users/forms.py index ca01c52d..81c31cae 100644 --- a/users/forms.py +++ b/users/forms.py @@ -368,6 +368,7 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): remove_user_room(self.cleaned_data.get('room')) return + class AdherentCreationForm(AdherentForm): """Formulaire de création d'un user. AdherentForm auquel on ajoute une checkbox afin d'éviter les @@ -398,12 +399,6 @@ class AdherentEditForm(AdherentForm): if 'shell' in self.fields: self.fields['shell'].empty_label = _("Default shell") - def clean_gpg_fingerprint(self): - """Format the GPG fingerprint""" - gpg_fingerprint = self.cleaned_data.get('gpg_fingerprint', None) - if gpg_fingerprint: - return gpg_fingerprint.replace(' ', '').upper() - class Meta: model = Adherent fields = [ diff --git a/users/migrations/0079_auto_20181228_2039.py b/users/migrations/0079_auto_20181228_2039.py new file mode 100644 index 00000000..79ab56d9 --- /dev/null +++ b/users/migrations/0079_auto_20181228_2039.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-12-28 19:39 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0078_auto_20181011_1405'), + ] + + operations = [ + migrations.AlterField( + model_name='adherent', + name='gpg_fingerprint', + field=models.CharField(blank=True, max_length=49, null=True), + ), + ] diff --git a/users/models.py b/users/models.py index 9f17615d..b8f79942 100755 --- a/users/models.py +++ b/users/models.py @@ -1053,20 +1053,27 @@ class Adherent(User): null=True ) gpg_fingerprint = models.CharField( - max_length=40, + max_length=49, blank=True, null=True, - validators=[RegexValidator( - '^[0-9A-F]{40}$', - message=_("A GPG fingerprint must contain 40 hexadecimal" - " characters.") - )] ) class Meta(User.Meta): verbose_name = _("member") verbose_name_plural = _("members") + def format_gpgfp(self): + """Format gpg finger print as AAAA BBBB... from a string AAAABBBB....""" + self.gpg_fingerprint = ' '.join([self.gpg_fingerprint[i:i + 4] for i in range(0, len(self.gpg_fingerprint), 4)]) + + def validate_gpgfp(self): + """Validate from raw entry if is it a valid gpg fp""" + if self.gpg_fingerprint: + gpg_fingerprint = self.gpg_fingerprint.replace(' ', '').upper() + if not re.compile("^[0-9A-F]{40}$").match(gpg_fingerprint): + raise ValidationError(_("A gpg fingerprint must contain 40 hexadecimal carracters")) + self.gpg_fingerprint = gpg_fingerprint + @classmethod def get_instance(cls, adherentid, *_args, **_kwargs): """Try to find an instance of `Adherent` with the given id. @@ -1097,6 +1104,13 @@ class Adherent(User): _("You don't have the right to create a user.") ) + def clean(self, *args, **kwargs): + """Format the GPG fingerprint""" + super(Adherent, self).clean(*args, **kwargs) + if self.gpg_fingerprint: + self.validate_gpgfp() + self.format_gpgfp() + class Club(User): """ A class representing a club (it is considered as a user From e076c1da33f340c90081d9447da535108af7bfa0 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Fri, 28 Dec 2018 23:23:05 +0100 Subject: [PATCH 03/73] Re match direct --- users/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/users/models.py b/users/models.py index b8f79942..a0985675 100755 --- a/users/models.py +++ b/users/models.py @@ -1070,7 +1070,7 @@ class Adherent(User): """Validate from raw entry if is it a valid gpg fp""" if self.gpg_fingerprint: gpg_fingerprint = self.gpg_fingerprint.replace(' ', '').upper() - if not re.compile("^[0-9A-F]{40}$").match(gpg_fingerprint): + if not re.match("^[0-9A-F]{40}$", gpg_fingerprint): raise ValidationError(_("A gpg fingerprint must contain 40 hexadecimal carracters")) self.gpg_fingerprint = gpg_fingerprint From 70a5996f5d47b1091906e7e8397cf1ba94573c0c Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Fri, 28 Dec 2018 23:27:56 +0100 Subject: [PATCH 04/73] Fix available articles --- cotisations/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cotisations/models.py b/cotisations/models.py index 6dd63b6f..f8e53b50 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -624,7 +624,7 @@ class Article(RevMixin, AclMixin, models.Model): objects_pool = cls.objects.filter( Q(type_user='All') | Q(type_user='Adherent') ) - if not target_user.is_adherent(): + if target_user is not None and not target_user.is_adherent(): objects_pool = objects_pool.filter( Q(type_cotisation='All') | Q(type_cotisation='Adhesion') ) From 97593920e5a6d9adbfce7f23e5ea0a5e6d76b203 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sat, 29 Dec 2018 20:35:01 +0100 Subject: [PATCH 05/73] =?UTF-8?q?Fix=20#150=20:=20l'utilisateur=20asso=20e?= =?UTF-8?q?t=20ses=20machines=20ont=20toujours=20acc=C3=A8s=20=C3=A0=20int?= =?UTF-8?q?ernet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- re2o/utils.py | 17 ++++++++++++----- users/models.py | 3 ++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/re2o/utils.py b/re2o/utils.py index 7ec4bd36..20218a81 100644 --- a/re2o/utils.py +++ b/re2o/utils.py @@ -42,7 +42,7 @@ from django.db.models import Q from cotisations.models import Cotisation, Facture, Vente from machines.models import Interface, Machine from users.models import Adherent, User, Ban, Whitelist - +from preferences.models import AssoOption def all_adherent(search_time=None): """ Fonction renvoyant tous les users adherents. Optimisee pour n'est @@ -88,11 +88,14 @@ def all_whitelisted(search_time=None): def all_has_access(search_time=None): - """ Renvoie tous les users beneficiant d'une connexion - : user adherent ou whiteliste et non banni """ + """ Return all connected users : active users and whitelisted + + asso_user defined in AssoOption pannel + ---- + Renvoie tous les users beneficiant d'une connexion + : user adherent et whiteliste non banni plus l'utilisateur asso""" if search_time is None: search_time = timezone.now() - return User.objects.filter( + filter_user = ( Q(state=User.STATE_ACTIVE) & ~Q(ban__in=Ban.objects.filter(Q(date_start__lt=search_time) & Q(date_end__gt=search_time))) & (Q(whitelist__in=Whitelist.objects.filter(Q(date_start__lt=search_time) & Q(date_end__gt=search_time))) | @@ -107,7 +110,11 @@ def all_has_access(search_time=None): ).filter(Q(date_start__lt=search_time) & Q(date_end__gt=search_time)) ) ))) - ).distinct() + ) + asso_user = AssoOption.get_cached_value('utilisateur_asso') + if asso_user: + filter_user |= Q(id=asso_user.id) + return User.objects.filter(filter_user).distinct() def filter_active_interfaces(interface_set): diff --git a/users/models.py b/users/models.py index a0985675..fe96df1e 100755 --- a/users/models.py +++ b/users/models.py @@ -475,7 +475,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, """ Renvoie si un utilisateur a accès à internet """ return (self.state == User.STATE_ACTIVE and not self.is_ban() and - (self.is_connected() or self.is_whitelisted())) + (self.is_connected() or self.is_whitelisted())) \ + or self == AssoOption.get_cached_value('utilisateur_asso') def end_access(self): """ Renvoie la date de fin normale d'accès (adhésion ou whiteliste)""" From 573e6c2ad244a8e41f90f525e3b94fac5dc26563 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Sun, 30 Dec 2018 12:06:20 +0100 Subject: [PATCH 06/73] Use a detailed list rather than a table on profile --- static/css/base.css | 18 +- users/templates/users/profil.html | 288 +++++++++++++++++------------- 2 files changed, 170 insertions(+), 136 deletions(-) diff --git a/static/css/base.css b/static/css/base.css index dcb88db8..05409553 100644 --- a/static/css/base.css +++ b/static/css/base.css @@ -79,19 +79,6 @@ a > i.fa { vertical-align: middle; } -/* Pull sidebars to the bottom */ -@media (min-width: 767px) { - .row { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - } - .row > [class*='col-'] { - flex-direction: column; - } -} - /* On small screens, set height to 'auto' for sidenav and grid */ @media screen and (max-width: 767px) { .sidenav { @@ -145,3 +132,8 @@ th.long_text{ .dashboard{ text-align: center; } + +/* Detailed information on profile page */ +dl.profile-info > div { + padding: 8px; +} diff --git a/users/templates/users/profil.html b/users/templates/users/profil.html index cdc9a9d1..370089ff 100644 --- a/users/templates/users/profil.html +++ b/users/templates/users/profil.html @@ -117,147 +117,189 @@ with this program; if not, write to the Free Software Foundation, Inc.,
-
-

- {% trans " Detailed information" %} +
+

+ {% trans " Detailed information" %}

-
- - - {% trans "Edit" %} - - - - {% trans "Change the password" %} - - {% can_change User state %} - - - {% trans "Change the state" %} - - {% acl_end %} - {% can_change User groups %} - - - {% trans "Edit the groups" %} - - {% acl_end %} - {% history_button users text=True %} +
+ + + {% trans "Edit" %} + + + + {% trans "Change the password" %} + + {% can_change User state %} + + + {% trans "Change the state" %} + + {% acl_end %} + {% can_change User groups %} + + + {% trans "Edit the groups" %} + + {% acl_end %} + {% history_button users text=True %}
-
- - +
+
{% if users.is_class_club %} -
- {% if users.club.mailing %} - - {% else %} - - {% endif %} - {% else %} - - - {% endif %} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {% if users.end_adhesion != None %} - +
{% trans "Mailing" %}
+ {% if users.club.mailing %} +
{{ users.pseudo }}(-admin)
+ {% else %} +
{% trans "Mailing disabled" %}
+ {% endif %} {% else %} - +
{% trans "Firt name" %}
+
{{ users.name }}
{% endif %} - - {% if users.end_whitelist != None %} - - {% else %} - - {% endif %} - - - {% if users.end_ban != None %} - - {% else %} - - {% endif %} - - {% if users.state == 0 %} - - {% elif users.state == 1 %} - - {% elif users.state == 2 %} - - {% elif users.state == 3 %} - + +
+
{% trans "Surname" %}
+
{{ users.surname }}
+
+ +
+
{% trans "Username" %}
+
{{ users.pseudo }}
+
+ +
+
{% trans "Email address" %}
+
{{ users.email }}
+
+ +
+
{% trans "Room" %}
+
+ {{ users.room }} {% can_view_all Port %}{% if users.room.port_set.all %} / + {{ users.room.port_set.all|join:", " }} {% endif %}{% acl_end %} +
+
+ +
+
{% trans "Telephone number" %}
+
{{ users.telephone }}
+
+ +
+
{% trans "School" %}
+
{{ users.school }}
+
+ +
+
{% trans "Comment" %}
+
{{ users.comment }}
+
+ +
+
{% trans "Registration date" %}
+
{{ users.registered }}
+
+ +
+
{% trans "Last login" %}
+
{{ users.last_login }}
+
+ +
+
{% trans "End of membership" %}
+ {% if users.end_adhesion != None %} +
{{ users.end_adhesion }}
+ {% else %} +
{% trans "Not a member" %}
{% endif %} -
- - + + +
+
{% trans "Whitelist" %}
+ {% if users.end_whitelist != None %} +
{{ users.end_whitelist }}
+ {% else %} +
{% trans "None" %}
+ {% endif %} +
+ +
+
{% trans "Ban" %}
+ {% if users.end_ban != None %} +
{{ users.end_ban }}
+ {% else %} +
{% trans "Not banned" %}
+ {% endif %} +
+ +
+
{% trans "State" %}
+ {% if users.state == 0 %} +
{% trans "Active" %}
+ {% elif users.state == 1 %} +
{% trans "Disabled" %}
+ {% elif users.state == 2 %} +
{% trans "Archived" %}
+ {% elif users.state == 3 %} +
{% trans "Not yet Member" %}
+ {% endif %} +
+ +
+
{% trans "Internet access" %}
{% if users.has_access == True %} -
+
+ {% blocktrans with end_access=users.end_access %}Active + (until {{ end_access }}){% endblocktrans %}
{% else %} - +
{% trans "Disabled" %}
{% endif %} - + + +
+
{% trans "Groups of rights" %}
{% if users.groups.all %} -
+
{{ users.groups.all|join:", " }}
{% else %} - +
{% trans "None" %}
{% endif %} - - - - - {% if users.adherent.gpg_fingerprint %} - - - {% endif %} - - - {% if users.shell %} - - - {% endif %} - -
{% trans "Mailing" %}{{ users.pseudo }}(-admin){% trans "Mailing disabled" %}{% trans "Firt name" %}{{ users.name }}{% trans "Surname" %}{{ users.surname }}
{% trans "Username" %}{{ users.pseudo }}{% trans "Email address" %}{{users.email}}
{% trans "Room" %}{{ users.room }} {% can_view_all Port %}{% if users.room.port_set.all %} / {{ users.room.port_set.all|join:", " }} {% endif %}{% acl_end %}{% trans "Telephone number" %}{{ users.telephone }}
{% trans "School" %}{{ users.school }}{% trans "Comment" %}{{ users.comment }}
{% trans "Registration date" %}{{ users.registered }}{% trans "Last login" %}{{ users.last_login }}
{% trans "End of membership" %}{{ users.end_adhesion }}{% trans "Not a member" %}{% trans "Whitelist" %}{{ users.end_whitelist }}{% trans "None" %}
{% trans "Ban" %}{{ users.end_ban }}{% trans "Not banned" %}{% trans "State" %}{% trans "Active" %}{% trans "Disabled" %}{% trans "Archived" %}{% trans "Not yet Member" %}
{% trans "Internet access" %}{% blocktrans with end_access=users.end_access %}Active (until {{ end_access }}){% endblocktrans %}{% trans "Disabled" %}{% trans "Groups of rights" %}{{ users.groups.all|join:", "}}{% trans "None" %}
{% trans "Balance" %}{{ users.solde }} € - {% if user_solde %} - - - {% trans "Refill" %} - + + +
+
{% trans "Balance" %}
+
+ {{ users.solde }} € + {% if user_solde %} + + + {% trans "Refill" %} + + {% endif %} +
+
+ +
+ {% if users.adherent.gpg_fingerprint %} +
{% trans "GPG fingerprint" %}
+
{{ users.adherent.gpg_fingerprint }}
{% endif %} -
{% trans "GPG fingerprint" %}{{ users.adherent.gpg_fingerprint }}
{% trans "Shell" %}{{ users.shell }}
-
+
+ +
+ {% if users.shell %} +
{% trans "Shell" %}
+
{{ users.shell }}
+ {% endif %} +
+

From 5ae1a53172a79d812bbbaa1ad7ef97c5a9a2d7dd Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Sun, 30 Dec 2018 12:35:41 +0100 Subject: [PATCH 07/73] Add lines to split profile information --- static/css/base.css | 6 ++++++ users/templates/users/profil.html | 16 ++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/static/css/base.css b/static/css/base.css index 05409553..a13c596f 100644 --- a/static/css/base.css +++ b/static/css/base.css @@ -134,6 +134,12 @@ th.long_text{ } /* Detailed information on profile page */ +dl.profile-info { + margin-top: -16px; + margin-bottom: 0; +} + dl.profile-info > div { padding: 8px; + border-top: 1px solid #ddd; } diff --git a/users/templates/users/profil.html b/users/templates/users/profil.html index 370089ff..741ecac0 100644 --- a/users/templates/users/profil.html +++ b/users/templates/users/profil.html @@ -286,19 +286,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
-
- {% if users.adherent.gpg_fingerprint %} + {% if users.adherent.gpg_fingerprint %} +
{% trans "GPG fingerprint" %}
{{ users.adherent.gpg_fingerprint }}
- {% endif %} -
+
+ {% endif %} -
- {% if users.shell %} + {% if users.shell %} +
{% trans "Shell" %}
{{ users.shell }}
- {% endif %} -
+
+ {% endif %}
From 509390590bf7f3e9571d68b39cafdf932dd47baf Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Sun, 30 Dec 2018 10:42:05 +0100 Subject: [PATCH 08/73] Split migration 0056 We can not change structure and migrate data at the same time on some db engines. So this commit splits the operation. --- ...radiusoption.py => 0056_1_radiusoption.py} | 27 --------------- preferences/migrations/0056_2_radiusoption.py | 33 +++++++++++++++++++ preferences/migrations/0056_3_radiusoption.py | 31 +++++++++++++++++ .../migrations/0057_auto_20181204_0757.py | 2 +- 4 files changed, 65 insertions(+), 28 deletions(-) rename preferences/migrations/{0056_radiusoption.py => 0056_1_radiusoption.py} (84%) create mode 100644 preferences/migrations/0056_2_radiusoption.py create mode 100644 preferences/migrations/0056_3_radiusoption.py diff --git a/preferences/migrations/0056_radiusoption.py b/preferences/migrations/0056_1_radiusoption.py similarity index 84% rename from preferences/migrations/0056_radiusoption.py rename to preferences/migrations/0056_1_radiusoption.py index e329f598..8a7cb45c 100644 --- a/preferences/migrations/0056_radiusoption.py +++ b/preferences/migrations/0056_1_radiusoption.py @@ -7,19 +7,6 @@ import django.db.models.deletion import re2o.mixins -def create_radius_policy(apps, schema_editor): - OptionalTopologie = apps.get_model('preferences', 'OptionalTopologie') - RadiusOption = apps.get_model('preferences', 'RadiusOption') - - option,_ = OptionalTopologie.objects.get_or_create() - - radius_option = RadiusOption() - radius_option.radius_general_policy = option.radius_general_policy - radius_option.vlan_decision_ok = option.vlan_decision_ok - - radius_option.save() - - class Migration(migrations.Migration): dependencies = [ @@ -94,18 +81,4 @@ class Migration(migrations.Migration): name='vlan_decision_ok', field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vlan_ok_option', to='machines.Vlan'), ), - - migrations.RunPython(create_radius_policy), - migrations.RemoveField( - model_name='optionaltopologie', - name='radius_general_policy', - ), - migrations.RemoveField( - model_name='optionaltopologie', - name='vlan_decision_nok', - ), - migrations.RemoveField( - model_name='optionaltopologie', - name='vlan_decision_ok', - ), ] diff --git a/preferences/migrations/0056_2_radiusoption.py b/preferences/migrations/0056_2_radiusoption.py new file mode 100644 index 00000000..69d81055 --- /dev/null +++ b/preferences/migrations/0056_2_radiusoption.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-10-13 14:29 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import re2o.mixins + + +def create_radius_policy(apps, schema_editor): + OptionalTopologie = apps.get_model('preferences', 'OptionalTopologie') + RadiusOption = apps.get_model('preferences', 'RadiusOption') + + option,_ = OptionalTopologie.objects.get_or_create() + + radius_option = RadiusOption() + radius_option.radius_general_policy = option.radius_general_policy + radius_option.vlan_decision_ok = option.vlan_decision_ok + + radius_option.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0095_auto_20180919_2225'), + ('preferences', '0055_generaloption_main_site_url'), + ('preferences', '0056_1_radiusoption'), + ] + + operations = [ + migrations.RunPython(create_radius_policy), + ] diff --git a/preferences/migrations/0056_3_radiusoption.py b/preferences/migrations/0056_3_radiusoption.py new file mode 100644 index 00000000..f3e5f98c --- /dev/null +++ b/preferences/migrations/0056_3_radiusoption.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-10-13 14:29 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import re2o.mixins + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0095_auto_20180919_2225'), + ('preferences', '0055_generaloption_main_site_url'), + ('preferences', '0056_2_radiusoption'), + ] + + operations = [ + migrations.RemoveField( + model_name='optionaltopologie', + name='radius_general_policy', + ), + migrations.RemoveField( + model_name='optionaltopologie', + name='vlan_decision_nok', + ), + migrations.RemoveField( + model_name='optionaltopologie', + name='vlan_decision_ok', + ), + ] diff --git a/preferences/migrations/0057_auto_20181204_0757.py b/preferences/migrations/0057_auto_20181204_0757.py index ba4e1a6f..8d93fff9 100644 --- a/preferences/migrations/0057_auto_20181204_0757.py +++ b/preferences/migrations/0057_auto_20181204_0757.py @@ -8,7 +8,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('preferences', '0056_radiusoption'), + ('preferences', '0056_3_radiusoption'), ] operations = [ From 7318ee47583bb1cf7d0e68e209f2fcee72e4d267 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 30 Dec 2018 14:56:25 +0100 Subject: [PATCH 09/73] Rename migration + revert function radiusoption --- preferences/migrations/0056_2_radiusoption.py | 5 ++++- .../{0057_auto_20181204_0757.py => 0056_4_radiusoption.py} | 0 2 files changed, 4 insertions(+), 1 deletion(-) rename preferences/migrations/{0057_auto_20181204_0757.py => 0056_4_radiusoption.py} (100%) diff --git a/preferences/migrations/0056_2_radiusoption.py b/preferences/migrations/0056_2_radiusoption.py index 69d81055..1a8ecccd 100644 --- a/preferences/migrations/0056_2_radiusoption.py +++ b/preferences/migrations/0056_2_radiusoption.py @@ -19,6 +19,9 @@ def create_radius_policy(apps, schema_editor): radius_option.save() +def revert_radius(apps, schema_editor): + pass + class Migration(migrations.Migration): @@ -29,5 +32,5 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(create_radius_policy), + migrations.RunPython(create_radius_policy, revert_radius), ] diff --git a/preferences/migrations/0057_auto_20181204_0757.py b/preferences/migrations/0056_4_radiusoption.py similarity index 100% rename from preferences/migrations/0057_auto_20181204_0757.py rename to preferences/migrations/0056_4_radiusoption.py From 58ede006968d0390e2cc49becc83cdb581d434ca Mon Sep 17 00:00:00 2001 From: detraz Date: Mon, 31 Dec 2018 00:13:01 +0100 Subject: [PATCH 10/73] Hotfix autocreate --- users/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/users/models.py b/users/models.py index fe96df1e..e4c25956 100755 --- a/users/models.py +++ b/users/models.py @@ -696,7 +696,8 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, def autoregister_machine(self, mac_address, nas_type): """ Fonction appellée par freeradius. Enregistre la mac pour une machine inconnue sur le compte de l'user""" - if Machine.can_create(self): + allowed, _message = Machine.can_create(self, self.id) + if not allowed: return False, _("Maximum number of registered machines reached.") if not nas_type: return False, _("Re2o doesn't know wich machine type to assign.") From e7a7e81a2c9916a624b3aff11935677e9b5aae80 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sat, 29 Dec 2018 14:01:22 +0100 Subject: [PATCH 11/73] Add discount for custom invoices. --- cotisations/forms.py | 45 +++- .../templates/cotisations/facture.html | 196 ++++++++++-------- cotisations/tex.py | 15 ++ cotisations/views.py | 14 +- 4 files changed, 172 insertions(+), 98 deletions(-) diff --git a/cotisations/forms.py b/cotisations/forms.py index 01e52756..73cb4971 100644 --- a/cotisations/forms.py +++ b/cotisations/forms.py @@ -46,7 +46,7 @@ from django.shortcuts import get_object_or_404 from re2o.field_permissions import FieldPermissionFormMixin from re2o.mixins import FormRevMixin -from .models import Article, Paiement, Facture, Banque, CustomInvoice +from .models import Article, Paiement, Facture, Banque, CustomInvoice, Vente from .payment_methods import balance @@ -104,7 +104,44 @@ class SelectArticleForm(FormRevMixin, Form): user = kwargs.pop('user') target_user = kwargs.pop('target_user', None) super(SelectArticleForm, self).__init__(*args, **kwargs) - self.fields['article'].queryset = Article.find_allowed_articles(user, target_user) + self.fields['article'].queryset = Article.find_allowed_articles( + user, target_user) + + +class DiscountForm(Form): + """ + Form used in oder to create a discount on an invoice. + """ + is_relative = forms.BooleanField( + label=_("Discount is on percentage"), + required=False, + ) + discount = forms.DecimalField( + label=_("Discount"), + max_value=100, + min_value=0, + max_digits=5, + decimal_places=2, + required=False, + ) + + def apply_to_invoice(self, invoice): + invoice_price = invoice.prix_total() + discount = self.cleaned_data['discount'] + is_relative = self.cleaned_data['is_relative'] + if is_relative: + amount = discount/100 * invoice_price + else: + amount = discount + if amount > 0: + name = _("{}% discount") if is_relative else _("{}€ discount") + name = name.format(discount) + Vente.objects.create( + facture=invoice, + name=name, + prix=-amount, + number=1 + ) class CustomInvoiceForm(FormRevMixin, ModelForm): @@ -248,7 +285,8 @@ class RechargeForm(FormRevMixin, Form): super(RechargeForm, self).__init__(*args, **kwargs) self.fields['payment'].empty_label = \ _("Select a payment method") - self.fields['payment'].queryset = Paiement.find_allowed_payments(user_source).exclude(is_balance=True) + self.fields['payment'].queryset = Paiement.find_allowed_payments( + user_source).exclude(is_balance=True) def clean(self): """ @@ -266,4 +304,3 @@ class RechargeForm(FormRevMixin, Form): } ) return self.cleaned_data - diff --git a/cotisations/templates/cotisations/facture.html b/cotisations/templates/cotisations/facture.html index 1f87f579..ff9ed837 100644 --- a/cotisations/templates/cotisations/facture.html +++ b/cotisations/templates/cotisations/facture.html @@ -44,6 +44,8 @@ with this program; if not, write to the Free Software Foundation, Inc., {% blocktrans %}Current balance: {{ balance }} €{% endblocktrans %}

{% endif %} +{% bootstrap_form_errors factureform %} +{% bootstrap_form_errors discount_form %}
{% csrf_token %} @@ -68,8 +70,12 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endfor %} +

{% trans "Discount" %}

+ {% if discount_form %} + {% bootstrap_form discount_form %} + {% endif %}

- {% blocktrans %}Total price: 0,00 €{% endblocktrans %} + {% blocktrans %}Total price: 0,00 €{% endblocktrans %}

{% endif %} {% bootstrap_button action_name button_type='submit' icon='ok' button_class='btn-success' %} @@ -78,105 +84,117 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if articlesformset or payment_method%} {% endif %} diff --git a/cotisations/tex.py b/cotisations/tex.py index 3f404f22..d6c0ae5f 100644 --- a/cotisations/tex.py +++ b/cotisations/tex.py @@ -36,6 +36,7 @@ from django.template import Context from django.http import HttpResponse from django.conf import settings from django.utils.text import slugify +import logging TEMP_PREFIX = getattr(settings, 'TEX_TEMP_PREFIX', 'render_tex-') @@ -93,6 +94,20 @@ def create_pdf(template, ctx={}): return pdf +def escape_chars(string): + """Escape the '%' and the '€' signs to avoid messing with LaTeX""" + if not isinstance(string, str): + return string + mapping = ( + ('€', r'\euro'), + ('%', r'\%'), + ) + r = str(string) + for k, v in mapping: + r = r.replace(k, v) + return r + + def render_tex(_request, template, ctx={}): """Creates a PDF from a LaTex templates using pdflatex. diff --git a/cotisations/views.py b/cotisations/views.py index 68118711..7d4185cc 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -80,9 +80,10 @@ from .forms import ( DelBanqueForm, SelectArticleForm, RechargeForm, - CustomInvoiceForm + CustomInvoiceForm, + DiscountForm ) -from .tex import render_invoice +from .tex import render_invoice, escape_chars from .payment_methods.forms import payment_method_factory from .utils import find_payment_method @@ -198,8 +199,9 @@ def new_custom_invoice(request): request.POST or None, form_kwargs={'user': request.user} ) + discount_form = DiscountForm(request.POST or None) - if invoice_form.is_valid() and articles_formset.is_valid(): + if invoice_form.is_valid() and articles_formset.is_valid() and discount_form.is_valid(): new_invoice_instance = invoice_form.save() for art_item in articles_formset: if art_item.cleaned_data: @@ -213,6 +215,7 @@ def new_custom_invoice(request): duration=article.duration, number=quantity ) + discount_form.apply_to_invoice(new_invoice_instance) messages.success( request, _("The custom invoice was created.") @@ -223,7 +226,8 @@ def new_custom_invoice(request): 'factureform': invoice_form, 'action_name': _("Confirm"), 'articlesformset': articles_formset, - 'articlelist': articles + 'articlelist': articles, + 'discount_form': discount_form }, 'cotisations/facture.html', request) @@ -382,7 +386,7 @@ def custom_invoice_pdf(request, invoice, **_kwargs): purchases_info = [] for purchase in purchases_objects: purchases_info.append({ - 'name': purchase.name, + 'name': escape_chars(purchase.name), 'price': purchase.prix, 'quantity': purchase.number, 'total_price': purchase.prix_total From fd57a9b9250543763be85d34d0b640ed999ad158 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sat, 29 Dec 2018 15:15:33 +0100 Subject: [PATCH 12/73] Display payment method on invoices --- .../templates/cotisations/factures.tex | 24 ++++++++++++------- cotisations/views.py | 6 +++-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/cotisations/templates/cotisations/factures.tex b/cotisations/templates/cotisations/factures.tex index 3f2ebedc..226682e7 100644 --- a/cotisations/templates/cotisations/factures.tex +++ b/cotisations/templates/cotisations/factures.tex @@ -43,7 +43,7 @@ \begin{document} - + %---------------------------------------------------------------------------------------- % HEADING SECTION %---------------------------------------------------------------------------------------- @@ -70,7 +70,7 @@ {\bf Siret :} {{siret|safe}} \vspace{2cm} - + \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}} l r} {\bf Pour :} {{recipient_name|safe}} & {\bf Date :} {{DATE}} \\ {\bf Adresse :} {% if address is None %}Aucune adresse renseignée{% else %}{{address}}{% endif %} & \\ @@ -84,20 +84,20 @@ %---------------------------------------------------------------------------------------- % TABLE OF EXPENSES %---------------------------------------------------------------------------------------- - + \begin{tabularx}{\textwidth}{|X|r|r|r|} \hline \textbf{Désignation} & \textbf{Prix Unit.} \euro & \textbf{Quantité} & \textbf{Prix total} \euro\\ \doublehline - + {% for a in article %} {{a.name}} & {{a.price}} \euro & {{a.quantity}} & {{a.total_price}} \euro\\ \hline {% endfor %} - + \end{tabularx} - + \vspace{1cm} \hfill @@ -109,14 +109,22 @@ \textbf{À PAYER} & {% if not paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \euro\\ \hline \end{tabular} - + + \vspace{1cm} + \begin{tabularx}{\textwidth}{c X} + \hline + \textbf{Moyen de paiement} & {{payment_method|default:"Non spécifié"}} \\ + \hline + \end{tabularx} + + \vfill %---------------------------------------------------------------------------------------- % FOOTNOTE %---------------------------------------------------------------------------------------- - + \hrule \smallskip \footnotesize{TVA non applicable, art. 293 B du CGI} diff --git a/cotisations/views.py b/cotisations/views.py index 7d4185cc..902db508 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -270,7 +270,8 @@ def facture_pdf(request, facture, **_kwargs): 'siret': AssoOption.get_cached_value('siret'), 'email': AssoOption.get_cached_value('contact'), 'phone': AssoOption.get_cached_value('telephone'), - 'tpl_path': os.path.join(settings.BASE_DIR, LOGO_PATH) + 'tpl_path': os.path.join(settings.BASE_DIR, LOGO_PATH), + 'payment_method': facture.paiement.moyen, }) @@ -405,7 +406,8 @@ def custom_invoice_pdf(request, invoice, **_kwargs): 'siret': AssoOption.get_cached_value('siret'), 'email': AssoOption.get_cached_value('contact'), 'phone': AssoOption.get_cached_value('telephone'), - 'tpl_path': os.path.join(settings.BASE_DIR, LOGO_PATH) + 'tpl_path': os.path.join(settings.BASE_DIR, LOGO_PATH), + 'payment_method': invoice.payment, }) From f612e4192f8ae5d4a5cf039d0453979e3553508c Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sat, 29 Dec 2018 15:25:52 +0100 Subject: [PATCH 13/73] Add remark to custom invoices --- .../migrations/0036_custominvoice_remark.py | 20 +++++++++++++++++++ cotisations/models.py | 5 +++++ .../templates/cotisations/factures.tex | 6 +++++- cotisations/views.py | 1 + 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 cotisations/migrations/0036_custominvoice_remark.py diff --git a/cotisations/migrations/0036_custominvoice_remark.py b/cotisations/migrations/0036_custominvoice_remark.py new file mode 100644 index 00000000..7719b31d --- /dev/null +++ b/cotisations/migrations/0036_custominvoice_remark.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-12-29 14:22 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cotisations', '0035_notepayment'), + ] + + operations = [ + migrations.AddField( + model_name='custominvoice', + name='remark', + field=models.TextField(blank=True, null=True, verbose_name='Remark'), + ), + ] diff --git a/cotisations/models.py b/cotisations/models.py index f8e53b50..979b444a 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -286,6 +286,11 @@ class CustomInvoice(BaseInvoice): paid = models.BooleanField( verbose_name=_("Paid") ) + remark = models.TextField( + verbose_name=_("Remark"), + blank=True, + null=True + ) # TODO : change Vente to Purchase diff --git a/cotisations/templates/cotisations/factures.tex b/cotisations/templates/cotisations/factures.tex index 226682e7..11e490d7 100644 --- a/cotisations/templates/cotisations/factures.tex +++ b/cotisations/templates/cotisations/factures.tex @@ -111,10 +111,14 @@ \end{tabular} \vspace{1cm} - \begin{tabularx}{\textwidth}{c X} + \begin{tabularx}{\textwidth}{r X} \hline \textbf{Moyen de paiement} & {{payment_method|default:"Non spécifié"}} \\ \hline + {% if remark %} + \textbf{Remarque} & {{remark|safe}} \\ + \hline + {% endif %} \end{tabularx} diff --git a/cotisations/views.py b/cotisations/views.py index 902db508..ec746bb7 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -408,6 +408,7 @@ def custom_invoice_pdf(request, invoice, **_kwargs): 'phone': AssoOption.get_cached_value('telephone'), 'tpl_path': os.path.join(settings.BASE_DIR, LOGO_PATH), 'payment_method': invoice.payment, + 'remark': invoice.remark, }) From b85384b226a67f040c78aa34850aebf16d37a0e3 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Sat, 29 Dec 2018 23:55:18 +0100 Subject: [PATCH 14/73] Do not fail on empty discount --- cotisations/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cotisations/forms.py b/cotisations/forms.py index 73cb4971..56e90c58 100644 --- a/cotisations/forms.py +++ b/cotisations/forms.py @@ -133,7 +133,7 @@ class DiscountForm(Form): amount = discount/100 * invoice_price else: amount = discount - if amount > 0: + if amount: name = _("{}% discount") if is_relative else _("{}€ discount") name = name.format(discount) Vente.objects.create( From 37dbfd2fbf3d41590d12d08b9a50d00fbb7fcd27 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Mon, 31 Dec 2018 23:58:37 +0100 Subject: [PATCH 15/73] Add Cost Estimates --- cotisations/admin.py | 8 +- cotisations/forms.py | 14 +- cotisations/migrations/0037_costestimate.py | 28 +++ .../migrations/0038_auto_20181231_1657.py | 31 +++ cotisations/models.py | 54 ++++- .../cotisations/aff_cost_estimate.html | 101 +++++++++ .../templates/cotisations/edit_facture.html | 4 + .../templates/cotisations/factures.tex | 10 + .../cotisations/index_cost_estimate.html | 36 ++++ .../templates/cotisations/sidebar.html | 5 + cotisations/tex.py | 3 +- cotisations/urls.py | 30 +++ cotisations/views.py | 196 +++++++++++++++++- 13 files changed, 511 insertions(+), 9 deletions(-) create mode 100644 cotisations/migrations/0037_costestimate.py create mode 100644 cotisations/migrations/0038_auto_20181231_1657.py create mode 100644 cotisations/templates/cotisations/aff_cost_estimate.html create mode 100644 cotisations/templates/cotisations/index_cost_estimate.html diff --git a/cotisations/admin.py b/cotisations/admin.py index afe4621c..4b47ccc8 100644 --- a/cotisations/admin.py +++ b/cotisations/admin.py @@ -30,7 +30,7 @@ from django.contrib import admin from reversion.admin import VersionAdmin from .models import Facture, Article, Banque, Paiement, Cotisation, Vente -from .models import CustomInvoice +from .models import CustomInvoice, CostEstimate class FactureAdmin(VersionAdmin): @@ -38,6 +38,11 @@ class FactureAdmin(VersionAdmin): pass +class CostEstimateAdmin(VersionAdmin): + """Admin class for cost estimates.""" + pass + + class CustomInvoiceAdmin(VersionAdmin): """Admin class for custom invoices.""" pass @@ -76,3 +81,4 @@ admin.site.register(Paiement, PaiementAdmin) admin.site.register(Vente, VenteAdmin) admin.site.register(Cotisation, CotisationAdmin) admin.site.register(CustomInvoice, CustomInvoiceAdmin) +admin.site.register(CostEstimate, CostEstimateAdmin) diff --git a/cotisations/forms.py b/cotisations/forms.py index 56e90c58..57bd7355 100644 --- a/cotisations/forms.py +++ b/cotisations/forms.py @@ -46,7 +46,10 @@ from django.shortcuts import get_object_or_404 from re2o.field_permissions import FieldPermissionFormMixin from re2o.mixins import FormRevMixin -from .models import Article, Paiement, Facture, Banque, CustomInvoice, Vente +from .models import ( + Article, Paiement, Facture, Banque, + CustomInvoice, Vente, CostEstimate +) from .payment_methods import balance @@ -153,6 +156,15 @@ class CustomInvoiceForm(FormRevMixin, ModelForm): fields = '__all__' +class CostEstimateForm(FormRevMixin, ModelForm): + """ + Form used to create a cost estimate. + """ + class Meta: + model = CostEstimate + exclude = ['paid', 'final_invoice'] + + class ArticleForm(FormRevMixin, ModelForm): """ Form used to create an article. diff --git a/cotisations/migrations/0037_costestimate.py b/cotisations/migrations/0037_costestimate.py new file mode 100644 index 00000000..3d97f3f3 --- /dev/null +++ b/cotisations/migrations/0037_costestimate.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-12-29 21:03 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('cotisations', '0036_custominvoice_remark'), + ] + + operations = [ + migrations.CreateModel( + name='CostEstimate', + fields=[ + ('custominvoice_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='cotisations.CustomInvoice')), + ('validity', models.DurationField(verbose_name='Period of validity')), + ('final_invoice', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='origin_cost_estimate', to='cotisations.CustomInvoice')), + ], + options={ + 'permissions': (('view_costestimate', 'Can view a cost estimate object'),), + }, + bases=('cotisations.custominvoice',), + ), + ] diff --git a/cotisations/migrations/0038_auto_20181231_1657.py b/cotisations/migrations/0038_auto_20181231_1657.py new file mode 100644 index 00000000..a9415bf0 --- /dev/null +++ b/cotisations/migrations/0038_auto_20181231_1657.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-12-31 22:57 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('cotisations', '0037_costestimate'), + ] + + operations = [ + migrations.AlterField( + model_name='costestimate', + name='final_invoice', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='origin_cost_estimate', to='cotisations.CustomInvoice'), + ), + migrations.AlterField( + model_name='costestimate', + name='validity', + field=models.DurationField(help_text='DD HH:MM:SS', verbose_name='Period of validity'), + ), + migrations.AlterField( + model_name='custominvoice', + name='paid', + field=models.BooleanField(default=False, verbose_name='Paid'), + ), + ] diff --git a/cotisations/models.py b/cotisations/models.py index 979b444a..623db068 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -284,7 +284,8 @@ class CustomInvoice(BaseInvoice): verbose_name=_("Address") ) paid = models.BooleanField( - verbose_name=_("Paid") + verbose_name=_("Paid"), + default=False ) remark = models.TextField( verbose_name=_("Remark"), @@ -293,6 +294,57 @@ class CustomInvoice(BaseInvoice): ) +class CostEstimate(CustomInvoice): + class Meta: + permissions = ( + ('view_costestimate', _("Can view a cost estimate object")), + ) + validity = models.DurationField( + verbose_name=_("Period of validity"), + help_text="DD HH:MM:SS" + ) + final_invoice = models.ForeignKey( + CustomInvoice, + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name="origin_cost_estimate", + primary_key=False + ) + + def create_invoice(self): + """Create a CustomInvoice from the CostEstimate.""" + if self.final_invoice is not None: + return self.final_invoice + invoice = CustomInvoice() + invoice.recipient = self.recipient + invoice.payment = self.payment + invoice.address = self.address + invoice.paid = False + invoice.remark = self.remark + invoice.date = timezone.now() + invoice.save() + self.final_invoice = invoice + self.save() + for sale in self.vente_set.all(): + Vente.objects.create( + facture=invoice, + name=sale.name, + prix=sale.prix, + number=sale.number, + ) + return invoice + + def can_delete(self, user_request, *args, **kwargs): + if not user_request.has_perm('cotisations.delete_costestimate'): + return False, _("You don't have the right " + "to delete a cost estimate.") + if self.final_invoice is not None: + return False, _("The cost estimate has an " + "invoice and cannot be deleted.") + return True, None + + # TODO : change Vente to Purchase class Vente(RevMixin, AclMixin, models.Model): """ diff --git a/cotisations/templates/cotisations/aff_cost_estimate.html b/cotisations/templates/cotisations/aff_cost_estimate.html new file mode 100644 index 00000000..d4a3f60d --- /dev/null +++ b/cotisations/templates/cotisations/aff_cost_estimate.html @@ -0,0 +1,101 @@ +{% comment %} +Re2o est un logiciel d'administration développé initiallement au rezometz. Il +se veut agnostique au réseau considéré, de manière à être installable en +quelques clics. + +Copyright © 2018 Hugo Levy-Falk + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +{% endcomment %} +{% load i18n %} +{% load acl %} +{% load logs_extra %} +{% load design %} + +
+ {% if cost_estimate_list.paginator %} + {% include 'pagination.html' with list=cost_estimate_list%} + {% endif %} + + + + + + + + + + + + + + + + + {% for estimate in cost_estimate_list %} + + + + + + + + + + + + {% endfor %} +
+ {% trans "Recipient" as tr_recip %} + {% include 'buttons/sort.html' with prefix='invoice' col='user' text=tr_user %} + {% trans "Designation" %}{% trans "Total price" %} + {% trans "Payment method" as tr_payment_method %} + {% include 'buttons/sort.html' with prefix='invoice' col='payement' text=tr_payment_method %} + + {% trans "Date" as tr_date %} + {% include 'buttons/sort.html' with prefix='invoice' col='date' text=tr_date %} + + {% trans "Validity" as tr_validity %} + {% include 'buttons/sort.html' with prefix='invoice' col='validity' text=tr_validity %} + + {% trans "Cost estimate ID" as tr_estimate_id %} + {% include 'buttons/sort.html' with prefix='invoice' col='id' text=tr_estimate_id %} + + {% trans "Invoice created" as tr_invoice_created%} + {% include 'buttons/sort.html' with prefix='invoice' col='paid' text=tr_invoice_created %} +
{{ estimate.recipient }}{{ estimate.name }}{{ estimate.prix_total }}{{ estimate.payment }}{{ estimate.date }}{{ estimate.validity }}{{ estimate.id }} + {% if estimate.final_invoice %} + + {% else %} + ' + {% endif %} + + {% can_edit estimate %} + {% include 'buttons/edit.html' with href='cotisations:edit-cost-estimate' id=estimate.id %} + {% acl_end %} + {% history_button estimate %} + {% include 'buttons/suppr.html' with href='cotisations:del-cost-estimate' id=estimate.id %} + + + + + {% trans "PDF" %} + +
+ + {% if custom_invoice_list.paginator %} + {% include 'pagination.html' with list=custom_invoice_list %} + {% endif %} +
diff --git a/cotisations/templates/cotisations/edit_facture.html b/cotisations/templates/cotisations/edit_facture.html index a00084f6..c7a6975c 100644 --- a/cotisations/templates/cotisations/edit_facture.html +++ b/cotisations/templates/cotisations/edit_facture.html @@ -35,7 +35,11 @@ with this program; if not, write to the Free Software Foundation, Inc., {% csrf_token %} + {% if title %} +

{{title}}

+ {% else %}

{% trans "Edit the invoice" %}

+ {% endif %} {% massive_bootstrap_form factureform 'user' %} {{ venteform.management_form }}

{% trans "Articles" %}

diff --git a/cotisations/templates/cotisations/factures.tex b/cotisations/templates/cotisations/factures.tex index 11e490d7..2cfd4f46 100644 --- a/cotisations/templates/cotisations/factures.tex +++ b/cotisations/templates/cotisations/factures.tex @@ -75,8 +75,12 @@ {\bf Pour :} {{recipient_name|safe}} & {\bf Date :} {{DATE}} \\ {\bf Adresse :} {% if address is None %}Aucune adresse renseignée{% else %}{{address}}{% endif %} & \\ {% if fid is not None %} + {% if is_estimate %} + {\bf Devis n\textsuperscript{o} :} {{ fid }} & \\ + {% else %} {\bf Facture n\textsuperscript{o} :} {{ fid }} & \\ {% endif %} + {% endif %} \end{tabular*} \\ @@ -104,9 +108,11 @@ \begin{tabular}{|l|r|} \hline \textbf{Total} & {{total|floatformat:2}} \euro \\ + {% if not is_estimate %} \textbf{Votre règlement} & {% if paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \euro \\ \doublehline \textbf{À PAYER} & {% if not paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \euro\\ + {% endif %} \hline \end{tabular} @@ -119,6 +125,10 @@ \textbf{Remarque} & {{remark|safe}} \\ \hline {% endif %} + {% if end_validity %} + \textbf{Validité} & Jusqu'au {{end_validity}} \\ + \hline + {% endif %} \end{tabularx} diff --git a/cotisations/templates/cotisations/index_cost_estimate.html b/cotisations/templates/cotisations/index_cost_estimate.html new file mode 100644 index 00000000..a0b3a661 --- /dev/null +++ b/cotisations/templates/cotisations/index_cost_estimate.html @@ -0,0 +1,36 @@ +{% extends "cotisations/sidebar.html" %} +{% comment %} +Re2o est un logiciel d'administration développé initiallement au rezometz. Il +se veut agnostique au réseau considéré, de manière à être installable en +quelques clics. + +Copyright © 2017 Gabriel Détraz +Copyright © 2017 Goulven Kermarec +Copyright © 2017 Augustin Lemesle + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +{% endcomment %} +{% load acl %} +{% load i18n %} + +{% block title %}{% trans "Cost estimates" %}{% endblock %} + +{% block content %} +

{% trans "Cost estimates list" %}

+{% can_create CostEstimate %} +{% include "buttons/add.html" with href='cotisations:new-cost-estimate'%} +{% acl_end %} +{% include 'cotisations/aff_cost_estimate.html' %} +{% endblock %} diff --git a/cotisations/templates/cotisations/sidebar.html b/cotisations/templates/cotisations/sidebar.html index 4f077fad..c3240a9a 100644 --- a/cotisations/templates/cotisations/sidebar.html +++ b/cotisations/templates/cotisations/sidebar.html @@ -45,6 +45,11 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Custom invoices" %} {% acl_end %} + {% can_view_all CostEstimate %} + + {% trans "Cost estimate" %} + + {% acl_end %} {% can_view_all Article %} {% trans "Available articles" %} diff --git a/cotisations/tex.py b/cotisations/tex.py index d6c0ae5f..4d3715af 100644 --- a/cotisations/tex.py +++ b/cotisations/tex.py @@ -49,8 +49,9 @@ def render_invoice(_request, ctx={}): Render an invoice using some available information such as the current date, the user, the articles, the prices, ... """ + is_estimate = ctx.get('is_estimate', False) filename = '_'.join([ - 'invoice', + 'cost_estimate' if is_estimate else 'invoice', slugify(ctx.get('asso_name', "")), slugify(ctx.get('recipient_name', "")), str(ctx.get('DATE', datetime.now()).year), diff --git a/cotisations/urls.py b/cotisations/urls.py index edc448fe..45032fe2 100644 --- a/cotisations/urls.py +++ b/cotisations/urls.py @@ -51,11 +51,41 @@ urlpatterns = [ views.facture_pdf, name='facture-pdf' ), + url( + r'^new_cost_estimate/$', + views.new_cost_estimate, + name='new-cost-estimate' + ), + url( + r'^index_cost_estimate/$', + views.index_cost_estimate, + name='index-cost-estimate' + ), + url( + r'^cost_estimate_pdf/(?P[0-9]+)$', + views.cost_estimate_pdf, + name='cost-estimate-pdf', + ), url( r'^index_custom_invoice/$', views.index_custom_invoice, name='index-custom-invoice' ), + url( + r'^edit_cost_estimate/(?P[0-9]+)$', + views.edit_cost_estimate, + name='edit-cost-estimate' + ), + url( + r'^cost_estimate_to_invoice/(?P[0-9]+)$', + views.cost_estimate_to_invoice, + name='cost-estimate-to-invoice' + ), + url( + r'^del_cost_estimate/(?P[0-9]+)$', + views.del_cost_estimate, + name='del-cost-estimate' + ), url( r'^new_custom_invoice/$', views.new_custom_invoice, diff --git a/cotisations/views.py b/cotisations/views.py index ec746bb7..d4805dc2 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -68,7 +68,8 @@ from .models import ( Paiement, Banque, CustomInvoice, - BaseInvoice + BaseInvoice, + CostEstimate ) from .forms import ( FactureForm, @@ -81,7 +82,8 @@ from .forms import ( SelectArticleForm, RechargeForm, CustomInvoiceForm, - DiscountForm + DiscountForm, + CostEstimateForm, ) from .tex import render_invoice, escape_chars from .payment_methods.forms import payment_method_factory @@ -179,7 +181,58 @@ def new_facture(request, user, userid): ) -# TODO : change facture to invoice +@login_required +@can_create(CostEstimate) +def new_cost_estimate(request): + """ + View used to generate a custom invoice. It's mainly used to + get invoices that are not taken into account, for the administrative + point of view. + """ + # The template needs the list of articles (for the JS part) + articles = Article.objects.filter( + Q(type_user='All') | Q(type_user=request.user.class_name) + ) + # Building the invocie form and the article formset + cost_estimate_form = CostEstimateForm(request.POST or None) + + articles_formset = formset_factory(SelectArticleForm)( + request.POST or None, + form_kwargs={'user': request.user} + ) + discount_form = DiscountForm(request.POST or None) + + if cost_estimate_form.is_valid() and articles_formset.is_valid() and discount_form.is_valid(): + cost_estimate_instance = cost_estimate_form.save() + for art_item in articles_formset: + if art_item.cleaned_data: + article = art_item.cleaned_data['article'] + quantity = art_item.cleaned_data['quantity'] + Vente.objects.create( + facture=cost_estimate_instance, + name=article.name, + prix=article.prix, + type_cotisation=article.type_cotisation, + duration=article.duration, + number=quantity + ) + discount_form.apply_to_invoice(cost_estimate_instance) + messages.success( + request, + _("The cost estimate was created.") + ) + return redirect(reverse('cotisations:index-cost-estimate')) + + return form({ + 'factureform': cost_estimate_form, + 'action_name': _("Confirm"), + 'articlesformset': articles_formset, + 'articlelist': articles, + 'discount_form': discount_form, + 'title': _("Cost estimate"), + }, 'cotisations/facture.html', request) + + @login_required @can_create(CustomInvoice) def new_custom_invoice(request): @@ -336,6 +389,55 @@ def del_facture(request, facture, **_kwargs): }, 'cotisations/delete.html', request) +@login_required +@can_edit(CostEstimate) +def edit_cost_estimate(request, invoice, **kwargs): + # Building the invocie form and the article formset + invoice_form = CostEstimateForm( + request.POST or None, + instance=invoice + ) + purchases_objects = Vente.objects.filter(facture=invoice) + purchase_form_set = modelformset_factory( + Vente, + fields=('name', 'number'), + extra=0, + max_num=len(purchases_objects) + ) + purchase_form = purchase_form_set( + request.POST or None, + queryset=purchases_objects + ) + if invoice_form.is_valid() and purchase_form.is_valid(): + if invoice_form.changed_data: + invoice_form.save() + purchase_form.save() + messages.success( + request, + _("The cost estimate was edited.") + ) + return redirect(reverse('cotisations:index-cost-estimate')) + + return form({ + 'factureform': invoice_form, + 'venteform': purchase_form, + 'title': "Edit the cost estimate" + }, 'cotisations/edit_facture.html', request) + + +@login_required +@can_edit(CostEstimate) +@can_create(CustomInvoice) +def cost_estimate_to_invoice(request, cost_estimate, **_kwargs): + """Create a custom invoice from a cos estimate""" + cost_estimate.create_invoice() + messages.success( + request, + _("An invoice was successfully created from your cost estimate.") + ) + return redirect(reverse('cotisations:index-custom-invoice')) + + @login_required @can_edit(CustomInvoice) def edit_custom_invoice(request, invoice, **kwargs): @@ -371,6 +473,68 @@ def edit_custom_invoice(request, invoice, **kwargs): }, 'cotisations/edit_facture.html', request) +@login_required +@can_view(CostEstimate) +def cost_estimate_pdf(request, invoice, **_kwargs): + """ + View used to generate a PDF file from an existing cost estimate in database + Creates a line for each Purchase (thus article sold) and generate the + invoice with the total price, the payment method, the address and the + legal information for the user. + """ + # TODO : change vente to purchase + purchases_objects = Vente.objects.all().filter(facture=invoice) + # Get the article list and build an list out of it + # contiaining (article_name, article_price, quantity, total_price) + purchases_info = [] + for purchase in purchases_objects: + purchases_info.append({ + 'name': escape_chars(purchase.name), + 'price': purchase.prix, + 'quantity': purchase.number, + 'total_price': purchase.prix_total + }) + return render_invoice(request, { + 'paid': invoice.paid, + 'fid': invoice.id, + 'DATE': invoice.date, + 'recipient_name': invoice.recipient, + 'address': invoice.address, + 'article': purchases_info, + 'total': invoice.prix_total(), + 'asso_name': AssoOption.get_cached_value('name'), + 'line1': AssoOption.get_cached_value('adresse1'), + 'line2': AssoOption.get_cached_value('adresse2'), + 'siret': AssoOption.get_cached_value('siret'), + 'email': AssoOption.get_cached_value('contact'), + 'phone': AssoOption.get_cached_value('telephone'), + 'tpl_path': os.path.join(settings.BASE_DIR, LOGO_PATH), + 'payment_method': invoice.payment, + 'remark': invoice.remark, + 'end_validity': invoice.date + invoice.validity, + 'is_estimate': True, + }) + + +@login_required +@can_delete(CostEstimate) +def del_cost_estimate(request, estimate, **_kwargs): + """ + View used to delete an existing invocie. + """ + if request.method == "POST": + estimate.delete() + messages.success( + request, + _("The cost estimate was deleted.") + ) + return redirect(reverse('cotisations:index-cost-estimate')) + return form({ + 'objet': estimate, + 'objet_name': _("Cost Estimate") + }, 'cotisations/delete.html', request) + + @login_required @can_view(CustomInvoice) def custom_invoice_pdf(request, invoice, **_kwargs): @@ -412,7 +576,6 @@ def custom_invoice_pdf(request, invoice, **_kwargs): }) -# TODO : change facture to invoice @login_required @can_delete(CustomInvoice) def del_custom_invoice(request, invoice, **_kwargs): @@ -763,12 +926,35 @@ def index_banque(request): }) +@login_required +@can_view_all(CustomInvoice) +def index_cost_estimate(request): + """View used to display every custom invoice.""" + pagination_number = GeneralOption.get_cached_value('pagination_number') + cost_estimate_list = CostEstimate.objects.prefetch_related('vente_set') + cost_estimate_list = SortTable.sort( + cost_estimate_list, + request.GET.get('col'), + request.GET.get('order'), + SortTable.COTISATIONS_CUSTOM + ) + cost_estimate_list = re2o_paginator( + request, + cost_estimate_list, + pagination_number, + ) + return render(request, 'cotisations/index_cost_estimate.html', { + 'cost_estimate_list': cost_estimate_list + }) + + @login_required @can_view_all(CustomInvoice) def index_custom_invoice(request): """View used to display every custom invoice.""" pagination_number = GeneralOption.get_cached_value('pagination_number') - custom_invoice_list = CustomInvoice.objects.prefetch_related('vente_set') + cost_estimate_ids = [i for i, in CostEstimate.objects.values_list('id')] + custom_invoice_list = CustomInvoice.objects.prefetch_related('vente_set').exclude(id__in=cost_estimate_ids) custom_invoice_list = SortTable.sort( custom_invoice_list, request.GET.get('col'), From 4de9c1efd264c454275af5f98661b502485b1175 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Sun, 30 Dec 2018 15:27:07 +0100 Subject: [PATCH 16/73] Make URL hash control Bootstrap collapse --- static/js/collapse-from-url.js | 33 +++++++++++++++++++++++++++++++++ templates/base.html | 1 + 2 files changed, 34 insertions(+) create mode 100644 static/js/collapse-from-url.js diff --git a/static/js/collapse-from-url.js b/static/js/collapse-from-url.js new file mode 100644 index 00000000..6c85762b --- /dev/null +++ b/static/js/collapse-from-url.js @@ -0,0 +1,33 @@ +// Re2o est un logiciel d'administration développé initiallement au rezometz. Il +// se veut agnostique au réseau considéré, de manière à être installable en +// quelques clics. +// +// Copyright © 2018 Alexandre Iooss +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +// This script makes URL hash controls Bootstrap collapse +// e.g. if there is #information in the URL +// then the collapse with id "information" will be open. + +$(document).ready(function () { + if(location.hash != null && location.hash !== ""){ + // Open the collapse corresponding to URL hash + $(location.hash + '.collapse').collapse('show'); + } else { + // Open default collapse + $('.collapse-default.collapse').collapse('show'); + } +}); diff --git a/templates/base.html b/templates/base.html index 76ba975a..867be422 100644 --- a/templates/base.html +++ b/templates/base.html @@ -45,6 +45,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% bootstrap_javascript %} + {# Load CSS #} {% bootstrap_css %} From 45cda20c71249837d83b60ba7559ee901f35f770 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Sun, 30 Dec 2018 15:36:15 +0100 Subject: [PATCH 17/73] Rename user profile collapses --- users/templates/users/profil.html | 46 +++++++++++++++++-------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/users/templates/users/profil.html b/users/templates/users/profil.html index 741ecac0..b4fa7875 100644 --- a/users/templates/users/profil.html +++ b/users/templates/users/profil.html @@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. {% endcomment %} -{% load bootstrap3 %} {% load acl %} {% load logs_extra %} {% load design %} @@ -78,8 +77,9 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if solde_activated %}
-
- {{ users.solde }} +
+ {{ users.solde }}
@@ -92,8 +92,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if nb_machines %}
-
- {% trans " Machines" %} {{ nb_machines }} +
+ {% trans " Machines" %} {{ nb_machines }}
{% else %}
-
{% trans "No machine" %}
+
+ {% trans "No machine" %} +
{% trans " Add a machine" %} @@ -118,12 +122,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
+ data-target="#information">

{% trans " Detailed information" %}

-
+
{% if users.is_class_club %}
-
+

{% trans " Manage the club" %}

-
+
{% endif %}
-
+

{% trans "Machines" %} {{nb_machines}}

-
+
-
+

{% trans "Subscriptions" %}

-
+
-
+

{% trans "Bans" %}

-
+
-
+

{% trans "Whitelists" %}

-
+
-
+

{% trans " Email settings" %}

-
+
{% can_edit users %} From 3ed137cf3183b15b3ed9e4c630d0191c4b1c7998 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Sun, 30 Dec 2018 16:28:03 +0100 Subject: [PATCH 18/73] Paginator styling and go to id feature --- machines/templates/machines/aff_machines.html | 4 +- templates/pagination.html | 59 ++++++++++++++----- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/machines/templates/machines/aff_machines.html b/machines/templates/machines/aff_machines.html index 60e1a57a..d5a83ed3 100644 --- a/machines/templates/machines/aff_machines.html +++ b/machines/templates/machines/aff_machines.html @@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if machines_list.paginator %} - {% include "pagination.html" with list=machines_list %} + {% include "pagination.html" with list=machines_list go_to_id="machines" %} {% endif %} @@ -215,6 +215,6 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if machines_list.paginator %} - {% include "pagination.html" with list=machines_list %} + {% include "pagination.html" with list=machines_list go_to_id="machines" %} {% endif %} diff --git a/templates/pagination.html b/templates/pagination.html index cf488c5d..5ecced6d 100644 --- a/templates/pagination.html +++ b/templates/pagination.html @@ -23,23 +23,52 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% load url_insert_param %} +{% load i18n %} {% if list.paginator.num_pages > 1 %} - {% endif %} - From e1729235780fd9a4523a2534ec39a1a038082370 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 30 Dec 2018 00:18:35 +0100 Subject: [PATCH 19/73] Fix #103 --- topologie/models.py | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/topologie/models.py b/topologie/models.py index cd191d7e..25a7bda6 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -281,31 +281,18 @@ class Switch(AclMixin, Machine): def create_ports(self, begin, end): """ Crée les ports de begin à end si les valeurs données sont cohérentes. """ - - s_begin = s_end = 0 - nb_ports = self.ports.count() - if nb_ports > 0: - ports = self.ports.order_by('port').values('port') - s_begin = ports.first().get('port') - s_end = ports.last().get('port') - if end < begin: raise ValidationError(_("The end port is less than the start" " port.")) - if end - begin > self.number: + ports_to_create = list(range(begin, end + 1)) + existing_ports = Port.objects.filter(switch=self.switch).values_list('port', flat=True) + non_existing_ports = list(set(ports_to_create) - set(existing_ports)) + + if len(non_existing_ports) + existing_ports.count() > self.number: raise ValidationError(_("This switch can't have that many ports.")) - begin_range = range(begin, s_begin) - end_range = range(s_end+1, end+1) - for i in itertools.chain(begin_range, end_range): - port = Port() - port.switch = self - port.port = i - try: - with transaction.atomic(), reversion.create_revision(): - port.save() - reversion.set_comment(_("Creation")) - except IntegrityError: - ValidationError(_("Creation of an existing port.")) + with transaction.atomic(), reversion.create_revision(): + reversion.set_comment(_("Creation")) + Port.objects.bulk_create([Port(switch=self.switch, port=port_id) for port_id in non_existing_ports]) def main_interface(self): """ Returns the 'main' interface of the switch From 92e6ae45ad22413f370008f5fb5a83b81a77e9ee Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 30 Dec 2018 00:34:17 +0100 Subject: [PATCH 20/73] Refactor aussi la fonction du views pour la route --- topologie/views.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/topologie/views.py b/topologie/views.py index a4db2dc6..d852177d 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -533,19 +533,14 @@ def create_ports(request, switchid): except Switch.DoesNotExist: messages.error(request, _("Nonexistent switch")) return redirect(reverse('topologie:index')) - - s_begin = s_end = 0 - nb_ports = switch.ports.count() - if nb_ports > 0: - ports = switch.ports.order_by('port').values('port') - s_begin = ports.first().get('port') - s_end = ports.last().get('port') - + + first_port = getattr(switch.ports.order_by('port').first(), 'port', 1) + s_begin = first_port + s_end = switch.number + first_port - 1 port_form = CreatePortsForm( request.POST or None, initial={'begin': s_begin, 'end': s_end} ) - if port_form.is_valid(): begin = port_form.cleaned_data['begin'] end = port_form.cleaned_data['end'] From 7ddb627b6b0f780334712146e34dc8cdd73efcea Mon Sep 17 00:00:00 2001 From: klafyvel Date: Sun, 30 Dec 2018 14:27:41 +0100 Subject: [PATCH 21/73] Do not create an useless list since `set` can be created from any iterable. --- topologie/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/topologie/models.py b/topologie/models.py index 25a7bda6..269516ff 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -284,7 +284,7 @@ class Switch(AclMixin, Machine): if end < begin: raise ValidationError(_("The end port is less than the start" " port.")) - ports_to_create = list(range(begin, end + 1)) + ports_to_create = range(begin, end + 1) existing_ports = Port.objects.filter(switch=self.switch).values_list('port', flat=True) non_existing_ports = list(set(ports_to_create) - set(existing_ports)) From c238a9a2fa2dac6febc8bd5a5b01ac3bd25732cd Mon Sep 17 00:00:00 2001 From: klafyvel Date: Sun, 30 Dec 2018 14:31:36 +0100 Subject: [PATCH 22/73] Remove useless variable in create_ports and give explicit name to `s_end`. --- topologie/views.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/topologie/views.py b/topologie/views.py index d852177d..89d48b0b 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -535,11 +535,10 @@ def create_ports(request, switchid): return redirect(reverse('topologie:index')) first_port = getattr(switch.ports.order_by('port').first(), 'port', 1) - s_begin = first_port - s_end = switch.number + first_port - 1 + last_port = switch.number + first_port - 1 port_form = CreatePortsForm( request.POST or None, - initial={'begin': s_begin, 'end': s_end} + initial={'begin': first_port, 'end': last_port} ) if port_form.is_valid(): begin = port_form.cleaned_data['begin'] From 71dc9c9bd1ec3468bc49f712723267b09ef65e7d Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Tue, 1 Jan 2019 19:32:40 +0100 Subject: [PATCH 23/73] Remove code about radius in OptionalTopology edit form. --- preferences/forms.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/preferences/forms.py b/preferences/forms.py index 1126b399..fd052edd 100644 --- a/preferences/forms.py +++ b/preferences/forms.py @@ -115,11 +115,6 @@ class EditOptionalTopologieForm(ModelForm): prefix=prefix, **kwargs ) - self.fields['radius_general_policy'].label = _("RADIUS general policy") - self.fields['vlan_decision_ok'].label = _("VLAN for machines accepted" - " by RADIUS") - self.fields['vlan_decision_nok'].label = _("VLAN for machines rejected" - " by RADIUS") self.initial['automatic_provision_switchs'] = Switch.objects.filter(automatic_provision=True).order_by('interface__domain__name') From 21f54486b20e8413153e53d00fa5cab3132307c9 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Tue, 1 Jan 2019 20:17:27 +0100 Subject: [PATCH 24/73] Fix switch creation --- topologie/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/topologie/models.py b/topologie/models.py index 269516ff..e08a1b21 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -304,7 +304,7 @@ class Switch(AclMixin, Machine): @cached_property def get_name(self): - return self.name or self.main_interface().domain.name + return self.name or getattr(self.main_interface(), 'domain', 'Unknown') @cached_property def get_radius_key(self): From c76a5d237679e707b224b7867919a35e7347349d Mon Sep 17 00:00:00 2001 From: Maxime Bombar Date: Tue, 1 Jan 2019 16:11:02 +0100 Subject: [PATCH 25/73] Prevents from crashing where there is no defined prefix_v6 --- machines/models.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/machines/models.py b/machines/models.py index 888e4ac0..1cf840d7 100644 --- a/machines/models.py +++ b/machines/models.py @@ -1380,7 +1380,10 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model): .filter(interface=self.interface, slaac_ip=True) .exclude(id=self.id)): raise ValidationError(_("A SLAAC IP address is already registered.")) - prefix_v6 = self.interface.type.ip_type.prefix_v6.encode().decode('utf-8') + try: + prefix_v6 = self.interface.type.ip_type.prefix_v6.encode().decode('utf-8') + except AttributeError: # Prevents from crashing when there is no defined prefix_v6 + prefix_v6 = None if prefix_v6: if (IPv6Address(self.ipv6.encode().decode('utf-8')).exploded[:20] != IPv6Address(prefix_v6).exploded[:20]): From 4ac403ec29fbfc1ec8bec76deeed7b8380948d68 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Wed, 2 Jan 2019 15:18:40 +0100 Subject: [PATCH 26/73] Hotfix boostrapform --- cotisations/templates/cotisations/facture.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cotisations/templates/cotisations/facture.html b/cotisations/templates/cotisations/facture.html index ff9ed837..8a1a6d7a 100644 --- a/cotisations/templates/cotisations/facture.html +++ b/cotisations/templates/cotisations/facture.html @@ -44,8 +44,12 @@ with this program; if not, write to the Free Software Foundation, Inc., {% blocktrans %}Current balance: {{ balance }} €{% endblocktrans %}

{% endif %} +{% if factureform %} {% bootstrap_form_errors factureform %} +{% endif %} +{% if discount_form %} {% bootstrap_form_errors discount_form %} +{% endif %} {% csrf_token %} From 02229983a024fdce8020ffd60649a1f303841031 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 30 Dec 2018 11:27:54 +0100 Subject: [PATCH 27/73] =?UTF-8?q?Exporte=20la=20liste=20des=20r=C3=A9cursi?= =?UTF-8?q?fs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- preferences/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/preferences/models.py b/preferences/models.py index 4644aa1c..e8476354 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -278,12 +278,13 @@ class OptionalTopologie(AclMixin, PreferencesModel): log_servers = Role.all_interfaces_for_roletype("log-server").filter(type__ip_type=self.switchs_ip_type) radius_servers = Role.all_interfaces_for_roletype("radius-server").filter(type__ip_type=self.switchs_ip_type) dhcp_servers = Role.all_interfaces_for_roletype("dhcp-server") + dns_recursive_servers = Role.all_interfaces_for_roletype("dns-recursif-server").filter(type__ip_type=self.switchs_ip_type) subnet = None subnet6 = None if self.switchs_ip_type: subnet = self.switchs_ip_type.ip_set_full_info subnet6 = self.switchs_ip_type.ip6_set_full_info - return {'ntp_servers': return_ips_dict(ntp_servers), 'log_servers': return_ips_dict(log_servers), 'radius_servers': return_ips_dict(radius_servers), 'dhcp_servers': return_ips_dict(dhcp_servers), 'subnet': subnet, 'subnet6': subnet6} + return {'ntp_servers': return_ips_dict(ntp_servers), 'log_servers': return_ips_dict(log_servers), 'radius_servers': return_ips_dict(radius_servers), 'dhcp_servers': return_ips_dict(dhcp_servers), 'dns_recursive_servers': return_ips_dict(dns_recursive_servers), 'subnet': subnet, 'subnet6': subnet6} @cached_property def provision_switchs_enabled(self): From 2c9ff4ea8e7c78e226cead8b2fb179d0b5a91ece Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 30 Dec 2018 17:04:21 +0100 Subject: [PATCH 28/73] Module switch, model et fonctions basiques de modification --- topologie/forms.py | 21 ++++++ .../migrations/0067_auto_20181230_1556.py | 63 +++++++++++++++++ topologie/models.py | 64 +++++++++++++++++ .../templates/topologie/aff_modules.html | 67 ++++++++++++++++++ .../templates/topologie/index_module.html | 43 ++++++++++++ topologie/templates/topologie/sidebar.html | 4 ++ topologie/templates/topologie/topo.html | 2 +- topologie/urls.py | 8 ++- topologie/views.py | 70 +++++++++++++++++++ 9 files changed, 340 insertions(+), 2 deletions(-) create mode 100644 topologie/migrations/0067_auto_20181230_1556.py create mode 100644 topologie/templates/topologie/aff_modules.html create mode 100644 topologie/templates/topologie/index_module.html diff --git a/topologie/forms.py b/topologie/forms.py index fa089507..dc4a5e9b 100644 --- a/topologie/forms.py +++ b/topologie/forms.py @@ -55,6 +55,7 @@ from .models import ( SwitchBay, Building, PortProfile, + ModuleSwitch ) @@ -269,3 +270,23 @@ class EditPortProfileForm(FormRevMixin, ModelForm): prefix=prefix, **kwargs) +class EditModuleForm(FormRevMixin, ModelForm): + """Add and edit module instance""" + class Meta: + model = ModuleSwitch + fields = '__all__' + + def __init__(self, *args, **kwargs): + prefix = kwargs.pop('prefix', self.Meta.model.__name__) + super(EditModuleForm, self).__init__(*args, prefix=prefix, **kwargs) + self.fields['switchs'].queryset = (Switch.objects.filter(model__is_modular=True)) + + def save(self, commit=True): + # TODO : None of the parents of ServiceForm use the commit + # parameter in .save() + instance = super(EditModuleForm, self).save(commit=False) + if commit: + instance.save() + instance.process_link(self.cleaned_data.get('switchs')) + return instance + diff --git a/topologie/migrations/0067_auto_20181230_1556.py b/topologie/migrations/0067_auto_20181230_1556.py new file mode 100644 index 00000000..cd0d368c --- /dev/null +++ b/topologie/migrations/0067_auto_20181230_1556.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-12-30 14:56 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import re2o.mixins + + +class Migration(migrations.Migration): + + dependencies = [ + ('topologie', '0066_modelswitch_commercial_name'), + ] + + operations = [ + migrations.CreateModel( + name='ModuleOnSwitch', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('slot', models.CharField(help_text='Slot on switch', max_length=15, verbose_name='Slot')), + ], + options={ + 'verbose_name': 'link between switchs and modules', + 'permissions': (('view_moduleonswitch', 'Can view a moduleonswitch object'),), + }, + bases=(re2o.mixins.AclMixin, re2o.mixins.RevMixin, models.Model), + ), + migrations.CreateModel( + name='ModuleSwitch', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('reference', models.CharField(help_text='Reference of a module', max_length=255, verbose_name='Module reference')), + ('comment', models.CharField(blank=True, help_text='Comment', max_length=255, null=True, verbose_name='Comment')), + ('switchs', models.ManyToManyField(through='topologie.ModuleOnSwitch', to='topologie.Switch')), + ], + options={ + 'verbose_name': 'Module of a switch', + 'permissions': (('view_moduleswitch', 'Can view a module object'),), + }, + bases=(re2o.mixins.AclMixin, re2o.mixins.RevMixin, models.Model), + ), + migrations.AddField( + model_name='modelswitch', + name='is_itself_module', + field=models.BooleanField(default=False, help_text='Does the switch, itself, considered as a module'), + ), + migrations.AddField( + model_name='modelswitch', + name='is_modular', + field=models.BooleanField(default=False, help_text='Is this switch model modular'), + ), + migrations.AddField( + model_name='moduleonswitch', + name='module', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='topologie.ModuleSwitch'), + ), + migrations.AddField( + model_name='moduleonswitch', + name='switch', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='topologie.Switch'), + ), + ] diff --git a/topologie/models.py b/topologie/models.py index e08a1b21..a4f5f3bc 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -251,6 +251,7 @@ class Switch(AclMixin, Machine): default=False, help_text='Provision automatique de ce switch', ) + class Meta: unique_together = ('stack', 'stack_member_id') @@ -389,6 +390,14 @@ class ModelSwitch(AclMixin, RevMixin, models.Model): null=True, blank=True ) + is_modular = models.BooleanField( + default=False, + help_text=_("Is this switch model modular"), + ) + is_itself_module = models.BooleanField( + default=False, + help_text=_("Does the switch, itself, considered as a module"), + ) class Meta: permissions = ( @@ -404,6 +413,61 @@ class ModelSwitch(AclMixin, RevMixin, models.Model): return str(self.constructor) + ' ' + self.reference +class ModuleSwitch(AclMixin, RevMixin, models.Model): + """A module of a switch""" + reference = models.CharField( + max_length=255, + help_text=_("Reference of a module"), + verbose_name=_("Module reference") + ) + comment = models.CharField( + max_length=255, + null=True, + blank=True, + help_text=_("Comment"), + verbose_name=_("Comment") + ) + switchs = models.ManyToManyField('Switch', through='ModuleOnSwitch') + + class Meta: + permissions = ( + ("view_moduleswitch", _("Can view a module object")), + ) + verbose_name = _("Module of a switch") + + def process_link(self, switchs): + """Django can't create itself foreignkey with explicit through""" + ModuleOnSwitch.objects.bulk_create( + [ModuleOnSwitch( + module=self, switch=sw + ) for sw in switchs.exclude( + pk__in=Switch.objects.filter(moduleswitch=self) + )] + ) + ModuleOnSwitch.objects.filter(module=self).exclude(switch__in=switchs).delete() + return + + def __str__(self): + return str(self.reference) + + +class ModuleOnSwitch(AclMixin, RevMixin, models.Model): + """Link beetween module and switch""" + module = models.ForeignKey('ModuleSwitch', on_delete=models.CASCADE) + switch = models.ForeignKey('Switch', on_delete=models.CASCADE) + slot = models.CharField( + max_length=15, + help_text=_("Slot on switch"), + verbose_name=_("Slot") + ) + + class Meta: + permissions = ( + ("view_moduleonswitch", _("Can view a moduleonswitch object")), + ) + verbose_name = _("link between switchs and modules") + + class ConstructorSwitch(AclMixin, RevMixin, models.Model): """Un constructeur de switch""" diff --git a/topologie/templates/topologie/aff_modules.html b/topologie/templates/topologie/aff_modules.html new file mode 100644 index 00000000..8233260c --- /dev/null +++ b/topologie/templates/topologie/aff_modules.html @@ -0,0 +1,67 @@ +{% comment %} +Re2o est un logiciel d'administration développé initiallement au rezometz. Il +se veut agnostique au réseau considéré, de manière à être installable en +quelques clics. + +Copyright © 2017 Gabriel Détraz +Copyright © 2017 Goulven Kermarec +Copyright © 2017 Augustin Lemesle + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +{% endcomment %} + +{% load acl %} +{% load logs_extra %} +{% load i18n %} + +{% if module_list.paginator %} +{% include "pagination.html" with list=module_list %} +{% endif %} + +
+ + + + + + + + + {% for module in module_list %} + + + + + + + {% endfor %} +
{% trans "Reference" %}{% trans "Comment" %}{% trans "Switchs" %}
{{ module.reference }}{{ module.comment }}{{ module.switchs.all }} + {% can_edit module %} + + + + {% acl_end %} + {% history_button module %} + {% can_delete module %} + + + + {% acl_end %} +
+ +{% if module_list.paginator %} +{% include "pagination.html" with list=module_list %} +{% endif %} + diff --git a/topologie/templates/topologie/index_module.html b/topologie/templates/topologie/index_module.html new file mode 100644 index 00000000..5c4c5c7c --- /dev/null +++ b/topologie/templates/topologie/index_module.html @@ -0,0 +1,43 @@ +{% extends "topologie/sidebar.html" %} +{% comment %} +Re2o est un logiciel d'administration développé initiallement au rezometz. Il +se veut agnostique au réseau considéré, de manière à être installable en +quelques clics. + +Copyright © 2017 Gabriel Détraz +Copyright © 2017 Goulven Kermarec +Copyright © 2017 Augustin Lemesle + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +{% endcomment %} + +{% load bootstrap3 %} +{% load acl %} +{% load i18n %} + +{% block title %}{% trans "Topology" %}{% endblock %} + +{% block content %} +

{% trans "Modules of switchs" %}

+{% can_create ModuleSwitch %} +{% trans " Add a module" %} +
+{% acl_end %} + {% include "topologie/aff_modules.html" with module_list=module_list %} +
+
+
+{% endblock %} + diff --git a/topologie/templates/topologie/sidebar.html b/topologie/templates/topologie/sidebar.html index a35721f9..80317a16 100644 --- a/topologie/templates/topologie/sidebar.html +++ b/topologie/templates/topologie/sidebar.html @@ -33,6 +33,10 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Switches" %} + + + + {% trans "Switches modules" %} diff --git a/topologie/templates/topologie/topo.html b/topologie/templates/topologie/topo.html index bf9f760b..d1ec9bb3 100644 --- a/topologie/templates/topologie/topo.html +++ b/topologie/templates/topologie/topo.html @@ -37,7 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endif %} {% csrf_token %} - {% massive_bootstrap_form topoform 'room,related,machine_interface,members,vlan_tagged' %} + {% massive_bootstrap_form topoform 'room,related,machine_interface,members,vlan_tagged,switchs' %} {% bootstrap_button action_name icon='ok' button_class='btn-success' %}
diff --git a/topologie/urls.py b/topologie/urls.py index 77d68d50..7af7df9a 100644 --- a/topologie/urls.py +++ b/topologie/urls.py @@ -123,4 +123,10 @@ urlpatterns = [ url(r'^edit_vlanoptions/(?P[0-9]+)$', views.edit_vlanoptions, name='edit-vlanoptions'), - ] + url(r'^add_module/$', views.add_module, name='add-module'), + url(r'^edit_module/(?P[0-9]+)$', + views.edit_module, + name='edit-module'), + url(r'^del_module/(?P[0-9]+)$', views.del_module, name='del-module'), + url(r'^index_module/$', views.index_module, name='index-module'), +] diff --git a/topologie/views.py b/topologie/views.py index 89d48b0b..f5c72627 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -86,6 +86,7 @@ from .models import ( Building, Server, PortProfile, + ModuleSwitch, ) from .forms import ( EditPortForm, @@ -102,6 +103,7 @@ from .forms import ( EditSwitchBayForm, EditBuildingForm, EditPortProfileForm, + EditModuleForm ) from subprocess import ( @@ -316,6 +318,20 @@ def index_model_switch(request): ) +@login_required +@can_view_all(ModuleSwitch) +def index_module(request): + """Display all modules of switchs""" + module_list = ModuleSwitch.objects.all() + pagination_number = GeneralOption.get_cached_value('pagination_number') + module_list = re2o_paginator(request, module_list, pagination_number) + return render( + request, + 'topologie/index_module.html', + {'module_list': module_list} + ) + + @login_required @can_edit(Vlan) def edit_vlanoptions(request, vlan_instance, **_kwargs): @@ -1048,6 +1064,60 @@ def del_port_profile(request, port_profile, **_kwargs): ) +@can_create(ModuleSwitch) +def add_module(request): + """ View used to add a Module object """ + module = EditModuleForm(request.POST or None) + if module.is_valid(): + module.save() + messages.success(request, _("The module was created.")) + return redirect(reverse('topologie:index-module')) + return form( + {'topoform': module, 'action_name': _("Create a module")}, + 'topologie/topo.html', + request + ) + + +@login_required +@can_edit(ModuleSwitch) +def edit_module(request, module_instance, **_kwargs): + """ View used to edit a Module object """ + module = EditModuleForm(request.POST or None, instance=module_instance) + if module.is_valid(): + if module.changed_data: + module.save() + messages.success(request, _("The module was edited.")) + return redirect(reverse('topologie:index-module')) + return form( + {'topoform': module, 'action_name': _("Edit")}, + 'topologie/topo.html', + request + ) + + +@login_required +@can_delete(ModuleSwitch) +def del_module(request, module, **_kwargs): + """Compleete delete a module""" + if request.method == "POST": + try: + module.delete() + messages.success(request, _("The module was deleted.")) + except ProtectedError: + messages.error( + request, + (_("The module %s is used by another object, impossible to" + " deleted it.") % module) + ) + return redirect(reverse('topologie:index-module')) + return form( + {'objet': module, 'objet_name': _("Module")}, + 'topologie/delete.html', + request + ) + + def make_machine_graph(): """ Create the graph of switchs, machines and access points. From 4dbbb00cf7fc4867ce1ef0c2258600d54b150cf0 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 30 Dec 2018 17:16:30 +0100 Subject: [PATCH 29/73] Export of modules of a switch --- topologie/models.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/topologie/models.py b/topologie/models.py index a4f5f3bc..53e9ffe6 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -368,6 +368,17 @@ class Switch(AclMixin, Machine): """Return dict ip6:subnet for all ipv6 of the switch""" return dict((str(interface.ipv6().first()), interface.type.ip_type.ip6_set_full_info) for interface in self.interface_set.all()) + @cached_property + def list_modules(self): + """Return modules of that switch, list of dict (rank, reference)""" + modules = [] + if self.model.is_modular: + if self.model.is_itself_module: + modules.append((1, self.model.reference)) + for module_of_self in self.moduleonswitch_set.all(): + modules.append((module_of_self.slot, module_of_self.module.reference)) + return modules + def __str__(self): return str(self.get_name) From 683cf229e96fe4c9539a201790a32d8b126072cc Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 30 Dec 2018 18:20:06 +0100 Subject: [PATCH 30/73] Edition fine des modules pour chaque switchs avec le slot --- topologie/forms.py | 21 +++---- ...230_1556.py => 0067_auto_20181230_1819.py} | 7 ++- topologie/models.py | 16 ++--- .../templates/topologie/aff_modules.html | 20 ++++++- topologie/templates/topologie/topo.html | 2 +- topologie/urls.py | 9 ++- topologie/views.py | 59 ++++++++++++++++++- 7 files changed, 105 insertions(+), 29 deletions(-) rename topologie/migrations/{0067_auto_20181230_1556.py => 0067_auto_20181230_1819.py} (93%) diff --git a/topologie/forms.py b/topologie/forms.py index dc4a5e9b..ed6fa5b9 100644 --- a/topologie/forms.py +++ b/topologie/forms.py @@ -55,7 +55,8 @@ from .models import ( SwitchBay, Building, PortProfile, - ModuleSwitch + ModuleSwitch, + ModuleOnSwitch, ) @@ -279,14 +280,14 @@ class EditModuleForm(FormRevMixin, ModelForm): def __init__(self, *args, **kwargs): prefix = kwargs.pop('prefix', self.Meta.model.__name__) super(EditModuleForm, self).__init__(*args, prefix=prefix, **kwargs) - self.fields['switchs'].queryset = (Switch.objects.filter(model__is_modular=True)) - def save(self, commit=True): - # TODO : None of the parents of ServiceForm use the commit - # parameter in .save() - instance = super(EditModuleForm, self).save(commit=False) - if commit: - instance.save() - instance.process_link(self.cleaned_data.get('switchs')) - return instance +class EditSwitchModuleForm(FormRevMixin, ModelForm): + """Add/edit a switch to a module""" + class Meta: + model = ModuleOnSwitch + fields = '__all__' + + def __init__(self, *args, **kwargs): + prefix = kwargs.pop('prefix', self.Meta.model.__name__) + super(EditSwitchModuleForm, self).__init__(*args, prefix=prefix, **kwargs) diff --git a/topologie/migrations/0067_auto_20181230_1556.py b/topologie/migrations/0067_auto_20181230_1819.py similarity index 93% rename from topologie/migrations/0067_auto_20181230_1556.py rename to topologie/migrations/0067_auto_20181230_1819.py index cd0d368c..57f268ea 100644 --- a/topologie/migrations/0067_auto_20181230_1556.py +++ b/topologie/migrations/0067_auto_20181230_1819.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.10.7 on 2018-12-30 14:56 +# Generated by Django 1.10.7 on 2018-12-30 17:19 from __future__ import unicode_literals from django.db import migrations, models @@ -32,7 +32,6 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('reference', models.CharField(help_text='Reference of a module', max_length=255, verbose_name='Module reference')), ('comment', models.CharField(blank=True, help_text='Comment', max_length=255, null=True, verbose_name='Comment')), - ('switchs', models.ManyToManyField(through='topologie.ModuleOnSwitch', to='topologie.Switch')), ], options={ 'verbose_name': 'Module of a switch', @@ -60,4 +59,8 @@ class Migration(migrations.Migration): name='switch', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='topologie.Switch'), ), + migrations.AlterUniqueTogether( + name='moduleonswitch', + unique_together=set([('slot', 'switch')]), + ), ] diff --git a/topologie/models.py b/topologie/models.py index 53e9ffe6..b2c75f24 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -438,7 +438,6 @@ class ModuleSwitch(AclMixin, RevMixin, models.Model): help_text=_("Comment"), verbose_name=_("Comment") ) - switchs = models.ManyToManyField('Switch', through='ModuleOnSwitch') class Meta: permissions = ( @@ -446,17 +445,6 @@ class ModuleSwitch(AclMixin, RevMixin, models.Model): ) verbose_name = _("Module of a switch") - def process_link(self, switchs): - """Django can't create itself foreignkey with explicit through""" - ModuleOnSwitch.objects.bulk_create( - [ModuleOnSwitch( - module=self, switch=sw - ) for sw in switchs.exclude( - pk__in=Switch.objects.filter(moduleswitch=self) - )] - ) - ModuleOnSwitch.objects.filter(module=self).exclude(switch__in=switchs).delete() - return def __str__(self): return str(self.reference) @@ -477,6 +465,10 @@ class ModuleOnSwitch(AclMixin, RevMixin, models.Model): ("view_moduleonswitch", _("Can view a moduleonswitch object")), ) verbose_name = _("link between switchs and modules") + unique_together = ['slot', 'switch'] + + def __str__(self): + return 'On slot ' + str(self.slot) + ' of ' + str(self.switch) class ConstructorSwitch(AclMixin, RevMixin, models.Model): diff --git a/topologie/templates/topologie/aff_modules.html b/topologie/templates/topologie/aff_modules.html index 8233260c..d73fffeb 100644 --- a/topologie/templates/topologie/aff_modules.html +++ b/topologie/templates/topologie/aff_modules.html @@ -43,9 +43,27 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ module.reference }} {{ module.comment }} - {{ module.switchs.all }} + + {% for module_switch in module.moduleonswitch_set.all %} + Slot {{ module_switch.slot }} of {{ module_switch.switch }} + {% can_edit module_switch %} +
+ + + {% acl_end %} + {% can_delete module_switch %} + + + + {% acl_end %} +
+ {% endfor %} + {% can_edit module %} + + + diff --git a/topologie/templates/topologie/topo.html b/topologie/templates/topologie/topo.html index d1ec9bb3..a7824020 100644 --- a/topologie/templates/topologie/topo.html +++ b/topologie/templates/topologie/topo.html @@ -37,7 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endif %}
{% csrf_token %} - {% massive_bootstrap_form topoform 'room,related,machine_interface,members,vlan_tagged,switchs' %} + {% massive_bootstrap_form topoform 'room,related,machine_interface,members,vlan_tagged,switch' %} {% bootstrap_button action_name icon='ok' button_class='btn-success' %}

diff --git a/topologie/urls.py b/topologie/urls.py index 7af7df9a..70eae8e4 100644 --- a/topologie/urls.py +++ b/topologie/urls.py @@ -124,9 +124,14 @@ urlpatterns = [ views.edit_vlanoptions, name='edit-vlanoptions'), url(r'^add_module/$', views.add_module, name='add-module'), - url(r'^edit_module/(?P[0-9]+)$', + url(r'^edit_module/(?P[0-9]+)$', views.edit_module, name='edit-module'), - url(r'^del_module/(?P[0-9]+)$', views.del_module, name='del-module'), + url(r'^del_module/(?P[0-9]+)$', views.del_module, name='del-module'), url(r'^index_module/$', views.index_module, name='index-module'), + url(r'^add_module_on/$', views.add_module_on, name='add-module-on'), + url(r'^edit_module_on/(?P[0-9]+)$', + views.edit_module_on, + name='edit-module-on'), + url(r'^del_module_on/(?P[0-9]+)$', views.del_module_on, name='del-module-on'), ] diff --git a/topologie/views.py b/topologie/views.py index f5c72627..5174f05d 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -87,6 +87,7 @@ from .models import ( Server, PortProfile, ModuleSwitch, + ModuleOnSwitch, ) from .forms import ( EditPortForm, @@ -103,7 +104,8 @@ from .forms import ( EditSwitchBayForm, EditBuildingForm, EditPortProfileForm, - EditModuleForm + EditModuleForm, + EditSwitchModuleForm, ) from subprocess import ( @@ -1064,6 +1066,7 @@ def del_port_profile(request, port_profile, **_kwargs): ) +@login_required @can_create(ModuleSwitch) def add_module(request): """ View used to add a Module object """ @@ -1117,6 +1120,60 @@ def del_module(request, module, **_kwargs): request ) +@login_required +@can_create(ModuleOnSwitch) +def add_module_on(request): + """Add a module to a switch""" + module_switch = EditSwitchModuleForm(request.POST or None) + if module_switch.is_valid(): + module_switch.save() + messages.success(request, _("The module added to that switch")) + return redirect(reverse('topologie:index-module')) + return form( + {'topoform': module_switch, 'action_name': _("Create")}, + 'topologie/topo.html', + request + ) + + +@login_required +@can_edit(ModuleOnSwitch) +def edit_module_on(request, module_instance, **_kwargs): + """ View used to edit a Module object """ + module = EditSwitchModuleForm(request.POST or None, instance=module_instance) + if module.is_valid(): + if module.changed_data: + module.save() + messages.success(request, _("The module was edited.")) + return redirect(reverse('topologie:index-module')) + return form( + {'topoform': module, 'action_name': _("Edit")}, + 'topologie/topo.html', + request + ) + + +@login_required +@can_delete(ModuleOnSwitch) +def del_module_on(request, module, **_kwargs): + """Compleete delete a module""" + if request.method == "POST": + try: + module.delete() + messages.success(request, _("The module was deleted.")) + except ProtectedError: + messages.error( + request, + (_("The module %s is used by another object, impossible to" + " deleted it.") % module) + ) + return redirect(reverse('topologie:index-module')) + return form( + {'objet': module, 'objet_name': _("Module")}, + 'topologie/delete.html', + request + ) + def make_machine_graph(): """ From 82802de47706ed66299168d4e42d77f8bae02456 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 30 Dec 2018 18:45:18 +0100 Subject: [PATCH 31/73] More clear front of all switchs modular --- .../templates/topologie/aff_modules.html | 25 +++++++++++++++++++ .../templates/topologie/index_module.html | 2 +- topologie/views.py | 4 ++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/topologie/templates/topologie/aff_modules.html b/topologie/templates/topologie/aff_modules.html index d73fffeb..0c7a3207 100644 --- a/topologie/templates/topologie/aff_modules.html +++ b/topologie/templates/topologie/aff_modules.html @@ -83,3 +83,28 @@ with this program; if not, write to the Free Software Foundation, Inc., {% include "pagination.html" with list=module_list %} {% endif %} +

{% trans "All modular switchs" %}

+ + + + + + + + {% for switch in modular_switchs %} + {% if switch.list_modules %} + + + + {% for module in switch.list_modules %} + + + + + + {% endfor %} +{% endif %} +{% endfor %} +
{% trans "Switch" %}{% trans "Reference" %}{% trans "Slot" %}
+ {{ switch }} +
{{ module.1 }}{{ module.0 }}
diff --git a/topologie/templates/topologie/index_module.html b/topologie/templates/topologie/index_module.html index 5c4c5c7c..d9cc2925 100644 --- a/topologie/templates/topologie/index_module.html +++ b/topologie/templates/topologie/index_module.html @@ -35,7 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Add a module" %}
{% acl_end %} - {% include "topologie/aff_modules.html" with module_list=module_list %} + {% include "topologie/aff_modules.html" with module_list=module_list modular_switchs=modular_switchs %}


diff --git a/topologie/views.py b/topologie/views.py index 5174f05d..55f0a060 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -325,12 +325,14 @@ def index_model_switch(request): def index_module(request): """Display all modules of switchs""" module_list = ModuleSwitch.objects.all() + modular_switchs = Switch.objects.filter(model__is_modular=True) pagination_number = GeneralOption.get_cached_value('pagination_number') module_list = re2o_paginator(request, module_list, pagination_number) return render( request, 'topologie/index_module.html', - {'module_list': module_list} + {'module_list': module_list, + 'modular_switchs': modular_switchs} ) From 64301bda9f5e369e3f38a6e74b662f3e6f2e7478 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sun, 30 Dec 2018 19:22:43 +0100 Subject: [PATCH 32/73] Export list_modules + return [] if no models for modules --- api/serializers.py | 3 ++- topologie/models.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/api/serializers.py b/api/serializers.py index e7b23f32..af92e0d0 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -811,7 +811,8 @@ class SwitchPortSerializer(serializers.ModelSerializer): model = topologie.Switch fields = ('short_name', 'model', 'switchbay', 'ports', 'ipv4', 'ipv6', 'interfaces_subnet', 'interfaces6_subnet', 'automatic_provision', 'rest_enabled', - 'web_management_enabled', 'get_radius_key_value', 'get_management_cred_value') + 'web_management_enabled', 'get_radius_key_value', 'get_management_cred_value', + 'list_modules') # LOCAL EMAILS diff --git a/topologie/models.py b/topologie/models.py index b2c75f24..fd054c43 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -372,7 +372,7 @@ class Switch(AclMixin, Machine): def list_modules(self): """Return modules of that switch, list of dict (rank, reference)""" modules = [] - if self.model.is_modular: + if getattr(self.model, 'is_modular', None): if self.model.is_itself_module: modules.append((1, self.model.reference)) for module_of_self in self.moduleonswitch_set.all(): From 80e20d0f91324c0c0f21fb23a83994b12c73c0b5 Mon Sep 17 00:00:00 2001 From: klafyvel Date: Tue, 1 Jan 2019 20:31:36 +0100 Subject: [PATCH 33/73] English is a beautiful language --- preferences/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/preferences/models.py b/preferences/models.py index e8476354..104c261d 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -278,7 +278,7 @@ class OptionalTopologie(AclMixin, PreferencesModel): log_servers = Role.all_interfaces_for_roletype("log-server").filter(type__ip_type=self.switchs_ip_type) radius_servers = Role.all_interfaces_for_roletype("radius-server").filter(type__ip_type=self.switchs_ip_type) dhcp_servers = Role.all_interfaces_for_roletype("dhcp-server") - dns_recursive_servers = Role.all_interfaces_for_roletype("dns-recursif-server").filter(type__ip_type=self.switchs_ip_type) + dns_recursive_servers = Role.all_interfaces_for_roletype("dns-recursive-server").filter(type__ip_type=self.switchs_ip_type) subnet = None subnet6 = None if self.switchs_ip_type: From 80b8779c5579273ecc3b576fff18b821c19b8d26 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Thu, 3 Jan 2019 00:54:13 +0100 Subject: [PATCH 34/73] dns-recursif-server -> dns-recursive-server --- machines/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/machines/models.py b/machines/models.py index 1cf840d7..a4685676 100644 --- a/machines/models.py +++ b/machines/models.py @@ -1612,7 +1612,7 @@ class Role(RevMixin, AclMixin, models.Model): ROLE = ( ('dhcp-server', _("DHCP server")), ('switch-conf-server', _("Switches configuration server")), - ('dns-recursif-server', _("Recursive DNS server")), + ('dns-recursive-server', _("Recursive DNS server")), ('ntp-server', _("NTP server")), ('radius-server', _("RADIUS server")), ('log-server', _("Log server")), From 2e3be7ad56f7c430e5a8ee98d1e0b4beb8466445 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Thu, 3 Jan 2019 00:54:54 +0100 Subject: [PATCH 35/73] migrations for recursive dns --- .../migrations/0098_auto_20190102_1745.py | 20 ++++++++++++++ .../migrations/0099_role_recursive_dns.py | 26 +++++++++++++++++++ .../migrations/0100_auto_20190102_1753.py | 20 ++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 machines/migrations/0098_auto_20190102_1745.py create mode 100644 machines/migrations/0099_role_recursive_dns.py create mode 100644 machines/migrations/0100_auto_20190102_1753.py diff --git a/machines/migrations/0098_auto_20190102_1745.py b/machines/migrations/0098_auto_20190102_1745.py new file mode 100644 index 00000000..e886e8a1 --- /dev/null +++ b/machines/migrations/0098_auto_20190102_1745.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2019-01-02 23:45 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0097_extension_dnssec'), + ] + + operations = [ + migrations.AlterField( + model_name='role', + name='specific_role', + field=models.CharField(blank=True, choices=[('dhcp-server', 'DHCP server'), ('switch-conf-server', 'Switches configuration server'), ('dns-recursif-server', 'Recursive DNS server'), ('dns-recursive-server', 'Recursive DNS server'), ('ntp-server', 'NTP server'), ('radius-server', 'RADIUS server'), ('log-server', 'Log server'), ('ldap-master-server', 'LDAP master server'), ('ldap-backup-server', 'LDAP backup server'), ('smtp-server', 'SMTP server'), ('postgresql-server', 'postgreSQL server'), ('mysql-server', 'mySQL server'), ('sql-client', 'SQL client'), ('gateway', 'Gateway')], max_length=32, null=True), + ), + ] diff --git a/machines/migrations/0099_role_recursive_dns.py b/machines/migrations/0099_role_recursive_dns.py new file mode 100644 index 00000000..c1ce3965 --- /dev/null +++ b/machines/migrations/0099_role_recursive_dns.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2019-01-02 23:45 +from __future__ import unicode_literals + +from django.db import migrations, models + + +def migrate(apps, schema_editor): + Role = apps.get_model('machines', 'Role') + + for role in Role.objects.filter(specific_role='dns-recursif-server'): + role.specific_role = 'dns-recursive-server' + role.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0098_auto_20190102_1745'), + ] + + operations = [ + migrations.RunPython(migrate), + ] + + diff --git a/machines/migrations/0100_auto_20190102_1753.py b/machines/migrations/0100_auto_20190102_1753.py new file mode 100644 index 00000000..35f7b78d --- /dev/null +++ b/machines/migrations/0100_auto_20190102_1753.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2019-01-02 23:53 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0099_role_recursive_dns'), + ] + + operations = [ + migrations.AlterField( + model_name='role', + name='specific_role', + field=models.CharField(blank=True, choices=[('dhcp-server', 'DHCP server'), ('switch-conf-server', 'Switches configuration server'), ('dns-recursive-server', 'Recursive DNS server'), ('ntp-server', 'NTP server'), ('radius-server', 'RADIUS server'), ('log-server', 'Log server'), ('ldap-master-server', 'LDAP master server'), ('ldap-backup-server', 'LDAP backup server'), ('smtp-server', 'SMTP server'), ('postgresql-server', 'postgreSQL server'), ('mysql-server', 'mySQL server'), ('sql-client', 'SQL client'), ('gateway', 'Gateway')], max_length=32, null=True), + ), + ] From af714a7f331982a311a3aca76926c1a928e3edcb Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Thu, 3 Jan 2019 01:02:02 +0100 Subject: [PATCH 36/73] typo --- .../migrations/0068_auto_20190102_1758.py | 20 +++++++++++++++++++ topologie/models.py | 14 ++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 topologie/migrations/0068_auto_20190102_1758.py diff --git a/topologie/migrations/0068_auto_20190102_1758.py b/topologie/migrations/0068_auto_20190102_1758.py new file mode 100644 index 00000000..b03e7ae5 --- /dev/null +++ b/topologie/migrations/0068_auto_20190102_1758.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2019-01-02 23:58 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('topologie', '0067_auto_20181230_1819'), + ] + + operations = [ + migrations.AlterField( + model_name='modelswitch', + name='is_itself_module', + field=models.BooleanField(default=False, help_text='Is the switch, itself, considered as a module'), + ), + ] diff --git a/topologie/models.py b/topologie/models.py index fd054c43..e05fa50e 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -251,7 +251,7 @@ class Switch(AclMixin, Machine): default=False, help_text='Provision automatique de ce switch', ) - + class Meta: unique_together = ('stack', 'stack_member_id') @@ -404,11 +404,11 @@ class ModelSwitch(AclMixin, RevMixin, models.Model): is_modular = models.BooleanField( default=False, help_text=_("Is this switch model modular"), - ) + ) is_itself_module = models.BooleanField( default=False, - help_text=_("Does the switch, itself, considered as a module"), - ) + help_text=_("Is the switch, itself, considered as a module"), + ) class Meta: permissions = ( @@ -429,14 +429,14 @@ class ModuleSwitch(AclMixin, RevMixin, models.Model): reference = models.CharField( max_length=255, help_text=_("Reference of a module"), - verbose_name=_("Module reference") + verbose_name=_("Module reference") ) comment = models.CharField( max_length=255, null=True, blank=True, help_text=_("Comment"), - verbose_name=_("Comment") + verbose_name=_("Comment") ) class Meta: @@ -457,7 +457,7 @@ class ModuleOnSwitch(AclMixin, RevMixin, models.Model): slot = models.CharField( max_length=15, help_text=_("Slot on switch"), - verbose_name=_("Slot") + verbose_name=_("Slot") ) class Meta: From edf89dac982e4bca3a41134f768399c1c05b6902 Mon Sep 17 00:00:00 2001 From: detraz Date: Fri, 4 Jan 2019 12:31:10 +0100 Subject: [PATCH 37/73] Fix crash of optionaltopologie serializer --- api/serializers.py | 16 ++++++++++++++-- api/urls.py | 1 + api/views.py | 11 +++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/api/serializers.py b/api/serializers.py index af92e0d0..8c22ed21 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -391,13 +391,25 @@ class OptionalTopologieSerializer(NamespacedHMSerializer): class Meta: model = preferences.OptionalTopologie - fields = ('radius_general_policy', 'vlan_decision_ok', - 'vlan_decision_nok', 'switchs_ip_type', 'switchs_web_management', + fields = ('switchs_ip_type', 'switchs_web_management', 'switchs_web_management_ssl', 'switchs_rest_management', 'switchs_management_utils', 'switchs_management_interface_ip', 'provision_switchs_enabled', 'switchs_provision', 'switchs_management_sftp_creds') +class RadiusOptionSerializer(NamespacedHMSerializer): + """Serialize `preferences.models.RadiusOption` objects + """ + + class Meta: + model = preferences.RadiusOption + fields = ('radius_general_policy', 'unknown_machine', + 'unknown_machine_vlan', 'unknown_port', + 'unknown_port_vlan', 'unknown_room', 'unknown_room_vlan', + 'non_member', 'non_member_vlan', 'banned', 'banned_vlan', + 'vlan_decision_ok') + + class GeneralOptionSerializer(NamespacedHMSerializer): """Serialize `preferences.models.GeneralOption` objects. """ diff --git a/api/urls.py b/api/urls.py index 723ca78c..4a34c1de 100644 --- a/api/urls.py +++ b/api/urls.py @@ -67,6 +67,7 @@ router.register_viewset(r'machines/role', views.RoleViewSet) router.register_view(r'preferences/optionaluser', views.OptionalUserView), router.register_view(r'preferences/optionalmachine', views.OptionalMachineView), router.register_view(r'preferences/optionaltopologie', views.OptionalTopologieView), +router.register_view(r'preferences/radiusoption', views.RadiusOptionView), router.register_view(r'preferences/generaloption', views.GeneralOptionView), router.register_viewset(r'preferences/service', views.HomeServiceViewSet, base_name='homeservice'), router.register_view(r'preferences/assooption', views.AssoOptionView), diff --git a/api/views.py b/api/views.py index 21f7b438..8f7b9c1f 100644 --- a/api/views.py +++ b/api/views.py @@ -292,6 +292,17 @@ class OptionalTopologieView(generics.RetrieveAPIView): return preferences.OptionalTopologie.objects.first() +class RadiusOptionView(generics.RetrieveAPIView): + """Exposes details of `preferences.models.OptionalTopologie` settings. + """ + permission_classes = (ACLPermission,) + perms_map = {'GET': [preferences.RadiusOption.can_view_all]} + serializer_class = serializers.RadiusOptionSerializer + + def get_object(self): + return preferences.RadiusOption.objects.first() + + class GeneralOptionView(generics.RetrieveAPIView): """Exposes details of `preferences.models.GeneralOption` settings. """ From 20e1ee3bb47dc123cdbd031e0fdf4872364a1a49 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sat, 5 Jan 2019 16:19:38 +0100 Subject: [PATCH 38/73] A granted user can set active at creation --- users/forms.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/users/forms.py b/users/forms.py index 81c31cae..effcc60c 100644 --- a/users/forms.py +++ b/users/forms.py @@ -387,6 +387,20 @@ class AdherentCreationForm(AdherentForm): #gtu_check.label = mark_safe("{} {}{}".format( # _("I commit to accept the"), GeneralOption.get_cached_value('GTU'), _("General Terms of Use"), _("."))) + class Meta: + model = Adherent + fields = [ + 'name', + 'surname', + 'pseudo', + 'email', + 'school', + 'comment', + 'telephone', + 'room', + 'state', + ] + def __init__(self, *args, **kwargs): super(AdherentCreationForm, self).__init__(*args, **kwargs) From 0b1c35900fbec6d815a7f9e4a37993a290344619 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sat, 5 Jan 2019 18:32:54 +0100 Subject: [PATCH 39/73] =?UTF-8?q?Ajoute=20un=20reglage=20pour=20set=20tous?= =?UTF-8?q?=20les=20comptes=20actifs=20=C3=A0=20l'initialisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0057_optionaluser_all_users_active.py | 20 +++++++++++++++++++ preferences/models.py | 5 +++++ .../preferences/display_preferences.html | 4 ++++ users/forms.py | 1 + users/models.py | 2 +- 5 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 preferences/migrations/0057_optionaluser_all_users_active.py diff --git a/preferences/migrations/0057_optionaluser_all_users_active.py b/preferences/migrations/0057_optionaluser_all_users_active.py new file mode 100644 index 00000000..3f0cc8c1 --- /dev/null +++ b/preferences/migrations/0057_optionaluser_all_users_active.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2019-01-05 17:15 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('preferences', '0056_4_radiusoption'), + ] + + operations = [ + migrations.AddField( + model_name='optionaluser', + name='all_users_active', + field=models.BooleanField(default=False, help_text='If True, all new created and connected users are active. If False, only when a valid registration has been paid'), + ), + ] diff --git a/preferences/models.py b/preferences/models.py index 104c261d..228807a6 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -116,6 +116,11 @@ class OptionalUser(AclMixin, PreferencesModel): default=False, help_text=_("A new user can create their account on Re2o") ) + all_users_active = models.BooleanField( + default=False, + help_text=_("If True, all new created and connected users are active.\ + If False, only when a valid registration has been paid") + ) class Meta: permissions = ( diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html index 0e34d6e9..e4321f5b 100644 --- a/preferences/templates/preferences/display_preferences.html +++ b/preferences/templates/preferences/display_preferences.html @@ -122,6 +122,10 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Delete not yet active users after" %} {{ useroptions.delete_notyetactive }} days + + {% trans "All users are active by default" %} + {{ useroptions.all_users_active|tick }} +

{% trans "Users general permissions" %}

diff --git a/users/forms.py b/users/forms.py index effcc60c..d4110dcd 100644 --- a/users/forms.py +++ b/users/forms.py @@ -117,6 +117,7 @@ class PassForm(FormRevMixin, FieldPermissionFormMixin, forms.ModelForm): """Changement du mot de passe""" user = super(PassForm, self).save(commit=False) user.set_password(self.cleaned_data.get("passwd1")) + user.set_active() user.save() diff --git a/users/models.py b/users/models.py index e4c25956..c5287fb6 100755 --- a/users/models.py +++ b/users/models.py @@ -337,7 +337,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, def set_active(self): """Enable this user if he subscribed successfully one time before""" if self.state == self.STATE_NOT_YET_ACTIVE: - if self.facture_set.filter(valid=True).filter(Q(vente__type_cotisation='All') | Q(vente__type_cotisation='Adhesion')).exists(): + if self.facture_set.filter(valid=True).filter(Q(vente__type_cotisation='All') | Q(vente__type_cotisation='Adhesion')).exists() or OptionalUser.get_cached_value('all_users_active'): self.state = self.STATE_ACTIVE self.save() From 84889388c9bec59ec1dfd7007d2d86dddfe03cd3 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Sat, 5 Jan 2019 20:11:36 +0100 Subject: [PATCH 40/73] Avoid crash when 'email' field is not here --- users/models.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/users/models.py b/users/models.py index c5287fb6..a2798207 100755 --- a/users/models.py +++ b/users/models.py @@ -1026,17 +1026,12 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, ): raise ValidationError("This pseudo is already in use.") if not self.local_email_enabled and not self.email and not (self.state == self.STATE_ARCHIVE): - raise ValidationError( - {'email': ( - _("There is neither a local email address nor an external" + 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( - {'local_email_redirect': ( - _("You can't redirect your local emails if no external email" - " address has been set.")), } + raise ValidationError(_("You can't redirect your local emails if no external email" + " address has been set.") ) def __str__(self): From 2524c09e8e5036398076e6a2ebb5ba155d0f7a0b Mon Sep 17 00:00:00 2001 From: Grizzly Date: Mon, 10 Dec 2018 20:50:48 +0000 Subject: [PATCH 41/73] Exclusion d'users, anonymisation machine et domaines --- users/management/commands/anonymize.py | 114 +++++++++++++++---------- 1 file changed, 68 insertions(+), 46 deletions(-) diff --git a/users/management/commands/anonymize.py b/users/management/commands/anonymize.py index d2632576..e057cf24 100644 --- a/users/management/commands/anonymize.py +++ b/users/management/commands/anonymize.py @@ -1,71 +1,93 @@ from django.core.management.base import BaseCommand from users.models import User, School, Adherent, Club +from machines.models import Domain, Machine from django.db.models import F, Value +from django.db.models import Q from django.db.models.functions import Concat from re2o.login import hashNT, makeSecret import os, random, string +from random import randint class Command(BaseCommand): - help="Anonymize the data in the database in order to use them on critical servers (dev, personnal...). Every information will be overwritten using non-personnal informations. This script must follow any modification of the database." + help="Anonymize the data in the database in order to use them on critical servers (dev, personnal...). Every information will be overwritten using non-personnal informations. This script must follow any modification of the database.\nOptionnal argument: {id|id|id|...} to exclude users from anonymisation" + + def add_arguments(self, parser): + parser.add_argument('user_id', nargs='+', type=int, help='User ID') def handle(self, *args, **kwargs): + users_ids = kwargs['user_id'] + for user_id in users_ids: + self.stdout.write("User: {} will not be anonymised".format(User.objects.filter(id=user_id).get().name)) + + self.stdout.write(self.style.WARNING('\nDISCLAIMER\nThis function will make your database unusable for production. Are you sure you want to run this ?(doit): ')) + if(input()=="doit"): - total = Adherent.objects.count() - self.stdout.write("Starting anonymizing the {} users data.".format(total)) - - u = User.objects.all() - a = Adherent.objects.all() - c = Club.objects.all() + total = Adherent.objects.count() + self.stdout.write("Starting anonymizing the {} users data.".format(total)) + + u = User.objects.filter(~Q(id__in=users_ids)) + a = Adherent.objects.filter(~Q(id__in=users_ids)) + c = Club.objects.filter(~Q(id__in=users_ids)) + d = Domain.objects.all() + m = Machine.objects.filter(~Q(user_id__in=users_ids)) - self.stdout.write('Supression de l\'école...') - # Create a fake School to put everyone in it. - ecole = School(name="Ecole des Ninja") - ecole.save() - u.update(school=ecole) - self.stdout.write(self.style.SUCCESS('done ...')) + self.stdout.write('Supression de l\'école...') + # Create a fake School to put everyone in it. + ecole = School(name="Ecole des Ninja") + ecole.save() + u.update(school=ecole) + self.stdout.write(self.style.SUCCESS('done ...')) - self.stdout.write('Supression des chambres...') - a.update(room=None) - c.update(room=None) - self.stdout.write(self.style.SUCCESS('done ...')) + self.stdout.write('Supression des chambres...') + a.update(room=None) + c.update(room=None) + self.stdout.write(self.style.SUCCESS('done ...')) - self.stdout.write('Supression des mails...') - u.update(email='example@example.org', - local_email_redirect = False, - local_email_enabled=False) - self.stdout.write(self.style.SUCCESS('done ...')) + self.stdout.write('Supression des mails...') + u.update(email='example@example.org', + local_email_redirect = False, + local_email_enabled=False) + self.stdout.write(self.style.SUCCESS('done ...')) - self.stdout.write('Supression des noms, prenoms, pseudo, telephone, commentaire...') - a.update(name=Concat(Value('name of '), 'id')) - self.stdout.write(self.style.SUCCESS('done name')) + self.stdout.write('Supression des noms, prenoms, pseudo, telephone, commentaire...') + a.update(name=Concat(Value('name of '), 'id')) + self.stdout.write(self.style.SUCCESS('done name')) - a.update(surname=Concat(Value('surname of '), 'id')) - self.stdout.write(self.style.SUCCESS('done surname')) + a.update(surname=Concat(Value('surname of '), 'id')) + self.stdout.write(self.style.SUCCESS('done surname')) - u.update(pseudo=F('id')) - self.stdout.write(self.style.SUCCESS('done pseudo')) + u.update(pseudo=F('id')) + self.stdout.write(self.style.SUCCESS('done pseudo')) - a.update(telephone=Concat(Value('phone of '), 'id')) - self.stdout.write(self.style.SUCCESS('done phone')) + a.update(telephone=Concat(Value('phone of '), 'id')) + self.stdout.write(self.style.SUCCESS('done phone')) - a.update(comment=Concat(Value('commentaire of '), 'id')) - self.stdout.write(self.style.SUCCESS('done ...')) + a.update(comment=Concat(Value('commentaire of '), 'id')) + self.stdout.write(self.style.SUCCESS('done ...')) + + self.stdout.write('Renommage des machines...') + m.update(name=Concat(Value('Machine '),F('id'),Value(' of '),F('user_id'))) + d.update(name=Concat(Value('Domaine id '),F('id'))) + self.stdout.write(self.style.SUCCESS('done ...')) - self.stdout.write('Unification du mot de passe...') - # Define the password - chars = string.ascii_letters + string.digits + '!@#$%^&*()' - taille = 20 - random.seed = (os.urandom(1024)) - password = "" - for i in range(taille): - password+=random.choice(chars) + self.stdout.write('Unification du mot de passe...') + # Define the password + chars = string.ascii_letters + string.digits + '!@#$%^&*()' + taille = 20 + random.seed = (os.urandom(1024)) + password = "" + for i in range(taille): + password+=random.choice(chars) - self.stdout.write(self.style.HTTP_NOT_MODIFIED('The password will be: {}'.format(password))) + self.stdout.write(self.style.HTTP_NOT_MODIFIED('The password will be: {}'.format(password))) - u.update(pwd_ntlm = hashNT(password)) - u.update(password = makeSecret(password)) - self.stdout.write(self.style.SUCCESS('done...')) + u.update(pwd_ntlm = hashNT(password)) + u.update(password = makeSecret(password)) + self.stdout.write(self.style.SUCCESS('done...')) - self.stdout.write("Data anonymized!") + self.stdout.write("Data anonymized!") + + else: + self.stdout.write("Anonymisation aborted") From cbd85ff0eb32ed59af3b90c6ba30e235e2d3db70 Mon Sep 17 00:00:00 2001 From: Grizzly Date: Wed, 9 Jan 2019 18:14:06 +0000 Subject: [PATCH 42/73] Suppression de l'historique --- users/management/commands/anonymize.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/users/management/commands/anonymize.py b/users/management/commands/anonymize.py index e057cf24..a6bce971 100644 --- a/users/management/commands/anonymize.py +++ b/users/management/commands/anonymize.py @@ -1,6 +1,7 @@ from django.core.management.base import BaseCommand from users.models import User, School, Adherent, Club from machines.models import Domain, Machine +from reversion.models import Revision from django.db.models import F, Value from django.db.models import Q from django.db.models.functions import Concat @@ -87,6 +88,10 @@ class Command(BaseCommand): u.update(password = makeSecret(password)) self.stdout.write(self.style.SUCCESS('done...')) + self.stdout.write('Suppression de l\'historique (This may take some time)') + Revision.objects.all().delete() + self.stdout.write(self.style.SUCCESS('done...')) + self.stdout.write("Data anonymized!") else: From dc83766b5c1f0080b5c038a6727eb76378d54c2f Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Thu, 10 Jan 2019 16:10:43 +0100 Subject: [PATCH 43/73] Case insensitive search --- freeradius_utils/auth.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freeradius_utils/auth.py b/freeradius_utils/auth.py index e605aea5..0e83b610 100644 --- a/freeradius_utils/auth.py +++ b/freeradius_utils/auth.py @@ -289,7 +289,7 @@ def check_user_machine_and_register(nas_type, username, mac_address): Renvoie le mot de passe ntlm de l'user si tout est ok Utilise pour les authentifications en 802.1X""" interface = Interface.objects.filter(mac_address=mac_address).first() - user = User.objects.filter(pseudo=username).first() + user = User.objects.filter(pseudo__iexact=username).first() if not user: return (False, u"User inconnu", '') if not user.has_access(): From 4721d8763cbba5e0675af5c68c75e4c74e804831 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Fri, 11 Jan 2019 14:10:34 +0100 Subject: [PATCH 44/73] Fix invoice edit page, discount title is only displayed when needed. --- cotisations/templates/cotisations/facture.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cotisations/templates/cotisations/facture.html b/cotisations/templates/cotisations/facture.html index 8a1a6d7a..efa7b06d 100644 --- a/cotisations/templates/cotisations/facture.html +++ b/cotisations/templates/cotisations/facture.html @@ -74,8 +74,8 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endfor %}
-

{% trans "Discount" %}

{% if discount_form %} +

{% trans "Discount" %}

{% bootstrap_form discount_form %} {% endif %}

From 2ea0d77eb2349a2946c0475923441701e6513adc Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Fri, 11 Jan 2019 14:02:32 +0100 Subject: [PATCH 45/73] Fix error message when failing to decode an aes_key. --- re2o/aes_field.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/re2o/aes_field.py b/re2o/aes_field.py index 5f50ddd2..eeab5e12 100644 --- a/re2o/aes_field.py +++ b/re2o/aes_field.py @@ -82,16 +82,22 @@ class AESEncryptedField(models.CharField): return None try: return decrypt(settings.AES_KEY, binascii.a2b_base64(value)).decode('utf-8') - except Exception as e: - raise ValueError(value) + except UnicodeDecodeError as e: + raise ValueError( + "Could not decode your field %s, your settings.AES_KEY " + "is probably wrong." % self.name + ) def from_db_value(self, value, *args, **kwargs): if value is None: return value try: return decrypt(settings.AES_KEY, binascii.a2b_base64(value)).decode('utf-8') - except Exception as e: - raise ValueError(value) + except UnicodeDecodeError as e: + raise ValueError( + "Could not decode your field %s, your settings.AES_KEY " + "is probably wrong." % self.name + ) def get_prep_value(self, value): if value is None: From c92b68872edbce98025beffc0cafce88da6e8223 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Fri, 11 Jan 2019 13:43:57 +0100 Subject: [PATCH 46/73] Fix radius options, force to set a vlan when adding a policy which requires it. --- preferences/forms.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/preferences/forms.py b/preferences/forms.py index fd052edd..7e644808 100644 --- a/preferences/forms.py +++ b/preferences/forms.py @@ -231,6 +231,27 @@ class EditRadiusOptionForm(ModelForm): model = RadiusOption fields = '__all__' + def clean(self): + cleaned_data = super().clean() + ignored=('radius_general_policy', 'vlan_decision_ok') + fields = ( + f for f in self.fields.keys() + if 'vlan' not in f and f not in ignored + ) + for f in fields: + choice = cleaned_data.get(f) + vlan = cleaned_data.get(f+'_vlan') + if choice == RadiusOption.SET_VLAN and vlan is None: + self.add_error( + f, + _("You chose to set vlan but did not set any VLAN."), + ) + self.add_error( + f+'_vlan', + _("Please, choose a VLAN."), + ) + return cleaned_data + class ServiceForm(ModelForm): """Edition, ajout de services sur la page d'accueil""" From 950272dc189ca88734a84a3f6efc603a809f574f Mon Sep 17 00:00:00 2001 From: Laouen Fernet Date: Wed, 9 Jan 2019 00:37:45 +0100 Subject: [PATCH 47/73] add translations for api/ --- api/acl.py | 5 ++-- api/authentication.py | 2 +- api/locale/fr/LC_MESSAGES/django.po | 40 +++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 api/locale/fr/LC_MESSAGES/django.po diff --git a/api/acl.py b/api/acl.py index 9107a25d..0c336281 100644 --- a/api/acl.py +++ b/api/acl.py @@ -28,7 +28,7 @@ done. from django.conf import settings from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import ugettext as _ def _create_api_permission(): @@ -71,4 +71,5 @@ def can_view(user): 'codename': settings.API_PERMISSION_CODENAME } can = user.has_perm('%(app_label)s.%(codename)s' % kwargs) - return can, None if can else _("You cannot see this application.") + return can, None if can else _("You don't have the right to see this" + " application.") diff --git a/api/authentication.py b/api/authentication.py index cbc72b76..d426db24 100644 --- a/api/authentication.py +++ b/api/authentication.py @@ -46,6 +46,6 @@ class ExpiringTokenAuthentication(TokenAuthentication): ) utc_now = datetime.datetime.now(datetime.timezone.utc) if token.created < utc_now - token_duration: - raise exceptions.AuthenticationFailed(_('Token has expired')) + raise exceptions.AuthenticationFailed(_("The token has expired.")) return token.user, token diff --git a/api/locale/fr/LC_MESSAGES/django.po b/api/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 00000000..f2d6755e --- /dev/null +++ b/api/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,40 @@ +# Re2o est un logiciel d'administration développé initiallement au rezometz. Il +# se veut agnostique au réseau considéré, de manière à être installable en +# quelques clics. +# +# Copyright © 2018 Maël Kervella +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +msgid "" +msgstr "" +"Project-Id-Version: 2.5\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-01-08 23:06+0100\n" +"PO-Revision-Date: 2019-01-07 01:37+0100\n" +"Last-Translator: Laouen Fernet \n" +"Language-Team: \n" +"Language: fr_FR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: acl.py:74 +msgid "You don't have the right to see this application." +msgstr "Vous n'avez pas le droit de voir cette application." + +#: authentication.py:49 +msgid "The token has expired." +msgstr "Le jeton a expiré." From 2012f20352216c73939c92aee3c06ec25b0a54e7 Mon Sep 17 00:00:00 2001 From: Laouen Fernet Date: Wed, 9 Jan 2019 00:38:53 +0100 Subject: [PATCH 48/73] add translations for cotisations/ --- cotisations/forms.py | 6 +- cotisations/locale/fr/LC_MESSAGES/django.po | 437 +++++++++++------- cotisations/models.py | 2 +- .../payment_methods/note_kfet/views.py | 4 +- .../templates/cotisations/aff_article.html | 4 +- .../cotisations/aff_cost_estimate.html | 6 +- .../cotisations/aff_cotisations.html | 4 +- .../cotisations/aff_custom_invoice.html | 8 +- .../templates/cotisations/aff_paiement.html | 4 +- .../templates/cotisations/control.html | 6 +- cotisations/templates/cotisations/delete.html | 2 +- .../templates/cotisations/edit_facture.html | 4 +- .../templates/cotisations/facture.html | 2 +- cotisations/templates/cotisations/index.html | 2 +- .../templates/cotisations/index_article.html | 4 +- .../templates/cotisations/index_banque.html | 4 +- .../cotisations/index_cost_estimate.html | 6 +- .../cotisations/index_custom_invoice.html | 6 +- .../templates/cotisations/index_paiement.html | 2 +- .../templates/cotisations/payment.html | 2 +- .../templates/cotisations/sidebar.html | 20 +- cotisations/views.py | 8 +- 22 files changed, 323 insertions(+), 220 deletions(-) diff --git a/cotisations/forms.py b/cotisations/forms.py index 57bd7355..2eae5287 100644 --- a/cotisations/forms.py +++ b/cotisations/forms.py @@ -116,7 +116,7 @@ class DiscountForm(Form): Form used in oder to create a discount on an invoice. """ is_relative = forms.BooleanField( - label=_("Discount is on percentage"), + label=_("Discount is on percentage."), required=False, ) discount = forms.DecimalField( @@ -310,8 +310,8 @@ class RechargeForm(FormRevMixin, Form): if balance_method.maximum_balance is not None and \ value + self.user.solde > balance_method.maximum_balance: raise forms.ValidationError( - _("Requested amount is too high. Your balance can't exceed \ - %(max_online_balance)s €.") % { + _("Requested amount is too high. Your balance can't exceed" + " %(max_online_balance)s €.") % { 'max_online_balance': balance_method.maximum_balance } ) diff --git a/cotisations/locale/fr/LC_MESSAGES/django.po b/cotisations/locale/fr/LC_MESSAGES/django.po index 15f6a057..2c29dc8d 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: 2018-08-18 13:17+0200\n" +"POT-Creation-Date: 2019-01-12 16:50+0100\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n" "Last-Translator: Laouen Fernet \n" "Language: fr_FR\n" @@ -33,79 +33,98 @@ msgstr "" msgid "You don't have the right to view this application." msgstr "Vous n'avez pas le droit de voir cette application." -#: forms.py:63 forms.py:274 +#: forms.py:66 forms.py:299 msgid "Select a payment method" msgstr "Sélectionnez un moyen de paiement" -#: forms.py:66 models.py:510 +#: forms.py:69 models.py:579 msgid "Member" msgstr "Adhérent" -#: forms.py:68 +#: forms.py:71 msgid "Select the proprietary member" msgstr "Sélectionnez l'adhérent propriétaire" -#: forms.py:69 +#: forms.py:72 msgid "Validated invoice" msgstr "Facture validée" -#: forms.py:82 +#: forms.py:85 msgid "A payment method must be specified." msgstr "Un moyen de paiement doit être renseigné." -#: forms.py:96 forms.py:120 templates/cotisations/aff_article.html:33 -#: templates/cotisations/facture.html:61 +#: forms.py:97 templates/cotisations/aff_article.html:33 +#: templates/cotisations/facture.html:67 msgid "Article" msgstr "Article" -#: forms.py:100 forms.py:124 templates/cotisations/edit_facture.html:46 +#: forms.py:101 templates/cotisations/edit_facture.html:50 msgid "Quantity" msgstr "Quantité" -#: forms.py:154 +#: forms.py:119 +msgid "Discount is on percentage." +msgstr "La réduction est en pourcentage." + +#: forms.py:123 templates/cotisations/facture.html:78 +msgid "Discount" +msgstr "Réduction" + +#: forms.py:140 +#, python-format +msgid "{}% discount" +msgstr "{}% de réduction" + +#: forms.py:140 +msgid "{}€ discount" +msgstr "{}€ de réduction" + +#: forms.py:179 msgid "Article name" msgstr "Nom de l'article" -#: forms.py:164 templates/cotisations/sidebar.html:50 +#: forms.py:189 templates/cotisations/sidebar.html:55 msgid "Available articles" msgstr "Articles disponibles" -#: forms.py:192 +#: forms.py:217 msgid "Payment method name" msgstr "Nom du moyen de paiement" -#: forms.py:204 +#: forms.py:229 msgid "Available payment methods" msgstr "Moyens de paiement disponibles" -#: forms.py:230 +#: forms.py:255 msgid "Bank name" msgstr "Nom de la banque" -#: forms.py:242 +#: forms.py:267 msgid "Available banks" msgstr "Banques disponibles" -#: forms.py:261 +#: forms.py:286 msgid "Amount" msgstr "Montant" -#: forms.py:267 templates/cotisations/aff_cotisations.html:44 +#: forms.py:292 templates/cotisations/aff_cost_estimate.html:42 +#: templates/cotisations/aff_cotisations.html:44 #: templates/cotisations/aff_custom_invoice.html:42 #: templates/cotisations/control.html:66 msgid "Payment method" msgstr "Moyen de paiement" -#: forms.py:287 +#: forms.py:313 #, python-format msgid "" -"Requested amount is too high. Your balance can't exceed " +"Requested amount is too high. Your balance can't exceed " "%(max_online_balance)s €." msgstr "" -"Le montant demandé trop grand. Votre solde ne peut excéder " +"Le montant demandé est trop grand. Votre solde ne peut excéder " "%(max_online_balance)s €." -#: models.py:60 templates/cotisations/aff_cotisations.html:48 +#: models.py:60 templates/cotisations/aff_cost_estimate.html:46 +#: templates/cotisations/aff_cotisations.html:48 #: templates/cotisations/aff_custom_invoice.html:46 #: templates/cotisations/control.html:70 msgid "Date" @@ -133,9 +152,9 @@ msgstr "Peut voir un objet facture" #: models.py:158 msgid "Can edit all the previous invoices" -msgstr "Peut modifier toutes les factures existantes" +msgstr "Peut modifier toutes les factures précédentes" -#: models.py:160 models.py:305 +#: models.py:160 models.py:373 msgid "invoice" msgstr "facture" @@ -156,128 +175,149 @@ msgid "" "You don't have the right to edit an invoice already controlled or " "invalidated." msgstr "" -"Vous n'avez pas le droit de modifier une facture précedemment contrôlée ou " +"Vous n'avez pas le droit de modifier une facture précédemment contrôlée ou " "invalidée." #: models.py:184 msgid "You don't have the right to delete an invoice." msgstr "Vous n'avez pas le droit de supprimer une facture." -#: models.py:186 +#: models.py:187 msgid "You don't have the right to delete this user's invoices." msgstr "Vous n'avez pas le droit de supprimer les factures de cet utilisateur." -#: models.py:189 +#: models.py:191 msgid "" "You don't have the right to delete an invoice already controlled or " "invalidated." msgstr "" -"Vous n'avez pas le droit de supprimer une facture précedement contrôlée ou " +"Vous n'avez pas le droit de supprimer une facture précédemment contrôlée ou " "invalidée." -#: models.py:197 +#: models.py:199 msgid "You don't have the right to view someone else's invoices history." msgstr "" "Vous n'avez pas le droit de voir l'historique des factures d'un autre " "utilisateur." -#: models.py:200 +#: models.py:202 msgid "The invoice has been invalidated." msgstr "La facture a été invalidée." -#: models.py:210 +#: models.py:214 msgid "You don't have the right to edit the \"controlled\" state." msgstr "Vous n'avez pas le droit de modifier le statut \"contrôlé\"." -#: models.py:224 +#: models.py:228 msgid "There are no payment method which you can use." msgstr "Il n'y a pas de moyen de paiement que vous puissiez utiliser." -#: models.py:226 +#: models.py:230 msgid "There are no article that you can buy." msgstr "Il n'y a pas d'article que vous puissiez acheter." -#: models.py:261 +#: models.py:272 msgid "Can view a custom invoice object" msgstr "Peut voir un objet facture personnalisée" -#: models.py:265 templates/cotisations/aff_custom_invoice.html:36 +#: models.py:276 templates/cotisations/aff_cost_estimate.html:36 +#: templates/cotisations/aff_custom_invoice.html:36 msgid "Recipient" msgstr "Destinataire" -#: models.py:269 templates/cotisations/aff_paiement.html:33 +#: models.py:280 templates/cotisations/aff_paiement.html:33 msgid "Payment type" msgstr "Type de paiement" -#: models.py:273 +#: models.py:284 msgid "Address" msgstr "Adresse" -#: models.py:276 templates/cotisations/aff_custom_invoice.html:54 +#: models.py:287 templates/cotisations/aff_custom_invoice.html:54 msgid "Paid" msgstr "Payé" -#: models.py:296 models.py:516 models.py:764 +#: models.py:291 +msgid "Remark" +msgstr "Remarque" + +#: models.py:300 +msgid "Can view a cost estimate object" +msgstr "Peut voir un objet devis" + +#: models.py:303 +msgid "Period of validity" +msgstr "Période de validité" + +#: models.py:340 +msgid "You don't have the right to delete a cost estimate." +msgstr "Vous n'avez pas le droit de supprimer un devis." + +#: models.py:343 +msgid "The cost estimate has an invoice and can't be deleted." +msgstr "Le devis a une facture et ne peut pas être supprimé." + +#: models.py:364 models.py:585 models.py:852 msgid "Connection" msgstr "Connexion" -#: models.py:297 models.py:517 models.py:765 +#: models.py:365 models.py:586 models.py:853 msgid "Membership" msgstr "Adhésion" -#: models.py:298 models.py:512 models.py:518 models.py:766 +#: models.py:366 models.py:581 models.py:587 models.py:854 msgid "Both of them" msgstr "Les deux" -#: models.py:310 +#: models.py:378 msgid "amount" msgstr "montant" -#: models.py:315 +#: models.py:383 msgid "article" msgstr "article" -#: models.py:322 +#: models.py:390 msgid "price" msgstr "prix" -#: models.py:327 models.py:535 +#: models.py:395 models.py:604 msgid "duration (in months)" msgstr "durée (en mois)" -#: models.py:335 models.py:549 models.py:780 +#: models.py:403 models.py:618 models.py:868 msgid "subscription type" msgstr "type de cotisation" -#: models.py:340 +#: models.py:408 msgid "Can view a purchase object" msgstr "Peut voir un objet achat" -#: models.py:341 +#: models.py:409 msgid "Can edit all the previous purchases" msgstr "Peut modifier tous les achats précédents" -#: models.py:343 models.py:774 +#: models.py:411 models.py:862 msgid "purchase" msgstr "achat" -#: models.py:344 +#: models.py:412 msgid "purchases" msgstr "achats" -#: models.py:411 models.py:573 +#: models.py:479 models.py:642 msgid "Duration must be specified for a subscription." msgstr "La durée de la cotisation doit être indiquée." -#: models.py:418 +#: models.py:486 msgid "You don't have the right to edit the purchases." msgstr "Vous n'avez pas le droit de modifier les achats." -#: models.py:423 +#: models.py:491 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." -#: models.py:427 +#: models.py:495 msgid "" "You don't have the right to edit a purchase already controlled or " "invalidated." @@ -285,150 +325,150 @@ msgstr "" "Vous n'avez pas le droit de modifier un achat précédemment contrôlé ou " "invalidé." -#: models.py:434 +#: models.py:502 msgid "You don't have the right to delete a purchase." msgstr "Vous n'avez pas le droit de supprimer un achat." -#: models.py:436 +#: models.py:504 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." -#: models.py:439 +#: models.py:507 msgid "" "You don't have the right to delete a purchase already controlled or " "invalidated." msgstr "" -"Vous n'avez pas le droit de supprimer un achat précédement contrôlé ou " +"Vous n'avez pas le droit de supprimer un achat précédemment contrôlé ou " "invalidé." -#: models.py:447 +#: models.py:515 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." -#: models.py:511 +#: models.py:580 msgid "Club" msgstr "Club" -#: models.py:523 +#: models.py:592 msgid "designation" msgstr "désignation" -#: models.py:529 +#: models.py:598 msgid "unit price" msgstr "prix unitaire" -#: models.py:541 +#: models.py:610 msgid "type of users concerned" msgstr "type d'utilisateurs concernés" -#: models.py:553 models.py:649 +#: models.py:622 models.py:733 msgid "is available for every user" msgstr "est disponible pour chaque utilisateur" -#: models.py:560 +#: models.py:629 msgid "Can view an article object" msgstr "Peut voir un objet article" -#: models.py:561 +#: models.py:630 msgid "Can buy every article" msgstr "Peut acheter chaque article" -#: models.py:569 +#: models.py:638 msgid "Balance is a reserved article name." msgstr "Solde est un nom d'article réservé." -#: models.py:594 +#: models.py:663 msgid "You can't buy this article." msgstr "Vous ne pouvez pas acheter cet article." -#: models.py:624 +#: models.py:708 msgid "Can view a bank object" msgstr "Peut voir un objet banque" -#: models.py:626 +#: models.py:710 msgid "bank" msgstr "banque" -#: models.py:627 +#: models.py:711 msgid "banks" msgstr "banques" -#: models.py:645 +#: models.py:729 msgid "method" msgstr "moyen" -#: models.py:654 +#: models.py:738 msgid "is user balance" msgstr "est solde utilisateur" -#: models.py:655 +#: models.py:739 msgid "There should be only one balance payment method." msgstr "Il ne devrait y avoir qu'un moyen de paiement solde." -#: models.py:661 +#: models.py:745 msgid "Can view a payment method object" msgstr "Peut voir un objet moyen de paiement" -#: models.py:662 +#: models.py:746 msgid "Can use every payment method" msgstr "Peut utiliser chaque moyen de paiement" -#: models.py:664 +#: models.py:748 msgid "payment method" msgstr "moyen de paiement" -#: models.py:665 +#: models.py:749 msgid "payment methods" msgstr "moyens de paiement" -#: models.py:699 payment_methods/comnpay/views.py:63 +#: models.py:787 payment_methods/comnpay/views.py:63 #, 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." -#: models.py:709 +#: models.py:797 msgid "The invoice was created." msgstr "La facture a été créée." -#: models.py:730 +#: models.py:818 msgid "You can't use this payment method." msgstr "Vous ne pouvez pas utiliser ce moyen de paiement." -#: models.py:748 +#: models.py:836 msgid "No custom payment method." msgstr "Pas de moyen de paiement personnalisé." -#: models.py:783 +#: models.py:871 msgid "start date" msgstr "date de début" -#: models.py:786 +#: models.py:874 msgid "end date" msgstr "date de fin" -#: models.py:791 +#: models.py:879 msgid "Can view a subscription object" msgstr "Peut voir un objet cotisation" -#: models.py:792 +#: models.py:880 msgid "Can edit the previous subscriptions" msgstr "Peut modifier les cotisations précédentes" -#: models.py:794 +#: models.py:882 msgid "subscription" msgstr "cotisation" -#: models.py:795 +#: models.py:883 msgid "subscriptions" msgstr "cotisations" -#: models.py:799 +#: models.py:887 msgid "You don't have the right to edit a subscription." msgstr "Vous n'avez pas le droit de modifier une cotisation." -#: models.py:803 +#: models.py:891 msgid "" "You don't have the right to edit a subscription already controlled or " "invalidated." @@ -436,11 +476,11 @@ msgstr "" "Vous n'avez pas le droit de modifier une cotisation précédemment contrôlée " "ou invalidée." -#: models.py:810 +#: models.py:898 msgid "You don't have the right to delete a subscription." msgstr "Vous n'avez pas le droit de supprimer une cotisation." -#: models.py:813 +#: models.py:901 msgid "" "You don't have the right to delete a subscription already controlled or " "invalidated." @@ -448,7 +488,7 @@ msgstr "" "Vous n'avez pas le droit de supprimer une cotisation précédemment contrôlée " "ou invalidée." -#: models.py:821 +#: models.py:909 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 " @@ -482,11 +522,11 @@ msgstr "Le montant maximal d'argent autorisé pour le solde." msgid "Allow user to credit their balance" msgstr "Autorise l'utilisateur à créditer son solde" -#: payment_methods/balance/models.py:81 payment_methods/balance/models.py:112 +#: payment_methods/balance/models.py:79 payment_methods/balance/models.py:110 msgid "Your balance is too low for this operation." msgstr "Votre solde est trop bas pour cette opération." -#: payment_methods/balance/models.py:99 validators.py:20 +#: payment_methods/balance/models.py:97 validators.py:20 msgid "There is already a payment method for user balance." msgstr "Il y a déjà un moyen de paiement pour le solde utilisateur." @@ -523,11 +563,11 @@ msgstr "" msgid "Production mode enabled (production URL, instead of homologation)" msgstr "Mode production activé (URL de production, au lieu d'homologation)" -#: payment_methods/comnpay/models.py:104 +#: payment_methods/comnpay/models.py:102 msgid "Pay invoice number " msgstr "Payer la facture numéro " -#: payment_methods/comnpay/models.py:116 +#: payment_methods/comnpay/models.py:114 msgid "" "In order to pay your invoice with ComNpay, the price must be greater than {} " "€." @@ -559,6 +599,30 @@ msgstr "" msgid "no" msgstr "non" +#: payment_methods/note_kfet/forms.py:32 +msgid "pseudo note" +msgstr "pseudo note" + +#: payment_methods/note_kfet/forms.py:35 +msgid "Password" +msgstr "Mot de passe" + +#: payment_methods/note_kfet/models.py:40 +msgid "NoteKfet" +msgstr "NoteKfet" + +#: payment_methods/note_kfet/models.py:50 +msgid "server" +msgstr "serveur" + +#: payment_methods/note_kfet/views.py:60 +msgid "Unknown error." +msgstr "Erreur inconnue." + +#: payment_methods/note_kfet/views.py:88 +msgid "The payment with note was done." +msgstr "Le paiement par note a été effectué." + #: templates/cotisations/aff_article.html:34 msgid "Price" msgstr "Prix" @@ -579,34 +643,47 @@ msgstr "Utilisateurs concernés" msgid "Available for everyone" msgstr "Disponible pour tous" -#: templates/cotisations/aff_article.html:52 -#: templates/cotisations/aff_paiement.html:48 -#: templates/cotisations/control.html:107 views.py:483 views.py:570 -#: views.py:650 -msgid "Edit" -msgstr "Modifier" - #: templates/cotisations/aff_banque.html:32 msgid "Bank" msgstr "Banque" -#: templates/cotisations/aff_cotisations.html:38 -msgid "User" -msgstr "Utilisateur" - +#: templates/cotisations/aff_cost_estimate.html:39 #: templates/cotisations/aff_cotisations.html:41 #: templates/cotisations/aff_custom_invoice.html:39 #: templates/cotisations/control.html:63 -#: templates/cotisations/edit_facture.html:45 +#: templates/cotisations/edit_facture.html:49 msgid "Designation" msgstr "Désignation" +#: templates/cotisations/aff_cost_estimate.html:40 #: templates/cotisations/aff_cotisations.html:42 #: templates/cotisations/aff_custom_invoice.html:40 #: templates/cotisations/control.html:64 msgid "Total price" msgstr "Prix total" +#: templates/cotisations/aff_cost_estimate.html:50 +msgid "Validity" +msgstr "Validité" + +#: templates/cotisations/aff_cost_estimate.html:54 +msgid "Cost estimate ID" +msgstr "ID devis" + +#: templates/cotisations/aff_cost_estimate.html:58 +msgid "Invoice created" +msgstr "Facture créée" + +#: templates/cotisations/aff_cost_estimate.html:91 +#: templates/cotisations/aff_cotisations.html:81 +#: templates/cotisations/aff_custom_invoice.html:79 +msgid "PDF" +msgstr "PDF" + +#: templates/cotisations/aff_cotisations.html:38 +msgid "User" +msgstr "Utilisateur" + #: templates/cotisations/aff_cotisations.html:52 #: templates/cotisations/aff_custom_invoice.html:50 #: templates/cotisations/control.html:56 @@ -617,11 +694,6 @@ msgstr "ID facture" msgid "Controlled invoice" msgstr "Facture contrôlée" -#: templates/cotisations/aff_cotisations.html:81 -#: templates/cotisations/aff_custom_invoice.html:79 -msgid "PDF" -msgstr "PDF" - #: templates/cotisations/aff_cotisations.html:84 msgid "Invalidated invoice" msgstr "Facture invalidée" @@ -666,6 +738,11 @@ msgstr "Validé" msgid "Controlled" msgstr "Contrôlé" +#: templates/cotisations/control.html:107 views.py:642 views.py:729 +#: views.py:809 +msgid "Edit" +msgstr "Modifier" + #: templates/cotisations/delete.html:29 msgid "Deletion of subscriptions" msgstr "Suppression de cotisations" @@ -676,33 +753,33 @@ msgid "" "Warning: are you sure you really want to delete this %(object_name)s object " "( %(objet)s )?" msgstr "" -"\tAttention: voulez-vous vraiment supprimer cet objet %(object_name)s " +"Attention: voulez-vous vraiment supprimer cet objet %(object_name)s " "( %(objet)s ) ?" #: templates/cotisations/delete.html:38 -#: templates/cotisations/edit_facture.html:60 -#: views.py:181 views.py:235 +#: templates/cotisations/edit_facture.html:64 views.py:178 views.py:228 +#: views.py:280 msgid "Confirm" -msgstr "Valider" +msgstr "Confirmer" #: templates/cotisations/edit_facture.html:31 #: templates/cotisations/facture.html:30 msgid "Creation and editing of invoices" msgstr "Création et modification de factures" -#: templates/cotisations/edit_facture.html:38 -msgid "Edit the invoice" +#: templates/cotisations/edit_facture.html:41 +msgid "Edit invoice" msgstr "Modifier la facture" -#: templates/cotisations/edit_facture.html:41 -#: templates/cotisations/facture.html:56 +#: templates/cotisations/edit_facture.html:45 +#: templates/cotisations/facture.html:62 #: templates/cotisations/index_article.html:30 msgid "Articles" msgstr "Articles" #: templates/cotisations/facture.html:37 msgid "Buy" -msgstr "Acheter une cotisation" +msgstr "Acheter" #: templates/cotisations/facture.html:40 #, python-format @@ -714,11 +791,11 @@ msgstr "Solde maximum autorisé : %(max_balance)s €" msgid "Current balance: %(balance)s €" msgstr "Solde actuel : %(balance)s €" -#: templates/cotisations/facture.html:70 +#: templates/cotisations/facture.html:76 msgid "Add an extra article" msgstr "Ajouter un article supplémentaire" -#: templates/cotisations/facture.html:72 +#: templates/cotisations/facture.html:82 msgid "Total price: 0,00 €" msgstr "Prix total : 0,00 €" @@ -730,9 +807,8 @@ msgstr "Factures" msgid "Subscriptions" msgstr "Cotisations" - #: templates/cotisations/index_article.html:33 -msgid "Article types list" +msgid "List of article types" msgstr "Liste des types d'article" #: templates/cotisations/index_article.html:36 @@ -744,12 +820,12 @@ msgid "Delete one or several article types" msgstr "Supprimer un ou plusieurs types d'article" #: templates/cotisations/index_banque.html:30 -#: templates/cotisations/sidebar.html:55 +#: templates/cotisations/sidebar.html:60 msgid "Banks" msgstr "Banques" #: templates/cotisations/index_banque.html:33 -msgid "Banks list" +msgid "List of banks" msgstr "Liste des banques" #: templates/cotisations/index_banque.html:36 @@ -760,17 +836,26 @@ msgstr "Ajouter une banque" msgid "Delete one or several banks" msgstr "Supprimer une ou plusieurs banques" +#: templates/cotisations/index_cost_estimate.html:28 +#: templates/cotisations/sidebar.html:50 +msgid "Cost estimates" +msgstr "Devis" + +#: templates/cotisations/index_cost_estimate.html:31 +msgid "List of cost estimates" +msgstr "Liste des devis" + #: templates/cotisations/index_custom_invoice.html:28 #: templates/cotisations/sidebar.html:45 msgid "Custom invoices" msgstr "Factures personnalisées" #: templates/cotisations/index_custom_invoice.html:31 -msgid "Custom invoices list" -msgstr "Liste des factures personalisées" +msgid "List of custom invoices" +msgstr "Liste des factures personnalisées" #: templates/cotisations/index_paiement.html:30 -#: templates/cotisations/sidebar.html:60 +#: templates/cotisations/sidebar.html:65 msgid "Payment methods" msgstr "Moyens de paiement" @@ -793,9 +878,9 @@ msgstr "Rechargement de solde" #: templates/cotisations/payment.html:34 #, python-format msgid "Pay %(amount)s €" -msgstr "Recharger de %(amount)s €" +msgstr "Payer %(amount)s €" -#: templates/cotisations/payment.html:42 views.py:870 +#: templates/cotisations/payment.html:42 views.py:1049 msgid "Pay" msgstr "Payer" @@ -807,81 +892,104 @@ msgstr "Créer une facture" msgid "Control the invoices" msgstr "Contrôler les factures" -#: views.py:167 +#: views.py:164 msgid "You need to choose at least one article." msgstr "Vous devez choisir au moins un article." +#: views.py:222 +msgid "The cost estimate was created." +msgstr "Le devis a été créé." -#: views.py:228 +#: views.py:232 views.py:534 +msgid "Cost estimate" +msgstr "Devis" + +#: views.py:274 msgid "The custom invoice was created." msgstr "La facture personnalisée a été créée." -#: views.py:316 views.py:370 +#: views.py:363 views.py:466 msgid "The invoice was edited." msgstr "La facture a été modifiée." -#: views.py:336 views.py:430 +#: views.py:383 views.py:589 msgid "The invoice was deleted." msgstr "La facture a été supprimée." -#: views.py:341 views.py:435 +#: views.py:388 views.py:594 msgid "Invoice" msgstr "Facture" -#: views.py:456 +#: views.py:417 +msgid "The cost estimate was edited." +msgstr "Le devis a été modifié." + +#: views.py:424 +msgid "Edit cost estimate" +msgstr "Modifier le devis" + +#: views.py:436 +msgid "An invoice was successfully created from your cost estimate." +msgstr "Une facture a bien été créée à partir de votre devis." + +#: views.py:529 +msgid "The cost estimate was deleted." +msgstr "Le devis a été supprimé." + +#: views.py:615 msgid "The article was created." msgstr "L'article a été créé." -#: views.py:461 views.py:534 views.py:627 +#: views.py:620 views.py:693 views.py:786 msgid "Add" msgstr "Ajouter" -#: views.py:462 +#: views.py:621 msgid "New article" msgstr "Nouvel article" -#: views.py:478 +#: views.py:637 msgid "The article was edited." msgstr "L'article a été modifié." -#: views.py:484 +#: views.py:643 msgid "Edit article" msgstr "Modifier l'article" -#: views.py:500 +#: views.py:659 msgid "The articles were deleted." msgstr "Les articles ont été supprimés." -#: views.py:505 views.py:605 views.py:685 +#: views.py:664 views.py:764 views.py:844 msgid "Delete" msgstr "Supprimer" -#: views.py:506 +#: views.py:665 msgid "Delete article" msgstr "Supprimer l'article" -#: views.py:528 +#: views.py:687 msgid "The payment method was created." msgstr "Le moyen de paiment a été créé." -#: views.py:535 +#: views.py:694 msgid "New payment method" msgstr "Nouveau moyen de paiement" -#: views.py:564 +#: views.py:723 msgid "The payment method was edited." msgstr "Le moyen de paiment a été modifié." -#: views.py:571 +#: views.py:730 msgid "Edit payment method" msgstr "Modifier le moyen de paiement" -#: views.py:590 +#: views.py:749 #, python-format msgid "The payment method %(method_name)s was deleted." msgstr "Le moyen de paiement %(method_name)s a été supprimé." -#: views.py:597 +#: views.py:756 #, python-format msgid "" "The payment method %(method_name)s can't be deleted " @@ -890,52 +998,51 @@ msgstr "" "Le moyen de paiement %(method_name)s ne peut pas être supprimé car il y a " "des factures qui l'utilisent." -#: views.py:606 +#: views.py:765 msgid "Delete payment method" msgstr "Supprimer le moyen de paiement" -#: views.py:622 +#: views.py:781 msgid "The bank was created." msgstr "La banque a été créée." -#: views.py:628 +#: views.py:787 msgid "New bank" msgstr "Nouvelle banque" -#: views.py:645 +#: views.py:804 msgid "The bank was edited." msgstr "La banque a été modifiée." -#: views.py:651 +#: views.py:810 msgid "Edit bank" msgstr "Modifier la banque" -#: views.py:670 +#: views.py:829 #, python-format msgid "The bank %(bank_name)s was deleted." msgstr "La banque %(bank_name)s a été supprimée." -#: views.py:677 +#: views.py:836 #, python-format msgid "" -"The bank %(bank_name)s can't be deleted because there " -"are invoices using it." +"The bank %(bank_name)s can't be deleted because there are invoices using it." msgstr "" "La banque %(bank_name)s ne peut pas être supprimée car il y a des factures " "qui l'utilisent." -#: views.py:686 +#: views.py:845 msgid "Delete bank" msgstr "Supprimer la banque" -#: views.py:722 +#: views.py:881 msgid "Your changes have been properly taken into account." msgstr "Vos modifications ont correctement été prises en compte." -#: views.py:834 +#: views.py:1016 msgid "You are not allowed to credit your balance." msgstr "Vous n'êtes pas autorisés à créditer votre solde." -#: views.py:869 +#: views.py:1048 msgid "Refill your balance" msgstr "Recharger votre solde" diff --git a/cotisations/models.py b/cotisations/models.py index 623db068..ea565ac8 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -341,7 +341,7 @@ class CostEstimate(CustomInvoice): "to delete a cost estimate.") if self.final_invoice is not None: return False, _("The cost estimate has an " - "invoice and cannot be deleted.") + "invoice and can't be deleted.") return True, None diff --git a/cotisations/payment_methods/note_kfet/views.py b/cotisations/payment_methods/note_kfet/views.py index d4d0ac21..cfdda9b0 100644 --- a/cotisations/payment_methods/note_kfet/views.py +++ b/cotisations/payment_methods/note_kfet/views.py @@ -57,7 +57,7 @@ def note_payment(request, facture, factureid): user = facture.user payment_method = find_payment_method(facture.paiement) if not payment_method or not isinstance(payment_method, NotePayment): - messages.error(request, "Erreur inconnue") + messages.error(request, _("Unknown error.")) return redirect(reverse( 'users:profil', kwargs={'userid': user.id} @@ -85,7 +85,7 @@ def note_payment(request, facture, factureid): ) facture.valid = True facture.save() - messages.success(request, "Le paiement par note a bien été effectué") + messages.success(request, _("The payment with note was done.")) return redirect(reverse( 'users:profil', kwargs={'userid': user.id} diff --git a/cotisations/templates/cotisations/aff_article.html b/cotisations/templates/cotisations/aff_article.html index b07035da..682d6a05 100644 --- a/cotisations/templates/cotisations/aff_article.html +++ b/cotisations/templates/cotisations/aff_article.html @@ -49,9 +49,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ article.available_for_everyone | tick }} {% can_edit article %} - - - + {% include 'buttons/edit.html' with href='cotisations:edit-article' id=article.id %} {% acl_end %} {% history_button article %} diff --git a/cotisations/templates/cotisations/aff_cost_estimate.html b/cotisations/templates/cotisations/aff_cost_estimate.html index d4a3f60d..e591a5fe 100644 --- a/cotisations/templates/cotisations/aff_cost_estimate.html +++ b/cotisations/templates/cotisations/aff_cost_estimate.html @@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,

{% if cost_estimate_list.paginator %} - {% include 'pagination.html' with list=cost_estimate_list%} + {% include 'pagination.html' with list=cost_estimate_list%} {% endif %} @@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -96,6 +96,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% trans "Recipient" as tr_recip %} - {% include 'buttons/sort.html' with prefix='invoice' col='user' text=tr_user %} + {% include 'buttons/sort.html' with prefix='invoice' col='user' text=tr_recip %} {% trans "Designation" %} {% trans "Total price" %}
{% if custom_invoice_list.paginator %} - {% include 'pagination.html' with list=custom_invoice_list %} + {% include 'pagination.html' with list=custom_invoice_list %} {% endif %}
diff --git a/cotisations/templates/cotisations/aff_cotisations.html b/cotisations/templates/cotisations/aff_cotisations.html index 93384106..7dd64395 100644 --- a/cotisations/templates/cotisations/aff_cotisations.html +++ b/cotisations/templates/cotisations/aff_cotisations.html @@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if facture_list.paginator %} -{% include 'pagination.html' with list=facture_list %} + {% include 'pagination.html' with list=facture_list %} {% endif %} @@ -89,7 +89,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if facture_list.paginator %} -{% include 'pagination.html' with list=facture_list %} + {% include 'pagination.html' with list=facture_list %} {% endif %}
diff --git a/cotisations/templates/cotisations/aff_custom_invoice.html b/cotisations/templates/cotisations/aff_custom_invoice.html index 0f4605ad..c1c5a396 100644 --- a/cotisations/templates/cotisations/aff_custom_invoice.html +++ b/cotisations/templates/cotisations/aff_custom_invoice.html @@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if custom_invoice_list.paginator %} - {% include 'pagination.html' with list=custom_invoice_list %} + {% include 'pagination.html' with list=custom_invoice_list %} {% endif %} @@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -51,7 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% include 'buttons/sort.html' with prefix='invoice' col='id' text=tr_invoice_id %} @@ -84,6 +84,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% trans "Recipient" as tr_recip %} - {% include 'buttons/sort.html' with prefix='invoice' col='user' text=tr_user %} + {% include 'buttons/sort.html' with prefix='invoice' col='user' text=tr_recip %} {% trans "Designation" %} {% trans "Total price" %} - {% trans "Paid" as tr_invoice_paid%} + {% trans "Paid" as tr_invoice_paid %} {% include 'buttons/sort.html' with prefix='invoice' col='paid' text=tr_invoice_paid %}
{% if custom_invoice_list.paginator %} - {% include 'pagination.html' with list=custom_invoice_list %} + {% include 'pagination.html' with list=custom_invoice_list %} {% endif %}
diff --git a/cotisations/templates/cotisations/aff_paiement.html b/cotisations/templates/cotisations/aff_paiement.html index 633eb456..afb78b48 100644 --- a/cotisations/templates/cotisations/aff_paiement.html +++ b/cotisations/templates/cotisations/aff_paiement.html @@ -45,9 +45,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% can_edit paiement %} - - - + {% include 'buttons/edit.html' with href='cotisations:edit-paiement' id=paiement.id %} {% acl_end %} {% history_button paiement %} diff --git a/cotisations/templates/cotisations/control.html b/cotisations/templates/cotisations/control.html index 483c150c..5a18bd01 100644 --- a/cotisations/templates/cotisations/control.html +++ b/cotisations/templates/cotisations/control.html @@ -1,4 +1,4 @@ -{% extends "cotisations/sidebar.html" %} +{% extends 'cotisations/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,

{% trans "Invoice control and validation" %}

{% if facture_list.paginator %} -{% include 'pagination.html' with list=facture_list %} + {% include 'pagination.html' with list=facture_list %} {% endif %}
@@ -110,6 +110,6 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endblock %} {% if facture_list.paginator %} -{% include 'pagination.html' with list=facture_list %} + {% include 'pagination.html' with list=facture_list %} {% endif %} diff --git a/cotisations/templates/cotisations/delete.html b/cotisations/templates/cotisations/delete.html index 58ce8ad2..e6060d09 100644 --- a/cotisations/templates/cotisations/delete.html +++ b/cotisations/templates/cotisations/delete.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'cotisations/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/cotisations/templates/cotisations/edit_facture.html b/cotisations/templates/cotisations/edit_facture.html index c7a6975c..891f7476 100644 --- a/cotisations/templates/cotisations/edit_facture.html +++ b/cotisations/templates/cotisations/edit_facture.html @@ -1,4 +1,4 @@ -{% extends "cotisations/sidebar.html" %} +{% extends 'cotisations/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -38,7 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if title %}

{{title}}

{% else %} -

{% trans "Edit the invoice" %}

+

{% trans "Edit invoice" %}

{% endif %} {% massive_bootstrap_form factureform 'user' %} {{ venteform.management_form }} diff --git a/cotisations/templates/cotisations/facture.html b/cotisations/templates/cotisations/facture.html index efa7b06d..65b05199 100644 --- a/cotisations/templates/cotisations/facture.html +++ b/cotisations/templates/cotisations/facture.html @@ -1,4 +1,4 @@ -{% extends "cotisations/sidebar.html" %} +{% extends 'cotisations/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/cotisations/templates/cotisations/index.html b/cotisations/templates/cotisations/index.html index ca9cde5b..42b8a3bf 100644 --- a/cotisations/templates/cotisations/index.html +++ b/cotisations/templates/cotisations/index.html @@ -1,4 +1,4 @@ -{% extends "cotisations/sidebar.html" %} +{% extends 'cotisations/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/cotisations/templates/cotisations/index_article.html b/cotisations/templates/cotisations/index_article.html index 41ffb62e..5f93b5ce 100644 --- a/cotisations/templates/cotisations/index_article.html +++ b/cotisations/templates/cotisations/index_article.html @@ -1,4 +1,4 @@ -{% extends "cotisations/sidebar.html" %} +{% extends 'cotisations/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block title %}{% trans "Articles" %}{% endblock %} {% block content %} -

{% trans "Article types list" %}

+

{% trans "List of article types" %}

{% can_create Article %} {% trans "Add an article type" %} diff --git a/cotisations/templates/cotisations/index_banque.html b/cotisations/templates/cotisations/index_banque.html index f4dea1b1..87067222 100644 --- a/cotisations/templates/cotisations/index_banque.html +++ b/cotisations/templates/cotisations/index_banque.html @@ -1,4 +1,4 @@ -{% extends "cotisations/sidebar.html" %} +{% extends 'cotisations/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block title %}{% trans "Banks" %}{% endblock %} {% block content %} -

{% trans "Banks list" %}

+

{% trans "List of banks" %}

{% can_create Banque %}
{% trans "Add a bank" %} diff --git a/cotisations/templates/cotisations/index_cost_estimate.html b/cotisations/templates/cotisations/index_cost_estimate.html index a0b3a661..c3d57197 100644 --- a/cotisations/templates/cotisations/index_cost_estimate.html +++ b/cotisations/templates/cotisations/index_cost_estimate.html @@ -1,4 +1,4 @@ -{% extends "cotisations/sidebar.html" %} +{% extends 'cotisations/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -28,9 +28,9 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block title %}{% trans "Cost estimates" %}{% endblock %} {% block content %} -

{% trans "Cost estimates list" %}

+

{% trans "List of cost estimates" %}

{% can_create CostEstimate %} -{% include "buttons/add.html" with href='cotisations:new-cost-estimate'%} +{% include 'buttons/add.html' with href='cotisations:new-cost-estimate'%} {% acl_end %} {% include 'cotisations/aff_cost_estimate.html' %} {% endblock %} diff --git a/cotisations/templates/cotisations/index_custom_invoice.html b/cotisations/templates/cotisations/index_custom_invoice.html index 67d00126..9b539614 100644 --- a/cotisations/templates/cotisations/index_custom_invoice.html +++ b/cotisations/templates/cotisations/index_custom_invoice.html @@ -1,4 +1,4 @@ -{% extends "cotisations/sidebar.html" %} +{% extends 'cotisations/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -28,9 +28,9 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block title %}{% trans "Custom invoices" %}{% endblock %} {% block content %} -

{% trans "Custom invoices list" %}

+

{% trans "List of custom invoices" %}

{% can_create CustomInvoice %} -{% include "buttons/add.html" with href='cotisations:new-custom-invoice'%} +{% include 'buttons/add.html' with href='cotisations:new-custom-invoice'%} {% acl_end %} {% include 'cotisations/aff_custom_invoice.html' with custom_invoice_list=custom_invoice_list %} {% endblock %} diff --git a/cotisations/templates/cotisations/index_paiement.html b/cotisations/templates/cotisations/index_paiement.html index f4908d02..09b7e033 100644 --- a/cotisations/templates/cotisations/index_paiement.html +++ b/cotisations/templates/cotisations/index_paiement.html @@ -1,4 +1,4 @@ -{% extends "cotisations/sidebar.html" %} +{% extends 'cotisations/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/cotisations/templates/cotisations/payment.html b/cotisations/templates/cotisations/payment.html index ecd90ed8..ceb8db6f 100644 --- a/cotisations/templates/cotisations/payment.html +++ b/cotisations/templates/cotisations/payment.html @@ -1,4 +1,4 @@ -{% extends "cotisations/sidebar.html" %} +{% extends 'cotisations/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/cotisations/templates/cotisations/sidebar.html b/cotisations/templates/cotisations/sidebar.html index c3240a9a..608f95c2 100644 --- a/cotisations/templates/cotisations/sidebar.html +++ b/cotisations/templates/cotisations/sidebar.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends 'base.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -28,40 +28,40 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block sidebar %} {% can_create CustomInvoice %} -
+ {% trans "Create an invoice" %} - + {% trans "Control the invoices" %} {% acl_end %} {% can_view_all Facture %} - + {% trans "Invoices" %} {% acl_end %} {% can_view_all CustomInvoice %} - + {% trans "Custom invoices" %} {% acl_end %} {% can_view_all CostEstimate %} - - {% trans "Cost estimate" %} + + {% trans "Cost estimates" %} {% acl_end %} {% can_view_all Article %} - + {% trans "Available articles" %} {% acl_end %} {% can_view_all Banque %} - + {% trans "Banks" %} {% acl_end %} {% can_view_all Paiement %} - + {% trans "Payment methods" %} {% acl_end %} diff --git a/cotisations/views.py b/cotisations/views.py index d4805dc2..b713f3b9 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -421,7 +421,7 @@ def edit_cost_estimate(request, invoice, **kwargs): return form({ 'factureform': invoice_form, 'venteform': purchase_form, - 'title': "Edit the cost estimate" + 'title': _("Edit cost estimate") }, 'cotisations/edit_facture.html', request) @@ -531,7 +531,7 @@ def del_cost_estimate(request, estimate, **_kwargs): return redirect(reverse('cotisations:index-cost-estimate')) return form({ 'objet': estimate, - 'objet_name': _("Cost Estimate") + 'objet_name': _("Cost estimate") }, 'cotisations/delete.html', request) @@ -833,8 +833,8 @@ def del_banque(request, instances): except ProtectedError: messages.error( request, - _("The bank %(bank_name)s can't be deleted \ - because there are invoices using it.") % { + _("The bank %(bank_name)s can't be deleted because there" + " are invoices using it.") % { 'bank_name': bank_del } ) From 9683e0d688518769fd865c9247e0eee10149f025 Mon Sep 17 00:00:00 2001 From: Laouen Fernet Date: Wed, 9 Jan 2019 00:39:08 +0100 Subject: [PATCH 49/73] add translations for logs/ --- logs/locale/fr/LC_MESSAGES/django.po | 96 +++++++++++++------------ logs/templates/logs/aff_stats_logs.html | 8 +-- logs/templates/logs/aff_summary.html | 6 +- logs/templates/logs/delete.html | 2 +- logs/templates/logs/index.html | 4 +- logs/templates/logs/sidebar.html | 14 ++-- logs/templates/logs/stats_general.html | 4 +- logs/templates/logs/stats_logs.html | 4 +- logs/templates/logs/stats_models.html | 4 +- logs/templates/logs/stats_users.html | 4 +- 10 files changed, 77 insertions(+), 69 deletions(-) diff --git a/logs/locale/fr/LC_MESSAGES/django.po b/logs/locale/fr/LC_MESSAGES/django.po index 70c58073..807bda76 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: 2018-08-15 20:12+0200\n" +"POT-Creation-Date: 2019-01-08 23:16+0100\n" "PO-Revision-Date: 2018-06-23 16:01+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -57,7 +57,7 @@ msgstr "Commentaire" #: templates/logs/aff_stats_logs.html:58 templates/logs/aff_summary.html:62 #: templates/logs/aff_summary.html:85 templates/logs/aff_summary.html:104 -#: templates/logs/aff_summary.html:123 templates/logs/aff_summary.html:142 +#: templates/logs/aff_summary.html:128 templates/logs/aff_summary.html:147 msgid "Cancel" msgstr "Annuler" @@ -113,15 +113,19 @@ msgstr "%(username)s a mis à jour" #: templates/logs/aff_summary.html:113 #, python-format -msgid "%(username)s has sold %(number)sx %(name)s to" -msgstr "%(username)s a vendu %(number)sx %(name)s à" +msgid "%(username)s has sold %(number)sx %(name)s" +msgstr "%(username)s a vendu %(number)sx %(name)s" #: templates/logs/aff_summary.html:116 +msgid " to" +msgstr " à" + +#: templates/logs/aff_summary.html:119 #, python-format msgid "+%(duration)s months" msgstr "+%(duration)s mois" -#: templates/logs/aff_summary.html:132 +#: templates/logs/aff_summary.html:137 #, python-format msgid "%(username)s has edited an interface of" msgstr "%(username)s a modifié une interface de" @@ -149,7 +153,7 @@ msgstr "Confirmer" msgid "Statistics" msgstr "Statistiques" -#: templates/logs/index.html:32 templates/logs/stats_logs.html:32 views.py:403 +#: templates/logs/index.html:32 templates/logs/stats_logs.html:32 views.py:414 msgid "Actions performed" msgstr "Actions effectuées" @@ -173,7 +177,7 @@ msgstr "Base de données" msgid "Wiring actions" msgstr "Actions de câblage" -#: templates/logs/sidebar.html:53 views.py:325 +#: templates/logs/sidebar.html:53 views.py:336 msgid "Users" msgstr "Utilisateurs" @@ -189,150 +193,154 @@ msgstr "Statistiques sur la base de données" msgid "Statistics about users" msgstr "Statistiques sur les utilisateurs" -#: views.py:191 +#: views.py:194 msgid "Nonexistent revision." msgstr "Révision inexistante." -#: views.py:194 +#: views.py:197 msgid "The action was deleted." msgstr "L'action a été supprimée." -#: views.py:227 +#: views.py:230 msgid "Category" msgstr "Catégorie" -#: views.py:228 +#: views.py:231 msgid "Number of users (members and clubs)" msgstr "Nombre d'utilisateurs (adhérents et clubs)" -#: views.py:229 +#: views.py:232 msgid "Number of members" msgstr "Nombre d'adhérents" -#: views.py:230 +#: views.py:233 msgid "Number of clubs" msgstr "Nombre de clubs" -#: views.py:234 +#: views.py:237 msgid "Activated users" msgstr "Utilisateurs activés" -#: views.py:242 +#: views.py:245 msgid "Disabled users" msgstr "Utilisateurs désactivés" -#: views.py:250 +#: views.py:253 msgid "Archived users" msgstr "Utilisateurs archivés" -#: views.py:258 +#: views.py:261 +msgid "Not yet active users" +msgstr "Utilisateurs pas encore actifs" + +#: views.py:269 msgid "Contributing members" msgstr "Adhérents cotisants" -#: views.py:264 +#: views.py:275 msgid "Users benefiting from a connection" msgstr "Utilisateurs bénéficiant d'une connexion" -#: views.py:270 +#: views.py:281 msgid "Banned users" msgstr "Utilisateurs bannis" -#: views.py:276 +#: views.py:287 msgid "Users benefiting from a free connection" msgstr "Utilisateurs bénéficiant d'une connexion gratuite" -#: views.py:282 +#: views.py:293 msgid "Active interfaces (with access to the network)" msgstr "Interfaces actives (ayant accès au réseau)" -#: views.py:292 +#: views.py:303 msgid "Active interfaces assigned IPv4" msgstr "Interfaces actives assignées IPv4" -#: views.py:305 +#: views.py:316 msgid "IP range" msgstr "Plage d'IP" -#: views.py:306 +#: views.py:317 msgid "VLAN" msgstr "VLAN" -#: views.py:307 +#: views.py:318 msgid "Total number of IP addresses" msgstr "Nombre total d'adresses IP" -#: views.py:308 +#: views.py:319 msgid "Number of assigned IP addresses" msgstr "Nombre d'adresses IP non assignées" -#: views.py:309 +#: views.py:320 msgid "Number of IP address assigned to an activated machine" msgstr "Nombre d'adresses IP assignées à une machine activée" -#: views.py:310 +#: views.py:321 msgid "Number of nonassigned IP addresses" msgstr "Nombre d'adresses IP non assignées" -#: views.py:337 +#: views.py:348 msgid "Subscriptions" msgstr "Cotisations" -#: views.py:359 views.py:420 +#: views.py:370 views.py:431 msgid "Machines" msgstr "Machines" -#: views.py:386 +#: views.py:397 msgid "Topology" msgstr "Topologie" -#: views.py:405 +#: views.py:416 msgid "Number of actions" msgstr "Nombre d'actions" -#: views.py:419 views.py:437 views.py:442 views.py:447 views.py:462 +#: views.py:430 views.py:448 views.py:453 views.py:458 views.py:473 msgid "User" msgstr "Utilisateur" -#: views.py:423 +#: views.py:434 msgid "Invoice" msgstr "Facture" -#: views.py:426 +#: views.py:437 msgid "Ban" msgstr "Bannissement" -#: views.py:429 +#: views.py:440 msgid "Whitelist" msgstr "Accès gracieux" -#: views.py:432 +#: views.py:443 msgid "Rights" msgstr "Droits" -#: views.py:436 +#: views.py:447 msgid "School" msgstr "Établissement" -#: views.py:441 +#: views.py:452 msgid "Payment method" msgstr "Moyen de paiement" -#: views.py:446 +#: views.py:457 msgid "Bank" msgstr "Banque" -#: views.py:463 +#: views.py:474 msgid "Action" msgstr "Action" -#: views.py:494 +#: views.py:505 msgid "No model found." msgstr "Aucun modèle trouvé." -#: views.py:500 +#: views.py:511 msgid "Nonexistent entry." msgstr "Entrée inexistante." -#: views.py:507 +#: views.py:518 msgid "You don't have the right to access this menu." msgstr "Vous n'avez pas le droit d'accéder à ce menu." diff --git a/logs/templates/logs/aff_stats_logs.html b/logs/templates/logs/aff_stats_logs.html index 1ca79df9..44a937f9 100644 --- a/logs/templates/logs/aff_stats_logs.html +++ b/logs/templates/logs/aff_stats_logs.html @@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% if revisions_list.paginator %} -{% include "pagination.html" with list=revisions_list %} + {% include 'pagination.html' with list=revisions_list %} {% endif %} {% load logs_extra %} @@ -36,9 +36,9 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Edited object" %} {% trans "Object type" %} {% trans "Edited by" as tr_edited_by %} - {% include "buttons/sort.html" with prefix='logs' col='author' text=tr_edited_by %} + {% include 'buttons/sort.html' with prefix='logs' col='author' text=tr_edited_by %} {% trans "Date of editing" as tr_date_of_editing %} - {% include "buttons/sort.html" with prefix='logs' col='date' text=tr_date_of_editing %} + {% include 'buttons/sort.html' with prefix='logs' col='date' text=tr_date_of_editing %} {% trans "Comment" %} @@ -65,6 +65,6 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if revisions_list.paginator %} -{% include "pagination.html" with list=revisions_list %} + {% include 'pagination.html' with list=revisions_list %} {% endif %} diff --git a/logs/templates/logs/aff_summary.html b/logs/templates/logs/aff_summary.html index 366e07e7..3c43e2ac 100644 --- a/logs/templates/logs/aff_summary.html +++ b/logs/templates/logs/aff_summary.html @@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% if versions_list.paginator %} -{% include "pagination.html" with list=versions_list %} + {% include 'pagination.html' with list=versions_list %} {% endif %} {% load logs_extra %} @@ -35,7 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Date" as tr_date %} - {% include "buttons/sort.html" with prefix='sum' col='date' text=tr_date %} + {% include 'buttons/sort.html' with prefix='sum' col='date' text=tr_date %} {% trans "Editing" %} @@ -154,6 +154,6 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if versions_list.paginator %} -{% include "pagination.html" with list=versions_list %} + {% include 'pagination.html' with list=versions_list %} {% endif %} diff --git a/logs/templates/logs/delete.html b/logs/templates/logs/delete.html index 6ad11195..a8f6b52f 100644 --- a/logs/templates/logs/delete.html +++ b/logs/templates/logs/delete.html @@ -1,4 +1,4 @@ -{% extends "logs/sidebar.html" %} +{% extends 'logs/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/logs/templates/logs/index.html b/logs/templates/logs/index.html index dde47c7d..3bd61b40 100644 --- a/logs/templates/logs/index.html +++ b/logs/templates/logs/index.html @@ -1,4 +1,4 @@ -{% extends "logs/sidebar.html" %} +{% extends 'logs/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block content %}

{% trans "Actions performed" %}

- {% include "logs/aff_summary.html" with versions_list=versions_list %} + {% include 'logs/aff_summary.html' with versions_list=versions_list %}


diff --git a/logs/templates/logs/sidebar.html b/logs/templates/logs/sidebar.html index d2ee3002..e997abd5 100644 --- a/logs/templates/logs/sidebar.html +++ b/logs/templates/logs/sidebar.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends 'base.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -28,27 +28,27 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block sidebar %} {% can_view_app logs %} - + {% trans "Summary" %} - + {% trans "Events" %} - + {% trans "General" %} - + {% trans "Database" %} - + {% trans "Wiring actions" %} - + {% trans "Users" %} diff --git a/logs/templates/logs/stats_general.html b/logs/templates/logs/stats_general.html index 07e3ec26..96d5612c 100644 --- a/logs/templates/logs/stats_general.html +++ b/logs/templates/logs/stats_general.html @@ -1,4 +1,4 @@ -{% extends "logs/sidebar.html" %} +{% extends 'logs/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block content %}

{% trans "General statistics" %}

- {% include "logs/aff_stats_general.html" with stats_list=stats_list %} + {% include 'logs/aff_stats_general.html' with stats_list=stats_list %}


diff --git a/logs/templates/logs/stats_logs.html b/logs/templates/logs/stats_logs.html index 4f547cc3..df9708b1 100644 --- a/logs/templates/logs/stats_logs.html +++ b/logs/templates/logs/stats_logs.html @@ -1,4 +1,4 @@ -{% extends "logs/sidebar.html" %} +{% extends 'logs/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block content %}

{% trans "Actions performed" %}

- {% include "logs/aff_stats_logs.html" with revisions_list=revisions_list %} + {% include 'logs/aff_stats_logs.html' with revisions_list=revisions_list %}


diff --git a/logs/templates/logs/stats_models.html b/logs/templates/logs/stats_models.html index 9b912da2..ddc66c15 100644 --- a/logs/templates/logs/stats_models.html +++ b/logs/templates/logs/stats_models.html @@ -1,4 +1,4 @@ -{% extends "logs/sidebar.html" %} +{% extends 'logs/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block content %}

{% trans "Database statistics" %}

- {% include "logs/aff_stats_models.html" with stats_list=stats_list %} + {% include 'logs/aff_stats_models.html' with stats_list=stats_list %}


diff --git a/logs/templates/logs/stats_users.html b/logs/templates/logs/stats_users.html index 8cc645ab..d55d1e52 100644 --- a/logs/templates/logs/stats_users.html +++ b/logs/templates/logs/stats_users.html @@ -1,4 +1,4 @@ -{% extends "logs/sidebar.html" %} +{% extends 'logs/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block content %}

{% trans "Statistics about users" %}

- {% include "logs/aff_stats_users.html" with stats_list=stats_list %} + {% include 'logs/aff_stats_users.html' with stats_list=stats_list %}


From 62d09760b31697f936e97ecbbf4078e95fe68efe Mon Sep 17 00:00:00 2001 From: Laouen Fernet Date: Wed, 9 Jan 2019 00:39:31 +0100 Subject: [PATCH 50/73] add translations for machines/ --- machines/locale/fr/LC_MESSAGES/django.po | 623 +++++++++--------- .../migrations/0101_auto_20190108_1623.py | 34 + machines/models.py | 19 +- machines/templates/machines/aff_alias.html | 2 +- machines/templates/machines/aff_dname.html | 2 +- .../templates/machines/aff_extension.html | 2 +- machines/templates/machines/aff_iptype.html | 2 +- machines/templates/machines/aff_ipv6.html | 4 +- machines/templates/machines/aff_machines.html | 18 +- .../templates/machines/aff_machinetype.html | 2 +- machines/templates/machines/aff_mx.html | 2 +- machines/templates/machines/aff_nas.html | 2 +- machines/templates/machines/aff_ns.html | 2 +- machines/templates/machines/aff_role.html | 2 +- machines/templates/machines/aff_service.html | 2 +- machines/templates/machines/aff_soa.html | 2 +- machines/templates/machines/aff_srv.html | 2 +- machines/templates/machines/aff_sshfp.html | 4 +- machines/templates/machines/aff_txt.html | 2 +- machines/templates/machines/aff_vlan.html | 2 +- machines/templates/machines/delete.html | 7 +- .../templates/machines/edit_portlist.html | 2 +- machines/templates/machines/index.html | 4 +- machines/templates/machines/index_alias.html | 4 +- .../templates/machines/index_extension.html | 16 +- machines/templates/machines/index_iptype.html | 4 +- machines/templates/machines/index_ipv6.html | 4 +- .../templates/machines/index_machinetype.html | 4 +- machines/templates/machines/index_nas.html | 4 +- .../templates/machines/index_portlist.html | 2 +- machines/templates/machines/index_role.html | 4 +- .../templates/machines/index_service.html | 6 +- machines/templates/machines/index_sshfp.html | 4 +- machines/templates/machines/index_vlan.html | 4 +- machines/templates/machines/machine.html | 3 +- machines/templates/machines/sidebar.html | 21 +- 36 files changed, 444 insertions(+), 379 deletions(-) create mode 100644 machines/migrations/0101_auto_20190108_1623.py diff --git a/machines/locale/fr/LC_MESSAGES/django.po b/machines/locale/fr/LC_MESSAGES/django.po index 50ab03a8..bd36fb61 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: 2018-08-15 18:10+0200\n" +"POT-Creation-Date: 2019-01-12 16:43+0100\n" "PO-Revision-Date: 2018-06-23 16:35+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -38,220 +38,232 @@ msgstr "Vous n'avez pas le droit de voir cette application." msgid "Machine name" msgstr "Nom de la machine" -#: forms.py:97 templates/machines/aff_machines.html:46 +#: forms.py:99 templates/machines/aff_machines.html:46 msgid "MAC address" msgstr "Adresse MAC" -#: forms.py:98 templates/machines/aff_machinetype.html:32 +#: forms.py:100 templates/machines/aff_machinetype.html:32 #: templates/machines/machine.html:112 msgid "Machine type" msgstr "Type de machine" -#: forms.py:99 +#: forms.py:101 msgid "Select a machine type" msgstr "Sélectionnez un type de machine" -#: forms.py:101 +#: forms.py:103 msgid "Automatic IPv4 assignment" msgstr "Assignation automatique IPv4" -#: forms.py:172 +#: forms.py:177 msgid "Current aliases" msgstr "Alias actuels" -#: forms.py:193 +#: forms.py:199 msgid "Machine type to add" msgstr "Type de machine à ajouter" -#: forms.py:194 +#: forms.py:200 msgid "Related IP type" msgstr "Type d'IP relié" -#: forms.py:201 +#: forms.py:207 msgid "Current machine types" msgstr "Types de machines actuels" -#: forms.py:224 +#: forms.py:231 msgid "IP type to add" msgstr "Type d'IP à ajouter" -#: forms.py:241 +#: forms.py:249 msgid "Current IP types" msgstr "Types d'IP actuels" -#: forms.py:263 +#: forms.py:272 msgid "Extension to add" msgstr "Extension à ajouter" -#: forms.py:264 templates/machines/aff_extension.html:37 +#: forms.py:273 templates/machines/aff_extension.html:37 msgid "A record origin" msgstr "Enregistrement A origin" -#: forms.py:265 templates/machines/aff_extension.html:39 +#: forms.py:274 templates/machines/aff_extension.html:39 msgid "AAAA record origin" msgstr "Enregistrement AAAA origin" -#: forms.py:266 +#: forms.py:275 msgid "SOA record to use" msgstr "Enregistrement SOA à utiliser" -#: forms.py:273 +#: forms.py:276 +msgid "Sign with DNSSEC" +msgstr "Signer avec DNSSEC" + +#: forms.py:283 msgid "Current extensions" msgstr "Extensions actuelles" -#: forms.py:312 +#: forms.py:324 msgid "Current SOA records" msgstr "Enregistrements SOA actuels" -#: forms.py:343 +#: forms.py:356 msgid "Current MX records" msgstr "Enregistrements MX actuels" -#: forms.py:376 +#: forms.py:390 msgid "Current NS records" msgstr "Enregistrements NS actuels" -#: forms.py:404 +#: forms.py:419 msgid "Current TXT records" msgstr "Enregistrements TXT actuels" -#: forms.py:432 +#: forms.py:448 msgid "Current DNAME records" msgstr "Enregistrements DNAME actuels" -#: forms.py:460 +#: forms.py:477 msgid "Current SRV records" msgstr "Enregistrements SRV actuels" -#: forms.py:489 +#: forms.py:507 msgid "Current NAS devices" msgstr "Dispositifs NAS actuels" -#: forms.py:521 +#: forms.py:540 msgid "Current roles" msgstr "Rôles actuels" -#: forms.py:562 +#: forms.py:582 msgid "Current services" msgstr "Services actuels" -#: forms.py:590 +#: forms.py:622 msgid "Current VLANs" msgstr "VLANs actuels" -#: models.py:63 +#: models.py:61 msgid "Optional" msgstr "Optionnel" -#: models.py:71 +#: models.py:69 msgid "Can view a machine object" msgstr "Peut voir un objet machine" -#: models.py:73 +#: models.py:71 msgid "Can change the user of a machine" msgstr "Peut changer l'utilisateur d'une machine" -#: models.py:75 +#: models.py:73 msgid "machine" msgstr "machine" -#: models.py:76 +#: models.py:74 msgid "machines" msgstr "machines" -#: models.py:109 +#: models.py:107 msgid "You don't have the right to change the machine's user." msgstr "Vous n'avez pas le droit de changer l'utilisateur de la machine." -#: models.py:118 +#: models.py:116 msgid "You don't have the right to view all the machines." msgstr "Vous n'avez pas le droit de voir toutes les machines." -#: models.py:132 +#: models.py:130 msgid "Nonexistent user." msgstr "Utilisateur inexistant." -#: models.py:140 +#: models.py:138 msgid "You don't have the right to add a machine." msgstr "Vous n'avez pas le droit d'ajouter une machine." -#: models.py:142 +#: models.py:140 msgid "You don't have the right to add a machine to another user." msgstr "Vous n'avez pas le droit d'ajouter une machine à un autre utilisateur." -#: models.py:145 models.py:1152 +#: models.py:143 models.py:1182 #, python-format msgid "" "You reached the maximum number of interfaces that you are allowed to create " "yourself (%s)." msgstr "" "Vous avez atteint le nombre maximal d'interfaces que vous pouvez créer vous-" -"mêmes (%s)." +"même (%s)." -#: models.py:164 models.py:1177 models.py:1194 models.py:1296 models.py:1313 +#: models.py:162 models.py:1207 models.py:1224 models.py:1326 models.py:1343 msgid "You don't have the right to edit a machine of another user." msgstr "" "Vous n'avez pas le droit de modifier une machine d'un autre utilisateur." -#: models.py:182 +#: models.py:180 msgid "You don't have the right to delete a machine of another user." msgstr "" "Vous n'avez pas le droit de supprimer une machine d'une autre utilisateur." -#: models.py:194 +#: models.py:192 msgid "You don't have the right to view other machines than yours." msgstr "Vous n'avez pas le droit de voir d'autres machines que les vôtres." -#: models.py:241 +#: models.py:204 templates/machines/aff_machines.html:53 +msgid "No name" +msgstr "Sans nom" + +#: models.py:254 msgid "Can view a machine type object" msgstr "Peut voir un objet type de machine" -#: models.py:242 +#: models.py:255 msgid "Can use all machine types" msgstr "Peut utiliser tous les types de machine" -#: models.py:244 +#: models.py:257 msgid "machine type" msgstr "type de machine" -#: models.py:245 +#: models.py:258 msgid "machine types" msgstr "types de machine" -#: models.py:263 +#: models.py:276 msgid "You don't have the right to use all machine types." msgstr "Vous n'avez pas le droit d'utiliser tous les types de machine." -#: models.py:282 +#: models.py:295 msgid "Network containing the domain's IPv4 range (optional)" msgstr "Réseau contenant la plage IPv4 du domaine (optionnel)" -#: models.py:290 +#: models.py:303 msgid "Netmask for the domain's IPv4 range" msgstr "Masque de sous-réseau pour la plage IPv4 du domaine" -#: models.py:294 +#: models.py:307 msgid "Enable reverse DNS for IPv4" msgstr "Activer DNS inverse pour IPv4" -#: models.py:310 +#: models.py:323 msgid "Enable reverse DNS for IPv6" -msgstr "Activer DNS inverser pour IPv6" +msgstr "Activer DNS inverse pour IPv6" -#: models.py:326 +#: models.py:339 msgid "Can view an IP type object" msgstr "Peut voir un objet type d'IP" -#: models.py:327 +#: models.py:340 msgid "Can use all IP types" msgstr "Peut utiliser tous les types d'IP" -#: models.py:329 templates/machines/aff_iptype.html:35 +#: models.py:342 templates/machines/aff_iptype.html:35 #: templates/machines/machine.html:108 msgid "IP type" msgstr "type d'IP" -#: models.py:433 +#: models.py:343 +msgid "IP types" +msgstr "types d'IP" + +#: models.py:446 msgid "" "One or several IP addresses from the range are affected, impossible to " "delete the range." @@ -259,57 +271,69 @@ msgstr "" "Une ou plusieurs adresses IP de la plage sont affectées, impossible de " "supprimer la plage." -#: models.py:475 +#: models.py:488 msgid "Range end must be after range start..." msgstr "La fin de la plage doit être après le début..." -#: models.py:478 +#: models.py:491 msgid "The range is too large, you can't create a larger one than a /16." msgstr "" "La plage est trop grande, vous ne pouvez pas en créer une plus grande " "qu'un /16." -#: models.py:483 +#: models.py:496 msgid "The specified range is not disjoint from existing ranges." msgstr "La plage renseignée n'est pas disjointe des plages existantes." -#: models.py:491 +#: models.py:504 msgid "" "If you specify a domain network or netmask, it must contain the domain's IP " "range." msgstr "" -"Si vous renseignez un réseau ou masque de sous-réseau, il doit contenir" -" la plage IP du domaine." +"Si vous renseignez un réseau ou masque de sous-réseau, il doit contenir la " +"plage IP du domaine." -#: models.py:521 +#: models.py:537 +msgid "v4 multicast management" +msgstr "gestion de multidiffusion v4" + +#: models.py:541 +msgid "v6 multicast management" +msgstr "gestion de multidiffusion v6" + +#: models.py:546 msgid "Can view a VLAN object" msgstr "Peut voir un objet VLAN" -#: models.py:523 templates/machines/machine.html:160 +#: models.py:548 templates/machines/machine.html:160 msgid "VLAN" msgstr "VLAN" -#: models.py:524 templates/machines/sidebar.html:57 +#: models.py:549 templates/machines/sidebar.html:57 msgid "VLANs" msgstr "VLANs" -#: models.py:560 +#: models.py:562 +msgid "MAC-address" +msgstr "MAC-address" + +#: models.py:585 msgid "Can view a NAS device object" msgstr "Peut voir un objet dispositif NAS" -#: models.py:562 templates/machines/machine.html:164 +#: models.py:587 templates/machines/machine.html:164 msgid "NAS device" msgstr "dispositif NAS" -#: models.py:563 templates/machines/sidebar.html:63 +#: models.py:588 templates/machines/sidebar.html:63 msgid "NAS devices" msgstr "dispositifs NAS" -#: models.py:577 +#: models.py:602 msgid "Contact email address for the zone" msgstr "Adresse mail de contact pour la zone" -#: models.py:581 +#: models.py:606 msgid "" "Seconds before the secondary DNS have to ask the primary DNS serial to " "detect a modification" @@ -317,7 +341,7 @@ msgstr "" "Secondes avant que le DNS secondaire demande au DNS primaire le serial pour " "détecter une modification" -#: models.py:586 +#: models.py:611 msgid "" "Seconds before the secondary DNS ask the serial again in case of a primary " "DNS timeout" @@ -325,7 +349,7 @@ msgstr "" "Secondes avant que le DNS secondaire demande le serial de nouveau dans le " "cas d'un délai d'attente du DNS primaire" -#: models.py:591 +#: models.py:616 msgid "" "Seconds before the secondary DNS stop answering requests in case of primary " "DNS timeout" @@ -333,108 +357,112 @@ msgstr "" "Secondes avant que le DNS secondaire arrête de répondre aux requêtes dans le " "cas d'un délai d'attente du DNS primaire" -#: models.py:596 models.py:846 +#: models.py:621 models.py:878 msgid "Time to Live" msgstr "Temps de vie" -#: models.py:601 +#: models.py:626 msgid "Can view an SOA record object" msgstr "Peut voir un objet enregistrement SOA" -#: models.py:603 templates/machines/aff_extension.html:36 +#: models.py:628 templates/machines/aff_extension.html:36 #: templates/machines/machine.html:120 msgid "SOA record" msgstr "enregistrement SOA" -#: models.py:604 +#: models.py:629 msgid "SOA records" msgstr "enregistrements SOA" -#: models.py:643 +#: models.py:668 msgid "SOA to edit" msgstr "SOA à modifier" -#: models.py:654 +#: models.py:679 msgid "Zone name, must begin with a dot (.example.org)" msgstr "Nom de zone, doit commencer par un point (.example.org)" -#: models.py:662 +#: models.py:687 msgid "A record associated with the zone" msgstr "Enregistrement A associé à la zone" -#: models.py:668 +#: models.py:693 msgid "AAAA record associated with the zone" msgstr "Enregristrement AAAA associé avec la zone" -#: models.py:677 +#: models.py:701 +msgid "Should the zone be signed with DNSSEC" +msgstr "La zone doit-elle être signée avec DNSSEC" + +#: models.py:706 msgid "Can view an extension object" msgstr "Peut voir un objet extension" -#: models.py:678 +#: models.py:707 msgid "Can use all extensions" msgstr "Peut utiliser toutes les extensions" -#: models.py:680 +#: models.py:709 msgid "DNS extension" msgstr "extension DNS" -#: models.py:681 +#: models.py:710 msgid "DNS extensions" msgstr "extensions DNS" -#: models.py:732 +#: models.py:764 msgid "An extension must begin with a dot." msgstr "Une extension doit commencer par un point." -#: models.py:746 +#: models.py:778 msgid "Can view an MX record object" msgstr "Peut voir un objet enregistrement MX" -#: models.py:748 templates/machines/machine.html:124 +#: models.py:780 templates/machines/machine.html:124 msgid "MX record" msgstr "enregistrement MX" -#: models.py:749 +#: models.py:781 msgid "MX records" msgstr "enregistrements MX" -#: models.py:771 +#: models.py:803 msgid "Can view an NS record object" msgstr "Peut voir un objet enregistrement NS" -#: models.py:773 templates/machines/machine.html:128 +#: models.py:805 templates/machines/machine.html:128 msgid "NS record" msgstr "enregistrement NS" -#: models.py:774 +#: models.py:806 msgid "NS records" msgstr "enregistrements NS" -#: models.py:793 +#: models.py:825 msgid "Can view a TXT record object" msgstr "Peut voir un objet enregistrement TXT" -#: models.py:795 templates/machines/machine.html:132 +#: models.py:827 templates/machines/machine.html:132 msgid "TXT record" msgstr "enregistrement TXT" -#: models.py:796 +#: models.py:828 msgid "TXT records" msgstr "enregistrements TXT" -#: models.py:815 +#: models.py:847 msgid "Can view a DNAME record object" msgstr "Peut voir un objet enregistrement DNAME" -#: models.py:817 templates/machines/machine.html:136 +#: models.py:849 templates/machines/machine.html:136 msgid "DNAME record" msgstr "enregistrement DNAME" -#: models.py:818 +#: models.py:850 msgid "DNAME records" msgstr "enregistrements DNAME" -#: models.py:851 +#: models.py:883 msgid "" "Priority of the target server (positive integer value, the lower it is, the " "more the server will be used if available)" @@ -442,7 +470,7 @@ msgstr "" "Priorité du serveur cible (entier positif, plus il est bas, plus le serveur " "sera utilisé si disponible)" -#: models.py:858 +#: models.py:890 msgid "" "Relative weight for records with the same priority (integer value between 0 " "and 65535)" @@ -450,128 +478,137 @@ msgstr "" "Poids relatif des enregistrements avec la même priorité (entier entre 0 et " "65535)" -#: models.py:863 +#: models.py:895 msgid "TCP/UDP port" msgstr "Port TCP/UDP" -#: models.py:868 +#: models.py:900 msgid "Target server" msgstr "Serveur cible" -#: models.py:873 +#: models.py:905 msgid "Can view an SRV record object" msgstr "Peut voir un objet enregistrement SRV" -#: models.py:875 templates/machines/machine.html:140 +#: models.py:907 templates/machines/machine.html:140 msgid "SRV record" msgstr "enregistrement SRV" -#: models.py:876 +#: models.py:908 msgid "SRV records" msgstr "enregistrements SRV" -#: models.py:940 +#: models.py:937 templates/machines/aff_sshfp.html:31 +msgid "SSH public key" +msgstr "Clé publique SSH" + +#: models.py:945 templates/machines/aff_sshfp.html:33 +#: templates/machines/aff_vlan.html:35 +msgid "Comment" +msgstr "Commentaire" + +#: models.py:972 msgid "Can view an SSHFP record object" msgstr "Peut voir un objet enregistrement SSHFP" -#: models.py:942 templates/machines/machine.html:144 +#: models.py:974 templates/machines/machine.html:144 msgid "SSHFP record" msgstr "enregistrement SSHFP" -#: models.py:943 +#: models.py:975 msgid "SSHFP records" msgstr "enregistrements SSHFP" -#: models.py:981 +#: models.py:1012 msgid "Can view an interface object" msgstr "Peut voir un objet interface" -#: models.py:983 +#: models.py:1014 msgid "Can change the owner of an interface" msgstr "Peut changer l'utilisateur d'une interface" -#: models.py:985 +#: models.py:1016 msgid "interface" msgstr "interface" -#: models.py:986 +#: models.py:1017 msgid "interfaces" msgstr "interfaces" -#: models.py:1080 +#: models.py:1111 msgid "The given MAC address is invalid." msgstr "L'adresse MAC indiquée est invalide." -#: models.py:1093 +#: models.py:1124 msgid "The selected IP type is invalid." msgstr "Le type d'IP sélectionné est invalide." -#: models.py:1106 +#: models.py:1136 msgid "There is no IP address available in the slash." msgstr "Il n'y a pas d'adresse IP disponible dans le slash." -#: models.py:1124 +#: models.py:1154 msgid "The IPv4 address and the machine type don't match." msgstr "L'adresse IPv4 et le type de machine ne correspondent pas." -#: models.py:1138 +#: models.py:1168 msgid "Nonexistent machine." msgstr "Machine inexistante." -#: models.py:1142 +#: models.py:1172 msgid "You can't add a machine." msgstr "Vous ne pouvez pas ajouter une machine." -#: models.py:1148 +#: models.py:1178 msgid "" "You don't have the right to add an interface to a machine of another user." msgstr "" "Vous n'avez pas le droit d'ajouter une interface à une machine d'un autre " "utilisateur." -#: models.py:1162 +#: models.py:1192 msgid "Permission required to edit the machine." msgstr "Permission requise pour modifier la machine." -#: models.py:1206 models.py:1325 models.py:1532 +#: models.py:1236 models.py:1355 models.py:1565 msgid "You don't have the right to view machines other than yours." msgstr "Vous n'avez pas le droit de voir d'autres machines que les vôtres." -#: models.py:1252 +#: models.py:1282 msgid "Can view an IPv6 addresses list object" msgstr "Peut voir un objet list d'adresses IPv6" -#: models.py:1253 +#: models.py:1283 msgid "Can change the SLAAC value of an IPv6 addresses list" msgstr "Peut modifier la valeur SLAAC d'une liste d'adresses IPv6" -#: models.py:1256 +#: models.py:1286 msgid "IPv6 addresses list" msgstr "Liste d'adresses IPv6" -#: models.py:1257 +#: models.py:1287 msgid "IPv6 addresses lists" msgstr "Listes d'adresses IPv6" -#: models.py:1269 models.py:1480 +#: models.py:1299 models.py:1513 msgid "Nonexistent interface." msgstr "Interface inexistante." -#: models.py:1272 models.py:1487 +#: models.py:1302 models.py:1520 msgid "You don't have the right to add an alias to a machine of another user." msgstr "" "Vous n'avez pas le droit d'ajouter un alias à une machine d'un autre " "utilisateur." -#: models.py:1280 +#: models.py:1310 msgid "Permission required to change the SLAAC value of an IPv6 address" msgstr "Permission requise pour changer la valeur SLAAC d'une adresse IPv6." -#: models.py:1352 +#: models.py:1382 msgid "A SLAAC IP address is already registered." msgstr "Une adresse IP SLAAC est déjà enregistrée." -#: models.py:1357 +#: models.py:1390 msgid "" "The v6 prefix is incorrect and doesn't match the type associated with the " "machine." @@ -579,207 +616,207 @@ msgstr "" "Le préfixe v6 est incorrect et ne correspond pas au type associé à la " "machine." -#: models.py:1383 +#: models.py:1416 msgid "Mandatory and unique, must not contain dots." msgstr "Obligatoire et unique, ne doit pas contenir de points." -#: models.py:1397 +#: models.py:1430 msgid "Can view a domain object" msgstr "Peut voir un objet domaine" -#: models.py:1399 +#: models.py:1432 msgid "domain" msgstr "domaine" -#: models.py:1400 +#: models.py:1433 msgid "domains" msgstr "domaines" -#: models.py:1422 +#: models.py:1455 msgid "You can't create a both A and CNAME record." msgstr "Vous ne pouvez pas créer un enregistrement à la fois A et CNAME." -#: models.py:1425 +#: models.py:1458 msgid "You can't create a CNAME record pointing to itself." msgstr "Vous ne pouvez pas créer un enregistrement CNAME vers lui-même." -#: models.py:1433 +#: models.py:1466 #, python-format msgid "The domain name %s is too long (over 63 characters)." msgstr "Le nom de domaine %s est trop long (plus de 63 caractères)." -#: models.py:1436 +#: models.py:1469 #, python-format msgid "The domain name %s contains forbidden characters." msgstr "Le nom de domaine %s contient des caractères interdits." -#: models.py:1454 +#: models.py:1487 msgid "Invalid extension." msgstr "Extension invalide." -#: models.py:1495 +#: models.py:1528 #, python-format msgid "" "You reached the maximum number of alias that you are allowed to create " "yourself (%s). " msgstr "" -"Vous avez atteint le nombre maximal d'alias que vous pouvez créer vous-mêmes " +"Vous avez atteint le nombre maximal d'alias que vous pouvez créer vous-même " "(%s)." -#: models.py:1508 +#: models.py:1541 msgid "You don't have the right to edit an alias of a machine of another user." msgstr "" "Vous n'avez pas le droit de modifier un alias d'une machine d'un autre " "utilisateur." -#: models.py:1520 +#: models.py:1553 msgid "" "You don't have the right to delete an alias of a machine of another user." msgstr "" "Vous n'avez pas le droit de supprimer un alias d'une machine d'un autre " "utilisateur." -#: models.py:1548 +#: models.py:1581 msgid "Can view an IPv4 addresses list object" msgstr "Peut voir un object liste d'adresses IPv4" -#: models.py:1550 +#: models.py:1583 msgid "IPv4 addresses list" msgstr "Liste d'adresses IPv4" -#: models.py:1551 +#: models.py:1584 msgid "IPv4 addresses lists" msgstr "Listes d'adresses IPv4" -#: models.py:1562 +#: models.py:1595 msgid "The IPv4 address and the range of the IP type don't match." msgstr "L'adresse IPv4 et la plage du type d'IP ne correspondent pas." -#: models.py:1580 +#: models.py:1613 msgid "DHCP server" msgstr "Serveur DHCP" -#: models.py:1581 +#: models.py:1614 msgid "Switches configuration server" msgstr "Serveur de configuration des commutateurs réseau" -#: models.py:1582 +#: models.py:1615 msgid "Recursive DNS server" msgstr "Serveur DNS récursif" -#: models.py:1583 +#: models.py:1616 msgid "NTP server" msgstr "Serveur NTP" -#: models.py:1584 +#: models.py:1617 msgid "RADIUS server" msgstr "Serveur RADIUS" -#: models.py:1585 +#: models.py:1618 msgid "Log server" msgstr "Serveur log" -#: models.py:1586 +#: models.py:1619 msgid "LDAP master server" msgstr "Serveur LDAP maître" -#: models.py:1587 +#: models.py:1620 msgid "LDAP backup server" msgstr "Serveur LDAP de secours" -#: models.py:1588 +#: models.py:1621 msgid "SMTP server" msgstr "Serveur SMTP" -#: models.py:1589 +#: models.py:1622 msgid "postgreSQL server" msgstr "Serveur postgreSQL" -#: models.py:1590 +#: models.py:1623 msgid "mySQL server" msgstr "Serveur mySQL" -#: models.py:1591 +#: models.py:1624 msgid "SQL client" msgstr "Client SQL" -#: models.py:1592 +#: models.py:1625 msgid "Gateway" msgstr "Passerelle" -#: models.py:1606 +#: models.py:1639 msgid "Can view a role object" msgstr "Peut voir un objet rôle" -#: models.py:1608 +#: models.py:1641 msgid "server role" msgstr "rôle de serveur" -#: models.py:1609 +#: models.py:1642 msgid "server roles" msgstr "rôles de serveur" -#: models.py:1650 +#: models.py:1676 msgid "Minimal time before regeneration of the service." msgstr "Temps minimal avant régénération du service." -#: models.py:1654 +#: models.py:1680 msgid "Maximal time before regeneration of the service." msgstr "Temps maximal avant régénération du service." -#: models.py:1660 +#: models.py:1686 msgid "Can view a service object" msgstr "Peut voir un objet service" -#: models.py:1662 +#: models.py:1688 msgid "service to generate (DHCP, DNS, ...)" msgstr "service à générer (DHCP, DNS, ...)" -#: models.py:1663 +#: models.py:1689 msgid "services to generate (DHCP, DNS, ...)" msgstr "services à générer (DHCP, DNS, ...)" -#: models.py:1709 +#: models.py:1735 msgid "Can view a service server link object" msgstr "Peut voir un objet lien service serveur" -#: models.py:1711 +#: models.py:1737 msgid "link between service and server" msgstr "lien entre service et serveur" -#: models.py:1712 +#: models.py:1738 msgid "links between service and server" msgstr "liens entre service et serveur" -#: models.py:1754 +#: models.py:1780 msgid "Name of the ports configuration" msgstr "Nom de la configuration de ports" -#: models.py:1760 +#: models.py:1786 msgid "Can view a ports opening list object" msgstr "Peut voir un objet liste d'ouverture de ports" -#: models.py:1763 +#: models.py:1789 msgid "ports opening list" msgstr "liste d'ouverture de ports" -#: models.py:1764 +#: models.py:1790 msgid "ports opening lists" msgstr "listes d'ouverture de ports" -#: models.py:1773 +#: models.py:1799 msgid "You don't have the right to delete a ports opening list." msgstr "Vous n'avez pas le droit de supprimer une liste d'ouverture de ports." -#: models.py:1776 +#: models.py:1802 msgid "This ports opening list is used." msgstr "Cette liste d'ouverture de ports est utilisée." -#: models.py:1849 +#: models.py:1875 msgid "ports opening" msgstr "ouverture de ports" -#: models.py:1850 +#: models.py:1876 msgid "ports openings" msgstr "ouvertures de ports" @@ -807,6 +844,10 @@ msgstr "Extension" msgid "'infra' right required" msgstr "droit 'infra' requis" +#: templates/machines/aff_extension.html:41 +msgid "DNSSEC" +msgstr "DNSSEC" + #: templates/machines/aff_iptype.html:38 msgid "IPv4 range" msgstr "Plage IPv4" @@ -851,43 +892,39 @@ msgstr "Adresse IP" msgid "Actions" msgstr "Actions" -#: templates/machines/aff_machines.html:53 -msgid "No name" -msgstr "Sans nom" - #: templates/machines/aff_machines.html:54 msgid "View the profile" msgstr "Voir le profil" -#: templates/machines/aff_machines.html:62 views.py:375 +#: templates/machines/aff_machines.html:62 views.py:374 msgid "Create an interface" msgstr "Créer une interface" -#: templates/machines/aff_machines.html:77 +#: templates/machines/aff_machines.html:79 msgid "Display the aliases" msgstr "Afficher les alias" -#: templates/machines/aff_machines.html:95 +#: templates/machines/aff_machines.html:99 msgid "Display the IPv6 address" msgstr "Afficher les adresses IPv6" -#: templates/machines/aff_machines.html:110 +#: templates/machines/aff_machines.html:116 msgid " Edit" msgstr " Modifier" -#: templates/machines/aff_machines.html:118 +#: templates/machines/aff_machines.html:124 msgid " Manage the aliases" msgstr " Gérer les alias" -#: templates/machines/aff_machines.html:126 +#: templates/machines/aff_machines.html:132 msgid " Manage the IPv6 addresses" msgstr " Gérer les adresses IPv6" -#: templates/machines/aff_machines.html:134 +#: templates/machines/aff_machines.html:140 msgid " Manage the SSH fingerprints" msgstr " Gérer les empreintes SSH" -#: templates/machines/aff_machines.html:142 +#: templates/machines/aff_machines.html:148 msgid " Manage the ports configuration" msgstr " Gérer les configuration de ports" @@ -906,7 +943,7 @@ msgstr "Priorité" #: templates/machines/aff_nas.html:33 templates/machines/aff_soa.html:32 #: templates/machines/aff_vlan.html:34 -#: templates/machines/index_portlist.html:18 +#: templates/machines/index_portlist.html:20 msgid "Name" msgstr "Nom" @@ -1019,18 +1056,10 @@ msgstr "Port" msgid "Target" msgstr "Cible" -#: templates/machines/aff_sshfp.html:31 -msgid "SSH public key" -msgstr "Clé publique SSH" - #: templates/machines/aff_sshfp.html:32 msgid "Algorithm used" msgstr "Algorithme utilisé" -#: templates/machines/aff_sshfp.html:33 templates/machines/aff_vlan.html:35 -msgid "Comment" -msgstr "Commentaire" - #: templates/machines/aff_vlan.html:33 msgid "ID" msgstr "ID" @@ -1040,8 +1069,8 @@ msgid "IP ranges" msgstr "Plages d'IP" #: templates/machines/delete.html:29 -msgid "Creation and editing of machines" -msgstr "Création et modification de machines" +msgid "Deletion of machines" +msgstr "Suppression de machines" #: templates/machines/delete.html:35 #, python-format @@ -1058,16 +1087,16 @@ msgstr "Confirmer" #: templates/machines/edit_portlist.html:29 templates/machines/index.html:29 #: templates/machines/index.html:32 templates/machines/index_alias.html:29 -#: templates/machines/index_extension.html:31 -#: templates/machines/index_iptype.html:31 +#: templates/machines/index_extension.html:30 +#: templates/machines/index_iptype.html:30 #: templates/machines/index_ipv6.html:30 #: templates/machines/index_machinetype.html:31 #: templates/machines/index_nas.html:31 #: templates/machines/index_portlist.html:8 -#: templates/machines/index_portlist.html:23 +#: templates/machines/index_portlist.html:25 #: templates/machines/index_role.html:30 #: templates/machines/index_service.html:30 -#: templates/machines/index_sshfp.html:28 templates/machines/index_vlan.html:31 +#: templates/machines/index_sshfp.html:28 templates/machines/index_vlan.html:30 #: templates/machines/machine.html:31 templates/machines/sidebar.html:33 msgid "Machines" msgstr "Machines" @@ -1084,99 +1113,99 @@ msgstr "Créer ou modifier" msgid "List of the aliases of the interface" msgstr "Liste des alias de l'interface" -#: templates/machines/index_alias.html:33 +#: templates/machines/index_alias.html:34 msgid " Add an alias" msgstr " Ajouter un alias" -#: templates/machines/index_alias.html:34 +#: templates/machines/index_alias.html:36 msgid " Delete one or several aliases" msgstr " Supprimer un ou plusieurs alias" -#: templates/machines/index_extension.html:34 +#: templates/machines/index_extension.html:33 msgid "List of extensions" msgstr "Liste des extensions" -#: templates/machines/index_extension.html:36 +#: templates/machines/index_extension.html:37 msgid " Add an extension" msgstr " Ajouter une extension" -#: templates/machines/index_extension.html:38 +#: templates/machines/index_extension.html:40 msgid " Delete one or several extensions" msgstr " Supprimer une ou plusieurs extensions" -#: templates/machines/index_extension.html:41 +#: templates/machines/index_extension.html:44 msgid "List of SOA records" msgstr "Liste des enregistrements SOA" -#: templates/machines/index_extension.html:43 +#: templates/machines/index_extension.html:47 msgid " Add an SOA record" msgstr " Ajouter un enregistrement SOA" -#: templates/machines/index_extension.html:45 +#: templates/machines/index_extension.html:51 msgid " Delete one or several SOA records" msgstr " Supprimer un ou plusieurs enregistrements SOA" -#: templates/machines/index_extension.html:48 +#: templates/machines/index_extension.html:55 msgid "List of MX records" msgstr "Liste des enregistrements MX" -#: templates/machines/index_extension.html:50 +#: templates/machines/index_extension.html:58 msgid " Add an MX record" msgstr " Ajouter un enregistrement MX" -#: templates/machines/index_extension.html:52 +#: templates/machines/index_extension.html:62 msgid " Delete one or several MX records" msgstr " Supprimer un ou plusieurs enregistrements MX" -#: templates/machines/index_extension.html:55 +#: templates/machines/index_extension.html:66 msgid "List of NS records" msgstr "Liste des enregistrements NS" -#: templates/machines/index_extension.html:57 +#: templates/machines/index_extension.html:69 msgid " Add an NS record" msgstr " Ajouter un enregistrement NS" -#: templates/machines/index_extension.html:59 +#: templates/machines/index_extension.html:73 msgid " Delete one or several NS records" msgstr " Supprimer un ou plusieurs enregistrements NS" -#: templates/machines/index_extension.html:62 +#: templates/machines/index_extension.html:77 msgid "List of TXT records" msgstr "Liste des enregistrements TXT" -#: templates/machines/index_extension.html:64 +#: templates/machines/index_extension.html:80 msgid " Add a TXT record" msgstr " Ajouter un enregistrement TXT" -#: templates/machines/index_extension.html:66 +#: templates/machines/index_extension.html:84 msgid " Delete one or several TXT records" msgstr " Supprimer un ou plusieurs enregistrements TXT" -#: templates/machines/index_extension.html:69 +#: templates/machines/index_extension.html:88 msgid "List of DNAME records" msgstr "Liste des enregistrements DNAME" -#: templates/machines/index_extension.html:72 +#: templates/machines/index_extension.html:91 msgid " Add a DNAME record" msgstr " Ajouter un enregistrement DNAME" -#: templates/machines/index_extension.html:76 +#: templates/machines/index_extension.html:95 msgid " Delete one or several DNAME records" msgstr " Supprimer un ou plusieurs enregistrements DNAME" -#: templates/machines/index_extension.html:80 +#: templates/machines/index_extension.html:99 msgid "List of SRV records" msgstr "Liste des enregistrements SRV" -#: templates/machines/index_extension.html:82 +#: templates/machines/index_extension.html:102 msgid " Add an SRV record" msgstr " Ajouter un enregistrement SRV" -#: templates/machines/index_extension.html:84 +#: templates/machines/index_extension.html:106 msgid " Delete one or several SRV records" msgstr " Supprimer un ou plusieurs enregistrements SRV" -#: templates/machines/index_iptype.html:34 +#: templates/machines/index_iptype.html:33 msgid "List of IP types" msgstr "Liste des types d'IP" @@ -1184,7 +1213,7 @@ msgstr "Liste des types d'IP" msgid " Add an IP type" msgstr " Ajouter un type d'IP" -#: templates/machines/index_iptype.html:38 +#: templates/machines/index_iptype.html:40 msgid " Delete one or several IP types" msgstr " Supprimer un ou plusieurs types d'IP" @@ -1192,7 +1221,7 @@ msgstr " Supprimer un ou plusieurs types d'IP" msgid "List of the IPv6 addresses of the interface" msgstr "Liste des adresses IPv6 de l'interface" -#: templates/machines/index_ipv6.html:35 +#: templates/machines/index_ipv6.html:36 msgid " Add an IPv6 address" msgstr " Ajouter une adresse IPv6" @@ -1200,11 +1229,11 @@ msgstr " Ajouter une adresse IPv6" msgid "List of machine types" msgstr "Liste des types de machine" -#: templates/machines/index_machinetype.html:36 +#: templates/machines/index_machinetype.html:37 msgid " Add a machine type" msgstr " Ajouter un type de machine" -#: templates/machines/index_machinetype.html:38 +#: templates/machines/index_machinetype.html:41 msgid " Delete one or several machine types" msgstr " Supprimer un ou plusieurs types de machine" @@ -1223,11 +1252,11 @@ msgstr "" "type de machine à assigner aux machines en fonction du type de dispositif " "NAS." -#: templates/machines/index_nas.html:37 +#: templates/machines/index_nas.html:38 msgid " Add a NAS device type" msgstr " Ajouter un type de dispositif NAS" -#: templates/machines/index_nas.html:39 +#: templates/machines/index_nas.html:42 msgid " Delete one or several NAS device types" msgstr " Supprimer un ou plusieurs types de dispositif NAS" @@ -1235,23 +1264,23 @@ msgstr " Supprimer un ou plusieurs types de dispositif NAS" msgid "List of ports configurations" msgstr "Liste des configurations de ports" -#: templates/machines/index_portlist.html:13 +#: templates/machines/index_portlist.html:14 msgid " Add a configuration" msgstr " Ajouter une configuration" -#: templates/machines/index_portlist.html:19 +#: templates/machines/index_portlist.html:21 msgid "TCP (input)" msgstr "TCP (entrée)" -#: templates/machines/index_portlist.html:20 +#: templates/machines/index_portlist.html:22 msgid "TCP (output)" msgstr "TCP (sortie)" -#: templates/machines/index_portlist.html:21 +#: templates/machines/index_portlist.html:23 msgid "UDP (input)" msgstr "UDP (entrée)" -#: templates/machines/index_portlist.html:22 +#: templates/machines/index_portlist.html:24 msgid "UDP (output)" msgstr "UDP (sortie)" @@ -1259,11 +1288,11 @@ msgstr "UDP (sortie)" msgid "List of roles" msgstr "Liste des rôles" -#: templates/machines/index_role.html:35 +#: templates/machines/index_role.html:36 msgid " Add a role" msgstr " Ajouter un rôle" -#: templates/machines/index_role.html:37 +#: templates/machines/index_role.html:39 msgid " Delete one or several roles" msgstr " Supprimer un ou plusieurs rôles" @@ -1271,15 +1300,15 @@ msgstr " Supprimer un ou plusieurs rôles" msgid "List of services" msgstr "Liste des services" -#: templates/machines/index_service.html:35 +#: templates/machines/index_service.html:36 msgid " Add a service" msgstr " Ajouter un service" -#: templates/machines/index_service.html:37 +#: templates/machines/index_service.html:39 msgid " Delete one or several services" msgstr " Supprimer un ou plusieurs services" -#: templates/machines/index_service.html:39 +#: templates/machines/index_service.html:42 msgid "States of servers" msgstr "États des serveurs" @@ -1291,7 +1320,7 @@ msgstr "Empreintes SSH" msgid " Add an SSH fingerprint" msgstr " Ajouter une empreinte SSH" -#: templates/machines/index_vlan.html:34 +#: templates/machines/index_vlan.html:33 msgid "List of VLANs" msgstr "Liste des VLANs" @@ -1299,7 +1328,7 @@ msgstr "Liste des VLANs" msgid " Add a VLAN" msgstr " Ajouter un VLAN" -#: templates/machines/index_vlan.html:38 +#: templates/machines/index_vlan.html:39 msgid " Delete one or several VLANs" msgstr " Supprimer un ou plusieurs VLANs" @@ -1343,90 +1372,90 @@ msgstr "Rôles de serveur" msgid "Ports openings" msgstr "Ouvertures de ports" -#: views.py:156 -msgid "Select a machine type first.}," -msgstr "Sélectionnez un type de machine d'abord.}," +#: views.py:155 +msgid "Select a machine type first." +msgstr "Sélectionnez un type de machine d'abord." -#: views.py:258 +#: views.py:257 msgid "The machine was created." msgstr "La machine a été créée." -#: views.py:270 +#: views.py:269 msgid "Create a machine" msgstr "Créer une machine" -#: views.py:310 +#: views.py:309 msgid "The machine was edited." msgstr "La machine a été modifiée." -#: views.py:322 views.py:446 views.py:512 views.py:568 views.py:630 -#: views.py:691 views.py:749 views.py:806 views.py:863 views.py:919 +#: views.py:321 views.py:445 views.py:511 views.py:567 views.py:629 +#: views.py:690 views.py:748 views.py:805 views.py:862 views.py:919 #: views.py:977 views.py:1034 views.py:1106 views.py:1169 views.py:1226 #: views.py:1292 views.py:1349 msgid "Edit" msgstr "Modifier" -#: views.py:335 +#: views.py:334 msgid "The machine was deleted." msgstr "La machine a été supprimée." -#: views.py:364 +#: views.py:363 msgid "The interface was created." msgstr "L'interface a été créée." -#: views.py:391 +#: views.py:390 msgid "The interface was deleted." msgstr "L'interface a été supprimée." -#: views.py:416 +#: views.py:415 msgid "The IPv6 addresses list was created." msgstr "La liste d'adresses IPv6 a été créée." -#: views.py:422 +#: views.py:421 msgid "Create an IPv6 addresses list" msgstr "Créer une liste d'adresses IPv6" -#: views.py:440 +#: views.py:439 msgid "The IPv6 addresses list was edited." msgstr "La liste d'adresses IPv6 a été modifiée." -#: views.py:459 +#: views.py:458 msgid "The IPv6 addresses list was deleted." msgstr "La liste d'adresses IPv6 a été supprimée." -#: views.py:483 +#: views.py:482 msgid "The SSHFP record was created." msgstr "L'enregistrement SSHFP a été créé." -#: views.py:489 +#: views.py:488 msgid "Create a SSHFP record" msgstr "Créer un enregistrement SSHFP" -#: views.py:506 +#: views.py:505 msgid "The SSHFP record was edited." msgstr "L'enregistrement SSHFP a été modifié." -#: views.py:525 +#: views.py:524 msgid "The SSHFP record was deleted." msgstr "L'enregistrement SSHFP a été supprimé." -#: views.py:546 +#: views.py:545 msgid "The IP type was created." msgstr "Le type d'IP a été créé." -#: views.py:549 +#: views.py:548 msgid "Create an IP type" msgstr "Créer un type d'IP" -#: views.py:565 +#: views.py:564 msgid "The IP type was edited." msgstr "Le type d'IP a été modifié." -#: views.py:584 +#: views.py:583 msgid "The IP type was deleted." msgstr "Le type d'IP a été supprimé." -#: views.py:588 +#: views.py:587 #, python-format msgid "" "The IP type %s is assigned to at least one machine, you can't delete it." @@ -1434,29 +1463,29 @@ msgstr "" "Le type d'IP %s est assigné à au moins une machine, vous ne pouvez pas le " "supprimer." -#: views.py:593 views.py:655 views.py:716 views.py:773 views.py:830 -#: views.py:887 views.py:944 views.py:1001 views.py:1058 views.py:1136 +#: views.py:592 views.py:654 views.py:715 views.py:772 views.py:829 +#: views.py:886 views.py:944 views.py:1001 views.py:1058 views.py:1136 #: views.py:1193 views.py:1250 views.py:1316 views.py:1373 msgid "Delete" msgstr "Supprimer" -#: views.py:606 +#: views.py:605 msgid "The machine type was created." msgstr "Le type de machine a été créé." -#: views.py:609 +#: views.py:608 msgid "Create a machine type" msgstr "Créer un type de machine" -#: views.py:627 +#: views.py:626 msgid "The machine type was edited." msgstr "Le type de machine a été modifié." -#: views.py:646 +#: views.py:645 msgid "The machine type was deleted." msgstr "Le type de machine a été supprimé." -#: views.py:650 +#: views.py:649 #, python-format msgid "" "The machine type %s is assigned to at least one machine, you can't delete it." @@ -1464,23 +1493,23 @@ msgstr "" "Le type de machine %s est assigné à au moins un machine, vous ne pouvez pas " "le supprimer." -#: views.py:668 +#: views.py:667 msgid "The extension was created." msgstr "L'extension a été créée." -#: views.py:671 +#: views.py:670 msgid "Create an extension" msgstr "Créer une extension" -#: views.py:688 +#: views.py:687 msgid "The extension was edited." msgstr "L'extension a été modifiée." -#: views.py:707 +#: views.py:706 msgid "The extension was deleted." msgstr "L'extension a été supprimée." -#: views.py:711 +#: views.py:710 #, python-format msgid "" "The extension %s is assigned to at least one machine type, you can't delete " @@ -1489,65 +1518,65 @@ msgstr "" "L'extension %s est assignée à au moins un type de machine, vous ne pouvez " "pas le supprimer." -#: views.py:729 +#: views.py:728 msgid "The SOA record was created." msgstr "L'enregistrement SOA a été créé." -#: views.py:732 +#: views.py:731 msgid "Create an SOA record" msgstr "Créer un enregistrement SOA" -#: views.py:746 +#: views.py:745 msgid "The SOA record was edited." msgstr "L'enregistrement SOA a été modifié." -#: views.py:765 +#: views.py:764 msgid "The SOA record was deleted." msgstr "L'enregistrement SOA a été supprimé." -#: views.py:769 +#: views.py:768 #, python-format msgid "Error: the SOA record %s can't be deleted." msgstr "Erreur : l'enregistrement SOA %s ne peut pas être supprimé." -#: views.py:786 +#: views.py:785 msgid "The MX record was created." msgstr "L'enregistrement MX a été créé." -#: views.py:789 +#: views.py:788 msgid "Create an MX record" msgstr "Créer un enregistrement MX" -#: views.py:803 +#: views.py:802 msgid "The MX record was edited." msgstr "L'enregistrement MX a été modifié." -#: views.py:822 +#: views.py:821 msgid "The MX record was deleted." msgstr "L'enregistrement MX a été supprimé." -#: views.py:826 +#: views.py:825 #, python-format msgid "Error: the MX record %s can't be deleted." msgstr "Erreur : l'enregistrement MX %s ne peut pas être supprimé." -#: views.py:843 +#: views.py:842 msgid "The NS record was created." msgstr "L'enregistrement NS a été créé." -#: views.py:846 +#: views.py:845 msgid "Create an NS record" msgstr "Créer un enregistrement NS" -#: views.py:860 +#: views.py:859 msgid "The NS record was edited." msgstr "L'enregistrement NS a été modifié." -#: views.py:879 +#: views.py:878 msgid "The NS record was deleted." msgstr "L'enregistrement NS a été supprimé." -#: views.py:883 +#: views.py:882 #, python-format msgid "Error: the NS record %s can't be deleted." msgstr "Erreur : l'enregistrement NS %s ne peut pas être supprimé." diff --git a/machines/migrations/0101_auto_20190108_1623.py b/machines/migrations/0101_auto_20190108_1623.py new file mode 100644 index 00000000..856721ac --- /dev/null +++ b/machines/migrations/0101_auto_20190108_1623.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2019-01-08 22:23 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0100_auto_20190102_1753'), + ] + + operations = [ + migrations.AlterModelOptions( + name='ouvertureport', + options={'verbose_name': 'ports opening', 'verbose_name_plural': 'ports openings'}, + ), + migrations.AlterField( + model_name='nas', + name='port_access_mode', + field=models.CharField(choices=[('802.1X', '802.1X'), ('Mac-address', 'MAC-address')], default='802.1X', max_length=32), + ), + migrations.AlterField( + model_name='vlan', + name='igmp', + field=models.BooleanField(default=False, help_text='v4 multicast management'), + ), + migrations.AlterField( + model_name='vlan', + name='mld', + field=models.BooleanField(default=False, help_text='v6 multicast management'), + ), + ] diff --git a/machines/models.py b/machines/models.py index a4685676..600114a3 100644 --- a/machines/models.py +++ b/machines/models.py @@ -201,7 +201,7 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model): if interfaces_set: return str(interfaces_set.domain.name) else: - return "None" + return _("No name") @cached_property def complete_name(self): @@ -340,7 +340,7 @@ class IpType(RevMixin, AclMixin, models.Model): ("use_all_iptype", _("Can use all IP types")), ) verbose_name = _("IP type") - verbose_name_plural = "IP types" + verbose_name_plural = _("IP types") @cached_property def ip_range(self): @@ -534,11 +534,11 @@ class Vlan(RevMixin, AclMixin, models.Model): dhcpv6_snooping = models.BooleanField(default=False) igmp = models.BooleanField( default=False, - help_text="Gestion multicast v4" + help_text=_("v4 multicast management") ) mld = models.BooleanField( default=False, - help_text="Gestion multicast v6" + help_text=_("v6 multicast management") ) class Meta: @@ -559,7 +559,7 @@ class Nas(RevMixin, AclMixin, models.Model): default_mode = '802.1X' AUTH = ( ('802.1X', '802.1X'), - ('Mac-address', 'Mac-address'), + ('Mac-address', _("MAC-address")), ) name = models.CharField(max_length=255, unique=True) @@ -666,7 +666,7 @@ class SOA(RevMixin, AclMixin, models.Model): utilisée dans les migrations de la BDD. """ return cls.objects.get_or_create( name=_("SOA to edit"), - mail="postmaser@example.com" + mail="postmaster@example.com" )[0].pk @@ -934,7 +934,7 @@ class SshFp(RevMixin, AclMixin, models.Model): machine = models.ForeignKey('Machine', on_delete=models.CASCADE) pub_key_entry = models.TextField( - help_text="SSH public key", + help_text=_("SSH public key"), max_length=2048 ) algo = models.CharField( @@ -942,7 +942,7 @@ class SshFp(RevMixin, AclMixin, models.Model): max_length=32 ) comment = models.CharField( - help_text="Comment", + help_text=_("Comment"), max_length=255, null=True, blank=True @@ -1872,7 +1872,8 @@ class OuverturePort(RevMixin, AclMixin, models.Model): ) class Meta: - verbose_name = _("ports openings") + verbose_name = _("ports opening") + verbose_name_plural = _("ports openings") def __str__(self): if self.begin == self.end: diff --git a/machines/templates/machines/aff_alias.html b/machines/templates/machines/aff_alias.html index 5a1bc8f8..ee8580b0 100644 --- a/machines/templates/machines/aff_alias.html +++ b/machines/templates/machines/aff_alias.html @@ -38,7 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ alias }} {% can_edit alias %} - {% include 'buttons/edit.html' with href='machines:edit-alias' id=alias.id %} + {% include 'buttons/edit.html' with href='machines:edit-alias' id=alias.id %} {% acl_end %} {% history_button alias %} diff --git a/machines/templates/machines/aff_dname.html b/machines/templates/machines/aff_dname.html index 66883057..6d07a7bc 100644 --- a/machines/templates/machines/aff_dname.html +++ b/machines/templates/machines/aff_dname.html @@ -38,7 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ dname.dns_entry }} {% can_edit dname %} - {% include 'buttons/edit.html' with href='machines:edit-dname' id=dname.id %} + {% include 'buttons/edit.html' with href='machines:edit-dname' id=dname.id %} {% acl_end %} {% history_button dname %} diff --git a/machines/templates/machines/aff_extension.html b/machines/templates/machines/aff_extension.html index fae4e25b..1083b1b1 100644 --- a/machines/templates/machines/aff_extension.html +++ b/machines/templates/machines/aff_extension.html @@ -54,7 +54,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ extension.dnssec|tick }} {% can_edit extension %} - {% include 'buttons/edit.html' with href='machines:edit-extension' id=extension.id %} + {% include 'buttons/edit.html' with href='machines:edit-extension' id=extension.id %} {% acl_end %} {% history_button extension %} diff --git a/machines/templates/machines/aff_iptype.html b/machines/templates/machines/aff_iptype.html index b408bfb1..c30c0c73 100644 --- a/machines/templates/machines/aff_iptype.html +++ b/machines/templates/machines/aff_iptype.html @@ -56,7 +56,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ type.ouverture_ports }} {% can_edit type %} - {% include 'buttons/edit.html' with href='machines:edit-iptype' id=type.id %} + {% include 'buttons/edit.html' with href='machines:edit-iptype' id=type.id %} {% acl_end %} {% history_button type %} diff --git a/machines/templates/machines/aff_ipv6.html b/machines/templates/machines/aff_ipv6.html index e8e4a48e..f67bf4c3 100644 --- a/machines/templates/machines/aff_ipv6.html +++ b/machines/templates/machines/aff_ipv6.html @@ -40,10 +40,10 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ ipv6.slaac_ip }} {% can_edit ipv6 %} - {% include 'buttons/edit.html' with href='machines:edit-ipv6list' id=ipv6.id %} + {% include 'buttons/edit.html' with href='machines:edit-ipv6list' id=ipv6.id %} {% acl_end %} {% can_delete ipv6 %} - {% include 'buttons/suppr.html' with href='machines:del-ipv6list' id=ipv6.id %} + {% include 'buttons/suppr.html' with href='machines:del-ipv6list' id=ipv6.id %} {% acl_end %} {% history_button ipv6 %} diff --git a/machines/templates/machines/aff_machines.html b/machines/templates/machines/aff_machines.html index d5a83ed3..4363cd6e 100644 --- a/machines/templates/machines/aff_machines.html +++ b/machines/templates/machines/aff_machines.html @@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if machines_list.paginator %} - {% include "pagination.html" with list=machines_list go_to_id="machines" %} + {% include 'pagination.html' with list=machines_list go_to_id="machines" %} {% endif %} @@ -41,7 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "DNS name" as tr_dns_name %} - + @@ -52,19 +52,19 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -153,7 +153,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% history_button interface %} {% can_delete interface %} - {% include 'buttons/suppr.html' with href='machines:del-interface' id=interface.id %} + {% include 'buttons/suppr.html' with href='machines:del-interface' id=interface.id %} {% acl_end %} @@ -215,6 +215,6 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if machines_list.paginator %} - {% include "pagination.html" with list=machines_list go_to_id="machines" %} + {% include 'pagination.html' with list=machines_list go_to_id="machines" %} {% endif %} diff --git a/machines/templates/machines/aff_machinetype.html b/machines/templates/machines/aff_machinetype.html index a55a5370..ebd77b4f 100644 --- a/machines/templates/machines/aff_machinetype.html +++ b/machines/templates/machines/aff_machinetype.html @@ -40,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/machines/templates/machines/aff_mx.html b/machines/templates/machines/aff_mx.html index 4a50724b..b10d4eff 100644 --- a/machines/templates/machines/aff_mx.html +++ b/machines/templates/machines/aff_mx.html @@ -42,7 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/machines/templates/machines/aff_nas.html b/machines/templates/machines/aff_nas.html index 84013f90..7a98a7f4 100644 --- a/machines/templates/machines/aff_nas.html +++ b/machines/templates/machines/aff_nas.html @@ -47,7 +47,7 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/machines/templates/machines/aff_ns.html b/machines/templates/machines/aff_ns.html index 2968607a..dda578f3 100644 --- a/machines/templates/machines/aff_ns.html +++ b/machines/templates/machines/aff_ns.html @@ -40,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/machines/templates/machines/aff_role.html b/machines/templates/machines/aff_role.html index b6303917..6f285c89 100644 --- a/machines/templates/machines/aff_role.html +++ b/machines/templates/machines/aff_role.html @@ -44,7 +44,7 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/machines/templates/machines/aff_service.html b/machines/templates/machines/aff_service.html index 102ceead..d3eb16ba 100644 --- a/machines/templates/machines/aff_service.html +++ b/machines/templates/machines/aff_service.html @@ -47,7 +47,7 @@ with this program; if not, write to the Free Software Foundation, Inc., class="fa fa-sync"> diff --git a/machines/templates/machines/aff_soa.html b/machines/templates/machines/aff_soa.html index 9199533e..50a4a5c3 100644 --- a/machines/templates/machines/aff_soa.html +++ b/machines/templates/machines/aff_soa.html @@ -48,7 +48,7 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/machines/templates/machines/aff_srv.html b/machines/templates/machines/aff_srv.html index 71fb78a2..1a699b49 100644 --- a/machines/templates/machines/aff_srv.html +++ b/machines/templates/machines/aff_srv.html @@ -52,7 +52,7 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/machines/templates/machines/aff_sshfp.html b/machines/templates/machines/aff_sshfp.html index 08d1df13..ca88d0f4 100644 --- a/machines/templates/machines/aff_sshfp.html +++ b/machines/templates/machines/aff_sshfp.html @@ -41,11 +41,11 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/machines/templates/machines/aff_txt.html b/machines/templates/machines/aff_txt.html index 456f7343..3da268ca 100644 --- a/machines/templates/machines/aff_txt.html +++ b/machines/templates/machines/aff_txt.html @@ -40,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/machines/templates/machines/aff_vlan.html b/machines/templates/machines/aff_vlan.html index 3ccbfcb0..0b10262b 100644 --- a/machines/templates/machines/aff_vlan.html +++ b/machines/templates/machines/aff_vlan.html @@ -45,7 +45,7 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/machines/templates/machines/delete.html b/machines/templates/machines/delete.html index f009f905..59ba2102 100644 --- a/machines/templates/machines/delete.html +++ b/machines/templates/machines/delete.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -26,14 +26,13 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load bootstrap3 %} {% load i18n %} -{% block title %}{% trans "Creation and editing of machines" %}{% endblock %} +{% block title %}{% trans "Deletion of machines" %}{% endblock %} {% block content %} {% csrf_token %} -

{% blocktrans %}Warning: are you sure you want to delete this object {{ objet_name }} ( {{ objet }} - )?{% endblocktrans %}

+

{% blocktrans %}Warning: are you sure you want to delete this object {{ objet_name }} ( {{ objet }} )?{% endblocktrans %}

{% trans "Confirm" as tr_confirm %} {% bootstrap_button tr_confirm button_type="submit" icon='trash' button_class='btn-danger' %} diff --git a/machines/templates/machines/edit_portlist.html b/machines/templates/machines/edit_portlist.html index a7aa6f04..fa9f771a 100644 --- a/machines/templates/machines/edit_portlist.html +++ b/machines/templates/machines/edit_portlist.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/machines/templates/machines/index.html b/machines/templates/machines/index.html index ceef062c..3aad6d06 100644 --- a/machines/templates/machines/index.html +++ b/machines/templates/machines/index.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block content %}

{% trans "Machines" %}

- {% include "machines/aff_machines.html" with machines_list=machines_list %} + {% include 'machines/aff_machines.html' with machines_list=machines_list %}


diff --git a/machines/templates/machines/index_alias.html b/machines/templates/machines/index_alias.html index a2ffe66b..7f392667 100644 --- a/machines/templates/machines/index_alias.html +++ b/machines/templates/machines/index_alias.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., class="fa fa-plus">{% trans " Add an alias" %}{% trans " Delete one or several aliases" %} - {% include "machines/aff_alias.html" with alias_list=alias_list %} + {% include 'machines/aff_alias.html' with alias_list=alias_list %}


diff --git a/machines/templates/machines/index_extension.html b/machines/templates/machines/index_extension.html index e689d479..636b314e 100644 --- a/machines/templates/machines/index_extension.html +++ b/machines/templates/machines/index_extension.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -39,7 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Delete one or several extensions" %} - {% include "machines/aff_extension.html" with extension_list=extension_list %} + {% include 'machines/aff_extension.html' with extension_list=extension_list %}

{% trans "List of SOA records" %}

{% can_create SOA %} @@ -50,7 +50,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Delete one or several SOA records" %} - {% include "machines/aff_soa.html" with soa_list=soa_list %} + {% include 'machines/aff_soa.html' with soa_list=soa_list %}

{% trans "List of MX records" %}

{% can_create Mx %} @@ -61,7 +61,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Delete one or several MX records" %} - {% include "machines/aff_mx.html" with mx_list=mx_list %} + {% include 'machines/aff_mx.html' with mx_list=mx_list %}

{% trans "List of NS records" %}

{% can_create Ns %} @@ -72,7 +72,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Delete one or several NS records" %} - {% include "machines/aff_ns.html" with ns_list=ns_list %} + {% include 'machines/aff_ns.html' with ns_list=ns_list %}

{% trans "List of TXT records" %}

{% can_create Txt %} @@ -83,7 +83,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Delete one or several TXT records" %} - {% include "machines/aff_txt.html" with txt_list=txt_list %} + {% include 'machines/aff_txt.html' with txt_list=txt_list %}

{% trans "List of DNAME records" %}

{% can_create DName %} @@ -94,7 +94,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Delete one or several DNAME records" %} - {% include "machines/aff_dname.html" with dname_list=dname_list %} + {% include 'machines/aff_dname.html' with dname_list=dname_list %}

{% trans "List of SRV records" %}

{% can_create Srv %} @@ -105,5 +105,5 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Delete one or several SRV records" %} - {% include "machines/aff_srv.html" with srv_list=srv_list %} + {% include 'machines/aff_srv.html' with srv_list=srv_list %} {% endblock %} diff --git a/machines/templates/machines/index_iptype.html b/machines/templates/machines/index_iptype.html index fea17993..7ffa8cf3 100644 --- a/machines/templates/machines/index_iptype.html +++ b/machines/templates/machines/index_iptype.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -39,5 +39,5 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Delete one or several IP types" %} - {% include "machines/aff_iptype.html" with iptype_list=iptype_list %} + {% include 'machines/aff_iptype.html' with iptype_list=iptype_list %} {% endblock %} diff --git a/machines/templates/machines/index_ipv6.html b/machines/templates/machines/index_ipv6.html index 2ab2231e..98ea697a 100644 --- a/machines/templates/machines/index_ipv6.html +++ b/machines/templates/machines/index_ipv6.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -36,7 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Add an IPv6 address" %} {% acl_end %} - {% include "machines/aff_ipv6.html" with ipv6_list=ipv6_list %} + {% include 'machines/aff_ipv6.html' with ipv6_list=ipv6_list %}


diff --git a/machines/templates/machines/index_machinetype.html b/machines/templates/machines/index_machinetype.html index 5d184e29..407aef5b 100644 --- a/machines/templates/machines/index_machinetype.html +++ b/machines/templates/machines/index_machinetype.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -40,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Delete one or several machine types" %} - {% include "machines/aff_machinetype.html" with machinetype_list=machinetype_list %} + {% include 'machines/aff_machinetype.html' with machinetype_list=machinetype_list %}


diff --git a/machines/templates/machines/index_nas.html b/machines/templates/machines/index_nas.html index c4da9779..bb17395a 100644 --- a/machines/templates/machines/index_nas.html +++ b/machines/templates/machines/index_nas.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -41,7 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Delete one or several NAS device types" %} - {% include "machines/aff_nas.html" with nas_list=nas_list %} + {% include 'machines/aff_nas.html' with nas_list=nas_list %}


diff --git a/machines/templates/machines/index_portlist.html b/machines/templates/machines/index_portlist.html index c6659b65..c540478d 100644 --- a/machines/templates/machines/index_portlist.html +++ b/machines/templates/machines/index_portlist.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% load bootstrap3 %} diff --git a/machines/templates/machines/index_role.html b/machines/templates/machines/index_role.html index 3271bc43..38799aa5 100644 --- a/machines/templates/machines/index_role.html +++ b/machines/templates/machines/index_role.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -37,5 +37,5 @@ with this program; if not, write to the Free Software Foundation, Inc., {% acl_end %} {% trans " Delete one or several roles" %} - {% include "machines/aff_role.html" with role_list=role_list %} + {% include 'machines/aff_role.html' with role_list=role_list %} {% endblock %} diff --git a/machines/templates/machines/index_service.html b/machines/templates/machines/index_service.html index a41c79c6..19244e71 100644 --- a/machines/templates/machines/index_service.html +++ b/machines/templates/machines/index_service.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -37,8 +37,8 @@ with this program; if not, write to the Free Software Foundation, Inc., {% acl_end %} {% trans " Delete one or several services" %} - {% include "machines/aff_service.html" with service_list=service_list %} + {% include 'machines/aff_service.html' with service_list=service_list %}

{% trans "States of servers" %}

- {% include "machines/aff_servers.html" with servers_list=servers_list %} + {% include 'machines/aff_servers.html' with servers_list=servers_list %} {% endblock %} diff --git a/machines/templates/machines/index_sshfp.html b/machines/templates/machines/index_sshfp.html index 0233bac4..c1508eaf 100644 --- a/machines/templates/machines/index_sshfp.html +++ b/machines/templates/machines/index_sshfp.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -34,5 +34,5 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Add an SSH fingerprint" %} {% acl_end %} - {% include "machines/aff_sshfp.html" with sshfp_list=sshfp_list %} + {% include 'machines/aff_sshfp.html' with sshfp_list=sshfp_list %} {% endblock %} diff --git a/machines/templates/machines/index_vlan.html b/machines/templates/machines/index_vlan.html index f34f3ebb..830cde65 100644 --- a/machines/templates/machines/index_vlan.html +++ b/machines/templates/machines/index_vlan.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -37,5 +37,5 @@ with this program; if not, write to the Free Software Foundation, Inc., {% acl_end %} {% trans " Delete one or several VLANs" %} - {% include "machines/aff_vlan.html" with vlan_list=vlan_list %} + {% include 'machines/aff_vlan.html' with vlan_list=vlan_list %} {% endblock %} diff --git a/machines/templates/machines/machine.html b/machines/templates/machines/machine.html index 1e2e3700..27c7ea27 100644 --- a/machines/templates/machines/machine.html +++ b/machines/templates/machines/machine.html @@ -1,4 +1,4 @@ -{% extends "machines/sidebar.html" %} +{% extends 'machines/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -171,3 +171,4 @@ with this program; if not, write to the Free Software Foundation, Inc., {% bootstrap_button action_name button_type="submit" icon='ok' button_class='btn-success' %} {% endblock %} + diff --git a/machines/templates/machines/sidebar.html b/machines/templates/machines/sidebar.html index 81c83ab9..f7c63f6f 100644 --- a/machines/templates/machines/sidebar.html +++ b/machines/templates/machines/sidebar.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends 'base.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -28,57 +28,58 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block sidebar %} {% can_view_all Machine %} - + {% trans "Machines" %} {% acl_end %} {% can_view_all MachineType %} - + {% trans "Machine types" %} {% acl_end %} {% can_view_all Extension %} - + {% trans "Extensions and zones" %} {% acl_end %} {% can_view_all IpType %} - + {% trans "IP ranges" %} {% acl_end %} {% can_view_all Vlan %} - + {% trans "VLANs" %} {% acl_end %} {% can_view_all Nas %} - + {% trans "NAS devices" %} {% acl_end %} {% can_view_all machines.Service %} - + {% trans "Services (DHCP, DNS, ...)" %} {% acl_end %} {% can_view_all Role %} - + {% trans "Server roles" %} {% acl_end %} {% can_view_all OuverturePortList %} - + {% trans "Ports openings" %} {% acl_end %} {% endblock %} + From 77e62df3b8b9348b4e13a715602ebf24be8f82a2 Mon Sep 17 00:00:00 2001 From: Laouen Fernet Date: Wed, 9 Jan 2019 00:39:47 +0100 Subject: [PATCH 51/73] add translations for preferences/ --- preferences/forms.py | 2 +- preferences/locale/fr/LC_MESSAGES/django.po | 968 +++++++++++++----- .../migrations/0058_auto_20190108_1650.py | 208 ++++ preferences/models.py | 126 ++- .../templates/preferences/aff_radiuskey.html | 36 +- .../preferences/aff_radiusoptions.html | 14 +- .../templates/preferences/aff_reminder.html | 36 +- .../templates/preferences/aff_service.html | 16 +- .../preferences/aff_switchmanagementcred.html | 32 +- preferences/templates/preferences/delete.html | 10 +- .../preferences/display_preferences.html | 72 +- .../preferences/edit_preferences.html | 2 +- .../templates/preferences/preferences.html | 2 +- .../templates/preferences/sidebar.html | 2 +- preferences/views.py | 39 +- 15 files changed, 1113 insertions(+), 452 deletions(-) create mode 100644 preferences/migrations/0058_auto_20190108_1650.py diff --git a/preferences/forms.py b/preferences/forms.py index 7e644808..3d461ef2 100644 --- a/preferences/forms.py +++ b/preferences/forms.py @@ -359,7 +359,7 @@ class DelMailContactForm(Form): """Delete contact email adress""" mailcontacts = forms.ModelMultipleChoiceField( queryset=MailContact.objects.none(), - label="Enregistrements adresses actuels", + label=_("Current email addresses"), widget=forms.CheckboxSelectMultiple ) diff --git a/preferences/locale/fr/LC_MESSAGES/django.po b/preferences/locale/fr/LC_MESSAGES/django.po index 65effeea..3528330e 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: 2018-10-15 00:30+0200\n" +"POT-Creation-Date: 2019-01-12 15:13+0100\n" "PO-Revision-Date: 2018-06-24 15:54+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -34,282 +34,386 @@ msgstr "" msgid "You don't have the right to view this application." msgstr "Vous n'avez pas le droit de voir cette application." -#: forms.py:62 templates/preferences/display_preferences.html:68 +#: forms.py:63 templates/preferences/display_preferences.html:142 msgid "Telephone number required" msgstr "Numéro de téléphone requis" -#: forms.py:64 +#: forms.py:65 msgid "GPG fingerprint" msgstr "Empreinte GPG" -#: forms.py:65 +#: forms.py:66 msgid "All can create a club" msgstr "Tous peuvent créer un club" -#: forms.py:66 +#: forms.py:67 msgid "All can create a member" msgstr "Tous peuvent créer un adhérent" -#: forms.py:67 templates/preferences/display_preferences.html:50 +#: forms.py:68 templates/preferences/display_preferences.html:120 msgid "Self registration" msgstr "Autoinscription" -#: forms.py:68 +#: forms.py:69 msgid "Default shell" -msgstr "Interface système par défaut" +msgstr "Interface en ligne de commande par défaut" -#: forms.py:84 +#: forms.py:85 msgid "Possibility to set a password per machine" msgstr "Possibilité de mettre un mot de passe par machine" -#: forms.py:86 templates/preferences/display_preferences.html:101 +#: forms.py:87 templates/preferences/display_preferences.html:172 msgid "Maximum number of interfaces allowed for a standard user" msgstr "Nombre maximum d'interfaces autorisé pour un utilisateur standard" -#: forms.py:90 templates/preferences/display_preferences.html:105 +#: forms.py:91 templates/preferences/display_preferences.html:176 msgid "Maximum number of DNS aliases allowed for a standard user" msgstr "Nombre maximum d'alias DNS autorisé pour un utilisateur standard" -#: forms.py:93 +#: forms.py:94 msgid "IPv6 mode" msgstr "Mode IPv6" -#: forms.py:94 +#: forms.py:95 msgid "Can create a machine" msgstr "Peut créer une machine" -#: forms.py:117 -msgid "RADIUS general policy" -msgstr "Politique générale de RADIUS" - -#: forms.py:118 templates/preferences/display_preferences.html:130 -msgid "VLAN for machines accepted by RADIUS" -msgstr "VLAN pour les machines acceptées par RADIUS" - -#: forms.py:120 templates/preferences/display_preferences.html:132 -msgid "VLAN for machines rejected by RADIUS" -msgstr "VLAN pour les machines rejetées par RADIUS" - -#: forms.py:145 -#, fuzzy -#| msgid "General message" +#: forms.py:141 msgid "General message in French" -msgstr "Message général" +msgstr "Message général en français" -#: forms.py:146 -#, fuzzy -#| msgid "General message" +#: forms.py:142 msgid "General message in English" -msgstr "Message général" +msgstr "Message général en anglais" -#: forms.py:147 templates/preferences/display_preferences.html:213 +#: forms.py:143 templates/preferences/display_preferences.html:58 msgid "Number of results displayed when searching" msgstr "Nombre de résultats affichés lors de la recherche" -#: forms.py:150 +#: forms.py:146 msgid "Number of items per page, standard size (e.g. users)" msgstr "Nombre d'éléments par page, taille standard (ex : utilisateurs)" -#: forms.py:153 +#: forms.py:149 msgid "Number of items per page, large size (e.g. machines)" msgstr "Nombre d'éléments par page, taille importante (ex : machines)" -#: forms.py:156 templates/preferences/display_preferences.html:221 +#: forms.py:152 templates/preferences/display_preferences.html:66 msgid "Time before expiration of the reset password link (in hours)" msgstr "" "Temps avant expiration du lien de réinitialisation de mot de passe (en " "heures)" -#: forms.py:159 templates/preferences/display_preferences.html:207 +#: forms.py:155 templates/preferences/display_preferences.html:52 msgid "Website name" msgstr "Nom du site" -#: forms.py:160 templates/preferences/display_preferences.html:209 +#: forms.py:156 templates/preferences/display_preferences.html:54 msgid "Email address for automatic emailing" msgstr "Adresse mail pour les mails automatiques" -#: forms.py:162 templates/preferences/display_preferences.html:227 +#: forms.py:158 templates/preferences/display_preferences.html:76 msgid "Summary of the General Terms of Use" msgstr "Résumé des Conditions Générales d'Utilisation" -#: forms.py:164 templates/preferences/display_preferences.html:231 +#: forms.py:160 templates/preferences/display_preferences.html:78 msgid "General Terms of Use" msgstr "Conditions Générales d'Utilisation" -#: forms.py:180 +#: forms.py:176 msgid "Organisation name" msgstr "Nom de l'association" -#: forms.py:181 templates/preferences/display_preferences.html:246 +#: forms.py:177 templates/preferences/display_preferences.html:323 msgid "SIRET number" msgstr "Numéro SIRET" -#: forms.py:182 +#: forms.py:178 msgid "Address (line 1)" msgstr "Adresse (ligne 1)" -#: forms.py:183 +#: forms.py:179 msgid "Address (line 2)" msgstr "Adresse (ligne 2)" -#: forms.py:184 models.py:482 -#: templates/preferences/display_preferences.html:254 +#: forms.py:180 models.py:476 +#: templates/preferences/display_preferences.html:331 msgid "Contact email address" msgstr "Adresse mail de contact" -#: forms.py:185 templates/preferences/display_preferences.html:258 +#: forms.py:181 templates/preferences/display_preferences.html:335 msgid "Telephone number" msgstr "Numéro de téléphone" -#: forms.py:186 templates/preferences/display_preferences.html:260 +#: forms.py:182 templates/preferences/display_preferences.html:337 msgid "Usual name" msgstr "Nom d'usage" -#: forms.py:187 +#: forms.py:183 msgid "Account used for editing from /admin" msgstr "Compte utilisé pour les modifications depuis /admin" -#: forms.py:189 +#: forms.py:185 msgid "Payment" msgstr "Paiement" -#: forms.py:190 +#: forms.py:186 msgid "Payment ID" msgstr "ID de paiement" -#: forms.py:191 +#: forms.py:187 msgid "Payment password" msgstr "Mot de passe de paiement" -#: forms.py:192 forms.py:243 templates/preferences/aff_service.html:33 +#: forms.py:188 forms.py:267 templates/preferences/aff_service.html:33 msgid "Description" msgstr "Description" -#: forms.py:208 +#: forms.py:204 msgid "Message for the French welcome email" msgstr "Message pour le mail de bienvenue en français" -#: forms.py:210 +#: forms.py:206 msgid "Message for the English welcome email" msgstr "Message pour le mail de bienvenue en anglais" -#: forms.py:227 +#: forms.py:223 msgid "Facebook URL" msgstr "URL du compte Facebook" -#: forms.py:228 +#: forms.py:224 msgid "Twitter URL" msgstr "URL du compte Twitter" -#: forms.py:229 templates/preferences/display_preferences.html:314 +#: forms.py:225 templates/preferences/display_preferences.html:445 msgid "Twitter account name" msgstr "Nom du compte Twitter" -#: forms.py:241 templates/preferences/aff_service.html:31 -#: templates/preferences/display_preferences.html:244 +#: forms.py:247 +msgid "You chose to set vlan but did not set any VLAN." +msgstr "" +"Vous avez choisi de paramétrer vlan mais vous n'avez indiqué aucun VLAN." + +#: forms.py:251 +msgid "Please, choose a VLAN." +msgstr "Veuillez choisir un VLAN." + +#: forms.py:265 templates/preferences/aff_service.html:31 +#: templates/preferences/display_preferences.html:321 msgid "Name" msgstr "Nom" -#: forms.py:242 templates/preferences/aff_service.html:32 +#: forms.py:266 templates/preferences/aff_service.html:32 msgid "URL" msgstr "URL" -#: forms.py:244 templates/preferences/aff_service.html:34 +#: forms.py:268 templates/preferences/aff_service.html:34 msgid "Image" msgstr "Image" -#: forms.py:251 +#: forms.py:275 msgid "Current services" msgstr "Services actuels" +#: forms.py:362 +msgid "Current email addresses" +msgstr "Adresses mail actuelles" + #: models.py:76 -msgid "Users can create a club" -msgstr "Les utilisateurs peuvent créer un club" +msgid "Users can create a club." +msgstr "Les utilisateurs peuvent créer un club." #: models.py:80 -msgid "Users can create a member" -msgstr "Les utilisateurs peuvent créer un adhérent" +msgid "Users can create a member." +msgstr "Les utilisateurs peuvent créer un adhérent." -#: models.py:91 templates/preferences/display_preferences.html:62 -msgid "Users can edit their shell" -msgstr "Les utilisateurs peuvent modifier leur interface système" +#: models.py:91 +msgid "Users can edit their shell." +msgstr "Les utilisateurs peuvent modifier leur interface en ligne de commande." -#: models.py:95 templates/preferences/display_preferences.html:66 -#, fuzzy -#| msgid "Users can edit their shell" -msgid "Users can edit their room" -msgstr "Les utilisateurs peuvent modifier leur interface système" +#: models.py:95 +msgid "Users can edit their room." +msgstr "Les utilisateurs peuvent modifier leur chambre." #: models.py:99 -msgid "Enable local email accounts for users" -msgstr "Active les comptes mail locaux pour les utilisateurs" +msgid "Enable local email accounts for users." +msgstr "Activer les comptes mail locaux pour les utilisateurs." #: models.py:104 msgid "Domain to use for local email accounts" msgstr "Domaine à utiliser pour les comptes mail locaux" #: models.py:108 -msgid "Maximum number of local email addresses for a standard user" +msgid "Maximum number of local email addresses for a standard user." msgstr "" -"Nombre maximum d'adresses mail locales autorisé pour un utilisateur standard" +"Nombre maximum d'adresses mail locales autorisé pour un utilisateur standard." #: models.py:113 -msgid "Inactive users will be deleted after this number of days" -msgstr "Les utilisateurs n'ayant jamais adhéré seront supprimés après (jours)" +msgid "Not yet active users will be deleted after this number of days." +msgstr "" +"Les utilisateurs n'ayant jamais adhéré seront supprimés après ce nombre de " +"jours." -#: models.py:117 -msgid "A new user can create their account on Re2o" -msgstr "Un nouvel utilisateur peut créer son compte sur Re2o" +#: models.py:118 +msgid "A new user can create their account on Re2o." +msgstr "Un nouvel utilisateur peut créer son compte sur Re2o." #: models.py:122 +msgid "" +"If True, all new created and connected users are active. If False, only when " +"a valid registration has been paid." +msgstr "" +"Si True, tous les nouveaux utilisations créés et connectés sont actifs. Si " +"False, seulement quand une inscription validée a été payée." + +#: models.py:128 msgid "Can view the user options" msgstr "Peut voir les options d'utilisateur" -#: models.py:124 +#: models.py:130 msgid "user options" msgstr "options d'utilisateur" -#: models.py:131 +#: models.py:137 msgid "Email domain must begin with @" msgstr "Un domaine mail doit commencer par @" -#: models.py:149 +#: models.py:155 msgid "Autoconfiguration by RA" msgstr "Configuration automatique par RA" -#: models.py:150 +#: models.py:156 msgid "IP addresses assigning by DHCPv6" msgstr "Attribution d'adresses IP par DHCPv6" -#: models.py:151 +#: models.py:157 msgid "Disabled" msgstr "Désactivé" -#: models.py:173 +#: models.py:179 msgid "Can view the machine options" msgstr "Peut voir les options de machine" -#: models.py:175 +#: models.py:181 msgid "machine options" msgstr "options de machine" -#: models.py:194 +#: models.py:200 models.py:592 msgid "On the IP range's VLAN of the machine" msgstr "Sur le VLAN de la plage d'IP de la machine" -#: models.py:195 +#: models.py:201 models.py:593 msgid "Preset in 'VLAN for machines accepted by RADIUS'" msgstr "Prédéfinie dans 'VLAN pour les machines acceptées par RADIUS'" -#: models.py:315 +#: models.py:210 templates/preferences/display_preferences.html:246 +msgid "Web management, activated in case of automatic provision" +msgstr "Gestion web, activée en cas de provision automatique" + +#: models.py:214 +msgid "" +"SSL web management, make sure that a certificate is installed on the switch" +msgstr "" +"Gestion web SSL, vérifiez qu'un certificat est installé sur le commutateur " +"réseau" + +#: models.py:219 templates/preferences/display_preferences.html:248 +msgid "REST management, activated in case of automatic provision" +msgstr "Gestion REST, activée en cas de provision automatique" + +#: models.py:226 templates/preferences/display_preferences.html:262 +msgid "IP range for the management of switches" +msgstr "Plage d'IP pour la gestion des commutateurs réseau" + +#: models.py:232 templates/preferences/display_preferences.html:270 +msgid "Provision of configuration mode for switches" +msgstr "Mode de provision de configuration pour les commutateurs réseau" + +#: models.py:238 +msgid "SFTP login for switches" +msgstr "Identifiant SFTP pour les commutateurs réseau" + +#: models.py:244 +msgid "SFTP password" +msgstr "Mot de passe SFTP" + +#: models.py:303 msgid "Can view the topology options" msgstr "Peut voir les options de topologie" -#: models.py:317 +#: models.py:305 msgid "topology options" msgstr "options de topologie" -#: models.py:419 +#: models.py:319 models.py:337 +msgid "RADIUS key" +msgstr "Clé RADIUS" + +#: models.py:325 +msgid "Comment for this key" +msgstr "Commentaire pour cette clé" + +#: models.py:330 +msgid "Default key for switches" +msgstr "Clé par défaut pour les commutateurs réseau" + +#: models.py:335 +msgid "Can view a RADIUS key object" +msgstr "Peut voir un objet clé RADIUS" + +#: models.py:338 templates/preferences/display_preferences.html:221 +msgid "RADIUS keys" +msgstr "clés RADIUS" + +#: models.py:341 +msgid "RADIUS key " +msgstr "clé RADIUS " + +#: models.py:348 templates/preferences/aff_switchmanagementcred.html:31 +msgid "Switch login" +msgstr "Identifiant du commutateur réseau" + +#: models.py:352 +msgid "Password" +msgstr "Mot de passe" + +#: models.py:357 +msgid "Default credentials for switches" +msgstr "Identifiants par défaut pour les commutateurs réseau" + +#: models.py:362 +msgid "Can view a switch management credentials object" +msgstr "Peut voir un objet identifiants de gestion de commutateur réseau" + +#: models.py:365 +msgid "switch management credentials" +msgstr "identifiants de gestion de commutateur réseau" + +#: models.py:368 +msgid "Switch login " +msgstr "Identifiant du commutateur réseau " + +#: models.py:380 +msgid "Delay between the email and the membership's end" +msgstr "Délai entre le mail et la fin d'adhésion" + +#: models.py:387 +msgid "Message displayed specifically for this reminder" +msgstr "Message affiché spécifiquement pour ce rappel" + +#: models.py:392 +msgid "Can view a reminder object" +msgstr "Peut voir un objet rappel" + +#: models.py:394 +msgid "reminder" +msgstr "rappel" + +#: models.py:395 +msgid "reminders" +msgstr "rappels" + +#: models.py:412 msgid "" "General message displayed on the French version of the website (e.g. in case " "of maintenance)" @@ -317,7 +421,7 @@ msgstr "" "Message général affiché sur la version française du site (ex : en cas de " "maintenance)" -#: models.py:425 +#: models.py:418 msgid "" "General message displayed on the English version of the website (e.g. in " "case of maintenance)" @@ -325,185 +429,199 @@ msgstr "" "Message général affiché sur la version anglaise du site (ex : en cas de " "maintenance)" -#: models.py:447 +#: models.py:441 msgid "Can view the general options" msgstr "Peut voir les options générales" -#: models.py:449 +#: models.py:443 msgid "general options" msgstr "options générales" -#: models.py:469 +#: models.py:463 msgid "Can view the service options" msgstr "Peut voir les options de service" -#: models.py:471 +#: models.py:465 msgid "service" msgstr "service" -#: models.py:472 +#: models.py:466 msgid "services" msgstr "services" -#: models.py:489 +#: models.py:482 msgid "Description of the associated email address." msgstr "Description de l'adresse mail associée." -#: models.py:499 +#: models.py:492 msgid "Can view a contact email address object" msgstr "Peut voir un objet adresse mail de contact" -#: models.py:501 +#: models.py:494 msgid "contact email address" msgstr "adresse mail de contact" -#: models.py:502 +#: models.py:495 msgid "contact email addresses" msgstr "adresses mail de contact" -#: models.py:512 +#: models.py:505 msgid "Networking organisation school Something" msgstr "Association de réseau de l'école Machin" -#: models.py:516 +#: models.py:509 msgid "Threadneedle Street" msgstr "1 rue de la Vrillière" -#: models.py:517 +#: models.py:510 msgid "London EC2R 8AH" msgstr "75001 Paris" -#: models.py:520 +#: models.py:513 msgid "Organisation" msgstr "Association" -#: models.py:534 +#: models.py:527 msgid "Can view the organisation options" msgstr "Peut voir les options d'association" -#: models.py:536 +#: models.py:529 msgid "organisation options" msgstr "options d'association" -#: models.py:565 +#: models.py:558 msgid "Can view the homepage options" msgstr "Peut voir les options de page d'accueil" -#: models.py:567 +#: models.py:560 msgid "homepage options" msgstr "options de page d'accueil" -#: models.py:585 +#: models.py:573 +msgid "Welcome email in French" +msgstr "Mail de bienvenue en français" + +#: models.py:574 +msgid "Welcome email in English" +msgstr "Mail de bienvenue en anglais" + +#: models.py:578 msgid "Can view the email message options" msgstr "Peut voir les options de message pour les mails" -#: models.py:588 +#: models.py:581 msgid "email message options" msgstr "options de messages pour les mails" +#: models.py:586 +msgid "RADIUS policy" +msgstr "Politique de RADIUS" + +#: models.py:587 +msgid "RADIUS policies" +msgstr "Politiques de RADIUS" + +#: models.py:598 +msgid "Reject the machine" +msgstr "Rejeter la machine" + +#: models.py:599 +msgid "Place the machine on the VLAN" +msgstr "Placer la machine sur le VLAN" + +#: models.py:610 +msgid "Policy for unknown machines" +msgstr "Politique pour les machines inconnues" + +#: models.py:618 +msgid "Unknown machines VLAN" +msgstr "VLAN pour les machines inconnues" + +#: models.py:619 +msgid "VLAN for unknown machines if not rejected" +msgstr "VLAN pour les machines inconnues si non rejeté" + +#: models.py:625 +msgid "Policy for unknown ports" +msgstr "Politique pour les ports inconnus" + +#: models.py:633 +msgid "Unknown ports VLAN" +msgstr "VLAN pour les ports inconnus" + +#: models.py:634 +msgid "VLAN for unknown ports if not rejected" +msgstr "VLAN pour les ports inconnus si non rejeté" + +#: models.py:640 +msgid "" +"Policy for machines connecting from unregistered rooms (relevant on ports " +"with STRICT RADIUS mode)" +msgstr "" +"Politique pour les machines se connectant depuis des chambre non " +"enregistrées (pertinent pour les ports avec le mode de RADIUS STRICT)" + +#: models.py:649 +msgid "Unknown rooms VLAN" +msgstr "VLAN pour les chambres inconnues" + +#: models.py:650 +msgid "VLAN for unknown rooms if not rejected" +msgstr "VLAN pour les chambres inconnues si non rejeté" + +#: models.py:656 +msgid "Policy for non members" +msgstr "Politique pour les non adhérents" + +#: models.py:664 +msgid "Non members VLAN" +msgstr "VLAN pour les non adhérents" + +#: models.py:665 +msgid "VLAN for non members if not rejected" +msgstr "VLAN pour les non adhérents si non rejeté" + +#: models.py:671 +msgid "Policy for banned users" +msgstr "Politique pour les utilisateurs bannis" + +#: models.py:679 +msgid "Banned users VLAN" +msgstr "VLAN pour les utilisateurs bannis" + +#: models.py:680 +msgid "VLAN for banned users if not rejected" +msgstr "VLAN pour les utilisateurs bannis si non rejeté" + #: templates/preferences/aff_mailcontact.html:31 -#: templates/preferences/display_preferences.html:250 +#: templates/preferences/display_preferences.html:327 msgid "Address" msgstr "Adresse" #: templates/preferences/aff_mailcontact.html:32 +#: templates/preferences/aff_radiuskey.html:32 msgid "Comment" msgstr "Commentaire" -#: templates/preferences/display_preferences.html:31 -#: templates/preferences/edit_preferences.html:30 -#: templates/preferences/preferences.html:30 -msgid "Preferences" -msgstr "Préférences" +#: templates/preferences/aff_radiuskey.html:31 +msgid "RADIUS key ID" +msgstr "ID de la clé RADIUS" -#: templates/preferences/display_preferences.html:34 -msgid "User preferences" -msgstr "Préférences d'utilisateur" +#: templates/preferences/aff_radiuskey.html:33 +msgid "Default RADIUS key for switches" +msgstr "Clé RADIUS par défaut pour les commutateurs réseau" -#: templates/preferences/display_preferences.html:37 -#: templates/preferences/display_preferences.html:93 -#: templates/preferences/display_preferences.html:118 -#: templates/preferences/display_preferences.html:201 -#: templates/preferences/display_preferences.html:238 -#: templates/preferences/display_preferences.html:273 -#: templates/preferences/display_preferences.html:300 -#: templates/preferences/edit_preferences.html:40 views.py:173 views.py:221 -#: views.py:375 -msgid "Edit" -msgstr "Modifier" +#: templates/preferences/aff_radiuskey.html:34 +msgid "RADIUS key used by the swithes" +msgstr "Clé RADIUS utilisée par les commutateurs réseau" -#: templates/preferences/display_preferences.html:41 -#: templates/preferences/display_preferences.html:198 -msgid "General preferences" -msgstr "Préférences générales" - -#: templates/preferences/display_preferences.html:44 -msgid "Creation of members by everyone" -msgstr "Création d'adhérents par tous" - -#: templates/preferences/display_preferences.html:46 -msgid "Creation of clubs by everyone" -msgstr "Création de clubs par tous" - -#: templates/preferences/display_preferences.html:52 -msgid "Delete not yet active users after" -msgstr "Suppression des utilisateurs n'ayant jamais adhéré après" - -#: templates/preferences/display_preferences.html:57 -#, fuzzy -#| msgid "general options" -msgid "Users general permissions" -msgstr "Permissions générales des utilisateurs" - -#: templates/preferences/display_preferences.html:60 -msgid "Default shell for users" -msgstr "Interface système par défaut pour les utilisateurs" - -#: templates/preferences/display_preferences.html:72 -msgid "GPG fingerprint field" -msgstr "Champ empreinte GPG" - -#: templates/preferences/display_preferences.html:77 -msgid "Email accounts preferences" -msgstr "Préférences de comptes mail" - -#: templates/preferences/display_preferences.html:80 -msgid "Local email accounts enabled" -msgstr "Comptes mail locaux activés" - -#: templates/preferences/display_preferences.html:82 -msgid "Local email domain" -msgstr "Domaine de mail local" - -#: templates/preferences/display_preferences.html:86 -msgid "Maximum number of email aliases allowed" -msgstr "Nombre maximum d'alias mail autorisé pour un utilisateur standard" - -#: templates/preferences/display_preferences.html:90 -msgid "Machines preferences" -msgstr "Préférences de machines" - -#: templates/preferences/display_preferences.html:99 -msgid "Password per machine" -msgstr "Mot de passe par machine" - -#: templates/preferences/display_preferences.html:107 -msgid "IPv6 support" -msgstr "Support de l'IPv6" - -#: templates/preferences/display_preferences.html:111 -msgid "Creation of machines" -msgstr "Création de machines" - -#: templates/preferences/display_preferences.html:115 -msgid "Topology preferences" -msgstr "Préférences de topologie" - -#: templates/preferences/display_preferences.html:124 +#: templates/preferences/aff_radiusoptions.html:28 +#: templates/preferences/display_preferences.html:204 msgid "General policy for VLAN setting" msgstr "Politique générale pour le placement sur un VLAN" -#: templates/preferences/display_preferences.html:126 +#: templates/preferences/aff_radiusoptions.html:30 +#: templates/preferences/display_preferences.html:206 msgid "" "This setting defines the VLAN policy after acceptance by RADIUS: either on " "the IP range's VLAN of the machine, or a VLAN preset in 'VLAN for machines " @@ -513,67 +631,356 @@ msgstr "" "par RADIUS: soit sur le VLAN de la plage d'IP de la machine, soit sur le " "VLAN prédéfini dans 'VLAN pour les machines acceptées par RADIUS'" -#: templates/preferences/display_preferences.html:215 +#: templates/preferences/aff_radiusoptions.html:33 +#: templates/preferences/display_preferences.html:210 +msgid "VLAN for machines accepted by RADIUS" +msgstr "VLAN pour les machines acceptées par RADIUS" + +#: templates/preferences/aff_radiusoptions.html:34 +#, python-format +msgid "VLAN %(vlan_decision_ok)s" +msgstr "VLAN %(vlan_decision_ok)s" + +#: templates/preferences/aff_radiusoptions.html:41 +msgid "Situation" +msgstr "Situation" + +#: templates/preferences/aff_radiusoptions.html:42 +msgid "Behaviour" +msgstr "Comportement" + +#: templates/preferences/aff_radiusoptions.html:46 +msgid "Unknown machine" +msgstr "Machine inconnue" + +#: templates/preferences/aff_radiusoptions.html:49 +#: templates/preferences/aff_radiusoptions.html:59 +#: templates/preferences/aff_radiusoptions.html:69 +#: templates/preferences/aff_radiusoptions.html:79 +#: templates/preferences/aff_radiusoptions.html:89 +msgid "Reject" +msgstr "Rejeter" + +#: templates/preferences/aff_radiusoptions.html:51 +#, python-format +msgid "VLAN %(unknown_machine_vlan)s" +msgstr "VLAN %(unknown_machine_vlan)s" + +#: templates/preferences/aff_radiusoptions.html:56 +msgid "Unknown port" +msgstr "Port inconnu" + +#: templates/preferences/aff_radiusoptions.html:61 +#, python-format +msgid "VLAN %(unknown_port_vlan)s" +msgstr "VLAN %(unknown_port_vlan)s" + +#: templates/preferences/aff_radiusoptions.html:66 +msgid "Unknown room" +msgstr "Chambre inconnue" + +#: templates/preferences/aff_radiusoptions.html:71 +#, python-format +msgid "VLAN %(unknown_room_vlan)s" +msgstr "VLAN %(unknown_room_vlan)s" + +#: templates/preferences/aff_radiusoptions.html:76 +msgid "Non member" +msgstr "Non adhérent" + +#: templates/preferences/aff_radiusoptions.html:81 +#, python-format +msgid "VLAN %(non_member_vlan)s" +msgstr "VLAN %(non_member_vlan)s" + +#: templates/preferences/aff_radiusoptions.html:86 +msgid "Banned user" +msgstr "Utilisateur banni" + +#: templates/preferences/aff_radiusoptions.html:91 +#, python-format +msgid "VLAN %(banned_vlan)s" +msgstr "VLAN %(banned_vlan)s" + +#: templates/preferences/aff_reminder.html:31 +msgid "Number of days before the reminder" +msgstr "Nombre de jours avant le rappel" + +#: templates/preferences/aff_reminder.html:32 +msgid "Message for this reminder" +msgstr "Message pour ce rappel" + +#: templates/preferences/aff_switchmanagementcred.html:32 +msgid "Default switch management credentials" +msgstr "Identifiants de gestion de commutateur réseau par défaut" + +#: templates/preferences/aff_switchmanagementcred.html:33 +msgid "Management credentials used by the switches" +msgstr "Identifiants de gestion utilisés par les commutateurs réseau" + +#: templates/preferences/delete.html:29 +msgid "Deletion of preferences" +msgstr "Suppression de préférences" + +#: templates/preferences/delete.html:35 +#, python-format +msgid "" +"Warning: are you sure you want to delete this %(objet_name)s object " +"( %(objet)s )?" +msgstr "" +"Attention : voulez-vous vraiment supprimer cet objet %(objet_name)s " +"( %(objet)s ) ?" + +#: templates/preferences/delete.html:36 +msgid "Confirm" +msgstr "Confirmer" + +#: templates/preferences/display_preferences.html:31 +#: templates/preferences/edit_preferences.html:30 +#: templates/preferences/preferences.html:30 +msgid "Preferences" +msgstr "Préférences" + +#: templates/preferences/display_preferences.html:39 +msgid "General preferences" +msgstr "Préférences générales" + +#: templates/preferences/display_preferences.html:46 +#: templates/preferences/display_preferences.html:108 +#: templates/preferences/display_preferences.html:165 +#: templates/preferences/display_preferences.html:199 +#: templates/preferences/display_preferences.html:240 +#: templates/preferences/display_preferences.html:301 +#: templates/preferences/display_preferences.html:316 +#: templates/preferences/display_preferences.html:360 +#: templates/preferences/display_preferences.html:438 +#: templates/preferences/edit_preferences.html:46 views.py:178 views.py:226 +#: views.py:272 views.py:321 views.py:381 +msgid "Edit" +msgstr "Modifier" + +#: templates/preferences/display_preferences.html:60 msgid "Number of items per page (standard size)" msgstr "Nombre d'éléments par page (taille standard)" -#: templates/preferences/display_preferences.html:219 +#: templates/preferences/display_preferences.html:64 msgid "Number of items per page (large size)" msgstr "Nombre d'éléments par page (taille importante)" -#: templates/preferences/display_preferences.html:225 +#: templates/preferences/display_preferences.html:70 msgid "General message displayed on the website" msgstr "Message général affiché sur le site" -#: templates/preferences/display_preferences.html:235 +#: templates/preferences/display_preferences.html:72 +msgid "Main site URL" +msgstr "URL du site principal" + +#: templates/preferences/display_preferences.html:84 +msgid "Local email accounts enabled" +msgstr "Comptes mail locaux activés" + +#: templates/preferences/display_preferences.html:86 +msgid "Local email domain" +msgstr "Domaine de mail local" + +#: templates/preferences/display_preferences.html:90 +msgid "Maximum number of email aliases allowed" +msgstr "Nombre maximum d'alias mail autorisé pour un utilisateur standard" + +#: templates/preferences/display_preferences.html:100 +msgid "User preferences" +msgstr "Préférences d'utilisateur" + +#: templates/preferences/display_preferences.html:114 +msgid "Creation of members by everyone" +msgstr "Création d'adhérents par tous" + +#: templates/preferences/display_preferences.html:116 +msgid "Creation of clubs by everyone" +msgstr "Création de clubs par tous" + +#: templates/preferences/display_preferences.html:122 +msgid "Delete not yet active users after" +msgstr "Suppression des utilisateurs n'ayant jamais adhéré après" + +#: templates/preferences/display_preferences.html:123 +#, python-format +msgid "%(delete_notyetactive)s days" +msgstr "%(delete_notyetactive)s jours" + +#: templates/preferences/display_preferences.html:126 +msgid "All users are active by default" +msgstr "Tous les utilisateurs sont actifs par défault" + +#: templates/preferences/display_preferences.html:131 +msgid "Users general permissions" +msgstr "Permissions générales des utilisateurs" + +#: templates/preferences/display_preferences.html:134 +msgid "Default shell for users" +msgstr "Interface en ligne de commande par défaut pour les utilisateurs" + +#: templates/preferences/display_preferences.html:136 +msgid "Users can edit their shell" +msgstr "Les utilisateurs peuvent modifier leur interface en ligne de commande" + +#: templates/preferences/display_preferences.html:140 +msgid "Users can edit their room" +msgstr "Les utilisateurs peuvent modifier leur chambre" + +#: templates/preferences/display_preferences.html:146 +msgid "GPG fingerprint field" +msgstr "Champ empreinte GPG" + +#: templates/preferences/display_preferences.html:157 +msgid "Machines preferences" +msgstr "Préférences de machines" + +#: templates/preferences/display_preferences.html:170 +msgid "Password per machine" +msgstr "Mot de passe par machine" + +#: templates/preferences/display_preferences.html:178 +msgid "IPv6 support" +msgstr "Support de l'IPv6" + +#: templates/preferences/display_preferences.html:182 +msgid "Creation of machines" +msgstr "Création de machines" + +#: templates/preferences/display_preferences.html:192 +msgid "Topology preferences" +msgstr "Préférences de topologie" + +#: templates/preferences/display_preferences.html:212 +msgid "VLAN for machines rejected by RADIUS" +msgstr "VLAN pour les machines rejetées par RADIUS" + +#: templates/preferences/display_preferences.html:216 +msgid "VLAN for non members machines" +msgstr "VLAN pour les machines des non adhérents" + +#: templates/preferences/display_preferences.html:223 +msgid " Add a RADIUS key" +msgstr " Ajouter une clé RADIUS" + +#: templates/preferences/display_preferences.html:233 +msgid "Configuration of switches" +msgstr "Configuration de commutateurs réseau" + +#: templates/preferences/display_preferences.html:255 +msgid "Provision of configuration for switches" +msgstr "Provision de configuration pour les commutateurs réseau" + +#: templates/preferences/display_preferences.html:258 +msgid "Switches with automatic provision" +msgstr "Commutateurs réseau avec provision automatique" + +#: templates/preferences/display_preferences.html:259 +#: templates/preferences/display_preferences.html:263 +#: templates/preferences/display_preferences.html:267 +#: templates/preferences/display_preferences.html:275 +#: templates/preferences/display_preferences.html:279 +#: templates/preferences/display_preferences.html:289 +msgid "OK" +msgstr "OK" + +#: templates/preferences/display_preferences.html:259 +#: templates/preferences/display_preferences.html:263 +#: templates/preferences/display_preferences.html:267 +#: templates/preferences/display_preferences.html:289 +msgid "Missing" +msgstr "Manquant" + +#: templates/preferences/display_preferences.html:266 +msgid "Server for the configuration of switches" +msgstr "Serveur pour la configuration des commutateurs réseau" + +#: templates/preferences/display_preferences.html:274 +msgid "TFTP mode" +msgstr "Mode TFTP" + +#: templates/preferences/display_preferences.html:278 +msgid "SFTP mode" +msgstr "Mode SFTP" + +#: templates/preferences/display_preferences.html:279 +msgid "Missing credentials" +msgstr "Identifiants manquants" + +#: templates/preferences/display_preferences.html:283 +msgid "Switch management credentials" +msgstr "Identifiants de gestion de commutateur réseau" + +#: templates/preferences/display_preferences.html:285 +msgid " Add switch management credentials" +msgstr " Ajouter des identifiants de gestion de commutateur réseau" + +#: templates/preferences/display_preferences.html:296 +msgid "RADIUS preferences" +msgstr "Préférences RADIUS" + +#: templates/preferences/display_preferences.html:310 msgid "Information about the organisation" msgstr "Informations sur l'association" -#: templates/preferences/display_preferences.html:264 +#: templates/preferences/display_preferences.html:341 msgid "User object of the organisation" msgstr "Objet utilisateur de l'association" -#: templates/preferences/display_preferences.html:266 +#: templates/preferences/display_preferences.html:343 msgid "Description of the organisation" msgstr "Description de l'association" -#: templates/preferences/display_preferences.html:270 -msgid "Custom email message" -msgstr "Message personnalisé pour les mails" +#: templates/preferences/display_preferences.html:353 +msgid "Message for emails" +msgstr "Message pour les mails" -#: templates/preferences/display_preferences.html:279 +#: templates/preferences/display_preferences.html:366 msgid "Welcome email (in French)" msgstr "Mail de bienvenue (en français)" -#: templates/preferences/display_preferences.html:283 +#: templates/preferences/display_preferences.html:370 msgid "Welcome email (in English)" msgstr "Mail de bienvenue (en anglais)" -#: templates/preferences/display_preferences.html:293 +#: templates/preferences/display_preferences.html:380 +msgid "Options for the membership's end email" +msgstr "Options pour le mail de fin d'adhésion" + +#: templates/preferences/display_preferences.html:386 +msgid " Add a reminder" +msgstr " Ajouter un rappel" + +#: templates/preferences/display_preferences.html:397 msgid "List of services and homepage preferences" msgstr "Liste des services et préférences de page d'accueil" -#: templates/preferences/display_preferences.html:295 +#: templates/preferences/display_preferences.html:403 msgid " Add a service" msgstr " Ajouter un service" -#: templates/preferences/display_preferences.html:302 +#: templates/preferences/display_preferences.html:414 msgid "List of contact email addresses" msgstr "Liste des adresses mail de contact" -#: templates/preferences/display_preferences.html:304 -msgid "Add an address" -msgstr "Ajouter une adresse" +#: templates/preferences/display_preferences.html:420 +msgid " Add an address" +msgstr " Ajouter une adresse" -#: templates/preferences/display_preferences.html:306 -msgid "Delete one or several addresses" +#: templates/preferences/display_preferences.html:422 +msgid " Delete one or several addresses" msgstr " Supprimer une ou plusieurs adresses" -#: templates/preferences/display_preferences.html:312 +#: templates/preferences/display_preferences.html:431 +msgid "Social networks" +msgstr "Réseaux sociaux" + +#: templates/preferences/display_preferences.html:443 msgid "Twitter account URL" msgstr "URL du compte Twitter" -#: templates/preferences/display_preferences.html:318 +#: templates/preferences/display_preferences.html:449 msgid "Facebook account URL" msgstr "URL du compte Facebook" @@ -581,61 +988,112 @@ msgstr "URL du compte Facebook" msgid "Editing of preferences" msgstr "Modification des préférences" -#: views.py:111 -msgid "Unknown object" -msgstr "Objet inconnu" +#: views.py:114 +msgid "Unknown object." +msgstr "Objet inconnu." -#: views.py:117 +#: views.py:120 msgid "You don't have the right to edit this option." msgstr "Vous n'avez pas le droit de modifier cette option." -#: views.py:134 +#: views.py:137 msgid "The preferences were edited." msgstr "Les préférences ont été modifiées." -#: views.py:150 +#: views.py:155 msgid "The service was added." msgstr "Le service a été ajouté." -#: views.py:153 views.py:202 +#: views.py:158 msgid "Add a service" -msgstr " Ajouter un service" +msgstr "Ajouter un service" -#: views.py:170 views.py:218 +#: views.py:175 msgid "The service was edited." msgstr "Le service a été modifié." -#: views.py:199 -#, fuzzy -#| msgid "The service was added." -msgid "The reminder was added." -msgstr "Le service a été ajouté." +#: views.py:189 +msgid "The service was deleted." +msgstr "Le service a été supprimé." -#: views.py:351 +#: views.py:204 +msgid "The reminder was added." +msgstr "Le rappel a été ajouté." + +#: views.py:207 +msgid "Add a reminder" +msgstr "Ajouter un rappel" + +#: views.py:223 +msgid "The reminder was edited." +msgstr "Le rappel a été modifié." + +#: views.py:239 +msgid "The reminder was deleted." +msgstr "Le rappel a été supprimé." + +#: views.py:255 +msgid "The RADIUS key was added." +msgstr "La clé RADIUS a été ajoutée." + +#: views.py:258 +msgid "Add a RADIUS key" +msgstr "Ajouter une clé RADIUS" + +#: views.py:269 +msgid "The RADIUS key was edited." +msgstr "La clé RADIUS a été modifiée." + +#: views.py:285 +msgid "The RADIUS key was deleted." +msgstr "La clé RADIUS a été supprimée." + +#: views.py:287 +msgid "The RADIUS key is assigned to at least one switch, you can't delete it." +msgstr "" +"La clé RADIUS est assignée a au moins un commutateur réseau, vous ne pouvez " +"pas la supprimer." + +#: views.py:304 +msgid "The switch management credentials were added." +msgstr "Les identifiants de gestion de commutateur réseay ont été ajoutés." + +#: views.py:307 +msgid "Add switch management credentials" +msgstr "Ajouter des identifiants de gestion de commutateur réseau" + +#: views.py:318 +msgid "The switch management credentials were edited." +msgstr "Les identifiants de gestion de commutateur réseau ont été modifiés." + +#: views.py:334 +msgid "The switch management credentials were deleted." +msgstr "Les identifiants de gestion de commutateur réseau ont été supprimés." + +#: views.py:336 +msgid "" +"The switch management credentials are assigned to at least one switch, you " +"can't delete them." +msgstr "" +"Les identifiants de gestion de commutateur réseau sont assignés à au moins " +"un commutateur réseau , vous ne pouvez pas les supprimer." + +#: views.py:357 msgid "The contact email address was created." msgstr "L'adresse mail de contact a été supprimée." -#: views.py:355 +#: views.py:361 msgid "Add a contact email address" msgstr "Ajouter une adresse mail de contact" -#: views.py:372 +#: views.py:378 msgid "The contact email address was edited." msgstr "L'adresse mail de contact a été modifiée." -#: views.py:394 +#: views.py:400 msgid "The contact email adress was deleted." msgstr "L'adresse mail de contact a été supprimée." -#: views.py:397 +#: views.py:403 msgid "Delete" msgstr "Supprimer" - -#~ msgid " Delete one or several services" -#~ msgstr " Supprimer un ou plusieurs services" - -#~ msgid "The service was deleted." -#~ msgstr "Le service a été supprimé." - -#~ msgid "Error: the service %s can't be deleted." -#~ msgstr "Erreur : le service %s ne peut pas être supprimé." diff --git a/preferences/migrations/0058_auto_20190108_1650.py b/preferences/migrations/0058_auto_20190108_1650.py new file mode 100644 index 00000000..e90b6067 --- /dev/null +++ b/preferences/migrations/0058_auto_20190108_1650.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2019-01-08 22:50 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import re2o.aes_field + + +class Migration(migrations.Migration): + + dependencies = [ + ('preferences', '0057_optionaluser_all_users_active'), + ] + + operations = [ + migrations.AlterModelOptions( + name='radiuskey', + options={'permissions': (('view_radiuskey', 'Can view a RADIUS key object'),), 'verbose_name': 'RADIUS key', 'verbose_name_plural': 'RADIUS keys'}, + ), + migrations.AlterModelOptions( + name='radiusoption', + options={'verbose_name': 'RADIUS policy', 'verbose_name_plural': 'RADIUS policies'}, + ), + migrations.AlterModelOptions( + name='reminder', + options={'permissions': (('view_reminder', 'Can view a reminder object'),), 'verbose_name': 'reminder', 'verbose_name_plural': 'reminders'}, + ), + migrations.AlterModelOptions( + name='switchmanagementcred', + options={'permissions': (('view_switchmanagementcred', 'Can view a switch management credentials object'),), 'verbose_name': 'switch management credentials'}, + ), + migrations.AlterField( + model_name='mailmessageoption', + name='welcome_mail_en', + field=models.TextField(default='', help_text='Welcome email in English'), + ), + migrations.AlterField( + model_name='mailmessageoption', + name='welcome_mail_fr', + field=models.TextField(default='', help_text='Welcome email in French'), + ), + migrations.AlterField( + model_name='optionaltopologie', + name='sftp_login', + field=models.CharField(blank=True, help_text='SFTP login for switches', max_length=32, null=True), + ), + migrations.AlterField( + model_name='optionaltopologie', + name='sftp_pass', + field=re2o.aes_field.AESEncryptedField(blank=True, help_text='SFTP password', max_length=63, null=True), + ), + migrations.AlterField( + model_name='optionaltopologie', + name='switchs_ip_type', + field=models.OneToOneField(blank=True, help_text='IP range for the management of switches', null=True, on_delete=django.db.models.deletion.PROTECT, to='machines.IpType'), + ), + migrations.AlterField( + model_name='optionaltopologie', + name='switchs_provision', + field=models.CharField(choices=[('sftp', 'sftp'), ('tftp', 'tftp')], default='tftp', help_text='Provision of configuration mode for switches', max_length=32), + ), + migrations.AlterField( + model_name='optionaltopologie', + name='switchs_rest_management', + field=models.BooleanField(default=False, help_text='REST management, activated in case of automatic provision'), + ), + migrations.AlterField( + model_name='optionaltopologie', + name='switchs_web_management', + field=models.BooleanField(default=False, help_text='Web management, activated in case of automatic provision'), + ), + migrations.AlterField( + model_name='optionaltopologie', + name='switchs_web_management_ssl', + field=models.BooleanField(default=False, help_text='SSL web management, make sure that a certificate is installed on the switch'), + ), + migrations.AlterField( + model_name='optionaluser', + name='all_can_create_adherent', + field=models.BooleanField(default=False, help_text='Users can create a member.'), + ), + migrations.AlterField( + model_name='optionaluser', + name='all_can_create_club', + field=models.BooleanField(default=False, help_text='Users can create a club.'), + ), + migrations.AlterField( + model_name='optionaluser', + name='all_users_active', + field=models.BooleanField(default=False, help_text='If True, all new created and connected users are active. If False, only when a valid registration has been paid.'), + ), + migrations.AlterField( + model_name='optionaluser', + name='delete_notyetactive', + field=models.IntegerField(default=15, help_text='Not yet active users will be deleted after this number of days.'), + ), + migrations.AlterField( + model_name='optionaluser', + name='local_email_accounts_enabled', + field=models.BooleanField(default=False, help_text='Enable local email accounts for users.'), + ), + migrations.AlterField( + model_name='optionaluser', + name='max_email_address', + field=models.IntegerField(default=15, help_text='Maximum number of local email addresses for a standard user.'), + ), + migrations.AlterField( + model_name='optionaluser', + name='self_adhesion', + field=models.BooleanField(default=False, help_text='A new user can create their account on Re2o.'), + ), + migrations.AlterField( + model_name='optionaluser', + name='self_change_room', + field=models.BooleanField(default=False, help_text='Users can edit their room.'), + ), + migrations.AlterField( + model_name='optionaluser', + name='self_change_shell', + field=models.BooleanField(default=False, help_text='Users can edit their shell.'), + ), + migrations.AlterField( + model_name='radiuskey', + name='comment', + field=models.CharField(blank=True, help_text='Comment for this key', max_length=255, null=True), + ), + migrations.AlterField( + model_name='radiuskey', + name='default_switch', + field=models.BooleanField(default=True, help_text='Default key for switches', unique=True), + ), + migrations.AlterField( + model_name='radiuskey', + name='radius_key', + field=re2o.aes_field.AESEncryptedField(help_text='RADIUS key', max_length=255), + ), + migrations.AlterField( + model_name='radiusoption', + name='banned', + field=models.CharField(choices=[('REJECT', 'Reject the machine'), ('SET_VLAN', 'Place the machine on the VLAN')], default='REJECT', max_length=32, verbose_name='Policy for banned users'), + ), + migrations.AlterField( + model_name='radiusoption', + name='banned_vlan', + field=models.ForeignKey(blank=True, help_text='VLAN for banned users if not rejected', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='banned_vlan', to='machines.Vlan', verbose_name='Banned users VLAN'), + ), + migrations.AlterField( + model_name='radiusoption', + name='non_member', + field=models.CharField(choices=[('REJECT', 'Reject the machine'), ('SET_VLAN', 'Place the machine on the VLAN')], default='REJECT', max_length=32, verbose_name='Policy for non members'), + ), + migrations.AlterField( + model_name='radiusoption', + name='non_member_vlan', + field=models.ForeignKey(blank=True, help_text='VLAN for non members if not rejected', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='non_member_vlan', to='machines.Vlan', verbose_name='Non members VLAN'), + ), + migrations.AlterField( + model_name='radiusoption', + name='unknown_machine_vlan', + field=models.ForeignKey(blank=True, help_text='VLAN for unknown machines if not rejected', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='unknown_machine_vlan', to='machines.Vlan', verbose_name='Unknown machines VLAN'), + ), + migrations.AlterField( + model_name='radiusoption', + name='unknown_port', + field=models.CharField(choices=[('REJECT', 'Reject the machine'), ('SET_VLAN', 'Place the machine on the VLAN')], default='REJECT', max_length=32, verbose_name='Policy for unknown ports'), + ), + migrations.AlterField( + model_name='radiusoption', + name='unknown_port_vlan', + field=models.ForeignKey(blank=True, help_text='VLAN for unknown ports if not rejected', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='unknown_port_vlan', to='machines.Vlan', verbose_name='Unknown ports VLAN'), + ), + migrations.AlterField( + model_name='radiusoption', + name='unknown_room', + field=models.CharField(choices=[('REJECT', 'Reject the machine'), ('SET_VLAN', 'Place the machine on the VLAN')], default='REJECT', max_length=32, verbose_name='Policy for machines connecting from unregistered rooms (relevant on ports with STRICT RADIUS mode)'), + ), + migrations.AlterField( + model_name='radiusoption', + name='unknown_room_vlan', + field=models.ForeignKey(blank=True, help_text='VLAN for unknown rooms if not rejected', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='unknown_room_vlan', to='machines.Vlan', verbose_name='Unknown rooms VLAN'), + ), + migrations.AlterField( + model_name='reminder', + name='days', + field=models.IntegerField(default=7, help_text="Delay between the email and the membership's end", unique=True), + ), + migrations.AlterField( + model_name='reminder', + name='message', + field=models.CharField(blank=True, default='', help_text='Message displayed specifically for this reminder', max_length=255, null=True), + ), + migrations.AlterField( + model_name='switchmanagementcred', + name='default_switch', + field=models.BooleanField(default=True, help_text='Default credentials for switches', unique=True), + ), + migrations.AlterField( + model_name='switchmanagementcred', + name='management_id', + field=models.CharField(help_text='Switch login', max_length=63), + ), + migrations.AlterField( + model_name='switchmanagementcred', + name='management_pass', + field=re2o.aes_field.AESEncryptedField(help_text='Password', max_length=63), + ), + ] diff --git a/preferences/models.py b/preferences/models.py index 228807a6..daeb4a05 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -73,11 +73,11 @@ class OptionalUser(AclMixin, PreferencesModel): gpg_fingerprint = models.BooleanField(default=True) all_can_create_club = models.BooleanField( default=False, - help_text=_("Users can create a club") + help_text=_("Users can create a club.") ) all_can_create_adherent = models.BooleanField( default=False, - help_text=_("Users can create a member"), + help_text=_("Users can create a member."), ) shell_default = models.OneToOneField( @@ -88,15 +88,15 @@ class OptionalUser(AclMixin, PreferencesModel): ) self_change_shell = models.BooleanField( default=False, - help_text=_("Users can edit their shell") + help_text=_("Users can edit their shell.") ) self_change_room = models.BooleanField( default=False, - help_text=_("Users can edit their room") + help_text=_("Users can edit their room.") ) local_email_accounts_enabled = models.BooleanField( default=False, - help_text=_("Enable local email accounts for users") + help_text=_("Enable local email accounts for users.") ) local_email_domain = models.CharField( max_length=32, @@ -106,20 +106,21 @@ class OptionalUser(AclMixin, PreferencesModel): max_email_address = models.IntegerField( default=15, help_text=_("Maximum number of local email addresses for a standard" - " user") + " user.") ) delete_notyetactive = models.IntegerField( default=15, - help_text=_("Inactive users will be deleted after this number of days") + help_text=_("Not yet active users will be deleted after this number of" + " days.") ) self_adhesion = models.BooleanField( default=False, - help_text=_("A new user can create their account on Re2o") + help_text=_("A new user can create their account on Re2o.") ) all_users_active = models.BooleanField( default=False, - help_text=_("If True, all new created and connected users are active.\ - If False, only when a valid registration has been paid") + help_text=_("If True, all new created and connected users are active." + " If False, only when a valid registration has been paid.") ) class Meta: @@ -206,40 +207,41 @@ class OptionalTopologie(AclMixin, PreferencesModel): switchs_web_management = models.BooleanField( default=False, - help_text="Web management, activé si provision automatique" + help_text=_("Web management, activated in case of automatic provision") ) switchs_web_management_ssl = models.BooleanField( default=False, - help_text="Web management ssl. Assurez-vous que un certif est installé sur le switch !" + help_text=_("SSL web management, make sure that a certificate is" + " installed on the switch") ) switchs_rest_management = models.BooleanField( default=False, - help_text="Rest management, activé si provision auto" + help_text=_("REST management, activated in case of automatic provision") ) switchs_ip_type = models.OneToOneField( 'machines.IpType', on_delete=models.PROTECT, blank=True, null=True, - help_text="Plage d'ip de management des switchs" + help_text=_("IP range for the management of switches") ) switchs_provision = models.CharField( max_length=32, choices=CHOICE_PROVISION, default='tftp', - help_text="Mode de récupération des confs par les switchs" + help_text=_("Provision of configuration mode for switches") ) sftp_login = models.CharField( max_length=32, null=True, blank=True, - help_text="Login sftp des switchs" + help_text=_("SFTP login for switches") ) sftp_pass = AESEncryptedField( max_length=63, null=True, blank=True, - help_text="Mot de passe sftp" + help_text=_("SFTP password") ) @cached_property @@ -314,52 +316,56 @@ class RadiusKey(AclMixin, models.Model): """Class of a radius key""" radius_key = AESEncryptedField( max_length=255, - help_text="Clef radius" + help_text=_("RADIUS key") ) comment = models.CharField( max_length=255, null=True, blank=True, - help_text="Commentaire de cette clef" + help_text=_("Comment for this key") ) default_switch = models.BooleanField( default=True, unique=True, - help_text= "Clef par défaut des switchs" + help_text=_("Default key for switches") ) class Meta: permissions = ( - ("view_radiuskey", "Peut voir un objet radiuskey"), + ("view_radiuskey", _("Can view a RADIUS key object")), ) + verbose_name = _("RADIUS key") + verbose_name_plural = _("RADIUS keys") def __str__(self): - return "Clef radius " + str(self.id) + " " + str(self.comment) + return _("RADIUS key ") + str(self.id) + " " + str(self.comment) class SwitchManagementCred(AclMixin, models.Model): """Class of a management creds of a switch, for rest management""" management_id = models.CharField( max_length=63, - help_text="Login du switch" + help_text=_("Switch login") ) management_pass = AESEncryptedField( max_length=63, - help_text="Mot de passe" + help_text=_("Password") ) default_switch = models.BooleanField( default=True, unique=True, - help_text= "Creds par défaut des switchs" + help_text=_("Default credentials for switches") ) class Meta: permissions = ( - ("view_switchmanagementcred", "Peut voir un objet switchmanagementcred"), + ("view_switchmanagementcred", _("Can view a switch management" + " credentials object")), ) + verbose_name = _("switch management credentials") def __str__(self): - return "Identifiant " + str(self.management_id) + return _("Switch login ") + str(self.management_id) class Reminder(AclMixin, models.Model): @@ -367,25 +373,26 @@ class Reminder(AclMixin, models.Model): Days: liste des nombres de jours pour lesquells un mail est envoyé optionalMessage: message additionel pour le mail """ - PRETTY_NAME="Options pour le mail de fin d'adhésion" days = models.IntegerField( default=7, unique=True, - help_text="Délais entre le mail et la fin d'adhésion" + help_text=_("Delay between the email and the membership's end") ) message = models.CharField( max_length=255, default="", null=True, blank=True, - help_text="Message affiché spécifiquement pour ce rappel" + help_text=_("Message displayed specifically for this reminder") ) class Meta: permissions = ( - ("view_reminder", "Peut voir un objet reminder"), + ("view_reminder", _("Can view a reminder object")), ) + verbose_name = _("reminder") + verbose_name_plural = _("reminders") def users_to_remind(self): from re2o.utils import all_has_access @@ -472,8 +479,7 @@ class MailContact(AclMixin, models.Model): commentary = models.CharField( blank = True, null = True, - help_text = _( - "Description of the associated email address."), + help_text = _("Description of the associated email address."), max_length = 256 ) @@ -564,8 +570,8 @@ def homeoption_post_save(**kwargs): class MailMessageOption(AclMixin, models.Model): """Reglages, mail de bienvenue et autre""" - welcome_mail_fr = models.TextField(default="", help_text="Mail de bienvenue en français") - welcome_mail_en = models.TextField(default="", help_text="Mail de bienvenue en anglais") + welcome_mail_fr = models.TextField(default="", help_text=_("Welcome email in French")) + welcome_mail_en = models.TextField(default="", help_text=_("Welcome email in English")) class Meta: permissions = ( @@ -577,7 +583,8 @@ class MailMessageOption(AclMixin, models.Model): class RadiusOption(AclMixin, PreferencesModel): class Meta: - verbose_name = _("radius policies") + verbose_name = _("RADIUS policy") + verbose_name_plural = _("RADIUS policies") MACHINE = 'MACHINE' DEFINED = 'DEFINED' @@ -588,8 +595,8 @@ class RadiusOption(AclMixin, PreferencesModel): REJECT = 'REJECT' SET_VLAN = 'SET_VLAN' CHOICE_POLICY = ( - (REJECT, _('Reject the machine')), - (SET_VLAN, _('Place the machine on the VLAN')) + (REJECT, _("Reject the machine")), + (SET_VLAN, _("Place the machine on the VLAN")) ) radius_general_policy = models.CharField( max_length=32, @@ -608,16 +615,14 @@ class RadiusOption(AclMixin, PreferencesModel): related_name='unknown_machine_vlan', blank=True, null=True, - verbose_name=_('Unknown machine Vlan'), - help_text=_( - 'Vlan for unknown machines if not rejected.' - ) + verbose_name=_("Unknown machines VLAN"), + help_text=_("VLAN for unknown machines if not rejected") ) unknown_port = models.CharField( max_length=32, choices=CHOICE_POLICY, default=REJECT, - verbose_name=_("Policy for unknown port"), + verbose_name=_("Policy for unknown ports"), ) unknown_port_vlan = models.ForeignKey( 'machines.Vlan', @@ -625,20 +630,15 @@ class RadiusOption(AclMixin, PreferencesModel): related_name='unknown_port_vlan', blank=True, null=True, - verbose_name=_('Unknown port Vlan'), - help_text=_( - 'Vlan for unknown ports if not rejected.' - ) + verbose_name=_("Unknown ports VLAN"), + help_text=_("VLAN for unknown ports if not rejected") ) unknown_room = models.CharField( max_length=32, choices=CHOICE_POLICY, default=REJECT, - verbose_name=_( - "Policy for machine connecting from " - "unregistered room (relevant on ports with STRICT " - "radius mode)" - ), + verbose_name=_("Policy for machines connecting from unregistered rooms" + " (relevant on ports with STRICT RADIUS mode)"), ) unknown_room_vlan = models.ForeignKey( 'machines.Vlan', @@ -646,16 +646,14 @@ class RadiusOption(AclMixin, PreferencesModel): on_delete=models.PROTECT, blank=True, null=True, - verbose_name=_('Unknown room Vlan'), - help_text=_( - 'Vlan for unknown room if not rejected.' - ) + verbose_name=_("Unknown rooms VLAN"), + help_text=_("VLAN for unknown rooms if not rejected") ) non_member = models.CharField( max_length=32, choices=CHOICE_POLICY, default=REJECT, - verbose_name=_("Policy non member users."), + verbose_name=_("Policy for non members"), ) non_member_vlan = models.ForeignKey( 'machines.Vlan', @@ -663,16 +661,14 @@ class RadiusOption(AclMixin, PreferencesModel): on_delete=models.PROTECT, blank=True, null=True, - verbose_name=_('Non member Vlan'), - help_text=_( - 'Vlan for non members if not rejected.' - ) + verbose_name=_("Non members VLAN"), + help_text=_("VLAN for non members if not rejected") ) banned = models.CharField( max_length=32, choices=CHOICE_POLICY, default=REJECT, - verbose_name=_("Policy for banned users."), + verbose_name=_("Policy for banned users"), ) banned_vlan = models.ForeignKey( 'machines.Vlan', @@ -680,10 +676,8 @@ class RadiusOption(AclMixin, PreferencesModel): on_delete=models.PROTECT, blank=True, null=True, - verbose_name=_('Banned Vlan'), - help_text=_( - 'Vlan for banned if not rejected.' - ) + verbose_name=_("Banned users VLAN"), + help_text=_("VLAN for banned users if not rejected") ) vlan_decision_ok = models.OneToOneField( 'machines.Vlan', diff --git a/preferences/templates/preferences/aff_radiuskey.html b/preferences/templates/preferences/aff_radiuskey.html index 0d58efe3..7c972abe 100644 --- a/preferences/templates/preferences/aff_radiuskey.html +++ b/preferences/templates/preferences/aff_radiuskey.html @@ -23,35 +23,35 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% load acl %} {% load logs_extra %} -
{% include "buttons/sort.html" with prefix='machine' col='name' text=tr_dns_name %}{% include 'buttons/sort.html' with prefix='machine' col='name' text=tr_dns_name %} {% trans "Type" %} {% trans "MAC address" %} {% trans "IP address" %} {% trans "No name" as tr_no_name %} {% trans "View the profile" as tr_view_the_profile %} - {{ machine.get_name|default:'tr_no_name' }} + {{ machine.get_name|default:tr_no_name }} {{ machine.user }} - {% can_create Interface machine.id %} - {% trans "Create an interface" as tr_create_an_interface %} - {% include 'buttons/add.html' with href='machines:new-interface' id=machine.id desc=tr_create_an_interface %} + {% can_create Interface machine.id %} + {% trans "Create an interface" as tr_create_an_interface %} + {% include 'buttons/add.html' with href='machines:new-interface' id=machine.id desc=tr_create_an_interface %} {% acl_end %} {% history_button machine %} {% can_delete machine %} - {% include 'buttons/suppr.html' with href='machines:del-machine' id=machine.id %} + {% include 'buttons/suppr.html' with href='machines:del-machine' id=machine.id %} {% acl_end %}
{{ type.ip_type }} {% can_edit type %} - {% include 'buttons/edit.html' with href='machines:edit-machinetype' id=type.id %} + {% include 'buttons/edit.html' with href='machines:edit-machinetype' id=type.id %} {% acl_end %} {% history_button type %} {{ mx.name }} {% can_edit mx %} - {% include 'buttons/edit.html' with href='machines:edit-mx' id=mx.id %} + {% include 'buttons/edit.html' with href='machines:edit-mx' id=mx.id %} {% acl_end %} {% history_button mx %} {{ nas.autocapture_mac|tick }} {% can_edit nas %} - {% include 'buttons/edit.html' with href='machines:edit-nas' id=nas.id %} + {% include 'buttons/edit.html' with href='machines:edit-nas' id=nas.id %} {% acl_end %} {% history_button nas %} {{ ns.ns }} {% can_edit ns %} - {% include 'buttons/edit.html' with href='machines:edit-ns' id=ns.id %} + {% include 'buttons/edit.html' with href='machines:edit-ns' id=ns.id %} {% acl_end %} {% history_button ns %} {% for serv in role.servers.all %}{{ serv }}, {% endfor %} {% can_edit role %} - {% include 'buttons/edit.html' with href='machines:edit-role' id=role.id %} + {% include 'buttons/edit.html' with href='machines:edit-role' id=role.id %} {% acl_end %} {% history_button role %} {% can_edit service %} - {% include 'buttons/edit.html' with href='machines:edit-service' id=service.id %} + {% include 'buttons/edit.html' with href='machines:edit-service' id=service.id %} {% acl_end %} {% history_button service %} {{ soa.ttl }} {% can_edit soa %} - {% include 'buttons/edit.html' with href='machines:edit-soa' id=soa.id %} + {% include 'buttons/edit.html' with href='machines:edit-soa' id=soa.id %} {% acl_end %} {% history_button soa %} {{ srv.target }} {% can_edit srv %} - {% include 'buttons/edit.html' with href='machines:edit-srv' id=srv.id %} + {% include 'buttons/edit.html' with href='machines:edit-srv' id=srv.id %} {% acl_end %} {% history_button srv %} {{ sshfp.comment }} {% can_edit sshfp %} - {% include 'buttons/edit.html' with href='machines:edit-sshfp' id=sshfp.id %} + {% include 'buttons/edit.html' with href='machines:edit-sshfp' id=sshfp.id %} {% acl_end %} {% history_button sshfp %} {% can_delete sshfp %} - {% include 'buttons/suppr.html' with href='machines:del-sshfp' id=sshfp.id %} + {% include 'buttons/suppr.html' with href='machines:del-sshfp' id=sshfp.id %} {% acl_end %}
{{ txt.dns_entry }} {% can_edit txt %} - {% include 'buttons/edit.html' with href='machines:edit-txt' id=txt.id %} + {% include 'buttons/edit.html' with href='machines:edit-txt' id=txt.id %} {% acl_end %} {% history_button txt %} {% for range in vlan.iptype_set.all %}{{ range }}, {% endfor %} {% can_edit vlan %} - {% include 'buttons/edit.html' with href='machines:edit-vlan' id=vlan.id %} + {% include 'buttons/edit.html' with href='machines:edit-vlan' id=vlan.id %} {% acl_end %} {% history_button vlan %}
- - - - - - - - +{% load i18n %} + +
Id ClefCommentaireClef par default des switchsClef utilisée par les switchs
+ + + + + + + + - - {% for radiuskey in radiuskey_list %} + + {% for radiuskey in radiuskey_list %} - + - {% endfor %} -
{% trans "RADIUS key ID" %}{% trans "Comment" %}{% trans "Default RADIUS key for switches" %}{% trans "RADIUS key used by the swithes" %}
{{ radiuskey.id }} {{ radiuskey.comment }} {{ radiuskey.default_switch }}{{ radiuskey.switch_set.all|join:", " }}{{ radiuskey.switch_set.all|join:", " }} {% can_edit radiuskey %} {% include 'buttons/edit.html' with href='preferences:edit-radiuskey' id=radiuskey.id %} {% acl_end %} - {% can_delete radiuskey %} - - - + {% can_delete radiuskey %} + {% include 'buttons/suppr.html' with href='preferences:del-radiuskey' id=radiuskey.id %} {% acl_end %} {% history_button radiuskey %}
+ {% endfor %} + diff --git a/preferences/templates/preferences/aff_radiusoptions.html b/preferences/templates/preferences/aff_radiusoptions.html index 17e2a869..41cb1846 100644 --- a/preferences/templates/preferences/aff_radiusoptions.html +++ b/preferences/templates/preferences/aff_radiusoptions.html @@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "VLAN for machines accepted by RADIUS" %} - Vlan {{ radiusoptions.vlan_decision_ok }} + {% blocktrans with vlan_decision_ok=radiusoptions.vlan_decision_ok %}VLAN {{ vlan_decision_ok }}{% endblocktrans %}
@@ -39,7 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Situation" %} - {% trans "Behavior" %} + {% trans "Behaviour" %} @@ -48,7 +48,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if radiusoptions.unknown_machine == 'REJECT' %} {% trans "Reject" %} {% else %} - Vlan {{ radiusoptions.unknown_machine_vlan }} + {% blocktrans with unknown_machine_vlan=radiusoptions.unknown_machine_vlan %}VLAN {{ unknown_machine_vlan }}{% endblocktrans %} {% endif %} @@ -58,7 +58,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if radiusoptions.unknown_port == 'REJECT' %} {% trans "Reject" %} {% else %} - Vlan {{ radiusoptions.unknown_port_vlan }} + {% blocktrans with unknown_port_vlan=radiusoptions.unknown_port_vlan %}VLAN {{ unknown_port_vlan }}{% endblocktrans %} {% endif %} @@ -68,7 +68,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if radiusoptions.unknown_room == 'REJECT' %} {% trans "Reject" %} {% else %} - Vlan {{ radiusoptions.unknown_room_vlan }} + {% blocktrans with unknown_room_vlan=radiusoptions.unknown_room_vlan %}VLAN {{ unknown_room_vlan }}{% endblocktrans %} {% endif %} @@ -78,7 +78,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if radiusoptions.non_member == 'REJECT' %} {% trans "Reject" %} {% else %} - Vlan {{ radiusoptions.non_member_vlan }} + {% blocktrans with non_member_vlan=radiusoptions.non_member_vlan %}VLAN {{ non_member_vlan }}{% endblocktrans %} {% endif %} @@ -88,7 +88,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if radiusoptions.unknown_port == 'REJECT' %} {% trans "Reject" %} {% else %} - Vlan {{ radiusoptions.banned_vlan }} + {% blocktrans with banned_vlan=radiusoptions.banned_vlan %}VLAN {{ banned_vlan }}{% endblocktrans %} {% endif %} diff --git a/preferences/templates/preferences/aff_reminder.html b/preferences/templates/preferences/aff_reminder.html index 8462fe22..c0586b31 100644 --- a/preferences/templates/preferences/aff_reminder.html +++ b/preferences/templates/preferences/aff_reminder.html @@ -23,31 +23,31 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% load acl %} {% load logs_extra %} +{% load i18n %} + - - - + + + {% for reminder in reminder_list %} - - - - - + + + + + {% endfor %}
Nombre de jours avant le rappelMessage custom pour ce rappel{% trans "Number of days before the reminder" %}{% trans "Message for this reminder" %}
{{ reminder.days }}{{ reminder.message }} - {% can_edit reminder %} - {% include 'buttons/edit.html' with href='preferences:edit-reminder' id=reminder.id %} - {% can_delete reminder %} - - - - {% acl_end %} - {% acl_end %} - {% history_button reminder %} -
{{ reminder.days }}{{ reminder.message }} + {% can_edit reminder %} + {% include 'buttons/edit.html' with href='preferences:edit-reminder' id=reminder.id %} + {% acl_end %} + {% can_delete reminder %} + {% include 'buttons/suppr.html' with href='preferences:del-reminder' id=reminder.id %} + {% acl_end %} + {% history_button reminder %} +
diff --git a/preferences/templates/preferences/aff_service.html b/preferences/templates/preferences/aff_service.html index 926b2626..dce81768 100644 --- a/preferences/templates/preferences/aff_service.html +++ b/preferences/templates/preferences/aff_service.html @@ -42,15 +42,13 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ service.description }} {{ service.image }} - {% can_edit service%} - {% include 'buttons/edit.html' with href='preferences:edit-service' id=service.id %} - {% can_delete service %} - - - - {% acl_end %} - {% acl_end %} - {% history_button service %} + {% can_edit service%} + {% include 'buttons/edit.html' with href='preferences:edit-service' id=service.id %} + {% acl_end %} + {% can_delete service %} + {% include 'buttons/suppr.html' with href='preferences:del-service' id=service.id %} + {% acl_end %} + {% history_button service %} {% endfor %} diff --git a/preferences/templates/preferences/aff_switchmanagementcred.html b/preferences/templates/preferences/aff_switchmanagementcred.html index ef8b0143..b45dd356 100644 --- a/preferences/templates/preferences/aff_switchmanagementcred.html +++ b/preferences/templates/preferences/aff_switchmanagementcred.html @@ -23,17 +23,19 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% load acl %} {% load logs_extra %} - - - - - - - - - - - {% for switchmanagementcred in switchmanagementcred_list %} +{% load i18n %} + +
IdentifiantCreds par default des switchsUtilisé pour les switchs
+ + + + + + + + + + {% for switchmanagementcred in switchmanagementcred_list %} @@ -43,13 +45,11 @@ with this program; if not, write to the Free Software Foundation, Inc., {% include 'buttons/edit.html' with href='preferences:edit-switchmanagementcred' id=switchmanagementcred.id %} {% acl_end %} {% can_delete switchmanagementcred %} - - - + {% include 'buttons/suppr.html' with href='preferences:del-switchmanagementcred' id=switchmanagementcred.id %} {% acl_end %} {% history_button switchmanagementcred %} - {% endfor %} -
{% trans "Switch login" %}{% trans "Default switch management credentials" %}{% trans "Management credentials used by the switches" %}
{{ switchmanagementcred.management_id }} {{ switchmanagementcred.default_switch }}
+ {% endfor %} + diff --git a/preferences/templates/preferences/delete.html b/preferences/templates/preferences/delete.html index ce277647..7897e286 100644 --- a/preferences/templates/preferences/delete.html +++ b/preferences/templates/preferences/delete.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'preferences/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -24,15 +24,17 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% load bootstrap3 %} +{% load i18n %} -{% block title %}Création et modification de machines{% endblock %} +{% block title %}{% trans "Deletion of preferences" %}{% endblock %} {% block content %}
{% csrf_token %} -

Attention, voulez-vous vraiment supprimer cet objet {{ objet_name }} ( {{ objet }} ) ?

- {% bootstrap_button "Confirmer" button_type="submit" icon="trash" %} +

{% blocktrans %}Warning: are you sure you want to delete this {{ objet_name }} object ( {{ objet }} )?{% endblocktrans %}

+ {% trans "Confirm" as tr_confirm %} + {% bootstrap_button tr_confirm button_type="submit" icon="trash" %}


diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html index e4321f5b..50b2b647 100644 --- a/preferences/templates/preferences/display_preferences.html +++ b/preferences/templates/preferences/display_preferences.html @@ -1,4 +1,4 @@ -{% extends "preferences/sidebar.html" %} +{% extends 'preferences/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -69,7 +69,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "General message displayed on the website" %} {{ generaloptions.general_message }} - {% trans "Main site url" %} + {% trans "Main site URL" %} {{ generaloptions.main_site_url }} @@ -120,7 +120,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Self registration" %} {{ useroptions.self_adhesion|tick }} {% trans "Delete not yet active users after" %} - {{ useroptions.delete_notyetactive }} days + {% blocktrans with delete_notyetactive=useroptions.delete_notyetactive %}{{ delete_notyetactive }} days{% endblocktrans %} {% trans "All users are active by default" %} @@ -218,11 +218,11 @@ with this program; if not, write to the Free Software Foundation, Inc., -

Clef radius

+

{% trans "RADIUS keys" %}

{% can_create RadiusKey%} - Ajouter une clef radius + {% trans " Add a RADIUS key" %} {% acl_end %} - {% include "preferences/aff_radiuskey.html" with radiuskey_list=radiuskey_list %} + {% include 'preferences/aff_radiuskey.html' with radiuskey_list=radiuskey_list %}
@@ -230,7 +230,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
@@ -243,64 +243,64 @@ with this program; if not, write to the Free Software Foundation, Inc., - + - +
Web management, activé si provision automatique{% trans "Web management, activated in case of automatic provision" %} {{ topologieoptions.switchs_web_management }}Rest management, activé si provision auto{% trans "REST management, activated in case of automatic provision" %} {{ topologieoptions.switchs_rest_management }}
-
{% if topologieoptions.provision_switchs_enabled %}Provision de la config des switchs{% else %}Provision de la config des switchs{% endif%}
+
{% if topologieoptions.provision_switchs_enabled %}{% trans "Provision of configuration for switches" %}{% else %}{% trans "Provision of configuration for switches" %}{% endif%}
- - + + - - + + - - + + - + - - + + - - + +
Switchs configurés automatiquement{{ topologieoptions.provisioned_switchs|join:", " }} {% if topologieoptions.provisioned_switchs %} OK{% else %}Manquant{% endif %}{% trans "Switches with automatic provision" %}{{ topologieoptions.provisioned_switchs|join:", " }} {% if topologieoptions.provisioned_switchs %}{% trans "OK" %}{% else %}{% trans "Missing" %}{% endif %}
Plage d'ip de management des switchs{{ topologieoptions.switchs_ip_type }} {% if topologieoptions.switchs_ip_type %} OK{% else %}Manquant{% endif %}{% trans "IP range for the management of switches" %}{{ topologieoptions.switchs_ip_type }} {% if topologieoptions.switchs_ip_type %}{% trans "OK" %}{% else %}{% trans "Missing" %}{% endif %}
Serveur des config des switchs{{ topologieoptions.switchs_management_interface }} {% if topologieoptions.switchs_management_interface %} - {{ topologieoptions.switchs_management_interface_ip }} OK{% else %}Manquant{% endif %}{% trans "Server for the configuration of switches" %}{{ topologieoptions.switchs_management_interface }} {% if topologieoptions.switchs_management_interface %} - {{ topologieoptions.switchs_management_interface_ip }} {% trans "OK" %}{% else %}{% trans "Missing" %}{% endif %}
Mode de provision des switchs{% trans "Provision of configuration mode for switches" %} {{ topologieoptions.switchs_provision }}
Mode TFTP OK{% trans "TFTP mode" %}{% trans "OK" %}
Mode SFTP{% if topologieoptions.switchs_management_sftp_creds %} OK{% else %}Creds manquants{% endif %}{% trans "SFTP mode" %}{% if topologieoptions.switchs_management_sftp_creds %}{% trans "OK" %}{% else %}{% trans "Missing credentials" %}{% endif %}
-
Creds de management des switchs
+
{% trans "Switch management credentials" %}
{% can_create SwitchManagementCred%} - Ajouter un id/mdp de management switch + {% trans " Add switch management credentials" %} {% acl_end %}

- {% if switchmanagementcred_list %} OK{% else %}Manquant{% endif %} - {% include "preferences/aff_switchmanagementcred.html" with switchmanagementcred_list=switchmanagementcred_list %} + {% if switchmanagementcred_list %}{% trans "OK" %}{% else %}{% trans "Missing" %}{% endif %} + {% include 'preferences/aff_switchmanagementcred.html' with switchmanagementcred_list=switchmanagementcred_list %}
{% trans "Edit" %} - {% include "preferences/aff_radiusoptions.html" %} + {% include 'preferences/aff_radiusoptions.html' %}
@@ -350,7 +350,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
@@ -377,16 +377,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% can_create preferences.Reminder%} - Ajouter un rappel + {% trans " Add a reminder" %}

{% acl_end %} - {% include "preferences/aff_reminder.html" with reminder_list=reminder_list %} + {% include 'preferences/aff_reminder.html' with reminder_list=reminder_list %}
@@ -403,7 +403,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Add a service" %}

{% acl_end %} - {% include "preferences/aff_service.html" with service_list=service_list %} + {% include 'preferences/aff_service.html' with service_list=service_list %}
@@ -417,18 +417,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% can_create preferences.MailContact %} - {% trans "Add an address" %} + {% trans " Add an address" %} {% acl_end %} - {% trans "Delete one or several addresses" %} + {% trans " Delete one or several addresses" %}

- {% include "preferences/aff_mailcontact.html" with mailcontact_list=mailcontact_list %} + {% include 'preferences/aff_mailcontact.html' with mailcontact_list=mailcontact_list %}
diff --git a/preferences/templates/preferences/edit_preferences.html b/preferences/templates/preferences/edit_preferences.html index c3dd4652..b5f8c506 100644 --- a/preferences/templates/preferences/edit_preferences.html +++ b/preferences/templates/preferences/edit_preferences.html @@ -1,4 +1,4 @@ -{% extends "preferences/sidebar.html" %} +{% extends 'preferences/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/preferences/templates/preferences/preferences.html b/preferences/templates/preferences/preferences.html index 8ae9b6bc..308d121e 100644 --- a/preferences/templates/preferences/preferences.html +++ b/preferences/templates/preferences/preferences.html @@ -1,4 +1,4 @@ -{% extends "preferences/sidebar.html" %} +{% extends 'preferences/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/preferences/templates/preferences/sidebar.html b/preferences/templates/preferences/sidebar.html index 98b597ea..2dccf639 100644 --- a/preferences/templates/preferences/sidebar.html +++ b/preferences/templates/preferences/sidebar.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends 'base.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/preferences/views.py b/preferences/views.py index 586be60f..0e86713c 100644 --- a/preferences/views.py +++ b/preferences/views.py @@ -111,7 +111,7 @@ def edit_options(request, section): model = getattr(models, section, None) form_instance = getattr(forms, 'Edit' + section + 'Form', None) if not (model or form_instance): - messages.error(request, _("Unknown object")) + messages.error(request, _("Unknown object.")) return redirect(reverse('preferences:display-options')) options_instance, _created = model.objects.get_or_create() @@ -186,7 +186,7 @@ def del_service(request, service_instance, **_kwargs): """Suppression d'un service de la page d'accueil""" if request.method == "POST": service_instance.delete() - messages.success(request, "Le service a été détruit") + messages.success(request, _("The service was deleted.")) return redirect(reverse('preferences:display-options')) return form( {'objet': service_instance, 'objet_name': 'service'}, @@ -204,7 +204,7 @@ def add_reminder(request): messages.success(request, _("The reminder was added.")) return redirect(reverse('preferences:display-options')) return form( - {'preferenceform': reminder, 'action_name': _("Add a service")}, + {'preferenceform': reminder, 'action_name': _("Add a reminder")}, 'preferences/preferences.html', request ) @@ -220,7 +220,7 @@ def edit_reminder(request, reminder_instance, **_kwargs): ) if reminder.is_valid(): reminder.save() - messages.success(request, _("The service was edited.")) + messages.success(request, _("The reminder was edited.")) return redirect(reverse('preferences:display-options')) return form( {'preferenceform': reminder, 'action_name': _("Edit")}, @@ -236,7 +236,7 @@ def del_reminder(request, reminder_instance, **_kwargs): """Destruction d'un reminder""" if request.method == "POST": reminder_instance.delete() - messages.success(request, "Le reminder a été détruit") + messages.success(request, _("The reminder was deleted.")) return redirect(reverse('preferences:display-options')) return form( {'objet': reminder_instance, 'objet_name': 'reminder'}, @@ -252,10 +252,10 @@ def add_radiuskey(request): radiuskey = RadiusKeyForm(request.POST or None) if radiuskey.is_valid(): radiuskey.save() - messages.success(request, "Cette clef a été ajouté") + messages.success(request, _("The RADIUS key was added.")) return redirect(reverse('preferences:display-options')) return form( - {'preferenceform': radiuskey, 'action_name': 'Ajouter'}, + {'preferenceform': radiuskey, 'action_name': _("Add a RADIUS key")}, 'preferences/preferences.html', request ) @@ -266,10 +266,10 @@ def edit_radiuskey(request, radiuskey_instance, **_kwargs): radiuskey = RadiusKeyForm(request.POST or None, instance=radiuskey_instance) if radiuskey.is_valid(): radiuskey.save() - messages.success(request, "Radiuskey modifié") + messages.success(request, _("The RADIUS key was edited.")) return redirect(reverse('preferences:display-options')) return form( - {'preferenceform': radiuskey, 'action_name': 'Editer'}, + {'preferenceform': radiuskey, 'action_name': _("Edit")}, 'preferences/preferences.html', request ) @@ -282,10 +282,10 @@ def del_radiuskey(request, radiuskey_instance, **_kwargs): if request.method == "POST": try: radiuskey_instance.delete() - messages.success(request, "La radiuskey a été détruite") + messages.success(request, _("The RADIUS key was deleted.")) except ProtectedError: - messages.error(request, "Erreur la\ - clef ne peut être supprimé, elle est affectée à des switchs") + messages.error(request, _("The RADIUS key is assigned to at least" + " one switch, you can't delete it.")) return redirect(reverse('preferences:display-options')) return form( {'objet': radiuskey_instance, 'objet_name': 'radiuskey'}, @@ -301,10 +301,10 @@ def add_switchmanagementcred(request): switchmanagementcred = SwitchManagementCredForm(request.POST or None) if switchmanagementcred.is_valid(): switchmanagementcred.save() - messages.success(request, "Ces creds ont été ajoutés") + messages.success(request, _("The switch management credentials were added.")) return redirect(reverse('preferences:display-options')) return form( - {'preferenceform': switchmanagementcred, 'action_name': 'Ajouter'}, + {'preferenceform': switchmanagementcred, 'action_name': _("Add switch management credentials")}, 'preferences/preferences.html', request ) @@ -315,10 +315,10 @@ def edit_switchmanagementcred(request, switchmanagementcred_instance, **_kwargs) switchmanagementcred = SwitchManagementCredForm(request.POST or None, instance=switchmanagementcred_instance) if switchmanagementcred.is_valid(): switchmanagementcred.save() - messages.success(request, "Creds de managament modifié") + messages.success(request, _("The switch management credentials were edited.")) return redirect(reverse('preferences:display-options')) return form( - {'preferenceform': switchmanagementcred, 'action_name': 'Editer'}, + {'preferenceform': switchmanagementcred, 'action_name': _("Edit")}, 'preferences/preferences.html', request ) @@ -331,10 +331,11 @@ def del_switchmanagementcred(request, switchmanagementcred_instance, **_kwargs): if request.method == "POST": try: switchmanagementcred_instance.delete() - messages.success(request, "Ces creds ont été détruits") + messages.success(request, _("The switch management credentials were deleted.")) except ProtectedError: - messages.error(request, "Erreur ces\ - creds ne peuvent être supprimés, ils sont affectés à des switchs") + messages.error(request, _("The switch management credentials are" + " assigned to at least one switch, you" + " can't delete them.")) return redirect(reverse('preferences:display-options')) return form( {'objet': switchmanagementcred_instance, 'objet_name': 'switchmanagementcred'}, From 3f601d74d1c82cb64cfef30079df61dc9ae20201 Mon Sep 17 00:00:00 2001 From: Laouen Fernet Date: Wed, 9 Jan 2019 00:40:08 +0100 Subject: [PATCH 52/73] add translations for re2o/ --- re2o/base.py | 4 +-- re2o/locale/fr/LC_MESSAGES/django.po | 54 ++++++++++++++++++---------- re2o/templates/re2o/about.html | 2 +- re2o/templates/re2o/contact.html | 2 +- re2o/templates/re2o/history.html | 4 +-- re2o/templates/re2o/index.html | 10 +++--- re2o/templates/re2o/sidebar.html | 2 +- re2o/views.py | 2 +- 8 files changed, 48 insertions(+), 32 deletions(-) diff --git a/re2o/base.py b/re2o/base.py index 023a16ff..fff2278c 100644 --- a/re2o/base.py +++ b/re2o/base.py @@ -73,9 +73,9 @@ def smtp_check(local_part): reply_code = srv.getreply()[0] srv.close() if reply_code in [250, 252]: - return True, _("This domain is already taken") + return True, _("This domain is already taken.") except: - return True, _("Smtp unreachable") + return True, _("SMTP unreachable.") return False, None diff --git a/re2o/locale/fr/LC_MESSAGES/django.po b/re2o/locale/fr/LC_MESSAGES/django.po index 9c9941b2..2f634fed 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: 2018-08-23 15:03+0200\n" +"POT-Creation-Date: 2019-01-12 16:48+0100\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -42,6 +42,14 @@ msgstr "Vous n'avez pas le droit d'accéder à ce menu." msgid "You don't have the right to edit the history." msgstr "Vous n'avez pas le droit de modifier l'historique." +#: base.py:76 +msgid "This domain is already taken." +msgstr "Ce domaine est déjà pris." + +#: base.py:78 +msgid "SMTP unreachable." +msgstr "SMTP injoignable." + #: mixins.py:111 #, python-format msgid "You don't have the right to create a %s object." @@ -87,15 +95,15 @@ msgstr "À propos de %(AssoName)s" #: templates/re2o/about.html:36 msgid "" "Re2o is an administration tool initiated by Rezo Metz and a few members of other FedeRez associations around the summer 2016.
It is " -"intended to be a tool independant from any network infrastructure so it can " -"be setup in \"a few steps\". This tool is entirely free and available under " -"a GNU Public License v2 (GPLv2) license on FedeRez gitlab.
Re2o's mainteners are " -"volunteers mainly from French schools.
If you want to get involved in " -"the development process, we will be glad to welcome you so do not hesitate " -"to contact us and come help us build the future of Re2o." +"\">Rezo Metz and a few members of other FedeRez associations around the summer 2016.
It is intended to " +"be a tool independant from any network infrastructure so it can be setup in " +"\"a few steps\". This tool is entirely free and available under a GNU Public " +"License v2 (GPLv2) license on FedeRez gitlab.
Re2o's mainteners are volunteers mainly " +"from French schools.
If you want to get involved in the development " +"process, we will be glad to welcome you so do not hesitate to contact us and " +"come help us build the future of Re2o." msgstr "" "Re2o est un outil d'administration initié par Rézo Metz et quelques membres d'autres associations de {% blocktrans %}History of {{ object }}{% endblocktrans %} - {% include "re2o/aff_history.html" with reversions=reversions %} + {% include 're2o/aff_history.html' with reversions=reversions %}


diff --git a/re2o/templates/re2o/index.html b/re2o/templates/re2o/index.html index f7adacbc..a6b1a8c5 100644 --- a/re2o/templates/re2o/index.html +++ b/re2o/templates/re2o/index.html @@ -1,4 +1,4 @@ -{% extends "re2o/sidebar.html" %} +{% extends 're2o/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -42,7 +42,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
@@ -53,8 +53,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,

{% trans "Logging in" %}

-

{% trans "If you already have an account, log in. You can manage your subscription to the organisation, your machines and all your services." %}

-

{% trans "Logging in" %}

+

{% trans "If you already have an account, log in. You can manage your subscriptions to the organisation, your machines and all your services." %}

+

{% trans "Log in" %}

@@ -66,7 +66,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,

{% trans "My profile" %}

-

{% trans "To manage your subscription, your machines and all your services, access your profile." %}

+

{% trans "To manage your subscriptions, your machines and all your services, access your profile." %}

{% trans "Access my profile" %}

diff --git a/re2o/templates/re2o/sidebar.html b/re2o/templates/re2o/sidebar.html index c9202d14..e7e58599 100644 --- a/re2o/templates/re2o/sidebar.html +++ b/re2o/templates/re2o/sidebar.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends 'base.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/re2o/views.py b/re2o/views.py index 15becb35..0ff2774b 100644 --- a/re2o/views.py +++ b/re2o/views.py @@ -84,7 +84,7 @@ def about_page(request): git_info_commit = last_commit.hexsha git_info_commit_date = last_commit.committed_datetime except: - NO_GIT_MSG = _("Unable to get the information") + NO_GIT_MSG = _("Unable to get the information.") git_info_remote = NO_GIT_MSG git_info_branch = NO_GIT_MSG git_info_commit = NO_GIT_MSG From cd2e39c480002005ce4dfffa8bceb16784f24d81 Mon Sep 17 00:00:00 2001 From: Laouen Fernet Date: Wed, 9 Jan 2019 00:40:19 +0100 Subject: [PATCH 53/73] add translations for search/ --- search/forms.py | 2 +- search/locale/fr/LC_MESSAGES/django.po | 38 ++++++++++++++------------ search/templates/search/index.html | 24 ++++++++-------- search/templates/search/search.html | 6 ++-- search/templates/search/sidebar.html | 6 ++-- 5 files changed, 40 insertions(+), 36 deletions(-) diff --git a/search/forms.py b/search/forms.py index 5fa5fca8..a32c8abc 100644 --- a/search/forms.py +++ b/search/forms.py @@ -33,7 +33,7 @@ CHOICES_USER = ( ('0', _("Active")), ('1', _("Disabled")), ('2', _("Archived")), - ('3', _("Not Yet Active")), + ('3', _("Not yet active")), ) CHOICES_AFF = ( diff --git a/search/locale/fr/LC_MESSAGES/django.po b/search/locale/fr/LC_MESSAGES/django.po index dd0b63a3..be2a79cc 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: 2018-08-15 18:15+0200\n" +"POT-Creation-Date: 2019-01-08 23:56+0100\n" "PO-Revision-Date: 2018-06-24 20:10+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -42,44 +42,48 @@ msgstr "Désactivés" msgid "Archived" msgstr "Archivés" -#: forms.py:39 +#: forms.py:36 +msgid "Not yet active" +msgstr "Pas encore adhéré" + +#: forms.py:40 msgid "Users" msgstr "Utilisateurs" -#: forms.py:40 +#: forms.py:41 msgid "Machines" msgstr "Machines" -#: forms.py:41 +#: forms.py:42 msgid "Invoices" msgstr "Factures" -#: forms.py:42 +#: forms.py:43 msgid "Bans" msgstr "Bannissements" -#: forms.py:43 +#: forms.py:44 msgid "Whitelists" msgstr "Accès gracieux" -#: forms.py:44 +#: forms.py:45 msgid "Rooms" msgstr "Chambres" -#: forms.py:45 +#: forms.py:46 msgid "Ports" msgstr "Ports" -#: forms.py:46 +#: forms.py:47 msgid "Switches" msgstr "Commutateurs réseau" -#: forms.py:59 forms.py:71 templates/search/search.html:29 +#: forms.py:60 forms.py:72 templates/search/search.html:29 #: templates/search/search.html:48 msgid "Search" msgstr "Rechercher" -#: forms.py:61 forms.py:73 +#: forms.py:62 forms.py:74 msgid "" "Use « » and «,» to specify distinct words, «\"query\"» for an exact search " "and «\\» to escape a character." @@ -87,19 +91,19 @@ msgstr "" "Utilisez « » et «,» pour spécifier différents mots, «\"query\"» pour une " "recherche exacte et «\\» pour échapper un caractère." -#: forms.py:80 +#: forms.py:81 msgid "Users filter" msgstr "Filtre utilisateurs" -#: forms.py:87 +#: forms.py:88 msgid "Display filter" msgstr "Filtre affichage" -#: forms.py:95 +#: forms.py:96 msgid "Start date" msgstr "Date de début" -#: forms.py:99 +#: forms.py:100 msgid "End date" msgstr "Date de fin" @@ -136,11 +140,11 @@ msgid "Results among rooms:" msgstr "Résultats parmi les chambres :" #: templates/search/index.html:61 -msgid "Results among ports" +msgid "Results among ports:" msgstr "Résultats parmi les ports :" #: templates/search/index.html:65 -msgid "Results among switches" +msgid "Results among switches:" msgstr "Résultats parmi les commutateurs réseau :" #: templates/search/index.html:69 diff --git a/search/templates/search/index.html b/search/templates/search/index.html index 84ba501c..4d3e2942 100644 --- a/search/templates/search/index.html +++ b/search/templates/search/index.html @@ -1,4 +1,4 @@ -{% extends "search/sidebar.html" %} +{% extends 'search/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -31,39 +31,39 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block content %} {% if users %}

{% trans "Results among users:" %}

- {% include "users/aff_users.html" with users_list=users %} + {% include 'users/aff_users.html' with users_list=users %} {% endif%} {% if clubs %}

{% trans "Results among clubs:" %}

- {% include "users/aff_clubs.html" with clubs_list=clubs %} + {% include 'users/aff_clubs.html' with clubs_list=clubs %} {% endif%} {% if machines %}

{% trans "Results among machines:" %}

- {% include "machines/aff_machines.html" with machines_list=machines %} + {% include 'machines/aff_machines.html' with machines_list=machines %} {% endif %} {% if factures %}

{% trans "Results among invoices:" %}

- {% include "cotisations/aff_cotisations.html" with facture_list=factures %} + {% include 'cotisations/aff_cotisations.html' with facture_list=factures %} {% endif %} {% if whitelists %}

{% trans "Results among whitelists:" %}

- {% include "users/aff_whitelists.html" with white_list=whitelists %} + {% include 'users/aff_whitelists.html' with white_list=whitelists %} {% endif %} {% if bans %}

{% trans "Results among bans:" %}

- {% include "users/aff_bans.html" with ban_list=bans %} + {% include 'users/aff_bans.html' with ban_list=bans %} {% endif %} {% if rooms %}

{% trans "Results among rooms:" %}

- {% include "topologie/aff_chambres.html" with room_list=rooms %} + {% include 'topologie/aff_chambres.html' with room_list=rooms %} {% endif %} {% if ports %} -

{% trans "Results among ports" %}

- {% include "topologie/aff_port.html" with port_list=ports search=True %} +

{% trans "Results among ports:" %}

+ {% include 'topologie/aff_port.html' with port_list=ports search=True %} {% endif %} {% if switches %} -

{% trans "Results among switches" %}

- {% include "topologie/aff_switch.html" with switch_list=switches %} +

{% trans "Results among switches:" %}

+ {% include 'topologie/aff_switch.html' with switch_list=switches %} {% endif %} {% if not users and not machines and not factures and not whitelists and not bans and not rooms and not ports and not switches %}

{% trans "No result" %}

diff --git a/search/templates/search/search.html b/search/templates/search/search.html index 42012339..d957a4cf 100644 --- a/search/templates/search/search.html +++ b/search/templates/search/search.html @@ -1,4 +1,4 @@ -{% extends "search/sidebar.html" %} +{% extends 'search/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -34,10 +34,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% bootstrap_field search_form.q %} {% if search_form.u %} - {% include "buttons/multiple_checkbox_alt.html" with field=search_form.u %} + {% include 'buttons/multiple_checkbox_alt.html' with field=search_form.u %} {% endif %} {% if search_form.a %} - {% include "buttons/multiple_checkbox_alt.html" with field=search_form.a %} + {% include 'buttons/multiple_checkbox_alt.html' with field=search_form.a %} {% endif %} {% if search_form.s %} {% bootstrap_field search_form.s %} diff --git a/search/templates/search/sidebar.html b/search/templates/search/sidebar.html index a445ef41..28d7a115 100644 --- a/search/templates/search/sidebar.html +++ b/search/templates/search/sidebar.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends 'base.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -26,11 +26,11 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load i18n %} {% block sidebar %} - + {% trans "Simple search" %} - + {% trans "Advanced search" %} From 4a8c161edc1e78a12462fe3fc75278761008de49 Mon Sep 17 00:00:00 2001 From: Laouen Fernet Date: Wed, 9 Jan 2019 00:40:30 +0100 Subject: [PATCH 54/73] add translations for templates/ --- templates/base.html | 26 +++--- templates/locale/fr/LC_MESSAGES/django.po | 101 ++++++++++++---------- templates/registration/login.html | 2 +- 3 files changed, 71 insertions(+), 58 deletions(-) diff --git a/templates/base.html b/templates/base.html index 867be422..401ece70 100644 --- a/templates/base.html +++ b/templates/base.html @@ -96,14 +96,14 @@ with this program; if not, write to the Free Software Foundation, Inc., {% acl_end %} {% can_view_app logs %} -
  • {% trans "Statistics" %}
  • +
  • {% trans "Statistics" %}
  • {% acl_end %} {% can_view_app preferences %}
  • @@ -137,12 +137,12 @@ with this program; if not, write to the Free Software Foundation, Inc., {% else %} {% can_view_any_app users machines cotisations %}
  • - +
    - +
  • @@ -153,7 +153,7 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -200,7 +200,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Internet access" %} {% if request_user.has_access %} - {% blocktrans with request.user.end_access|date:"d b Y" as date %}Until {{ date }}{% endblocktrans %} + {% blocktrans with end_access_date=request.user.end_access|date:"d b Y" %}Until {{ end_access_date }}{% endblocktrans %} {% else %} {% trans "Disabled" %} {% endif %} @@ -210,15 +210,15 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Membership" %} {% if request_user.is_adherent %} - {% blocktrans with request_user.end_adhesion|date:"d b Y" as date %}Until {{ date }}{% endblocktrans %} + {% blocktrans with end_adhesion_date=request_user.end_adhesion|date:"d b Y" %}Until {{ end_adhesion_date }}{% endblocktrans %} {% else %} - {% trans "Not a member" %} + {% trans "Non member" %} {% endif %}
    - + {% trans "View my profile" %} @@ -236,10 +236,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% for interface in interfaces|slice:":5" %} -
      {{interface}}
      +
      {{ interface }}
      {% endfor %} {% if interfaces|length > 5 %} - + {% trans "View my machines" %} diff --git a/templates/locale/fr/LC_MESSAGES/django.po b/templates/locale/fr/LC_MESSAGES/django.po index 75170dd3..2adc5854 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: 2018-08-15 16:10+0200\n" +"POT-Creation-Date: 2019-01-08 23:59+0100\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -38,116 +38,121 @@ msgstr "Site de gestion de réseau soutenu par FedeRez." msgid "Home" msgstr "Accueil" -#: base.html:81 +#: base.html:80 msgid "Users" msgstr "Utilisateurs" -#: base.html:84 +#: base.html:83 msgid "Manage the users" msgstr "Gérer les utilisateurs" -#: base.html:85 +#: base.html:84 msgid "Manage the clubs" msgstr "Gérer les clubs" -#: base.html:88 +#: base.html:87 msgid "Manage the machines" msgstr "Gérer les machines" -#: base.html:91 +#: base.html:90 msgid "Manage the subscriptions" msgstr "Gérer les cotisations" -#: base.html:98 +#: base.html:97 msgid "Topology" msgstr "Topologie" -#: base.html:100 +#: base.html:99 msgid "Switches" msgstr "Commutateurs réseau" -#: base.html:101 +#: base.html:100 msgid "Access points" msgstr "Points d'accès sans fil" -#: base.html:102 +#: base.html:101 msgid "Rooms" msgstr "Chambres" -#: base.html:107 +#: base.html:106 msgid "Statistics" msgstr "Statistiques" -#: base.html:112 +#: base.html:111 msgid "Administration" msgstr "Administration" -#: base.html:112 +#: base.html:118 msgid "More information" msgstr "Plus d'informations" -#: base.html:114 +#: base.html:120 msgid "About" msgstr "À propos" -#: base.html:122 +#: base.html:121 msgid "Contact" msgstr "Contact" -#: base.html:129 +#: base.html:128 msgid "Sign up" -msgstr "S'enregistrer" +msgstr "S'inscrire" -#: base.html:135 registration/login.html:30 registration/login.html:50 +#: base.html:134 registration/login.html:29 registration/login.html:36 msgid "Log in" msgstr "Se connecter" -#: base.html:143 +#: base.html:142 msgid "Search" msgstr "Rechercher" -#: base.html:157 +#: base.html:156 msgid "My profile" msgstr "Mon profil" -#: base.html:158 +#: base.html:157 msgid "Log out" msgstr "Se déconnecter" -#: base.html:194 +#: base.html:192 msgid "Username" msgstr "Pseudo" -#: base.html:198 +#: base.html:196 msgid "Room" msgstr "Chambre" -#: base.html:202 +#: base.html:200 msgid "Internet access" msgstr "Accès Internet" -#: base.html:205 base.html:215 +#: base.html:203 #, python-format -msgid "Until %(date)s" -msgstr "Jusqu'au %(date)s" +msgid "Until %(end_access_date)s" +msgstr "Jusqu'au %(end_access_date)s" -#: base.html:207 +#: base.html:205 msgid "Disabled" msgstr "Désactivé" -#: base.html:212 +#: base.html:210 msgid "Membership" msgstr "Adhésion" -#: base.html:217 -msgid "Not a member" +#: base.html:213 +#, python-format +msgid "Until %(end_adhesion_date)s" +msgstr "Jusqu'au %(end_adhesion_date)s" + +#: base.html:215 +msgid "Non member" msgstr "Non adhérent" -#: base.html:225 +#: base.html:223 msgid "View my profile" msgstr "Voir mon profil" -#: base.html:229 +#: base.html:228 msgid "You are not logged in." msgstr "Vous n'êtes pas connecté." @@ -180,11 +185,11 @@ msgstr "À propos de ce site" #: base.html:267 msgid "" -"This software is under the terms of the " -"GPLv2 License." +"This software is under the terms of the GPLv2 License." msgstr "" -"Ce logiciel est sous les termes de la licence " -"GPLv2." +"Ce logiciel est sous les termes de la licence GPLv2." #: buttons/add.html:27 msgid "Add" @@ -293,14 +298,22 @@ msgstr "Si vous n'avez aucune idée de ce que vous avez fait :" msgid "Go back to a safe page" msgstr "Retourner à une page sécurisée" -#: registration/login.html:35 -msgid "Your username and password didn't match. Please try again." -msgstr "Vos identifiants sont incorrects. Veuillez réessayer." +#: pagination.html:34 +msgid "First" +msgstr "Première page" -#: registration/login.html:43 -msgid "Please log in to see this page." -msgstr "Veuillez vous connecter pour voir cette page." +#: pagination.html:40 +msgid "Previous" +msgstr "Précédent" -#: registration/login.html:53 +#: pagination.html:60 +msgid "Next" +msgstr "Suivant" + +#: pagination.html:66 +msgid "Last" +msgstr "Dernière page" + +#: registration/login.html:40 msgid "Forgotten password?" msgstr "Mot de passe oublié ?" diff --git a/templates/registration/login.html b/templates/registration/login.html index 234144c5..f4226d7d 100644 --- a/templates/registration/login.html +++ b/templates/registration/login.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends 'base.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en From 69d80fcdb0360a8c54877a60511e029c9abcecac Mon Sep 17 00:00:00 2001 From: Laouen Fernet Date: Wed, 9 Jan 2019 00:40:48 +0100 Subject: [PATCH 55/73] add translations for topologie/ --- topologie/locale/fr/LC_MESSAGES/django.po | 484 +++++++++++------- .../migrations/0069_auto_20190108_1439.py | 59 +++ topologie/models.py | 45 +- topologie/templates/topologie/aff_ap.html | 18 +- .../templates/topologie/aff_building.html | 16 +- .../templates/topologie/aff_chambres.html | 14 +- .../topologie/aff_constructor_switch.html | 14 +- .../templates/topologie/aff_model_switch.html | 20 +- .../templates/topologie/aff_modules.html | 28 +- topologie/templates/topologie/aff_port.html | 16 +- .../templates/topologie/aff_port_profile.html | 8 +- .../templates/topologie/aff_repr_switch.html | 5 +- topologie/templates/topologie/aff_stacks.html | 14 +- topologie/templates/topologie/aff_switch.html | 20 +- .../templates/topologie/aff_switch_bay.html | 18 +- .../templates/topologie/aff_vlanoptions.html | 15 +- topologie/templates/topologie/delete.html | 2 +- .../templates/topologie/edit_stack_sw.html | 8 +- topologie/templates/topologie/index.html | 4 +- topologie/templates/topologie/index_ap.html | 4 +- .../topologie/index_model_switch.html | 6 +- .../templates/topologie/index_module.html | 6 +- topologie/templates/topologie/index_p.html | 12 +- .../topologie/index_physical_grouping.html | 8 +- .../topologie/index_portprofile.html | 8 +- topologie/templates/topologie/index_room.html | 4 +- topologie/templates/topologie/sidebar.html | 18 +- topologie/templates/topologie/switch.html | 4 +- topologie/templates/topologie/topo.html | 4 +- topologie/templates/topologie/topo_more.html | 2 +- topologie/views.py | 24 +- 31 files changed, 530 insertions(+), 378 deletions(-) create mode 100644 topologie/migrations/0069_auto_20190108_1439.py diff --git a/topologie/locale/fr/LC_MESSAGES/django.po b/topologie/locale/fr/LC_MESSAGES/django.po index a5db5085..b6242bc0 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: 2018-10-11 19:49+0200\n" +"POT-Creation-Date: 2019-01-09 00:01+0100\n" "PO-Revision-Date: 2018-06-25 14:53+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -34,11 +34,11 @@ msgstr "" msgid "You don't have the right to view this application." msgstr "Vous n'avez pas le droit de voir cette application." -#: forms.py:179 +#: forms.py:181 msgid "Start:" msgstr "Début :" -#: forms.py:180 +#: forms.py:182 msgid "End:" msgstr "Fin :" @@ -79,119 +79,204 @@ msgid "Number of ports" msgstr "Nombre de ports" #: models.py:228 templates/topologie/aff_switch.html:48 -#: templates/topologie/index_p.html:38 views.py:826 +#: templates/topologie/index_p.html:38 views.py:843 msgid "Switch model" msgstr "Modèle de commutateur réseau" -#: models.py:258 +#: models.py:241 +msgid "RADIUS key of the switch" +msgstr "Clé RADIUS du commutateur réseau" + +#: models.py:248 +msgid "Management credentials for the switch" +msgstr "Identifiants de gestion du commutateur réseau" + +#: models.py:252 +msgid "Automatic provision for the switch" +msgstr "Provision automatique pour le commutateur réseau" + +#: models.py:259 msgid "Can view a switch object" msgstr "Peut voir un objet commutateur réseau" -#: models.py:260 +#: models.py:261 msgid "switch" msgstr "commutateur réseau" -#: models.py:261 +#: models.py:262 msgid "switches" msgstr "commutateurs réseau" -#: models.py:272 +#: models.py:273 msgid "The switch ID exceeds the limits allowed by the stack." msgstr "L'ID du commutateur réseau dépasse les bornes autorisées par la pile." -#: models.py:277 +#: models.py:278 msgid "The stack member ID can't be void." msgstr "L'ID de membre dans la pile ne peut-être vide." -#: models.py:293 +#: models.py:286 msgid "The end port is less than the start port." msgstr "Le port de fin est inférieur au port de début." -#: models.py:296 +#: models.py:293 msgid "This switch can't have that many ports." msgstr "Ce commutateur réseau ne peut pas avoir autant de ports." -#: models.py:306 +#: models.py:295 msgid "Creation" msgstr "Création" -#: models.py:308 -msgid "Creation of an existing port." -msgstr "Création d'un port existant." +#: models.py:406 +msgid "The switch model is modular." +msgstr "Le modèle de commutateur réseau est modulaire." -#: models.py:408 +#: models.py:410 +msgid "The switch is considered as a module." +msgstr "Le commutateur réseau est considéré comme un module." + +#: models.py:415 msgid "Can view a switch model object" msgstr "Peut voir un objet modèle de commutateur réseau" -#: models.py:410 +#: models.py:417 msgid "switch model" msgstr "modèle de commutateur réseau" -#: models.py:411 +#: models.py:418 msgid "switch models" msgstr "modèles de commutateur réseau" -#: models.py:424 +#: models.py:431 +msgid "Reference of a module" +msgstr "Référence d'un module" + +#: models.py:432 +msgid "Module reference" +msgstr "Référence de module" + +#: models.py:438 models.py:439 templates/topologie/aff_modules.html:37 +msgid "Comment" +msgstr "Commentaire" + +#: models.py:444 +msgid "Can view a switch module object" +msgstr "Peut voir un objet module de commutateur réseau" + +#: models.py:446 +msgid "switch module" +msgstr "module de commutateur réseau" + +#: models.py:447 +msgid "switch modules" +msgstr "modules de commutateur réseau" + +#: models.py:460 +msgid "Slot on switch" +msgstr "Emplacement sur le commutateur réseau" + +#: models.py:461 templates/topologie/aff_modules.html:48 +#: templates/topologie/aff_modules.html:82 +msgid "Slot" +msgstr "Emplacement" + +#: models.py:466 +msgid "Can view a link between switch and module object" +msgstr "Peut voir un objet lien entre commutateur réseau et module" + +#: models.py:469 +msgid "link between switch and module" +msgstr "lien entre commutateur réseau et module" + +#: models.py:470 +msgid "links between switch and module" +msgstr "liens entre commutateur réseau et module" + +#: models.py:474 +msgid "On slot " +msgstr "Sur l'emplacement " + +#: models.py:474 +msgid " of " +msgstr " de " + +#: models.py:484 msgid "Can view a switch constructor object" msgstr "Peut voir un objet constructeur de commutateur réseau" -#: models.py:427 +#: models.py:487 msgid "switch constructor" msgstr "constructeur de commutateur réseau" -#: models.py:450 +#: models.py:510 msgid "Can view a switch bay object" msgstr "Peut voir un objet baie de brassage" -#: models.py:452 +#: models.py:512 msgid "switch bay" msgstr "baie de brassage" -#: models.py:453 +#: models.py:513 msgid "switch bays" msgstr "baies de brassage" -#: models.py:466 +#: models.py:526 msgid "Can view a building object" msgstr "Peut voir un objet bâtiment" -#: models.py:468 +#: models.py:528 msgid "building" msgstr "bâtiment" -#: models.py:469 +#: models.py:529 msgid "buildings" msgstr "bâtiments" -#: models.py:525 +#: models.py:588 models.py:589 msgid "Port state Active" msgstr "État du port Actif" -#: models.py:532 +#: models.py:596 msgid "Can view a port object" msgstr "Peut voir un objet port" -#: models.py:534 +#: models.py:598 msgid "port" msgstr "port" -#: models.py:535 +#: models.py:599 msgid "ports" msgstr "ports" -#: models.py:614 +#: models.py:605 +msgid "Uplink: " +msgstr "Liaison montante : " + +#: models.py:607 +msgid "Machine: " +msgstr "Machine : " + +#: models.py:609 +msgid "Room: " +msgstr "Chambre : " + +#: models.py:611 +msgid "Unknown" +msgstr "Inconnu" + +#: models.py:678 msgid "The port can't exist, its number is too great." msgstr "Le port ne peut pas exister, son numéro est trop grand." -#: models.py:620 +#: models.py:684 msgid "Room, interface and related port are mutually exclusive." msgstr "Chambre, interface et port relié sont mutuellement exclusifs." -#: models.py:623 +#: models.py:687 msgid "A port can't be related to itself." msgstr "Un port ne peut être relié à lui-même." -#: models.py:627 +#: models.py:691 msgid "" "The related port is already used, please clear it before creating the " "relation." @@ -199,124 +284,146 @@ msgstr "" "Le port relié est déjà utilisé, veuillez le modifier avant de créer la " "relation." -#: models.py:648 +#: models.py:712 msgid "Can view a room object" msgstr "Peut voir un objet chambre" -#: models.py:650 +#: models.py:714 msgid "room" msgstr "chambre" -#: models.py:651 +#: models.py:715 msgid "rooms" msgstr "chambres" -#: models.py:685 templates/topologie/aff_port_profile.html:37 +#: models.py:726 +msgid "MAC-RADIUS" +msgstr "MAC-RADIUS" + +#: models.py:743 templates/topologie/aff_chambres.html:36 +#: templates/topologie/aff_port.html:38 views.py:784 +msgid "Room" +msgstr "Chambre" + +#: models.py:744 templates/topologie/aff_ap.html:36 +msgid "Access point" +msgstr "Point d'accès sans fil" + +#: models.py:745 +msgid "Uplink" +msgstr "Liaison montante" + +#: models.py:746 +msgid "Organisation machine" +msgstr "Machine d'association" + +#: models.py:747 +msgid "Nothing" +msgstr "Rien" + +#: models.py:749 templates/topologie/aff_port_profile.html:37 +#: templates/topologie/aff_vlanoptions.html:34 msgid "Name" msgstr "Nom" -#: models.py:692 +#: models.py:756 msgid "Default profile" msgstr "Profil par défaut" -#: models.py:700 +#: models.py:764 msgid "VLAN untagged" msgstr "VLAN untagged" -#: models.py:706 +#: models.py:770 msgid "VLAN(s) tagged" msgstr "VLAN(s) tagged" -#: models.py:711 +#: models.py:775 msgid "Type of RADIUS authentication : inactive, MAC-address or 802.1X" msgstr "Type d'authentification RADIUS : inactive, MAC-address ou 802.1X" -#: models.py:713 +#: models.py:777 msgid "RADIUS type" msgstr "Type de RADIUS" -#: models.py:719 +#: models.py:783 msgid "In case of MAC-authentication : mode COMMON or STRICT on this port" msgstr "" "Dans le cas d'authentification par adresse MAC : mode COMMON ou STRICT sur " "ce port" -#: models.py:721 +#: models.py:785 msgid "RADIUS mode" msgstr "Mode de RADIUS" -#: models.py:727 +#: models.py:791 msgid "Port speed limit" msgstr "Limite de vitesse du port" -#: models.py:732 +#: models.py:796 msgid "Limit of MAC-address on this port" msgstr "Limite de MAC-address sur ce port" -#: models.py:733 +#: models.py:797 msgid "MAC limit" msgstr "Limite MAC" -#: models.py:737 +#: models.py:801 msgid "Flow control" msgstr "Contrôle du flux" -#: models.py:741 +#: models.py:805 msgid "Protect against rogue DHCP" msgstr "Protège contre les DHCP pirates" -#: models.py:742 +#: models.py:806 templates/topologie/aff_vlanoptions.html:36 msgid "DHCP snooping" msgstr "DHCP snooping" -#: models.py:746 +#: models.py:810 msgid "Protect against rogue DHCPv6" msgstr "Protège contre les DHCPv6 pirates" -#: models.py:747 +#: models.py:811 templates/topologie/aff_vlanoptions.html:37 msgid "DHCPv6 snooping" msgstr "DHCPv6 snooping" -#: models.py:751 +#: models.py:815 msgid "Check if IP adress is DHCP assigned" msgstr "Vérifie si l'adresse IP est attribuée par DHCP" -#: models.py:752 +#: models.py:816 msgid "ARP protection" msgstr "Protection ARP" -#: models.py:756 +#: models.py:820 msgid "Protect against rogue RA" msgstr "Protège contre les RA pirates" -#: models.py:757 +#: models.py:821 msgid "RA guard" msgstr "RA guard" -#: models.py:761 +#: models.py:825 msgid "Protect against loop" -msgstr "Protège contre un boucle" +msgstr "Protège contre une boucle" -#: models.py:762 +#: models.py:826 msgid "Loop protection" msgstr "Protection contre une boucle" -#: models.py:767 +#: models.py:831 msgid "Can view a port profile object" msgstr "Peut voir un objet profil de port" -#: models.py:769 +#: models.py:833 msgid "port profile" msgstr "profil de port" -#: models.py:770 +#: models.py:834 msgid "port profiles" msgstr "profils de port" -#: templates/topologie/aff_ap.html:36 -msgid "Access point" -msgstr "Point d'accès sans fil" - #: templates/topologie/aff_ap.html:38 msgid "MAC address" msgstr "Adresse MAC" @@ -336,44 +443,24 @@ msgstr "Détails" msgid "Location" msgstr "Emplacement" -#: templates/topologie/aff_ap.html:56 templates/topologie/aff_building.html:46 -#: templates/topologie/aff_chambres.html:48 -#: templates/topologie/aff_constructor_switch.html:46 -#: templates/topologie/aff_model_switch.html:61 -#: templates/topologie/aff_port.html:99 templates/topologie/aff_stacks.html:55 -#: templates/topologie/aff_switch_bay.html:59 -#: templates/topologie/edit_stack_sw.html:44 views.py:380 views.py:434 -#: views.py:745 views.py:804 views.py:859 views.py:914 views.py:973 -#: views.py:1028 -msgid "Edit" -msgstr "Modifier" - -#: templates/topologie/aff_ap.html:62 templates/topologie/aff_building.html:52 -#: templates/topologie/aff_chambres.html:54 -#: templates/topologie/aff_constructor_switch.html:52 -#: templates/topologie/aff_model_switch.html:67 -#: templates/topologie/aff_port.html:105 templates/topologie/aff_stacks.html:61 -#: templates/topologie/aff_switch_bay.html:65 -#: templates/topologie/edit_stack_sw.html:50 -msgid "Delete" -msgstr "Supprimer" - #: templates/topologie/aff_building.html:36 -#: templates/topologie/aff_switch_bay.html:38 views.py:936 +#: templates/topologie/aff_switch_bay.html:38 views.py:953 msgid "Building" msgstr "Bâtiment" -#: templates/topologie/aff_chambres.html:36 -#: templates/topologie/aff_port.html:38 views.py:767 -msgid "Room" -msgstr "Chambre" +#: templates/topologie/aff_building.html:38 +#: templates/topologie/index_ap.html:33 templates/topologie/sidebar.html:47 +msgid "Access points" +msgstr "Points d'accès sans fil" #: templates/topologie/aff_constructor_switch.html:36 -#: templates/topologie/aff_model_switch.html:40 views.py:996 +#: templates/topologie/aff_model_switch.html:40 views.py:1013 msgid "Switch constructor" msgstr "Constructeur de commutateur réseau" #: templates/topologie/aff_model_switch.html:36 +#: templates/topologie/aff_modules.html:36 +#: templates/topologie/aff_modules.html:81 msgid "Reference" msgstr "Référence" @@ -382,20 +469,27 @@ msgid "Commercial name" msgstr "Nom commercial" #: templates/topologie/aff_model_switch.html:42 -#: templates/topologie/index.html:66 templates/topologie/sidebar.html:35 +#: templates/topologie/aff_modules.html:38 templates/topologie/index.html:66 +#: templates/topologie/sidebar.html:35 msgid "Switches" msgstr "Commutateurs réseau" +#: templates/topologie/aff_modules.html:48 +msgid "of" +msgstr "de" + +#: templates/topologie/aff_modules.html:76 +msgid "All modular switchs" +msgstr "Tous les commutateurs réseau modulaires" + +#: templates/topologie/aff_modules.html:80 templates/topologie/aff_port.html:36 +msgid "Switch" +msgstr "Commutateur réseau" + #: templates/topologie/aff_port.html:33 msgid "Port" msgstr "Port" -#: templates/topologie/aff_port.html:36 -#, fuzzy -#| msgid "Switch:" -msgid "Switch" -msgstr "Commutateur réseau :" - #: templates/topologie/aff_port.html:40 msgid "Interface" msgstr "Interface" @@ -408,7 +502,7 @@ msgstr "Port relié" msgid "Port state" msgstr "État du port" -#: templates/topologie/aff_port.html:45 views.py:1048 +#: templates/topologie/aff_port.html:45 views.py:1065 msgid "Port profile" msgstr "Profil de port" @@ -464,6 +558,11 @@ msgstr "Type de RADIUS : " msgid "RADIUS mode: " msgstr "Mode de RADIUS : " +#: templates/topologie/aff_repr_switch.html:67 +#: templates/topologie/aff_repr_switch.html:110 +msgid "Empty" +msgstr "Vide" + #: templates/topologie/aff_stacks.html:32 #: templates/topologie/aff_switch.html:45 #: templates/topologie/edit_stack_sw.html:32 @@ -472,6 +571,7 @@ msgid "Stack" msgstr "Pile" #: templates/topologie/aff_stacks.html:34 +#: templates/topologie/aff_vlanoptions.html:33 msgid "ID" msgstr "ID" @@ -485,7 +585,7 @@ msgstr "Nom DNS" #: templates/topologie/aff_switch.html:41 #: templates/topologie/aff_switch_bay.html:36 -#: templates/topologie/index_p.html:37 views.py:881 +#: templates/topologie/index_p.html:37 views.py:898 msgid "Switch bay" msgstr "Baie de brassage" @@ -510,10 +610,22 @@ msgstr "Informations" msgid "Switches of the bay" msgstr "Commutateurs réseau de la baie" +#: templates/topologie/aff_vlanoptions.html:35 +msgid "ARP protect" +msgstr "Protection ARP" + +#: templates/topologie/aff_vlanoptions.html:38 +msgid "IGMP" +msgstr "IGMP" + +#: templates/topologie/aff_vlanoptions.html:39 +msgid "MLD" +msgstr "MLD" + #: templates/topologie/delete.html:29 templates/topologie/index.html:30 #: templates/topologie/index_ap.html:30 #: templates/topologie/index_model_switch.html:30 -#: templates/topologie/index_p.html:30 +#: templates/topologie/index_module.html:30 templates/topologie/index_p.html:30 #: templates/topologie/index_physical_grouping.html:30 #: templates/topologie/index_portprofile.html:29 #: templates/topologie/index_room.html:30 templates/topologie/switch.html:30 @@ -542,10 +654,6 @@ msgstr "Topologie des commutateurs réseau" msgid " Add a switch" msgstr " Ajouter un commutateur réseau" -#: templates/topologie/index_ap.html:33 templates/topologie/sidebar.html:43 -msgid "Access points" -msgstr "Points d'accès sans fil" - #: templates/topologie/index_ap.html:35 msgid " Add an access point" msgstr " Ajouter un point d'accès sans fil" @@ -566,22 +674,18 @@ msgstr "Constructeurs de commutateur réseau" msgid " Add a switch constructor" msgstr " Ajouter un constructeur de commutateur réseau" +#: templates/topologie/index_module.html:33 templates/topologie/sidebar.html:39 +msgid "Switch modules" +msgstr "Modules de commutateur réseau" + +#: templates/topologie/index_module.html:35 +msgid " Add a module" +msgstr " Ajouter un module" + #: templates/topologie/index_p.html:33 msgid "Switch:" msgstr "Commutateur réseau :" -#: templates/topologie/index_p.html:49 -msgid " Edit" -msgstr " Modifier" - -#: templates/topologie/index_p.html:51 -msgid " Add a port" -msgstr " Ajouter un port" - -#: templates/topologie/index_p.html:52 -msgid " Add ports" -msgstr " Ajouter des ports" - #: templates/topologie/index_physical_grouping.html:33 msgid "Stacks" msgstr "Piles" @@ -607,7 +711,7 @@ msgid " Add a building" msgstr " Ajouter un bâtiment" #: templates/topologie/index_portprofile.html:34 -#: templates/topologie/sidebar.html:39 +#: templates/topologie/sidebar.html:43 msgid "Port profiles" msgstr "Profils de port" @@ -616,8 +720,8 @@ msgid " Add a port profile" msgstr " Ajouter un profil de port" #: templates/topologie/index_portprofile.html:42 -msgid "Sécurité par vlan" -msgstr "" +msgid "VLAN security" +msgstr "Sécurité de VLAN" #: templates/topologie/index_room.html:33 msgid "Rooms" @@ -631,11 +735,11 @@ msgstr " Ajouter une chambre" msgid "Rooms and premises" msgstr "Chambres et locaux" -#: templates/topologie/sidebar.html:47 +#: templates/topologie/sidebar.html:51 msgid "Physical grouping" msgstr "Groupements physiques" -#: templates/topologie/sidebar.html:51 +#: templates/topologie/sidebar.html:55 msgid "Switch models and constructors" msgstr "Modèles et constructeurs de commutateur réseau" @@ -647,7 +751,8 @@ msgstr " Aller à la liste des ports" msgid "Specific settings for the switch" msgstr "Réglages spécifiques pour le commutateur réseau" -#: templates/topologie/switch.html:46 views.py:418 views.py:1010 +#: templates/topologie/switch.html:46 views.py:441 views.py:745 views.py:800 +#: views.py:859 views.py:914 views.py:969 views.py:1027 views.py:1081 msgid "Create" msgstr "Créer" @@ -665,51 +770,60 @@ msgstr "Réglages généraux pour la machine liée à l'objet %(device)s" msgid "Create or edit" msgstr "Créer ou modifier" -#: views.py:340 +#: views.py:347 +msgid "The VLAN was edited." +msgstr "Le VLAN a été modifié." + +#: views.py:350 views.py:403 views.py:457 views.py:762 views.py:821 +#: views.py:876 views.py:931 views.py:990 views.py:1045 views.py:1098 +#: views.py:1152 +msgid "Edit" +msgstr "Modifier" + +#: views.py:363 views.py:554 msgid "Nonexistent switch." msgstr "Commutateur réseau inexistant." -#: views.py:348 +#: views.py:371 msgid "The port was added." msgstr "Le port a été ajouté." -#: views.py:350 +#: views.py:373 msgid "The port already exists." msgstr "Le port existe déjà." -#: views.py:356 views.py:728 views.py:783 views.py:842 views.py:897 -#: views.py:952 +#: views.py:379 views.py:1135 msgid "Add" msgstr "Ajouter" -#: views.py:371 +#: views.py:394 msgid "The port was edited." msgstr "Le port a été modifié." -#: views.py:394 +#: views.py:417 msgid "The port was deleted." msgstr "Le port a été supprimé." -#: views.py:398 +#: views.py:421 #, python-format msgid "The port %s is used by another object, impossible to delete it." msgstr "Le port %s est utilisé par un autre objet, impossible de le supprimer." -#: views.py:415 +#: views.py:438 msgid "The stack was created." msgstr "La pile a été créée." -#: views.py:447 +#: views.py:470 msgid "The stack was deleted." msgstr "La pile a été supprimée." -#: views.py:451 +#: views.py:474 #, python-format msgid "The stack %s is used by another object, impossible to deleted it." msgstr "" "La pile %s est utilisée par un autre objet, impossible de la supprimer." -#: views.py:493 views.py:634 views.py:689 +#: views.py:516 views.py:651 views.py:706 msgid "" "The organisation's user doesn't exist yet, please create or link it in the " "preferences." @@ -717,117 +831,113 @@ msgstr "" "L'utilisateur de l'association n'existe pas encore, veuillez le créer ou le " "relier dans les préférences." -#: views.py:508 +#: views.py:531 msgid "The switch was created." msgstr "Le commutateur réseau a été créé." -#: views.py:531 -msgid "Nonexistent switch" -msgstr "Commutateur réseau inexistant." - -#: views.py:551 +#: views.py:568 msgid "The ports were created." msgstr "Les ports ont été créés." -#: views.py:595 +#: views.py:612 msgid "The switch was edited." msgstr "Le commutateur réseau a été modifié." -#: views.py:649 +#: views.py:666 msgid "The access point was created." msgstr "Le point d'accès sans fil a été créé." -#: views.py:702 +#: views.py:719 msgid "The access point was edited." msgstr "Le point d'accès sans fil a été modifié." -#: views.py:725 +#: views.py:742 msgid "The room was created." msgstr "La chambre a été créée." -#: views.py:742 +#: views.py:759 msgid "The room was edited." msgstr "La chambre a été modifiée." -#: views.py:758 +#: views.py:775 msgid "The room was deleted." msgstr "La chambre a été supprimée." -#: views.py:762 +#: views.py:779 #, python-format msgid "The room %s is used by another object, impossible to deleted it." msgstr "" "La chambre %s est utilisée par un autre objet, impossible de la supprimer." -#: views.py:780 -msgid "The swich model was created." +#: views.py:797 +msgid "The switch model was created." msgstr "Le modèle de commutateur réseau a été créé." -#: views.py:801 +#: views.py:818 msgid "The switch model was edited." msgstr "Le modèle de commutateur réseau a été modifié." -#: views.py:817 +#: views.py:834 msgid "The switch model was deleted." msgstr "Le modèle de commutateur réseau a été supprimé." -#: views.py:821 +#: views.py:838 #, python-format msgid "The switch model %s is used by another object, impossible to delete it." msgstr "" "Le modèle de commutateur réseau %s est utilisé par un autre objet, " "impossible de le supprimer." -#: views.py:839 +#: views.py:856 msgid "The switch bay was created." msgstr "La baie de brassage a été créée." -#: views.py:856 +#: views.py:873 msgid "The switch bay was edited." msgstr "La baie de brassage a été modifiée." -#: views.py:872 +#: views.py:889 msgid "The switch bay was deleted." msgstr "La baie de brassage a été supprimée." -#: views.py:876 +#: views.py:893 #, python-format msgid "The switch bay %s is used by another object, impossible to delete it." msgstr "" "La baie de brassage %s est utilisée par un autre objet, impossible de la " "supprimer." -#: views.py:894 +#: views.py:911 msgid "The building was created." msgstr "Le bâtiment a été créé." -#: views.py:911 +#: views.py:928 msgid "The building was edited." msgstr "Le bâtiment a été modifié." -#: views.py:927 +#: views.py:944 msgid "The building was deleted." msgstr "Le bâtiment a été supprimé." -#: views.py:931 +#: views.py:948 #, python-format msgid "The building %s is used by another object, impossible to delete it." msgstr "" "Le bâtiment %s est utilisé par un autre objet, impossible de le supprimer." -#: views.py:949 +#: views.py:966 msgid "The switch constructor was created." msgstr "Le constructeur de commutateur réseau a été créé." -#: views.py:970 +#: views.py:987 msgid "The switch constructor was edited." msgstr "Le constructeur de commutateur réseau a été modifié." -#: views.py:986 +#: views.py:1003 msgid "The switch constructor was deleted." msgstr "Le constructeur de commutateur réseau a été supprimé." -#: views.py:990 +#: views.py:1007 #, python-format msgid "" "The switch constructor %s is used by another object, impossible to delete it." @@ -835,23 +945,49 @@ msgstr "" "Le constructeur de commutateur réseau %s est utilisé par un autre objet, " "impossible de le supprimer." -#: views.py:1007 +#: views.py:1024 msgid "The port profile was created." msgstr "Le profil de port a été créé." -#: views.py:1025 +#: views.py:1042 msgid "The port profile was edited." msgstr "Le profil de port a été modifié." -#: views.py:1042 +#: views.py:1059 msgid "The port profile was deleted." msgstr "Le profil de port a été supprimé." -#: views.py:1045 +#: views.py:1062 msgid "Impossible to delete the port profile." msgstr "Impossible de supprimer le profil de port." -#: views.py:1165 +#: views.py:1078 +msgid "The module was created." +msgstr "Le module a été créé." + +#: views.py:1095 views.py:1149 +msgid "The module was edited." +msgstr "Le module a été modifié." + +#: views.py:1111 views.py:1165 +msgid "The module was deleted." +msgstr "Le module a été supprimé." + +#: views.py:1115 views.py:1169 +#, python-format +msgid "The module %s is used by another object, impossible to deleted it." +msgstr "" +"Le module %s est utilisé par un autre objet, impossible de le supprimer." + +#: views.py:1120 views.py:1174 +msgid "Module" +msgstr "Module" + +#: views.py:1132 +msgid "The module was added." +msgstr "Le module a été ajouté." + +#: views.py:1291 msgid "" "The default Django template isn't used. This can lead to rendering errors. " "Check the parameters." diff --git a/topologie/migrations/0069_auto_20190108_1439.py b/topologie/migrations/0069_auto_20190108_1439.py new file mode 100644 index 00000000..ba13942b --- /dev/null +++ b/topologie/migrations/0069_auto_20190108_1439.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2019-01-08 20:39 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('topologie', '0068_auto_20190102_1758'), + ] + + operations = [ + migrations.AlterModelOptions( + name='moduleonswitch', + options={'permissions': (('view_moduleonswitch', 'Can view a link between switch and module object'),), 'verbose_name': 'link between switch and module', 'verbose_name_plural': 'links between switch and module'}, + ), + migrations.AlterModelOptions( + name='moduleswitch', + options={'permissions': (('view_moduleswitch', 'Can view a switch module object'),), 'verbose_name': 'switch module', 'verbose_name_plural': 'switch modules'}, + ), + migrations.AlterField( + model_name='modelswitch', + name='is_itself_module', + field=models.BooleanField(default=False, help_text='The switch is considered as a module.'), + ), + migrations.AlterField( + model_name='modelswitch', + name='is_modular', + field=models.BooleanField(default=False, help_text='The switch model is modular.'), + ), + migrations.AlterField( + model_name='portprofile', + name='profil_default', + field=models.CharField(blank=True, choices=[('room', 'Room'), ('access_point', 'Access point'), ('uplink', 'Uplink'), ('asso_machine', 'Organisation machine'), ('nothing', 'Nothing')], max_length=32, null=True, unique=True, verbose_name='Default profile'), + ), + migrations.AlterField( + model_name='portprofile', + name='radius_type', + field=models.CharField(choices=[('NO', 'NO'), ('802.1X', '802.1X'), ('MAC-radius', 'MAC-RADIUS')], help_text='Type of RADIUS authentication : inactive, MAC-address or 802.1X', max_length=32, verbose_name='RADIUS type'), + ), + migrations.AlterField( + model_name='switch', + name='automatic_provision', + field=models.BooleanField(default=False, help_text='Automatic provision for the switch'), + ), + migrations.AlterField( + model_name='switch', + name='management_creds', + field=models.ForeignKey(blank=True, help_text='Management credentials for the switch', null=True, on_delete=django.db.models.deletion.PROTECT, to='preferences.SwitchManagementCred'), + ), + migrations.AlterField( + model_name='switch', + name='radius_key', + field=models.ForeignKey(blank=True, help_text='RADIUS key of the switch', null=True, on_delete=django.db.models.deletion.PROTECT, to='preferences.RadiusKey'), + ), + ] diff --git a/topologie/models.py b/topologie/models.py index e05fa50e..3e093b40 100644 --- a/topologie/models.py +++ b/topologie/models.py @@ -238,18 +238,18 @@ class Switch(AclMixin, Machine): blank=True, null=True, on_delete=models.PROTECT, - help_text="Clef radius du switch" + help_text=_("RADIUS key of the switch") ) management_creds = models.ForeignKey( 'preferences.SwitchManagementCred', blank=True, null=True, on_delete=models.PROTECT, - help_text="Identifiant de management de ce switch" + help_text=_("Management credentials for the switch") ) automatic_provision = models.BooleanField( default=False, - help_text='Provision automatique de ce switch', + help_text=_("Automatic provision for the switch") ) @@ -403,11 +403,11 @@ class ModelSwitch(AclMixin, RevMixin, models.Model): ) is_modular = models.BooleanField( default=False, - help_text=_("Is this switch model modular"), + help_text=_("The switch model is modular."), ) is_itself_module = models.BooleanField( default=False, - help_text=_("Is the switch, itself, considered as a module"), + help_text=_("The switch is considered as a module."), ) class Meta: @@ -441,9 +441,10 @@ class ModuleSwitch(AclMixin, RevMixin, models.Model): class Meta: permissions = ( - ("view_moduleswitch", _("Can view a module object")), + ("view_moduleswitch", _("Can view a switch module object")), ) - verbose_name = _("Module of a switch") + verbose_name = _("switch module") + verbose_name_plural = _("switch modules") def __str__(self): @@ -462,13 +463,15 @@ class ModuleOnSwitch(AclMixin, RevMixin, models.Model): class Meta: permissions = ( - ("view_moduleonswitch", _("Can view a moduleonswitch object")), + ("view_moduleonswitch", _("Can view a link between switch and" + " module object")), ) - verbose_name = _("link between switchs and modules") + verbose_name = _("link between switch and module") + verbose_name_plural = _("links between switch and module") unique_together = ['slot', 'switch'] def __str__(self): - return 'On slot ' + str(self.slot) + ' of ' + str(self.switch) + return _("On slot ") + str(self.slot) + _(" of ") + str(self.switch) class ConstructorSwitch(AclMixin, RevMixin, models.Model): @@ -582,7 +585,7 @@ class Port(AclMixin, RevMixin, models.Model): ) state = models.BooleanField( default=True, - help_text='Port state Active', + help_text=_("Port state Active"), verbose_name=_("Port state Active") ) details = models.CharField(max_length=255, blank=True) @@ -599,13 +602,13 @@ class Port(AclMixin, RevMixin, models.Model): def pretty_name(self): """More elaborated name for label on switch conf""" if self.related: - return "Uplink : " + self.related.switch.short_name + return _("Uplink: ") + self.related.switch.short_name elif self.machine_interface: - return "Machine : " + str(self.machine_interface.domain) + return _("Machine: ") + str(self.machine_interface.domain) elif self.room: - return "Chambre : " + str(self.room) + return _("Room: ") + str(self.room) else: - return "Inconnue" + return _("Unknown") @cached_property def get_port_profile(self): @@ -720,7 +723,7 @@ class PortProfile(AclMixin, RevMixin, models.Model): TYPES = ( ('NO', 'NO'), ('802.1X', '802.1X'), - ('MAC-radius', 'MAC-radius'), + ('MAC-radius', _("MAC-RADIUS")), ) MODES = ( ('STRICT', 'STRICT'), @@ -737,11 +740,11 @@ class PortProfile(AclMixin, RevMixin, models.Model): ('auto-100', 'auto-100'), ) PROFIL_DEFAULT = ( - ('room', 'room'), - ('access_point', 'access_point'), - ('uplink', 'uplink'), - ('asso_machine', 'asso_machine'), - ('nothing', 'nothing'), + ('room', _("Room")), + ('access_point', _("Access point")), + ('uplink', _("Uplink")), + ('asso_machine', _("Organisation machine")), + ('nothing', _("Nothing")), ) name = models.CharField(max_length=255, verbose_name=_("Name")) profil_default = models.CharField( diff --git a/topologie/templates/topologie/aff_ap.html b/topologie/templates/topologie/aff_ap.html index 4eadfede..1acd54bb 100644 --- a/topologie/templates/topologie/aff_ap.html +++ b/topologie/templates/topologie/aff_ap.html @@ -28,17 +28,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% if ap_list.paginator %} - {% include "pagination.html" with list=ap_list %} + {% include 'pagination.html' with list=ap_list %} {% endif %} {% trans "Access point" as tr_ap %} - + {% trans "MAC address" as tr_mac %} - + {% trans "IPv4 address" as tr_ip %} - + @@ -53,15 +53,11 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -69,7 +65,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% include "buttons/sort.html" with prefix='ap' col='name' text=tr_ap %}{% include 'buttons/sort.html' with prefix='ap' col='name' text=tr_ap %}{% include "buttons/sort.html" with prefix='ap' col='mac' text=tr_mac %}{% include 'buttons/sort.html' with prefix='ap' col='mac' text=tr_mac %}{% include "buttons/sort.html" with prefix='ap' col='ip' text=tr_ip %}{% include 'buttons/sort.html' with prefix='ap' col='ip' text=tr_ip %} {% trans "Details" %} {% trans "Location" %} {{ ap.location }} {% can_edit ap %} - - - + {% include 'buttons/edit.html' with href='topologie:edit-ap' id=ap.id %} {% acl_end %} {% history_button ap %} {% can_delete ap %} - - - + {% include 'buttons/suppr.html' with href='machines:del-machine' id=ap.id %} {% acl_end %}
      {% if ap_list.paginator %} - {% include "pagination.html" with list=ap_list %} + {% include 'pagination.html' with list=ap_list %} {% endif %}
      diff --git a/topologie/templates/topologie/aff_building.html b/topologie/templates/topologie/aff_building.html index 51302d24..9885f1c5 100644 --- a/topologie/templates/topologie/aff_building.html +++ b/topologie/templates/topologie/aff_building.html @@ -27,15 +27,15 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load i18n %} {% if building_list.paginator %} -{% include "pagination.html" with list=building_list %} + {% include 'pagination.html' with list=building_list %} {% endif %} {% trans "Building" as tr_building %} - - + + @@ -45,15 +45,11 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -61,6 +57,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% include "buttons/sort.html" with prefix='building' col='name' text=tr_building %}Wireless AP{% include 'buttons/sort.html' with prefix='building' col='name' text=tr_building %}{% trans "Access points" %}
      {% for ap in building.all_ap_in %} {{ ap.short_name }} {% endfor %} {% can_edit building %} - - - + {% include 'buttons/edit.html' with href='topologie:edit-building' id=building.id %} {% acl_end %} {% history_button building %} {% can_delete building %} - - - + {% include 'buttons/suppr.html' with href='topologie:del-building' id=building.id %} {% acl_end %}
      {% if building_list.paginator %} -{% include "pagination.html" with list=building_list %} + {% include 'pagination.html' with list=building_list %} {% endif %} diff --git a/topologie/templates/topologie/aff_chambres.html b/topologie/templates/topologie/aff_chambres.html index 04c010f4..6e2b181f 100644 --- a/topologie/templates/topologie/aff_chambres.html +++ b/topologie/templates/topologie/aff_chambres.html @@ -27,14 +27,14 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load i18n %} {% if room_list.paginator %} -{% include "pagination.html" with list=room_list %} + {% include 'pagination.html' with list=room_list %} {% endif %} {% trans "Room" as tr_room %} - + @@ -45,15 +45,11 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -61,6 +57,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% include "buttons/sort.html" with prefix='room' col='name' text=tr_room %}{% include 'buttons/sort.html' with prefix='room' col='name' text=tr_room %} {% trans "Details" %}
      {{ room.details }} {% can_edit room %} - - - + {% include 'buttons/edit.html' with href='topologie:edit-room' id=room.id %} {% acl_end %} {% history_button room %} {% can_delete room %} - - - + {% include 'buttons/suppr.html' with href='topologie:del-room' id=room.id %} {% acl_end %}
      {% if room_list.paginator %} -{% include "pagination.html" with list=room_list %} + {% include 'pagination.html' with list=room_list %} {% endif %} diff --git a/topologie/templates/topologie/aff_constructor_switch.html b/topologie/templates/topologie/aff_constructor_switch.html index 6298f73d..eceeb682 100644 --- a/topologie/templates/topologie/aff_constructor_switch.html +++ b/topologie/templates/topologie/aff_constructor_switch.html @@ -27,14 +27,14 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load i18n %} {% if constructor_switch_list.paginator %} -{% include "pagination.html" with list=constructor_switch_list %} + {% include 'pagination.html' with list=constructor_switch_list %} {% endif %} {% trans "Switch constructor" as tr_constructor %} - + @@ -43,15 +43,11 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -59,6 +55,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% include "buttons/sort.html" with prefix='constructor-switch' col='name' text=tr_constructor %}{% include 'buttons/sort.html' with prefix='constructor-switch' col='name' text=tr_constructor %}
      {{ constructor_switch }} {% can_edit constructor_switch %} - - - + {% include 'buttons/edit.html' with href='topologie:edit-constructor-switch' id=constructor_switch.id %} {% acl_end %} {% history_button constructor_switch %} {% can_delete constructor_switch %} - - - + {% include 'buttons/suppr.html' with href='topologie:del-constructor-switch' id=constructor_switch.id %} {% acl_end %}
      {% if constructor_switch_list.paginator %} -{% include "pagination.html" with list=constructor_switch_list %} + {% include 'pagination.html' with list=constructor_switch_list %} {% endif %} diff --git a/topologie/templates/topologie/aff_model_switch.html b/topologie/templates/topologie/aff_model_switch.html index 6a296ad7..426b308a 100644 --- a/topologie/templates/topologie/aff_model_switch.html +++ b/topologie/templates/topologie/aff_model_switch.html @@ -27,18 +27,18 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load i18n %} {% if model_switch_list.paginator %} -{% include "pagination.html" with list=model_switch_list %} + {% include 'pagination.html' with list=model_switch_list %} {% endif %} {% trans "Reference" as tr_ref %} - + {% trans "Switch constructor" as tr_constructor %} - + @@ -47,7 +47,7 @@ with this program; if not, write to the Free Software Foundation, Inc., - + @@ -74,8 +70,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% include "buttons/sort.html" with prefix='model-switch' col='reference' text=tr_ref %}{% include 'buttons/sort.html' with prefix='model-switch' col='reference' text=tr_ref %} {% trans "Commercial name" %} Firmware{% include "buttons/sort.html" with prefix='model-switch' col='constructor' text=tr_constructor %}{% include 'buttons/sort.html' with prefix='model-switch' col='constructor' text=tr_constructor %} {% trans "Switches" %}
      {{ model_switch.reference }} {{ model_switch.commercial_name }}{{model_switch.firmware}}{{ model_switch.firmware }} {{ model_switch.constructor }} {% for switch in model_switch.switch_set.all %} @@ -58,15 +58,11 @@ with this program; if not, write to the Free Software Foundation, Inc., {% can_edit model_switch %} - - - + {% include 'buttons/edit.html' with href='topologie:edit-model-switch' id=model_switch.id %} {% acl_end %} {% history_button model_switch %} {% can_delete model_switch %} - - - + {% include 'buttons/suppr.html' with href='topologie:del-model-switch' id=model_switch.id %} {% acl_end %}
      {% if model_switch_list.paginator %} -{% include "pagination.html" with list=model_switch_list %} + {% include 'pagination.html' with list=model_switch_list %} {% endif %} - - diff --git a/topologie/templates/topologie/aff_modules.html b/topologie/templates/topologie/aff_modules.html index 0c7a3207..021457f2 100644 --- a/topologie/templates/topologie/aff_modules.html +++ b/topologie/templates/topologie/aff_modules.html @@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load i18n %} {% if module_list.paginator %} -{% include "pagination.html" with list=module_list %} + {% include 'pagination.html' with list=module_list %} {% endif %} @@ -35,7 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., - + @@ -45,34 +45,24 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -80,7 +70,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% trans "Reference" %} {% trans "Comment" %}{% trans "Switchs" %}{% trans "Switches" %}
      {{ module.comment }} {% for module_switch in module.moduleonswitch_set.all %} - Slot {{ module_switch.slot }} of {{ module_switch.switch }} + {% trans "Slot" %} {{ module_switch.slot }} {% trans "of" %} {{ module_switch.switch }} {% can_edit module_switch %} - - - + {% include 'buttons/edit.html' with href='topologie:edit-module-on' id=module_switch.id %} {% acl_end %} {% can_delete module_switch %} - - - + {% include 'buttons/suppr.html' with href='topologie:del-module-on' id=module_switch.id %} {% acl_end %}
      {% endfor %}
      {% can_edit module %} - - - - - - + {% include 'buttons/add.html' with href='topologie:add-module-on' %} + {% include 'buttons/edit.html' with href='topologie:edit-module' id=module.id %} {% acl_end %} {% history_button module %} {% can_delete module %} - - - + {% include 'buttons/suppr.html' with href='topologie:del-module' id=module.id %} {% acl_end %}
      {% if module_list.paginator %} -{% include "pagination.html" with list=module_list %} + {% include 'pagination.html' with list=module_list %} {% endif %}

      {% trans "All modular switchs" %}

      diff --git a/topologie/templates/topologie/aff_port.html b/topologie/templates/topologie/aff_port.html index ef7e259c..6a02b484 100644 --- a/topologie/templates/topologie/aff_port.html +++ b/topologie/templates/topologie/aff_port.html @@ -31,16 +31,16 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Port" as tr_port %} - {% include "buttons/sort.html" with prefix='port' col='port' text=tr_port %} + {% include 'buttons/sort.html' with prefix='port' col='port' text=tr_port %} {% if search %} {% trans "Switch" %} {% endif %} {% trans "Room" as tr_room %} - {% include "buttons/sort.html" with prefix='port' col='room' text=tr_room %} + {% include 'buttons/sort.html' with prefix='port' col='room' text=tr_room %} {% trans "Interface" as tr_interface %} - {% include "buttons/sort.html" with prefix='port' col='interface' text=tr_interface %} + {% include 'buttons/sort.html' with prefix='port' col='interface' text=tr_interface %} {% trans "Related port" as tr_related_port %} - {% include "buttons/sort.html" with prefix='port' col='related' text=tr_related_port %} + {% include 'buttons/sort.html' with prefix='port' col='related' text=tr_related_port %} {% trans "Port state" %} {% trans "Port profile" %} {% trans "Details" %} @@ -96,15 +96,11 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ port.details }} {% can_edit port %} - - - + {% include 'buttons/edit.html' with href='topologie:edit-port' id=port.id %} {% acl_end %} {% history_button port %} {% can_delete port %} - - - + {% include 'buttons/suppr.html' with href='topologie:del-port' id=port.id %} {% acl_end %} diff --git a/topologie/templates/topologie/aff_port_profile.html b/topologie/templates/topologie/aff_port_profile.html index 9714f1d9..b335904e 100644 --- a/topologie/templates/topologie/aff_port_profile.html +++ b/topologie/templates/topologie/aff_port_profile.html @@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% if port_profile_list.paginator %} - {% include "pagination.html" with list=port_profile_list %} + {% include 'pagination.html' with list=port_profile_list %} {% endif %} @@ -68,11 +68,11 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ port_profile.security_parameters_enabled|join:"
      " }} {% can_edit port_profile %} - {% include 'buttons/edit.html' with href='topologie:edit-port-profile' id=port_profile.pk %} + {% include 'buttons/edit.html' with href='topologie:edit-port-profile' id=port_profile.id %} {% acl_end %} {% history_button port_profile %} {% can_delete port_profile %} - {% include 'buttons/suppr.html' with href='topologie:del-port-profile' id=port_profile.pk %} + {% include 'buttons/suppr.html' with href='topologie:del-port-profile' id=port_profile.id %} {% acl_end %} @@ -80,7 +80,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if port_profile_list.paginator %} - {% include "pagination.html" with list=port_profile_list %} + {% include 'pagination.html' with list=port_profile_list %} {% endif %}
      diff --git a/topologie/templates/topologie/aff_repr_switch.html b/topologie/templates/topologie/aff_repr_switch.html index f9e6e648..c482da7a 100644 --- a/topologie/templates/topologie/aff_repr_switch.html +++ b/topologie/templates/topologie/aff_repr_switch.html @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% load acl %} +{% load i18n %}
      @@ -63,7 +64,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% else %} {% endif %} {% endfor %} @@ -106,7 +107,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% else %} {% endif %} {% endfor %} diff --git a/topologie/templates/topologie/aff_stacks.html b/topologie/templates/topologie/aff_stacks.html index c5366cd7..c1032ee6 100644 --- a/topologie/templates/topologie/aff_stacks.html +++ b/topologie/templates/topologie/aff_stacks.html @@ -30,9 +30,9 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Stack" as tr_stack %} - + {% trans "ID" as tr_id %} - + @@ -45,22 +45,18 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/topologie/templates/topologie/aff_switch.html b/topologie/templates/topologie/aff_switch.html index d900a1f9..93c05530 100644 --- a/topologie/templates/topologie/aff_switch.html +++ b/topologie/templates/topologie/aff_switch.html @@ -28,22 +28,22 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% if switch_list.paginator %} - {% include "pagination.html" with list=switch_list %} + {% include 'pagination.html' with list=switch_list %} {% endif %}
      - Vide + {% trans "Empty" %} - Vide + {% trans "Empty" %}
      {% include "buttons/sort.html" with prefix='stack' col='name' text=tr_stack %}{% include 'buttons/sort.html' with prefix='stack' col='name' text=tr_stack %}{% include "buttons/sort.html" with prefix='stack' col='id' text=id %}{% include 'buttons/sort.html' with prefix='stack' col='id' text=id %} {% trans "Details" %} {% trans "Members" %} {{ stack.details }} {% for switch in stack.switch_set.all %} - + {{ switch }} {% endfor %} {% can_edit stack %} - - - + {% include 'buttons/edit.html' with href='topologie:edit-stack' id=stack.id %} {% acl_end %} {% history_button stack %} {% can_delete stack %} - - - + {% include 'buttons/suppr.html' with href='topologie:del-stack' id=stack.id %} {% acl_end %}
      {% trans "DNS name" as tr_dns %} - + {% trans "IPv4 address" as tr_ip %} - + {% trans "Switch bay" as tr_bay %} - + {% trans "Ports" as tr_ports %} - + {% trans "Stack" as tr_stack %} - + @@ -53,7 +53,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% for switch in switch_list %} @@ -66,7 +66,7 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -82,7 +82,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% include "buttons/sort.html" with prefix='switch' col='dns' text=tr_dns %}{% include 'buttons/sort.html' with prefix='switch' col='dns' text=tr_dns %}{% include "buttons/sort.html" with prefix='switch' col='ip' text=tr_ip %}{% include 'buttons/sort.html' with prefix='switch' col='ip' text=tr_ip %}{% include "buttons/sort.html" with prefix='switch' col='loc' text=tr_bay %}{% include 'buttons/sort.html' with prefix='switch' col='loc' text=tr_bay %}{% include "buttons/sort.html" with prefix='switch' col='ports' text=tr_ports %}{% include 'buttons/sort.html' with prefix='switch' col='ports' text=tr_ports %}{% include "buttons/sort.html" with prefix='switch' col='stack' text=tr_stack %}{% include 'buttons/sort.html' with prefix='switch' col='stack' text=tr_stack %} {% trans "Stack ID" %} {% trans "Switch model" %} {% trans "Details" %}
      - + {{ switch }} {{ switch.interface_set.first.details }} {% can_edit switch %} - {% include 'buttons/edit.html' with href='topologie:edit-switch' id=switch.pk %} + {% include 'buttons/edit.html' with href='topologie:edit-switch' id=switch.id %} {% acl_end %} {% history_button switch %} {% can_delete switch %} @@ -74,7 +74,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% acl_end %} {% can_create Port %} {% trans "Creation of ports" as tr_creation %} - {% include 'buttons/add.html' with href='topologie:create-ports' id=switch.pk desc=tr_creation %} + {% include 'buttons/add.html' with href='topologie:create-ports' id=switch.id desc=tr_creation %} {% acl_end %}
      {% if switch_list.paginator %} - {% include "pagination.html" with list=switch_list %} + {% include 'pagination.html' with list=switch_list %} {% endif %}
      diff --git a/topologie/templates/topologie/aff_switch_bay.html b/topologie/templates/topologie/aff_switch_bay.html index 0909c264..0aa81449 100644 --- a/topologie/templates/topologie/aff_switch_bay.html +++ b/topologie/templates/topologie/aff_switch_bay.html @@ -27,16 +27,16 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load i18n %} {% if switch_bay_list.paginator %} -{% include "pagination.html" with list=switch_bay_list %} + {% include 'pagination.html' with list=switch_bay_list %} {% endif %} {% trans "Switch bay" as tr_bay %} - + {% trans "Building" as tr_building %} - + @@ -49,22 +49,18 @@ with this program; if not, write to the Free Software Foundation, Inc., @@ -72,6 +68,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% include "buttons/sort.html" with prefix='switch-bay' col='name' text=tr_bay %}{% include 'buttons/sort.html' with prefix='switch-bay' col='name' text=tr_bay %}{% include "buttons/sort.html" with prefix='switch-bay' col='building' text=tr_building %}{% include 'buttons/sort.html' with prefix='switch-bay' col='building' text=tr_building %} {% trans "Information" %} {% trans "Switches of the bay" %} {{ switch_bay.info }} {% for switch in switch_bay.switch_set.all %} - + {{ switch }} {% endfor %} {% can_edit switch_bay %} - - - + {% include 'buttons/edit.html' with href='topologie:edit-switch-bay' id=switch_bay.id %} {% acl_end %} {% history_button switch_bay %} {% can_delete switch_bay %} - - - + {% include 'buttons/suppr.html' with href='topologie:del-switch-bay' id=switch_bay.id %} {% acl_end %}
      {% if switch_bay_list.paginator %} -{% include "pagination.html" with list=switch_bay_list %} + {% include 'pagination.html' with list=switch_bay_list %} {% endif %} diff --git a/topologie/templates/topologie/aff_vlanoptions.html b/topologie/templates/topologie/aff_vlanoptions.html index 3810cb7f..9b2dc913 100644 --- a/topologie/templates/topologie/aff_vlanoptions.html +++ b/topologie/templates/topologie/aff_vlanoptions.html @@ -24,18 +24,19 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load acl %} {% load logs_extra %} +{% load i18n %}
      - - - - - - - + + + + + + + diff --git a/topologie/templates/topologie/delete.html b/topologie/templates/topologie/delete.html index a3b85254..24e6edad 100644 --- a/topologie/templates/topologie/delete.html +++ b/topologie/templates/topologie/delete.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/topologie/templates/topologie/edit_stack_sw.html b/topologie/templates/topologie/edit_stack_sw.html index 8c29c85c..bf094f07 100644 --- a/topologie/templates/topologie/edit_stack_sw.html +++ b/topologie/templates/topologie/edit_stack_sw.html @@ -41,15 +41,11 @@ with this program; if not, write to the Free Software Foundation, Inc., diff --git a/topologie/templates/topologie/index.html b/topologie/templates/topologie/index.html index 1c13b928..be3667ca 100644 --- a/topologie/templates/topologie/index.html +++ b/topologie/templates/topologie/index.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -68,7 +68,7 @@ function toggle_graph() { {% trans " Add a switch" %}
      {% acl_end %} - {% include "topologie/aff_switch.html" with switch_list=switch_list %} + {% include 'topologie/aff_switch.html' with switch_list=switch_list %}


      diff --git a/topologie/templates/topologie/index_ap.html b/topologie/templates/topologie/index_ap.html index e1292bb9..5fbd3d94 100644 --- a/topologie/templates/topologie/index_ap.html +++ b/topologie/templates/topologie/index_ap.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -35,7 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Add an access point" %}
      {% acl_end %} - {% include "topologie/aff_ap.html" with ap_list=ap_list %} + {% include 'topologie/aff_ap.html' with ap_list=ap_list %}


      diff --git a/topologie/templates/topologie/index_model_switch.html b/topologie/templates/topologie/index_model_switch.html index b89b7415..e7ad725f 100644 --- a/topologie/templates/topologie/index_model_switch.html +++ b/topologie/templates/topologie/index_model_switch.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -37,7 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% acl_end %} - {% include "topologie/aff_model_switch.html" with model_switch_list=model_switch_list %} + {% include 'topologie/aff_model_switch.html' with model_switch_list=model_switch_list %}

      {% trans "Switch constructors" %}

      {% can_create ConstructorSwitch %} @@ -46,6 +46,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% acl_end %} - {% include "topologie/aff_constructor_switch.html" with constructor_switch_list=constructor_switch_list %} + {% include 'topologie/aff_constructor_switch.html' with constructor_switch_list=constructor_switch_list %} {% endblock %} diff --git a/topologie/templates/topologie/index_module.html b/topologie/templates/topologie/index_module.html index d9cc2925..a7fee190 100644 --- a/topologie/templates/topologie/index_module.html +++ b/topologie/templates/topologie/index_module.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -30,12 +30,12 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block title %}{% trans "Topology" %}{% endblock %} {% block content %} -

      {% trans "Modules of switchs" %}

      +

      {% trans "Switch modules" %}

      {% can_create ModuleSwitch %} {% trans " Add a module" %}
      {% acl_end %} - {% include "topologie/aff_modules.html" with module_list=module_list modular_switchs=modular_switchs %} + {% include 'topologie/aff_modules.html' with module_list=module_list modular_switchs=modular_switchs %}


      diff --git a/topologie/templates/topologie/index_p.html b/topologie/templates/topologie/index_p.html index f44a48c6..04a516ec 100644 --- a/topologie/templates/topologie/index_p.html +++ b/topologie/templates/topologie/index_p.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -46,14 +46,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      IdNomArp ProtectDhcp SnoopingDhcpv6 SnoopingIgmpMld{% trans "ID" %}{% trans "Name" %}{% trans "ARP protect" %}{% trans "DHCP snooping" %}{% trans "DHCPv6 snooping" %}{% trans "IGMP" %}{% trans "MLD" %}
      {{ stack.details }} {% can_edit stack %} - - - + {% include 'buttons/edit.html' with href='topologie:edit-stack' id=stack.id %} {% acl_end %} {% history_button stack %} {% can_delete stack %} - - - + {% include 'buttons/suppr.html' with href='topologie:del-stack' id=stack.id %} {% acl_end %}

      -{% trans " Edit" %} +{% include 'buttons/edit.html' with href='topologie:edit-switch' id=id_switch %} {% can_create Port %} -{% trans " Add a port" %} -{% trans " Add ports" %} +{% include 'buttons/add.html' with href='topologie:new-port' id=id_switch %} +{% include 'buttons/add.html' with href='topologie:create-ports' id=id_switch %} {% acl_end %}
      -{% include "topologie/aff_repr_switch.html" with port_list=port_list %} -{% include "topologie/aff_port.html" with port_list=port_list %} +{% include 'topologie/aff_repr_switch.html' with port_list=port_list %} +{% include 'topologie/aff_port.html' with port_list=port_list %}


      diff --git a/topologie/templates/topologie/index_physical_grouping.html b/topologie/templates/topologie/index_physical_grouping.html index 763d7820..d2defa0c 100644 --- a/topologie/templates/topologie/index_physical_grouping.html +++ b/topologie/templates/topologie/index_physical_grouping.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -36,7 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Add a stack" %} {% acl_end %} - {% include "topologie/aff_stacks.html" with stack_list=stack_list %} + {% include 'topologie/aff_stacks.html' with stack_list=stack_list %}

      {% trans "Switch bays" %}

      {% can_create SwitchBay %} @@ -45,7 +45,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% acl_end %} - {% include "topologie/aff_switch_bay.html" with switch_bay_list=switch_bay_list %} + {% include 'topologie/aff_switch_bay.html' with switch_bay_list=switch_bay_list %}

      {% trans "Buildings" %}

      {% can_create Building %} @@ -54,6 +54,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% acl_end %} - {% include "topologie/aff_building.html" with building_list=building_list %} + {% include 'topologie/aff_building.html' with building_list=building_list %} {% endblock %} diff --git a/topologie/templates/topologie/index_portprofile.html b/topologie/templates/topologie/index_portprofile.html index 4a603210..a528b992 100644 --- a/topologie/templates/topologie/index_portprofile.html +++ b/topologie/templates/topologie/index_portprofile.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -36,11 +36,11 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Add a port profile" %}
      {% acl_end %} -{% include "topologie/aff_port_profile.html" with port_profile_list=port_profile_list %} +{% include 'topologie/aff_port_profile.html' with port_profile_list=port_profile_list %} -

      {% trans "Sécurité par vlan" %}

      -{% include "topologie/aff_vlanoptions.html" with vlan_list=vlan_list %} +

      {% trans "VLAN security" %}

      +{% include 'topologie/aff_vlanoptions.html' with vlan_list=vlan_list %}

      diff --git a/topologie/templates/topologie/index_room.html b/topologie/templates/topologie/index_room.html index ea6ed6f3..248ce05d 100644 --- a/topologie/templates/topologie/index_room.html +++ b/topologie/templates/topologie/index_room.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -35,7 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans " Add a room" %}
      {% acl_end %} - {% include "topologie/aff_chambres.html" with room_list=room_list %} + {% include 'topologie/aff_chambres.html' with room_list=room_list %}


      diff --git a/topologie/templates/topologie/sidebar.html b/topologie/templates/topologie/sidebar.html index 80317a16..249c4308 100644 --- a/topologie/templates/topologie/sidebar.html +++ b/topologie/templates/topologie/sidebar.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends 'base.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -26,31 +26,31 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load i18n %} {% block sidebar %} - + {% trans "Rooms and premises" %} - + {% trans "Switches" %} - + - {% trans "Switches modules" %} + {% trans "Switch modules" %} - + {% trans "Port profiles" %} - + {% trans "Access points" %} - + {% trans "Physical grouping" %} - + {% trans "Switch models and constructors" %} diff --git a/topologie/templates/topologie/switch.html b/topologie/templates/topologie/switch.html index 48d220fc..5bb738f6 100644 --- a/topologie/templates/topologie/switch.html +++ b/topologie/templates/topologie/switch.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -36,7 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., -{% bootstrap_icon "list" %}{% trans " Go to the ports list" %} +{% bootstrap_icon "list" %}{% trans " Go to the ports list" %}
      {% csrf_token %} {% if topoform %} diff --git a/topologie/templates/topologie/topo.html b/topologie/templates/topologie/topo.html index a7824020..2f6449e5 100644 --- a/topologie/templates/topologie/topo.html +++ b/topologie/templates/topologie/topo.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en @@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% bootstrap_form_errors topoform %} {% if id_switch %} -{% bootstrap_icon "list" %}{% trans " Go to the ports list" %} +{% bootstrap_icon "list" %}{% trans " Go to the ports list" %} {% endif %} {% csrf_token %} diff --git a/topologie/templates/topologie/topo_more.html b/topologie/templates/topologie/topo_more.html index 02171bd0..89f6404d 100644 --- a/topologie/templates/topologie/topo_more.html +++ b/topologie/templates/topologie/topo_more.html @@ -1,4 +1,4 @@ -{% extends "topologie/sidebar.html" %} +{% extends 'topologie/sidebar.html' %} {% comment %} Re2o est un logiciel d'administration développé initiallement au rezometz. Il se veut agnostique au réseau considéré, de manière à être installable en diff --git a/topologie/views.py b/topologie/views.py index 55f0a060..2eeb3d55 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -344,10 +344,10 @@ def edit_vlanoptions(request, vlan_instance, **_kwargs): if vlan.is_valid(): if vlan.changed_data: vlan.save() - messages.success(request, "Vlan modifié") + messages.success(request, _("The VLAN was edited.")) return redirect(reverse('topologie:index-port-profile')) return form( - {'vlanform': vlan, 'action_name': 'Editer'}, + {'vlanform': vlan, 'action_name': _("Edit")}, 'machines/machine.html', request ) @@ -551,7 +551,7 @@ def create_ports(request, switchid): try: switch = Switch.objects.get(pk=switchid) except Switch.DoesNotExist: - messages.error(request, _("Nonexistent switch")) + messages.error(request, _("Nonexistent switch.")) return redirect(reverse('topologie:index')) first_port = getattr(switch.ports.order_by('port').first(), 'port', 1) @@ -742,7 +742,7 @@ def new_room(request): messages.success(request, _("The room was created.")) return redirect(reverse('topologie:index-room')) return form( - {'topoform': room, 'action_name': _("Add")}, + {'topoform': room, 'action_name': _("Create")}, 'topologie/topo.html', request ) @@ -794,10 +794,10 @@ def new_model_switch(request): model_switch = EditModelSwitchForm(request.POST or None) if model_switch.is_valid(): model_switch.save() - messages.success(request, _("The swich model was created.")) + messages.success(request, _("The switch model was created.")) return redirect(reverse('topologie:index-model-switch')) return form( - {'topoform': model_switch, 'action_name': _("Add")}, + {'topoform': model_switch, 'action_name': _("Create")}, 'topologie/topo.html', request ) @@ -856,7 +856,7 @@ def new_switch_bay(request): messages.success(request, _("The switch bay was created.")) return redirect(reverse('topologie:index-physical-grouping')) return form( - {'topoform': switch_bay, 'action_name': _("Add")}, + {'topoform': switch_bay, 'action_name': _("Create")}, 'topologie/topo.html', request ) @@ -911,7 +911,7 @@ def new_building(request): messages.success(request, _("The building was created.")) return redirect(reverse('topologie:index-physical-grouping')) return form( - {'topoform': building, 'action_name': _("Add")}, + {'topoform': building, 'action_name': _("Create")}, 'topologie/topo.html', request ) @@ -966,7 +966,7 @@ def new_constructor_switch(request): messages.success(request, _("The switch constructor was created.")) return redirect(reverse('topologie:index-model-switch')) return form( - {'topoform': constructor_switch, 'action_name': _("Add")}, + {'topoform': constructor_switch, 'action_name': _("Create")}, 'topologie/topo.html', request ) @@ -1078,7 +1078,7 @@ def add_module(request): messages.success(request, _("The module was created.")) return redirect(reverse('topologie:index-module')) return form( - {'topoform': module, 'action_name': _("Create a module")}, + {'topoform': module, 'action_name': _("Create")}, 'topologie/topo.html', request ) @@ -1129,10 +1129,10 @@ def add_module_on(request): module_switch = EditSwitchModuleForm(request.POST or None) if module_switch.is_valid(): module_switch.save() - messages.success(request, _("The module added to that switch")) + messages.success(request, _("The module was added.")) return redirect(reverse('topologie:index-module')) return form( - {'topoform': module_switch, 'action_name': _("Create")}, + {'topoform': module_switch, 'action_name': _("Add")}, 'topologie/topo.html', request ) From 1c28c2d1bc3aaf5cb35370e487b4759ab0b6d780 Mon Sep 17 00:00:00 2001 From: Laouen Fernet Date: Wed, 9 Jan 2019 00:40:59 +0100 Subject: [PATCH 56/73] add translations for users/ --- users/forms.py | 4 +- users/locale/fr/LC_MESSAGES/django.po | 771 +++++++++--------- users/migrations/0080_auto_20190108_1726.py | 20 + users/models.py | 22 +- users/templates/users/aff_bans.html | 12 +- users/templates/users/aff_clubs.html | 12 +- users/templates/users/aff_emailaddress.html | 4 +- users/templates/users/aff_listright.html | 14 +- users/templates/users/aff_schools.html | 6 +- users/templates/users/aff_users.html | 14 +- users/templates/users/aff_whitelists.html | 12 +- users/templates/users/delete.html | 4 +- users/templates/users/index.html | 4 +- users/templates/users/index_ban.html | 4 +- users/templates/users/index_clubs.html | 4 +- users/templates/users/index_emailaddress.html | 4 +- users/templates/users/index_listright.html | 4 +- users/templates/users/index_rights.html | 4 +- users/templates/users/index_schools.html | 6 +- users/templates/users/index_serviceusers.html | 4 +- users/templates/users/index_shell.html | 4 +- users/templates/users/index_whitelist.html | 4 +- users/templates/users/mass_archive.html | 4 +- users/templates/users/plugin_out.html | 2 +- users/templates/users/profil.html | 27 +- users/templates/users/sidebar.html | 24 +- users/templates/users/user.html | 2 +- users/templates/users/user_autocapture.html | 14 +- users/views.py | 2 +- 29 files changed, 507 insertions(+), 505 deletions(-) create mode 100644 users/migrations/0080_auto_20190108_1726.py diff --git a/users/forms.py b/users/forms.py index d4110dcd..6fcfea81 100644 --- a/users/forms.py +++ b/users/forms.py @@ -381,7 +381,7 @@ class AdherentCreationForm(AdherentForm): + "using the forgotten password button on the "\ + "login page or contacting support.") former_user_check = forms.BooleanField(required=True, help_text=former_user_check_info) - former_user_check.label = _("I certifie that I have not had an account before") + former_user_check.label = _("I certify that I have not had an account before") # Checkbox for GTU gtu_check = forms.BooleanField(required=True) @@ -439,7 +439,7 @@ class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): self.fields['surname'].label = _("Name") self.fields['school'].label = _("School") self.fields['comment'].label = _("Comment") - self.fields['email'].label = _("Email Address") + self.fields['email'].label = _("Email address") if 'room' in self.fields: self.fields['room'].label = _("Room") self.fields['room'].empty_label = _("No room") diff --git a/users/locale/fr/LC_MESSAGES/django.po b/users/locale/fr/LC_MESSAGES/django.po index 7db3099a..965a1a8a 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: 2018-10-03 02:50+0200\n" +"POT-Creation-Date: 2019-01-09 00:27+0100\n" "PO-Revision-Date: 2018-06-27 23:35+0200\n" "Last-Translator: Laouen Fernet \n" "Language-Team: \n" @@ -35,116 +35,117 @@ msgstr "" msgid "You don't have the right to view this application." msgstr "Vous n'avez pas le droit de voir cette application." -#: forms.py:75 +#: forms.py:76 msgid "Current password" msgstr "Mot de passe actuel" -#: forms.py:80 forms.py:492 +#: forms.py:81 forms.py:507 forms.py:534 msgid "New password" msgstr "Nouveau mot de passe" -#: forms.py:86 +#: forms.py:87 msgid "New password confirmation" msgstr "Confirmation du nouveau mot de passe" -#: forms.py:103 +#: forms.py:104 msgid "The new passwords don't match." msgstr "Les nouveaux mots de passe ne correspondent pas." -#: forms.py:112 +#: forms.py:113 msgid "The current password is incorrect." msgstr "Le mot de passe actuel est incorrect." -#: forms.py:130 forms.py:183 models.py:1580 +#: forms.py:132 forms.py:185 models.py:1597 msgid "Password" msgstr "Mot de passe" -#: forms.py:136 forms.py:189 +#: forms.py:138 forms.py:191 msgid "Password confirmation" msgstr "Confirmation du mot de passe" -#: forms.py:141 forms.py:232 +#: forms.py:143 forms.py:234 msgid "Is admin" msgstr "Est admin" -#: forms.py:151 +#: forms.py:153 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." -#: forms.py:164 forms.py:213 +#: forms.py:166 forms.py:215 msgid "The passwords don't match." msgstr "Les mots de passe ne correspondent pas." -#: forms.py:241 +#: forms.py:243 #, python-format msgid "User is admin: %s" msgstr "L'utilisateur est admin : %s" -#: forms.py:289 templates/users/aff_clubs.html:38 +#: forms.py:291 templates/users/aff_clubs.html:38 #: templates/users/aff_listright.html:63 templates/users/aff_listright.html:168 -#: templates/users/aff_users.html:39 templates/users/profil.html:169 -#: templates/users/profil.html:286 templates/users/profil.html:305 +#: templates/users/aff_users.html:39 templates/users/profil.html:177 +#: templates/users/profil.html:331 templates/users/profil.html:350 msgid "Username" msgstr "Pseudo" -#: forms.py:304 +#: forms.py:306 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." -#: forms.py:316 templates/users/profil.html:285 templates/users/profil.html:304 +#: forms.py:318 templates/users/profil.html:166 templates/users/profil.html:330 +#: templates/users/profil.html:349 msgid "First name" msgstr "Prénom" -#: forms.py:317 templates/users/aff_users.html:37 -#: templates/users/profil.html:165 templates/users/profil.html:284 -#: templates/users/profil.html:303 +#: forms.py:319 templates/users/aff_users.html:37 +#: templates/users/profil.html:172 templates/users/profil.html:329 +#: templates/users/profil.html:348 msgid "Surname" msgstr "Nom" -#: forms.py:318 models.py:1581 templates/users/aff_emailaddress.html:36 -#: templates/users/profil.html:171 +#: forms.py:320 forms.py:442 models.py:1598 +#: templates/users/aff_emailaddress.html:36 templates/users/profil.html:182 msgid "Email address" msgstr "Adresse mail" -#: forms.py:319 forms.py:430 forms.py:561 templates/users/aff_schools.html:37 -#: templates/users/profil.html:181 +#: forms.py:321 forms.py:440 forms.py:590 templates/users/aff_schools.html:37 +#: templates/users/profil.html:200 msgid "School" msgstr "Établissement" -#: forms.py:320 forms.py:431 models.py:1234 -#: templates/users/aff_serviceusers.html:34 templates/users/profil.html:183 +#: forms.py:322 forms.py:441 models.py:1251 +#: templates/users/aff_serviceusers.html:34 templates/users/profil.html:205 msgid "Comment" msgstr "Commentaire" -#: forms.py:322 forms.py:433 templates/users/aff_clubs.html:40 -#: templates/users/aff_users.html:41 templates/users/profil.html:175 +#: forms.py:324 forms.py:444 templates/users/aff_clubs.html:40 +#: templates/users/aff_users.html:41 templates/users/profil.html:187 msgid "Room" msgstr "Chambre" -#: forms.py:323 forms.py:434 +#: forms.py:325 forms.py:445 msgid "No room" msgstr "Pas de chambre" -#: forms.py:324 forms.py:435 +#: forms.py:326 forms.py:446 msgid "Select a school" msgstr "Sélectionnez un établissement" -#: forms.py:331 forms.py:701 -msgid "You can't use a {} address." -msgstr "Vous ne pouvez pas utiliser une adresse {}." - -#: forms.py:354 forms.py:456 -msgid "A valid telephone number is required." -msgstr "Un numéro de téléphone valide est requis." - -#: forms.py:359 +#: forms.py:342 msgid "Force the move?" msgstr "Forcer le déménagement ?" -#: forms.py:377 +#: forms.py:352 forms.py:730 +msgid "You can't use a {} address." +msgstr "Vous ne pouvez pas utiliser une adresse {}." + +#: forms.py:361 forms.py:470 +msgid "A valid telephone number is required." +msgstr "Un numéro de téléphone valide est requis." + +#: forms.py:379 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 " @@ -155,207 +156,218 @@ msgstr "" "passe oublié est à votre disposition. Si vous avez oublié votre login, " "contactez le support." -#: forms.py:382 -msgid "I certifie that I have not had an account before" +#: forms.py:384 +msgid "I certify that I have not had an account before" msgstr "Je certifie sur l'honneur ne pas déjà avoir de compte" -#: forms.py:387 -msgid "I commit to accept the" -msgstr "J'accepte les conditions générales" - -#: forms.py:387 -msgid "General Terms of Use" -msgstr "Conditions Générales d'Utilisation" - -#: forms.py:387 -msgid "." -msgstr "." - -#: forms.py:397 +#: forms.py:413 msgid "Leave empty if you don't have any GPG key." msgstr "Laissez vide si vous n'avez pas de clé GPG." -#: forms.py:399 +#: forms.py:415 msgid "Default shell" -msgstr "Interface système par défaut" +msgstr "Interface en ligne de commande par défaut" -#: forms.py:429 templates/users/aff_clubs.html:36 +#: forms.py:439 templates/users/aff_clubs.html:36 #: templates/users/aff_serviceusers.html:32 msgid "Name" msgstr "Nom" -#: forms.py:436 +#: forms.py:447 msgid "Use a mailing list" msgstr "Utiliser une liste de diffusion" -#: forms.py:549 templates/users/aff_listright.html:38 +#: forms.py:578 templates/users/aff_listright.html:38 msgid "Superuser" msgstr "Superutilisateur" -#: forms.py:573 +#: forms.py:602 msgid "Shell name" -msgstr "Nom de l'interface système" +msgstr "Nom de l'interface en ligne de commande" -#: forms.py:592 +#: forms.py:621 msgid "Name of the group of rights" msgstr "Nom du groupe de droits" -#: forms.py:603 +#: forms.py:632 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." -#: forms.py:611 +#: forms.py:640 msgid "Current groups of rights" msgstr "Groupes de droits actuels" -#: forms.py:628 +#: forms.py:657 msgid "Current schools" msgstr "Établissements actuels" -#: forms.py:646 forms.py:660 templates/users/aff_bans.html:41 +#: forms.py:675 forms.py:689 templates/users/aff_bans.html:41 #: templates/users/aff_whitelists.html:41 msgid "End date" msgstr "Date de fin" -#: forms.py:674 models.py:1778 +#: forms.py:703 models.py:1795 msgid "Local part of the email address" msgstr "Partie locale de l'adresse mail" -#: forms.py:675 +#: forms.py:704 msgid "Can't contain @" msgstr "Ne peut pas contenir @" -#: forms.py:690 +#: forms.py:719 msgid "Main email address" msgstr "Adresse mail principale" -#: forms.py:692 +#: forms.py:721 msgid "Redirect local emails" msgstr "Rediriger les mails locaux" -#: forms.py:694 +#: forms.py:723 msgid "Use local emails" msgstr "Utiliser les mails locaux" -#: forms.py:734 +#: forms.py:763 msgid "This room is my room" msgstr "Il s'agit bien de ma chambre" -#: forms.py:738 +#: forms.py:767 msgid "This new connected device is mine" msgstr "Ce nouvel appareil connecté m'appartient" -#: models.py:105 +#: models.py:106 #, python-format msgid "The username '%(label)s' contains forbidden characters." msgstr "Le pseudo '%(label)s' contient des caractères interdits." -#: models.py:147 +#: models.py:148 msgid "Users must have an username." msgstr "Les utilisateurs doivent avoir un pseudo." -#: models.py:150 +#: models.py:151 msgid "Username should only contain [a-z0-9-]." msgstr "Le pseudo devrait seulement contenir [a-z0-9-]" -#: models.py:201 models.py:1225 +#: models.py:192 templates/users/aff_clubs.html:55 +#: templates/users/aff_users.html:57 templates/users/profil.html:249 +msgid "Active" +msgstr "Actif" + +#: models.py:193 templates/users/aff_clubs.html:57 +#: templates/users/aff_users.html:59 templates/users/profil.html:251 +#: templates/users/profil.html:265 +msgid "Disabled" +msgstr "Désactivé" + +#: models.py:194 templates/users/profil.html:253 +msgid "Archived" +msgstr "Archivé" + +#: models.py:195 +msgid "Not yet active" +msgstr "Pas encore adhéré" + +#: models.py:202 models.py:1242 msgid "Must only contain letters, numerals or dashes." msgstr "Doit seulement contenir des lettres, chiffres ou tirets." -#: models.py:207 +#: models.py:208 msgid "External email address allowing us to contact you." msgstr "Adresse mail externe nous permettant de vous contacter." -#: models.py:211 +#: models.py:212 msgid "" "Enable redirection of the local email messages to the main email address." msgstr "" "Activer la redirection des mails locaux vers l'adresse mail principale." -#: models.py:216 +#: models.py:217 msgid "Enable the local email account." msgstr "Activer le compte mail local" -#: models.py:231 +#: models.py:232 msgid "Comment, school year" msgstr "Commentaire, promotion" -#: models.py:257 +#: models.py:258 msgid "Can change the password of a user" msgstr "Peut changer le mot de passe d'un utilisateur" -#: models.py:258 +#: models.py:259 msgid "Can edit the state of a user" msgstr "Peut changer l'état d'un utilisateur" -#: models.py:259 +#: models.py:260 msgid "Can force the move" msgstr "Peut forcer le déménagement" -#: models.py:260 +#: models.py:261 msgid "Can edit the shell of a user" -msgstr "Peut modifier l'interface système d'un utilisateur" +msgstr "Peut modifier l'interface en ligne de commande d'un utilisateur" -#: models.py:262 +#: models.py:263 msgid "Can edit the groups of rights of a user (critical permission)" msgstr "" "Peut modifier les groupes de droits d'un utilisateur (permission critique)" -#: models.py:265 +#: models.py:266 msgid "Can edit all users, including those with rights." msgstr "" "Peut modifier tous les utilisateurs, y compris ceux possédant des droits." -#: models.py:267 +#: models.py:268 msgid "Can view a user object" msgstr "Peut voir un objet utilisateur" -#: models.py:269 +#: models.py:270 msgid "user (member or club)" msgstr "utilisateur (adhérent ou club)" -#: models.py:270 +#: models.py:271 msgid "users (members or clubs)" msgstr "utilisateurs (adhérents ou clubs)" -#: models.py:288 models.py:312 +#: models.py:289 models.py:313 msgid "Unknown type." msgstr "Type inconnu." -#: models.py:308 templates/users/aff_listright.html:75 +#: models.py:309 templates/users/aff_listright.html:75 #: templates/users/aff_listright.html:180 msgid "Member" msgstr "Adhérent" -#: models.py:310 +#: models.py:311 msgid "Club" msgstr "Club" -#: models.py:534 +#: models.py:536 msgid "IPv4 assigning" msgstr "Attribution de l'IPv4" -#: models.py:543 +#: models.py:545 msgid "IPv4 unassigning" msgstr "Désattribution de l'IPv4" -#: models.py:693 +#: models.py:701 msgid "Maximum number of registered machines reached." msgstr "Nombre maximum de machines enregistrées atteint." -#: models.py:695 +#: models.py:703 msgid "Re2o doesn't know wich machine type to assign." msgstr "Re2o ne sait pas quel type de machine attribuer." -#: models.py:791 models.py:828 +#: models.py:726 templates/users/user_autocapture.html:64 +msgid "OK" +msgstr "OK" + +#: models.py:799 models.py:836 msgid "You don't have the right to edit this club." msgstr "Vous n'avez pas le droit de modifier ce club." -#: models.py:799 +#: models.py:807 msgid "User with critical rights, can't be edited." msgstr "Utilisateur avec des droits critiques, ne peut être modifié." -#: models.py:802 +#: models.py:810 msgid "" "Impossible to edit the organisation's user without the 'change_all_users' " "right." @@ -363,52 +375,60 @@ msgstr "" "Impossible de modifier l'utilisateur de l'association sans le droit " "'change_all_users'." -#: models.py:810 models.py:839 +#: models.py:818 models.py:847 msgid "You don't have the right to edit another user." msgstr "Vous n'avez pas le droit de modifier un autre utilisateur." -#: models.py:858 models.py:871 +#: models.py:865 +msgid "Permission required to change the room." +msgstr "Permission requise pour changer la chambre." + +#: models.py:879 msgid "Permission required to change the state." msgstr "Permission requise pour changer l'état." -#: models.py:883 +#: models.py:891 msgid "Permission required to change the shell." -msgstr "Permission requise pour changer l'interface système." +msgstr "Permission requise pour changer l'interface en ligne de commande." -#: models.py:897 models.py:910 +#: models.py:905 models.py:918 msgid "Local email accounts must be enabled." msgstr "Les comptes mail locaux doivent être activés." -#: models.py:923 +#: models.py:931 msgid "Permission required to force the move." msgstr "Permission requise pour forcer le déménagement." -#: models.py:936 +#: models.py:944 msgid "Permission required to edit the user's groups of rights." msgstr "" "Permission requise pour modifier les groupes de droits de l'utilisateur." -#: models.py:948 +#: models.py:956 msgid "'superuser' right required to edit the superuser flag." msgstr "Droit 'superuser' requis pour modifier le signalement superuser." -#: models.py:966 +#: models.py:974 msgid "You don't have the right to view this club." msgstr "Vous n'avez pas le droit de voir ce club." -#: models.py:972 +#: models.py:980 msgid "You don't have the right to view another user." msgstr "Vous n'avez pas le droit de voir un autre utilisateur." -#: models.py:985 models.py:1157 +#: models.py:993 models.py:1174 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." -#: models.py:998 +#: models.py:1006 msgid "You don't have the right to delete this user." msgstr "Vous n'avez pas le droit de supprimer cet utilisateur." -#: models.py:1023 +#: models.py:1027 +msgid "This username is already used." +msgstr "Ce pseudo est déjà utilisé." + +#: models.py:1029 msgid "" "There is neither a local email address nor an external email address for " "this user." @@ -416,7 +436,7 @@ msgstr "" "Il n'y a pas d'adresse mail locale ni d'adresse mail externe pour cet " "utilisateur." -#: models.py:1030 +#: models.py:1033 msgid "" "You can't redirect your local emails if no external email address has been " "set." @@ -424,178 +444,178 @@ msgstr "" "Vous ne pouvez pas rediriger vos mails locaux si aucune adresse mail externe " "n'a été définie." -#: models.py:1055 -msgid "A GPG fingerprint must contain 40 hexadecimal characters." -msgstr "Une empreinte GPG doit contenir 40 caractères hexadécimaux." - -#: models.py:1061 +#: models.py:1059 msgid "member" msgstr "adhérent" -#: models.py:1062 +#: models.py:1060 msgid "members" msgstr "adhérents" -#: models.py:1091 +#: models.py:1071 +msgid "A GPG fingerprint must contain 40 hexadecimal characters" +msgstr "Une empreinte GPG doit contenir 40 caractères hexadécimaux" + +#: models.py:1101 msgid "You don't have the right to create a user." msgstr "Vous n'avez pas le droit de créer un utilisateur." -#: models.py:1120 +#: models.py:1137 msgid "club" msgstr "club" -#: models.py:1121 +#: models.py:1138 msgid "clubs" msgstr "clubs" -#: models.py:1139 +#: models.py:1156 msgid "You don't have the right to create a club." msgstr "Vous n'avez pas le droit de créer un club." -#: models.py:1244 +#: models.py:1261 msgid "Can view a service user object" msgstr "Peut voir un objet utilisateur service" -#: models.py:1246 +#: models.py:1263 msgid "service user" msgstr "utilisateur service" -#: models.py:1247 +#: models.py:1264 msgid "service users" msgstr "utilisateurs service" -#: models.py:1251 +#: models.py:1268 #, python-brace-format msgid "Service user <{name}>" msgstr "Utilisateur service <{name}>" -#: models.py:1313 +#: models.py:1330 msgid "Can view a school object" msgstr "Peut voir un objet établissement" -#: models.py:1315 +#: models.py:1332 msgid "school" msgstr "établissement" -#: models.py:1316 +#: models.py:1333 msgid "schools" msgstr "établissements" -#: models.py:1334 +#: models.py:1351 msgid "UNIX groups can only contain lower case letters." msgstr "Les groupes UNIX peuvent seulement contenir des lettres minuscules." -#: models.py:1340 +#: models.py:1357 msgid "Description" msgstr "Description" -#: models.py:1347 +#: models.py:1364 msgid "Can view a group of rights object" msgstr "Peut voir un objet groupe de droits" -#: models.py:1349 +#: models.py:1366 msgid "group of rights" msgstr "groupe de droits" -#: models.py:1350 +#: models.py:1367 msgid "groups of rights" msgstr "groupes de droits" -#: models.py:1397 +#: models.py:1414 msgid "Can view a shell object" -msgstr "Peut voir un objet interface système" +msgstr "Peut voir un objet interface en ligne de commande" -#: models.py:1399 +#: models.py:1416 msgid "shell" -msgstr "interface système" +msgstr "interface en ligne de commande" -#: models.py:1400 +#: models.py:1417 msgid "shells" -msgstr "interfaces système" +msgstr "interfaces en ligne de commande" -#: models.py:1419 +#: models.py:1436 msgid "HARD (no access)" msgstr "HARD (pas d'accès)" -#: models.py:1420 +#: models.py:1437 msgid "SOFT (local access only)" msgstr "SOFT (accès local uniquement)" -#: models.py:1421 +#: models.py:1438 msgid "RESTRICTED (speed limitation)" msgstr "RESTRICTED (limitation de vitesse)" -#: models.py:1432 +#: models.py:1449 msgid "Can view a ban object" msgstr "Peut voir un objet bannissement" -#: models.py:1434 +#: models.py:1451 msgid "ban" msgstr "bannissement" -#: models.py:1435 +#: models.py:1452 msgid "bans" msgstr "bannissements" -#: models.py:1469 +#: models.py:1486 msgid "You don't have the right to view bans other than yours." msgstr "" "Vous n'avez pas le droit de voir des bannissements autres que les vôtres." -#: models.py:1517 +#: models.py:1534 msgid "Can view a whitelist object" msgstr "Peut voir un objet accès gracieux" -#: models.py:1519 +#: models.py:1536 msgid "whitelist (free of charge access)" msgstr "Accès gracieux" -#: models.py:1520 +#: models.py:1537 msgid "whitelists (free of charge access)" msgstr "Accès gracieux" -#: models.py:1536 +#: models.py:1553 msgid "You don't have the right to view whitelists other than yours." msgstr "" "Vous n'avez pas le droit de voir des accès gracieux autres que les vôtres." -#: models.py:1773 +#: models.py:1790 msgid "User of the local email account" msgstr "Utilisateur du compte mail local" -#: models.py:1783 +#: models.py:1800 msgid "Can view a local email account object" msgstr "Peut voir un objet compte mail local" -#: models.py:1785 +#: models.py:1802 msgid "local email account" msgstr "compte mail local" -#: models.py:1786 +#: models.py:1803 msgid "local email accounts" msgstr "comptes mail locaux" -#: models.py:1810 models.py:1833 models.py:1855 models.py:1877 +#: models.py:1827 models.py:1850 models.py:1872 models.py:1894 msgid "The local email accounts are not enabled." msgstr "Les comptes mail locaux ne sont pas activés." -#: models.py:1812 +#: models.py:1829 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." -#: models.py:1815 +#: models.py:1832 msgid "You reached the limit of {} local email accounts." msgstr "Vous avez atteint la limite de {} comptes mail locaux." -#: models.py:1836 models.py:1880 +#: models.py:1853 models.py:1897 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." -#: models.py:1850 +#: models.py:1867 msgid "" "You can't delete a local email account whose local part is the same as the " "username." @@ -603,13 +623,13 @@ msgstr "" "Vous ne pouvez pas supprimer un compte mail local dont la partie locale est " "la même que le pseudo." -#: models.py:1858 +#: models.py:1875 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." -#: models.py:1872 +#: models.py:1889 msgid "" "You can't edit a local email account whose local part is the same as the " "username." @@ -617,9 +637,9 @@ msgstr "" "Vous ne pouvez pas modifier un compte mail local dont la partie locale est " "la même que le pseudo." -#: models.py:1886 -msgid "The local part must not contain @." -msgstr "La partie locale ne doit pas contenir @." +#: models.py:1903 +msgid "The local part must not contain @ or +." +msgstr "La partie locale ne doit pas contenir @ ou +." #: templates/users/aff_bans.html:36 templates/users/aff_whitelists.html:36 msgid "User" @@ -638,43 +658,38 @@ msgid "End of subscription on" msgstr "Fin de cotisation le" #: templates/users/aff_clubs.html:43 templates/users/aff_users.html:44 -#: templates/users/profil.html:225 +#: templates/users/profil.html:260 msgid "Internet access" msgstr "Accès Internet" #: templates/users/aff_clubs.html:44 templates/users/aff_users.html:45 -#: templates/users/profil.html:32 +#: templates/users/profil.html:31 msgid "Profile" msgstr "Profil" #: templates/users/aff_clubs.html:53 templates/users/aff_users.html:54 -#: templates/users/profil.html:197 +#: templates/users/profil.html:224 msgid "Not a member" msgstr "Non adhérent" -#: templates/users/aff_clubs.html:55 templates/users/aff_users.html:57 -#: templates/users/profil.html:214 -msgid "Active" -msgstr "Actif" - -#: templates/users/aff_clubs.html:57 templates/users/aff_users.html:59 -#: templates/users/profil.html:216 templates/users/profil.html:229 -msgid "Disabled" -msgstr "Désactivé" - #: templates/users/aff_listright.html:40 msgid "Django's specific pre-defined right that supersed any other rights." msgstr "" "Droit prédéfini spécifique à Django qui outrepasse tous les autres droits." #: templates/users/aff_listright.html:44 -msgid "Total: All permissions" -msgstr "Total: Toutes les permissions" +msgid "Total: all permissions" +msgstr "Total: toutes les permissions" -#: templates/users/aff_listright.html:56 +#: templates/users/aff_listright.html:49 templates/users/aff_listright.html:56 msgid "Users in Superuser" msgstr "Utilisateurs dans Superuser" +#: templates/users/aff_listright.html:53 templates/users/aff_listright.html:154 +#: widgets.py:35 +msgid "Close" +msgstr "Fermer" + #: templates/users/aff_listright.html:64 templates/users/aff_listright.html:169 msgid "Membership" msgstr "Adhésion" @@ -693,7 +708,7 @@ msgstr "Dernière action" #: templates/users/aff_listright.html:77 templates/users/aff_listright.html:182 msgid "No membership records" -msgstr "Aucune adhésion" +msgstr "Aucune adhésion enregistrée" #: templates/users/aff_listright.html:80 templates/users/aff_listright.html:185 #, python-format @@ -716,6 +731,19 @@ msgid_plural "Total: %(perm_count)s permissions" msgstr[0] "Total: %(perm_count)s permission" msgstr[1] "Total: %(perm_count)s permissions" +#: templates/users/aff_listright.html:150 templates/users/index.html:29 +#: templates/users/index.html:32 templates/users/index_ban.html:29 +#: templates/users/index_clubs.html:29 +#: templates/users/index_emailaddress.html:29 +#: templates/users/index_listright.html:30 templates/users/index_rights.html:29 +#: templates/users/index_schools.html:30 +#: templates/users/index_serviceusers.html:30 +#: templates/users/index_shell.html:30 templates/users/index_whitelist.html:29 +#: templates/users/plugin_out.html:31 templates/users/sidebar.html:52 +#: templates/users/user.html:30 templates/users/user_autocapture.html:30 +msgid "Users" +msgstr "Utilisateurs" + #: templates/users/aff_listright.html:158 #, python-format msgid "Users in %(right_name)s" @@ -725,17 +753,17 @@ msgstr "Utilisateurs dans %(right_name)s" msgid "Role" msgstr "Rôle" -#: templates/users/aff_shell.html:32 templates/users/profil.html:255 +#: templates/users/aff_shell.html:32 templates/users/profil.html:301 msgid "Shell" -msgstr "Interface système" +msgstr "Interface en ligne de commande" -#: templates/users/aff_users.html:35 templates/users/profil.html:162 +#: templates/users/aff_users.html:35 msgid "Firt name" msgstr "Prénom" #: templates/users/delete.html:29 -msgid "Deletion of objects" -msgstr "Suppression d'objets" +msgid "Deletion of users" +msgstr "Suppression d'utilisateurs" #: templates/users/delete.html:35 #, python-format @@ -750,19 +778,7 @@ msgstr "" msgid "Confirm" msgstr "Confirmer" -#: templates/users/index.html:29 templates/users/index.html:32 -#: templates/users/index_ban.html:29 templates/users/index_clubs.html:29 -#: templates/users/index_emailaddress.html:29 -#: templates/users/index_listright.html:30 templates/users/index_rights.html:29 -#: templates/users/index_schools.html:30 -#: templates/users/index_serviceusers.html:30 -#: templates/users/index_shell.html:30 templates/users/index_whitelist.html:29 -#: templates/users/plugin_out.html:31 templates/users/sidebar.html:52 -#: templates/users/user.html:30 templates/users/user_autocapture.html:30 -msgid "Users" -msgstr "Utilisateurs" - -#: templates/users/index_ban.html:32 templates/users/profil.html:380 +#: templates/users/index_ban.html:32 templates/users/profil.html:427 #: templates/users/sidebar.html:58 msgid "Bans" msgstr "Bannissements" @@ -796,8 +812,8 @@ msgid "List of schools" msgstr "Liste des établissements" #: templates/users/index_schools.html:34 -msgid "List of schools for created users." -msgstr "Liste des établissement pour les utilisateurs créés." +msgid "List of schools for created users" +msgstr "Liste des établissements pour les utilisateurs créés" #: templates/users/index_schools.html:36 msgid " Add a school" @@ -827,13 +843,13 @@ msgstr " Ajouter un utilisateur" #: templates/users/index_shell.html:33 msgid "List of shells" -msgstr "Liste des interaces système" +msgstr "Liste des interfaces en ligne de commande" #: templates/users/index_shell.html:35 msgid " Add a shell" -msgstr " Ajouter une interface système" +msgstr " Ajouter une interface en ligne de commande" -#: templates/users/index_whitelist.html:32 templates/users/profil.html:405 +#: templates/users/index_whitelist.html:32 templates/users/profil.html:452 #: templates/users/sidebar.html:64 msgid "Whitelists" msgstr "Accès gracieux" @@ -850,7 +866,7 @@ msgstr "Rechercher" #, python-format msgid "The following users will be archived (%(to_archive_list|length)s):" msgstr "" -"Les utilisateus suivants vont être archivés (%(to_archive_list|length)s :" +"Les utilisateus suivants vont être archivés (%(to_archive_list|length)s) :" #: templates/users/plugin_out.html:35 msgid "" @@ -861,44 +877,44 @@ msgstr "" "débrancher et rebrancher votre câble Ethernet pour bénéficier d'une " "connexion filaire." -#: templates/users/profil.html:37 +#: templates/users/profil.html:36 #, python-format msgid "Welcome %(name)s %(surname)s" msgstr "Bienvenue %(name)s %(surname)s" -#: templates/users/profil.html:39 +#: templates/users/profil.html:38 #, python-format msgid "Profile of %(name)s %(surname)s" msgstr "Profil de %(name)s %(surname)s" -#: templates/users/profil.html:47 +#: templates/users/profil.html:46 msgid "Your account has been banned" msgstr "Votre compte a été banni" -#: templates/users/profil.html:49 +#: templates/users/profil.html:48 #, python-format -msgid "End of the ban: %(end_ban)s" -msgstr "Fin du bannissement : %(end_ban)s" +msgid "End of the ban: %(end_ban_date)s" +msgstr "Fin du bannissement : %(end_ban_date)s" -#: templates/users/profil.html:54 +#: templates/users/profil.html:53 msgid "No connection" msgstr "Pas de connexion" -#: templates/users/profil.html:58 +#: templates/users/profil.html:57 msgid "Pay for a connection" msgstr "Payer une connexion" -#: templates/users/profil.html:61 +#: templates/users/profil.html:60 msgid "Ask for someone with the appropriate rights to pay for a connection." msgstr "" "Demandez à quelqu'un ayant les droits appropriés de payer une connexion." -#: templates/users/profil.html:67 +#: templates/users/profil.html:66 #, python-format -msgid "Connection (until %(end_connection)s )" -msgstr "Connexion (jusqu'au %(end_connection)s)" +msgid "Connection (until %(end_connection_date)s )" +msgstr "Connexion (jusqu'au %(end_connection_date)s)" -#: templates/users/profil.html:71 +#: templates/users/profil.html:70 msgid "Extend the connection period" msgstr "Étendre la durée de connexion" @@ -906,190 +922,184 @@ msgstr "Étendre la durée de connexion" msgid "Refill the balance" msgstr "Recharger le solde" -#: templates/users/profil.html:96 +#: templates/users/profil.html:97 msgid " Machines" msgstr " Machines" -#: templates/users/profil.html:100 templates/users/profil.html:109 +#: templates/users/profil.html:101 templates/users/profil.html:113 msgid " Add a machine" msgstr " Ajouter une machine" -#: templates/users/profil.html:106 templates/users/profil.html:340 +#: templates/users/profil.html:109 templates/users/profil.html:386 msgid "No machine" msgstr "Pas de machine" -#: templates/users/profil.html:122 +#: templates/users/profil.html:127 msgid " Detailed information" msgstr " Informations détaillées" -#: templates/users/profil.html:129 +#: templates/users/profil.html:134 msgid "Edit" msgstr "Modifier" -#: templates/users/profil.html:133 views.py:284 views.py:1081 +#: templates/users/profil.html:138 views.py:286 views.py:1084 msgid "Change the password" msgstr "Changer le mot de passe" -#: templates/users/profil.html:138 +#: templates/users/profil.html:143 msgid "Change the state" msgstr "Changer l'état" -#: templates/users/profil.html:144 views.py:262 +#: templates/users/profil.html:149 views.py:264 msgid "Edit the groups" msgstr "Modifier les groupes" -#: templates/users/profil.html:155 +#: templates/users/profil.html:159 msgid "Mailing" msgstr "Envoi de mails" -#: templates/users/profil.html:159 +#: templates/users/profil.html:163 msgid "Mailing disabled" msgstr "Envoi de mails désactivé" -#: templates/users/profil.html:177 +#: templates/users/profil.html:195 msgid "Telephone number" msgstr "Numéro de téléphone" -#: templates/users/profil.html:187 +#: templates/users/profil.html:210 msgid "Registration date" msgstr "Date d'inscription" -#: templates/users/profil.html:189 +#: templates/users/profil.html:215 msgid "Last login" msgstr "Dernière connexion" -#: templates/users/profil.html:193 +#: templates/users/profil.html:220 msgid "End of membership" msgstr "Fin d'adhésion" -#: templates/users/profil.html:199 +#: templates/users/profil.html:229 msgid "Whitelist" msgstr "Accès gracieux" -#: templates/users/profil.html:203 templates/users/profil.html:235 +#: templates/users/profil.html:233 templates/users/profil.html:274 msgid "None" msgstr "Aucun" -#: templates/users/profil.html:206 +#: templates/users/profil.html:238 msgid "Ban" msgstr "Bannissement" -#: templates/users/profil.html:210 +#: templates/users/profil.html:242 msgid "Not banned" msgstr "Non banni" -#: templates/users/profil.html:212 +#: templates/users/profil.html:247 msgid "State" msgstr "État" -#: templates/users/profil.html:218 -msgid "Archived" -msgstr "Archivé" +#: templates/users/profil.html:255 +msgid "Not yet member" +msgstr "Pas encore adhérent" -#: templates/users/profil.html:220 -#, fuzzy -#| msgid "Not a member" -msgid "Not yet Member" -msgstr "Non adhérent" - -#: templates/users/profil.html:227 +#: templates/users/profil.html:263 #, python-format msgid "Active (until %(end_access)s)" msgstr "Actif (jusqu'au %(end_access)s)" -#: templates/users/profil.html:231 templates/users/sidebar.html:82 +#: templates/users/profil.html:270 templates/users/sidebar.html:82 msgid "Groups of rights" msgstr "Groupes de droits" -#: templates/users/profil.html:239 +#: templates/users/profil.html:279 msgid "Balance" msgstr "Solde" -#: templates/users/profil.html:244 +#: templates/users/profil.html:286 msgid "Refill" msgstr "Recharger" -#: templates/users/profil.html:249 +#: templates/users/profil.html:294 msgid "GPG fingerprint" msgstr "Empreinte GPG" -#: templates/users/profil.html:268 +#: templates/users/profil.html:313 msgid " Manage the club" msgstr " Gérer le club" -#: templates/users/profil.html:275 +#: templates/users/profil.html:320 msgid "Manage the admins and members" msgstr "Gérer les admins et les membres" -#: templates/users/profil.html:279 +#: templates/users/profil.html:324 msgid "Club admins" msgstr "Admins du clubs" -#: templates/users/profil.html:298 +#: templates/users/profil.html:343 msgid "Members" msgstr "Adhérents" -#: templates/users/profil.html:325 +#: templates/users/profil.html:371 msgid "Machines" msgstr "Machines" -#: templates/users/profil.html:333 +#: templates/users/profil.html:379 msgid "Add a machine" msgstr "Ajouter une machine" -#: templates/users/profil.html:349 +#: templates/users/profil.html:396 msgid "Subscriptions" msgstr "Cotisations" -#: templates/users/profil.html:357 -msgid "Add as subscription" +#: templates/users/profil.html:404 +msgid "Add a subscription" msgstr "Ajouter une cotisation" -#: templates/users/profil.html:362 +#: templates/users/profil.html:409 msgid "Edit the balance" msgstr "Modifier le solde" -#: templates/users/profil.html:371 +#: templates/users/profil.html:418 msgid "No invoice" msgstr "Pas de facture" -#: templates/users/profil.html:388 views.py:386 +#: templates/users/profil.html:435 views.py:388 msgid "Add a ban" msgstr "Ajouter un bannissement" -#: templates/users/profil.html:396 +#: templates/users/profil.html:443 msgid "No ban" msgstr "Pas de bannissement" -#: templates/users/profil.html:413 +#: templates/users/profil.html:460 msgid "Grant a whitelist" msgstr "Donner un accès gracieux" -#: templates/users/profil.html:421 +#: templates/users/profil.html:468 msgid "No whitelist" msgstr "Pas d'accès gracieux" -#: templates/users/profil.html:429 +#: templates/users/profil.html:476 msgid " Email settings" msgstr " Paramètres mail" -#: templates/users/profil.html:436 +#: templates/users/profil.html:483 msgid " Edit email settings" msgstr " Modifier les paramètres mail" -#: templates/users/profil.html:445 templates/users/profil.html:471 +#: templates/users/profil.html:492 templates/users/profil.html:518 msgid "Contact email address" msgstr "Adresse mail de contact" -#: templates/users/profil.html:449 +#: templates/users/profil.html:496 msgid "Enable the local email account" msgstr "Activer le compte mail local" -#: templates/users/profil.html:451 +#: templates/users/profil.html:498 msgid "Enable the local email redirection" msgstr "Activer la redirection mail locale" -#: templates/users/profil.html:455 +#: templates/users/profil.html:502 msgid "" "The contact email address is the email address where we send emails to " "contact you. If you would like to use your external email address for that, " @@ -1101,7 +1111,7 @@ msgstr "" "cela, vous pouvez soit désactiver votre adresse mail locale soit activer la " "redirection des mails locaux." -#: templates/users/profil.html:460 +#: templates/users/profil.html:507 msgid " Add an email address" msgstr " Ajouter une adresse mail" @@ -1110,10 +1120,8 @@ msgid "Create a club or organisation" msgstr "Créer un club ou une association" #: templates/users/sidebar.html:39 -#, fuzzy -#| msgid "Create a club" msgid "Create a user" -msgstr "Créer un club" +msgstr "Créer un utilisateur" #: templates/users/sidebar.html:46 msgid "Clubs and organisations" @@ -1125,7 +1133,7 @@ msgstr "Établissements" #: templates/users/sidebar.html:76 msgid "Shells" -msgstr "Interfaces système" +msgstr "Interfaces en ligne de commande" #: templates/users/sidebar.html:88 msgid "Service users" @@ -1144,298 +1152,298 @@ msgid "Device and room register form" msgstr "Enregistrement de votre chambre et machine fixe" #: templates/users/user_autocapture.html:44 -msgid "Connected from :" -msgstr "Connecté depuis" +msgid "Connected from:" +msgstr "Connecté depuis :" #: templates/users/user_autocapture.html:46 -#, fuzzy -msgid "Room " -msgstr "Chambre" +#, python-format +msgid "Room %(room)s" +msgstr "Chambre %(room)s" #: templates/users/user_autocapture.html:47 -msgid "Port " -msgstr "Port " +#, python-format +msgid "Port %(port)s" +msgstr "Port %(port)s" #: templates/users/user_autocapture.html:54 -msgid "Connected with device :" -msgstr "Connecté avec l'appareil suivant :" +msgid "Connected with device:" +msgstr "Connecté avec l'appareil :" #: templates/users/user_autocapture.html:56 -#, fuzzy -#| msgid "Email address" -msgid "Mac address " -msgstr "Adresse mail" +#, python-format +msgid "MAC address %(mac)s" +msgstr "Adresse MAC %(mac)s" -#: views.py:124 +#: views.py:126 #, 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é." -#: views.py:136 +#: views.py:138 msgid "Commit" msgstr "Valider" -#: views.py:153 +#: views.py:155 #, 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é." -#: views.py:160 +#: views.py:162 msgid "Create a club" msgstr "Créer un club" -#: views.py:178 +#: views.py:180 msgid "The club was edited." msgstr "Le club a été modifié." -#: views.py:187 +#: views.py:189 msgid "Edit the admins and members" msgstr "Modifier les admins et les membres" -#: views.py:215 +#: views.py:217 msgid "The user was edited." msgstr "L'utilisateur a été modifié." -#: views.py:221 +#: views.py:223 msgid "Edit the user" msgstr "Modifier l'utilisateur" -#: views.py:235 +#: views.py:237 msgid "The state was edited." msgstr "L'état a été modifié." -#: views.py:241 +#: views.py:243 msgid "Edit the state" msgstr "Modifier l'état" -#: views.py:256 +#: views.py:258 msgid "The groups were edited." msgstr "Les groupes ont été modifiés." -#: views.py:278 views.py:1078 +#: views.py:280 views.py:1081 msgid "The password was changed." msgstr "Le mot de passe a été changé." -#: views.py:296 +#: views.py:298 #, python-format msgid "%s was removed from the group." msgstr "%s a été retiré du groupe." -#: views.py:306 +#: views.py:308 #, python-format msgid "%s is no longer superuser." msgstr "%s n'est plus superutilisateur." -#: views.py:319 +#: views.py:321 msgid "The service user was created." msgstr "L'utilisateur service a été créé." -#: views.py:323 +#: views.py:325 msgid "Create a service user" msgstr "Créer un utilisateur service" -#: views.py:340 +#: views.py:342 msgid "The service user was edited." msgstr "L'utilisateur service a été modifié." -#: views.py:343 +#: views.py:345 msgid "Edit a service user" msgstr "Modifier un utilisateur service" -#: views.py:355 +#: views.py:357 msgid "The service user was deleted." msgstr "L'utilisateur service a été supprimé." -#: views.py:375 +#: views.py:377 msgid "The ban was added." msgstr "Le bannissement a été ajouté." -#: views.py:383 +#: views.py:385 msgid "Warning: this user already has an active ban." msgstr "Attention : cet utilisateur a déjà un bannissement actif." -#: views.py:402 +#: views.py:404 msgid "The ban was edited." msgstr "Le bannissement a été modifié." -#: views.py:405 +#: views.py:407 msgid "Edit a ban" msgstr "Modifier un bannissement" -#: views.py:417 +#: views.py:419 msgid "The ban was deleted." msgstr "Le bannissement a été supprimé." -#: views.py:444 +#: views.py:446 msgid "The whitelist was added." msgstr "L'accès gracieux a été ajouté." -#: views.py:452 +#: views.py:454 msgid "Warning: this user already has an active whitelist." msgstr "Attention : cet utilisateur a déjà un accès gracieux actif." -#: views.py:455 +#: views.py:457 msgid "Add a whitelist" msgstr "Ajouter un accès gracieux" -#: views.py:475 +#: views.py:477 msgid "The whitelist was edited." msgstr "L'accès gracieux a été ajouté." -#: views.py:478 +#: views.py:480 msgid "Edit a whitelist" msgstr "Modifier un accès gracieux" -#: views.py:490 +#: views.py:492 msgid "The whitelist was deleted." msgstr "L'accès gracieux a été supprimé." -#: views.py:514 +#: views.py:516 msgid "The local email account was created." msgstr "Le compte mail local a été créé." -#: views.py:522 +#: views.py:524 msgid "Add a local email account" msgstr "Ajouter un compte mail local" -#: views.py:539 +#: views.py:541 msgid "The local email account was edited." msgstr "Le compte mail local a été modifié." -#: views.py:547 +#: views.py:549 msgid "Edit a local email account" msgstr "Modifier un compte mail local" -#: views.py:559 +#: views.py:561 msgid "The local email account was deleted." msgstr "Le compte mail local a été supprimé." -#: views.py:583 +#: views.py:585 msgid "The email settings were edited." msgstr "Les paramètres mail ont été modifiés." -#: views.py:592 +#: views.py:594 msgid "Edit the email settings" msgstr "Modifier les paramètres mail" -#: views.py:606 +#: views.py:608 msgid "The school was added." msgstr "L'établissement a été ajouté." -#: views.py:609 +#: views.py:611 msgid "Add a school" msgstr "Ajouter un établissement" -#: views.py:624 +#: views.py:626 msgid "The school was edited." msgstr "L'établissement a été modifié." -#: views.py:627 +#: views.py:629 msgid "Edit a school" msgstr "Modifier un établissement" -#: views.py:646 +#: views.py:648 msgid "The school was deleted." msgstr "L'établissement a été supprimé." -#: views.py:650 +#: views.py:652 #, python-format msgid "" "The school %s is assigned to at least one user, impossible to delete it." msgstr "" -"L'établissement %s est affecté à au moins un utilisateur, impossible de le " +"L'établissement %s est assigné à au moins un utilisateur, impossible de le " "supprimer." -#: views.py:654 views.py:766 +#: views.py:656 views.py:768 msgid "Delete" msgstr "Supprimer" -#: views.py:667 +#: views.py:669 msgid "The shell was added." -msgstr "L'interface système a été ajoutée." +msgstr "L'interface en ligne de commande a été ajoutée." -#: views.py:670 +#: views.py:672 msgid "Add a shell" -msgstr "Ajouter une interface système" +msgstr "Ajouter une interface en ligne de commande" -#: views.py:684 +#: views.py:686 msgid "The shell was edited." -msgstr "L'interface système a été modifiée." +msgstr "L'interface en ligne de commande a été modifiée." -#: views.py:687 +#: views.py:689 msgid "Edit a shell" -msgstr "Modifier une interface système" +msgstr "Modifier une interface en ligne de commande" -#: views.py:699 +#: views.py:701 msgid "The shell was deleted." -msgstr "L'interface système a été supprimée." +msgstr "L'interface en ligne de commande a été supprimée." -#: views.py:716 +#: views.py:718 msgid "The group of rights was added." msgstr "Le groupe de droits a été ajouté." -#: views.py:719 +#: views.py:721 msgid "Add a group of rights" msgstr "Ajouter un groupe de droits" -#: views.py:737 +#: views.py:739 msgid "The group of rights was edited." msgstr "Le groupe de droits a été modifié." -#: views.py:740 +#: views.py:742 msgid "Edit a group of rights" msgstr "Modifier un groupe de droits" -#: views.py:757 +#: views.py:759 msgid "The group of rights was deleted." msgstr "Le groupe de droits a été supprimé." -#: views.py:762 +#: views.py:764 #, python-format msgid "" "The group of rights %s is assigned to at least one user, impossible to " "delete it." msgstr "" -"Le groupe de droits %s est affecté à au moins un utilisateur, impossible de " +"Le groupe de droits %s est assigné à au moins un utilisateur, impossible de " "le supprimer." -#: views.py:790 +#: views.py:792 msgid "Archiving" msgstr "Archivage" -#: views.py:791 +#: views.py:793 #, python-format msgid "%s users were archived." msgstr "%s utilisateurs ont été archivés." -#: views.py:1040 +#: views.py:1043 msgid "The user doesn't exist." msgstr "L'utilisateur n'existe pas." -#: views.py:1042 views.py:1050 +#: views.py:1045 views.py:1053 msgid "Reset" msgstr "Réinitialiser" -#: views.py:1047 +#: views.py:1050 msgid "An email to reset the password was sent." msgstr "Un mail pour réinitialiser le mot de passe a été envoyé." -#: views.py:1064 +#: views.py:1067 msgid "Error: please contact an admin." msgstr "Erreur : veuillez contacter un admin." -#: views.py:1076 +#: views.py:1079 msgid "Password reset" msgstr "Réinitialisation du mot de passe" -#: views.py:1093 -msgid "Incorrect URL, or already registered device" -msgstr "URL incorrect, ou appareil déjà enregistré" +#: views.py:1096 +msgid "Incorrect URL, or already registered device." +msgstr "URL incorrect, ou appareil déjà enregistré." -#: views.py:1101 +#: views.py:1104 msgid "" "Successful registration! Please disconnect and reconnect your Ethernet cable " "to get Internet access." @@ -1443,14 +1451,10 @@ msgstr "" "Enregistrement réussi ! Veuillez débrancher et rebrancher votre câble " "Ethernet pour avoir accès à Internet." -#: views.py:1145 views.py:1169 views.py:1184 +#: views.py:1148 views.py:1172 views.py:1187 msgid "The mailing list doesn't exist." msgstr "La liste de diffusion n'existe pas." -#: widgets.py:35 -msgid "Close" -msgstr "Fermer" - #: widgets.py:36 msgid "Today" msgstr "Aujourd'hui" @@ -1466,24 +1470,3 @@ msgstr "Précédent" #: widgets.py:46 msgid "Wk" msgstr "Wk" - -#~ msgid "" -#~ "New connection from room %s. Is it yours? If that is the case, type OK." -#~ msgstr "" -#~ "Nouvelle connexion depuis la chambre %s. Est-ce la vôtre ? Si c'est le " -#~ "cas, tapez OK." - -#~ msgid "" -#~ "New connection from new device. Register it? Say Yes to get Internet " -#~ "access from it (MAC Address : %s)." -#~ msgstr "" -#~ "Nouvelle connexion depuis un nouvel appareil. L'enregistrer ? Dites Oui " -#~ "pour avoir accès à Internet depuis cet appareil (adresse MAC : %s)." - -#~ msgid "Register device or room" -#~ msgstr "Enregistrer un appareil ou une chambre" - -#~ msgid "By clicking 'Create or edit', the user commits to respect the " -#~ msgstr "" -#~ "En cliquant sur 'Créer ou modifier', l 'utilisateur s'engage à respecter " -#~ "les" diff --git a/users/migrations/0080_auto_20190108_1726.py b/users/migrations/0080_auto_20190108_1726.py new file mode 100644 index 00000000..f3f872bc --- /dev/null +++ b/users/migrations/0080_auto_20190108_1726.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2019-01-08 23:26 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0079_auto_20181228_2039'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='state', + field=models.IntegerField(choices=[(0, 'Active'), (1, 'Disabled'), (2, 'Archived'), (3, 'Not yet active')], default=3), + ), + ] diff --git a/users/models.py b/users/models.py index a2798207..c1d0789a 100755 --- a/users/models.py +++ b/users/models.py @@ -189,10 +189,10 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, STATE_ARCHIVE = 2 STATE_NOT_YET_ACTIVE = 3 STATES = ( - (0, 'STATE_ACTIVE'), - (1, 'STATE_DISABLED'), - (2, 'STATE_ARCHIVE'), - (3, 'STATE_NOT_YET_ACTIVE'), + (0, _("Active")), + (1, _("Disabled")), + (2, _("Archived")), + (3, _("Not yet active")), ) surname = models.CharField(max_length=255) @@ -356,7 +356,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, """ Renvoie le nom complet de l'user formaté nom/prénom""" name = self.name if name: - return '%s %s' % (name, self.surname) + return "%s %s" % (name, self.surname) else: return self.surname @@ -510,7 +510,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, )['total'] or 0 somme_credit = Vente.objects.filter( facture__in=Facture.objects.filter(user=self, valid=True), - name="solde" + name='solde' ).aggregate( total=models.Sum( models.F('prix')*models.F('number'), @@ -681,7 +681,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, ), 'expire_in': str( GeneralOption.get_cached_value('req_expire_hrs') - ) + ' heures', + ) + ' hours', } send_mail( 'Changement de mot de passe du %(name)s / Password renewal for ' @@ -723,7 +723,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, self.notif_auto_newmachine(interface_cible) except Exception as error: return False, traceback.format_exc() - return interface_cible, "Ok" + return interface_cible, _("OK") def notif_auto_newmachine(self, interface): """Notification mail lorsque une machine est automatiquement @@ -1024,7 +1024,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, if (EMailAddress.objects .filter(local_part=self.pseudo.lower()).exclude(user_id=self.id) ): - raise ValidationError("This pseudo is already in use.") + raise ValidationError(_("This username is already used.")) if not self.local_email_enabled and not self.email and not (self.state == self.STATE_ARCHIVE): raise ValidationError(_("There is neither a local email address nor an external" " email address for this user.") @@ -1068,7 +1068,7 @@ class Adherent(User): if self.gpg_fingerprint: gpg_fingerprint = self.gpg_fingerprint.replace(' ', '').upper() if not re.match("^[0-9A-F]{40}$", gpg_fingerprint): - raise ValidationError(_("A gpg fingerprint must contain 40 hexadecimal carracters")) + raise ValidationError(_("A GPG fingerprint must contain 40 hexadecimal characters")) self.gpg_fingerprint = gpg_fingerprint @classmethod @@ -1461,7 +1461,7 @@ class Ban(RevMixin, AclMixin, models.Model): 'asso_name': AssoOption.get_cached_value('name'), }) send_mail( - 'Deconnexion disciplinaire', + 'Déconnexion disciplinaire / Disciplinary disconnection', template.render(context), GeneralOption.get_cached_value('email_from'), [self.user.email], diff --git a/users/templates/users/aff_bans.html b/users/templates/users/aff_bans.html index 1284bea8..30256747 100644 --- a/users/templates/users/aff_bans.html +++ b/users/templates/users/aff_bans.html @@ -27,19 +27,19 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load i18n %} {% if ban_list.paginator %} -{% include "pagination.html" with list=ban_list %} + {% include 'pagination.html' with list=ban_list %} {% endif %} {% trans "User" as tr_user %} - + {% trans "Start date" as tr_start %} - + {% trans "End date" as tr_end %} - + @@ -49,7 +49,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% else %} {% endif %} - + @@ -67,6 +67,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% include "buttons/sort.html" with prefix='ban' col="user" text=tr_user %}{% include 'buttons/sort.html' with prefix='ban' col="user" text=tr_user %} {% trans "Reason" %}{% include "buttons/sort.html" with prefix='ban' col="start" text=tr_start %}{% include 'buttons/sort.html' with prefix='ban' col="start" text=tr_start %}{% include "buttons/sort.html" with prefix='ban' col="end" text=tr_end %}{% include 'buttons/sort.html' with prefix='ban' col="end" text=tr_end %}
      {{ ban.user }} {{ ban.user }} {{ ban.raison }} {{ ban.date_start }} {{ ban.date_end }}
      {% if ban_list.paginator %} -{% include "pagination.html" with list=ban_list %} + {% include 'pagination.html' with list=ban_list %} {% endif %} diff --git a/users/templates/users/aff_clubs.html b/users/templates/users/aff_clubs.html index 1903a445..080dc031 100644 --- a/users/templates/users/aff_clubs.html +++ b/users/templates/users/aff_clubs.html @@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load i18n %} {% if clubs_list.paginator %} -{% include "pagination.html" with list=clubs_list %} + {% include 'pagination.html' with list=clubs_list %} {% endif %} {% load acl %} @@ -34,11 +34,11 @@ with this program; if not, write to the Free Software Foundation, Inc., {% trans "Name" as tr_name %} - {% include "buttons/sort.html" with prefix='club' col="surname" text=tr_name %} + {% include 'buttons/sort.html' with prefix='club' col="surname" text=tr_name %} {% trans "Username" as tr_username %} - {% include "buttons/sort.html" with prefix='club' col="pseudo" text=tr_username %} + {% include 'buttons/sort.html' with prefix='club' col="pseudo" text=tr_username %} {% trans "Room" as tr_room %} - {% include "buttons/sort.html" with prefix='club' col="room" text=tr_room %} + {% include 'buttons/sort.html' with prefix='club' col="room" text=tr_room %} {% trans "End of subscription on" %} {% trans "Internet access" %} {% trans "Profile" %} @@ -58,7 +58,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endif %} - + @@ -68,6 +68,6 @@ with this program; if not, write to the Free Software Foundation, Inc., {% if clubs_list.paginator %} -{% include "pagination.html" with list=clubs_list %} + {% include 'pagination.html' with list=clubs_list %} {% endif %} diff --git a/users/templates/users/aff_emailaddress.html b/users/templates/users/aff_emailaddress.html index 25048d6c..f5d5dd1d 100644 --- a/users/templates/users/aff_emailaddress.html +++ b/users/templates/users/aff_emailaddress.html @@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load logs_extra %} {% if emailaddress_list.paginator %} -{% include "pagination.html" with list=emailaddress_list %} + {% include 'pagination.html' with list=emailaddress_list %} {% endif %} @@ -53,6 +53,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
      {% if emailaddress_list.paginator %} -{% include "pagination.html" with list=emailaddress_list %} + {% include 'pagination.html' with list=emailaddress_list %} {% endif %} diff --git a/users/templates/users/aff_listright.html b/users/templates/users/aff_listright.html index cf78e295..8a069529 100644 --- a/users/templates/users/aff_listright.html +++ b/users/templates/users/aff_listright.html @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,

      @@ -41,16 +41,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,

      -

      {% trans "Total: All permissions" %}

      +

      {% trans "Total: all permissions" %}

      -