8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-04 17:06:27 +00:00

Merge branch 'translation' into 'dev'

Translation

See merge request federez/re2o!471
This commit is contained in:
chirac 2019-11-24 23:32:47 +01:00
commit 9afe81b9e2
163 changed files with 4398 additions and 3322 deletions

View file

@ -74,6 +74,6 @@ def can_view(user):
can = user.has_perm(permission)
return (
can,
None if can else _("You don't have the right to see this" " application."),
None if can else _("You don't have the right to view this application."),
(permission,),
)

View file

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-05 19:48+0200\n"
"POT-Creation-Date: 2019-11-19 23:43+0100\n"
"PO-Revision-Date: 2019-01-07 01:37+0100\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n"
@ -31,10 +31,10 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: api/acl.py:74
msgid "You don't have the right to see this application."
#: api/acl.py:77
msgid "You don't have the right to view this application."
msgstr "Vous n'avez pas le droit de voir cette application."
#: api/authentication.py:49
#: api/authentication.py:47
msgid "The token has expired."
msgstr "Le jeton a expiré."

View file

@ -116,7 +116,7 @@ class DiscountForm(Form):
"""
is_relative = forms.BooleanField(
label=_("Discount is on percentage."), required=False
label=_("Discount is in percentage."), required=False
)
discount = forms.DecimalField(
label=_("Discount"),
@ -184,7 +184,7 @@ class DelArticleForm(FormRevMixin, Form):
articles = forms.ModelMultipleChoiceField(
queryset=Article.objects.none(),
label=_("Available articles"),
label=_("Current articles"),
widget=forms.CheckboxSelectMultiple,
)
@ -226,7 +226,7 @@ class DelPaiementForm(FormRevMixin, Form):
# TODO : change paiement to payment
paiements = forms.ModelMultipleChoiceField(
queryset=Paiement.objects.none(),
label=_("Available payment methods"),
label=_("Current payment methods"),
widget=forms.CheckboxSelectMultiple,
)
@ -266,7 +266,7 @@ class DelBanqueForm(FormRevMixin, Form):
# TODO : change banque to bank
banques = forms.ModelMultipleChoiceField(
queryset=Banque.objects.none(),
label=_("Available banks"),
label=_("Current banks"),
widget=forms.CheckboxSelectMultiple,
)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,79 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.23 on 2019-11-20 00:59
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cotisations', '0041_auto_20191103_2131'),
]
operations = [
migrations.AlterModelOptions(
name='chequepayment',
options={'verbose_name': 'cheque'},
),
migrations.AlterField(
model_name='balancepayment',
name='credit_balance_allowed',
field=models.BooleanField(default=False, verbose_name='allow user to credit their balance'),
),
migrations.AlterField(
model_name='balancepayment',
name='maximum_balance',
field=models.DecimalField(blank=True, decimal_places=2, default=50, help_text='The maximal amount of money allowed for the balance.', max_digits=5, null=True, verbose_name='maximum balance'),
),
migrations.AlterField(
model_name='balancepayment',
name='minimum_balance',
field=models.DecimalField(decimal_places=2, default=0, help_text='The minimal amount of money allowed for the balance at the end of a payment. You can specify a negative amount.', max_digits=5, verbose_name='minimum balance'),
),
migrations.AlterField(
model_name='baseinvoice',
name='date',
field=models.DateTimeField(auto_now_add=True, verbose_name='date'),
),
migrations.AlterField(
model_name='comnpaypayment',
name='minimum_payment',
field=models.DecimalField(decimal_places=2, default=1, help_text='The minimal amount of money you have to use when paying with ComNpay.', max_digits=5, verbose_name='minimum payment'),
),
migrations.AlterField(
model_name='comnpaypayment',
name='production',
field=models.BooleanField(default=True, verbose_name='production mode enabled (production URL, instead of homologation)'),
),
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='address',
field=models.CharField(max_length=255, verbose_name='address'),
),
migrations.AlterField(
model_name='custominvoice',
name='paid',
field=models.BooleanField(default=False, verbose_name='paid'),
),
migrations.AlterField(
model_name='custominvoice',
name='payment',
field=models.CharField(max_length=255, verbose_name='payment type'),
),
migrations.AlterField(
model_name='custominvoice',
name='recipient',
field=models.CharField(max_length=255, verbose_name='recipient'),
),
migrations.AlterField(
model_name='custominvoice',
name='remark',
field=models.TextField(blank=True, null=True, verbose_name='remark'),
),
]

View file

@ -56,7 +56,7 @@ from cotisations.validators import check_no_balance
class BaseInvoice(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
date = models.DateTimeField(auto_now_add=True, verbose_name=_("Date"))
date = models.DateTimeField(auto_now_add=True, verbose_name=_("date"))
# TODO : change prix to price
def prix(self):
@ -138,7 +138,7 @@ class Facture(BaseInvoice):
abstract = False
permissions = (
# TODO : change facture to invoice
("change_facture_control", _('Can edit the "controlled" state')),
("change_facture_control", _("Can edit the \"controlled\" state")),
("view_facture", _("Can view an invoice object")),
("change_all_facture", _("Can edit all the previous invoices")),
)
@ -243,7 +243,7 @@ class Facture(BaseInvoice):
can = user_request.has_perm("cotisations.change_facture_control")
return (
can,
_('You don\'t have the right to edit the "controlled" state.')
_("You don't have the right to edit the \"controlled\" state.")
if not can
else None,
("cotisations.change_facture_control",),
@ -262,13 +262,13 @@ class Facture(BaseInvoice):
if len(Paiement.find_allowed_payments(user_request)) <= 0:
return (
False,
_("There are no payment method which you can use."),
_("There are no payment methods that you can use."),
("cotisations.add_facture",),
)
if len(Article.find_allowed_articles(user_request, user_request)) <= 0:
return (
False,
_("There are no article that you can buy."),
_("There are no articles that you can buy."),
("cotisations.add_facture",),
)
return True, None, None
@ -346,11 +346,11 @@ class CustomInvoice(BaseInvoice):
class Meta:
permissions = (("view_custominvoice", _("Can view a custom invoice object")),)
recipient = models.CharField(max_length=255, verbose_name=_("Recipient"))
payment = models.CharField(max_length=255, verbose_name=_("Payment type"))
address = models.CharField(max_length=255, verbose_name=_("Address"))
paid = models.BooleanField(verbose_name=_("Paid"), default=False)
remark = models.TextField(verbose_name=_("Remark"), blank=True, null=True)
recipient = models.CharField(max_length=255, verbose_name=_("recipient"))
payment = models.CharField(max_length=255, verbose_name=_("payment type"))
address = models.CharField(max_length=255, verbose_name=_("address"))
paid = models.BooleanField(verbose_name=_("paid"), default=False)
remark = models.TextField(verbose_name=_("remark"), blank=True, null=True)
class CostEstimate(CustomInvoice):
@ -358,7 +358,7 @@ class CostEstimate(CustomInvoice):
permissions = (("view_costestimate", _("Can view a cost estimate object")),)
validity = models.DurationField(
verbose_name=_("Period of validity"), help_text="DD HH:MM:SS"
verbose_name=_("period of validity"), help_text="DD HH:MM:SS"
)
final_invoice = models.ForeignKey(
CustomInvoice,
@ -547,7 +547,7 @@ class Vente(RevMixin, AclMixin, models.Model):
if not user_request.has_perm("cotisations.change_vente"):
return (
False,
_("You don't have the right to edit the purchases."),
_("You don't have the right to edit a purchase."),
("cotisations.change_vente",),
)
elif not (user_request.has_perm("cotisations.change_all_facture") or user_can):
@ -731,7 +731,7 @@ class Article(RevMixin, AclMixin, models.Model):
def clean(self):
if self.name.lower() == "solde":
raise ValidationError(_("Balance is a reserved article name."))
raise ValidationError(_("Solde is a reserved article name."))
if self.type_cotisation and not (self.duration or self.duration_days):
raise ValidationError(_("Duration must be specified for a subscription."))
@ -921,7 +921,7 @@ class Paiement(RevMixin, AclMixin, models.Model):
p = find_payment_method(self)
if p is not None:
return p._meta.verbose_name
return _("No custom payment method.")
return _("No custom payment methods.")
class Cotisation(RevMixin, AclMixin, models.Model):

View file

@ -44,18 +44,17 @@ class BalancePayment(PaymentMethodMixin, models.Model):
editable=False,
)
minimum_balance = models.DecimalField(
verbose_name=_("Minimum balance"),
verbose_name=_("minimum balance"),
help_text=_(
"The minimal amount of money allowed for the balance"
" at the end of a payment. You can specify negative "
"amount."
"The minimal amount of money allowed for the balance at the end"
" of a payment. You can specify a negative amount."
),
max_digits=5,
decimal_places=2,
default=0,
)
maximum_balance = models.DecimalField(
verbose_name=_("Maximum balance"),
verbose_name=_("maximum balance"),
help_text=_("The maximal amount of money allowed for the balance."),
max_digits=5,
decimal_places=2,
@ -64,7 +63,7 @@ class BalancePayment(PaymentMethodMixin, models.Model):
null=True,
)
credit_balance_allowed = models.BooleanField(
verbose_name=_("Allow user to credit their balance"), default=False
verbose_name=_("allow user to credit their balance"), default=False
)
def end_payment(self, invoice, request):

View file

@ -33,7 +33,7 @@ class ChequePayment(PaymentMethodMixin, models.Model):
"""
class Meta:
verbose_name = _("Cheque")
verbose_name = _("cheque")
payment = models.OneToOneField(
Paiement,

View file

@ -51,9 +51,10 @@ class ComnpayPayment(PaymentMethodMixin, models.Model):
max_length=255, null=True, blank=True, verbose_name=_("ComNpay secret key")
)
minimum_payment = models.DecimalField(
verbose_name=_("Minimum payment"),
verbose_name=_("minimum payment"),
help_text=_(
"The minimal amount of money you have to use when paying" " with ComNpay"
"The minimal amount of money you have to use when paying with"
" ComNpay."
),
max_digits=5,
decimal_places=2,
@ -62,7 +63,7 @@ class ComnpayPayment(PaymentMethodMixin, models.Model):
production = models.BooleanField(
default=True,
verbose_name=_(
"Production mode enabled (production URL, instead of homologation)"
"production mode enabled (production URL, instead of homologation)"
),
)

View file

@ -71,7 +71,7 @@ class PaymentMethodForm(forms.Form):
self.fields["payment_method"].choices = [
(i, p.NAME) for (i, p) in enumerate(PAYMENT_METHODS)
]
self.fields["payment_method"].choices.insert(0, ("", _("no")))
self.fields["payment_method"].choices.insert(0, ("", _("No")))
self.fields["payment_method"].widget.attrs = {"id": "paymentMethodSelect"}
self.templates = [
forms.modelform_factory(p.PaymentMethod, fields="__all__")(prefix=prefix)

View file

@ -51,4 +51,4 @@ class FreePayment(PaymentMethodMixin, models.Model):
"""Checks that the price meets the requirement to be paid with user
balance.
"""
return (price == 0, _("You cannot validate this invoice for free."))
return (price == 0, _("You can't pay this invoice for free."))

View file

@ -30,5 +30,5 @@ class NoteCredentialForm(forms.Form):
object.
"""
login = forms.CharField(label=_("pseudo note"))
login = forms.CharField(label=_("Username"))
password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)

View file

@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<thead>
<tr>
<th>{% trans "Payment type" %}</th>
<th>{% trans "Is available for everyone" %}</th>
<th>{% trans "Available for everyone" %}</th>
<th>{% trans "Custom payment method" %}</th>
<th></th>
</tr>

View file

@ -45,12 +45,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr>
<th>{% trans "Profile" %}</th>
<th>
{% trans "Last name" as tr_last_name %}
{% include 'buttons/sort.html' with prefix='control' col='name' text=tr_last_name %}
{% trans "First name" as tr_first_name %}
{% include 'buttons/sort.html' with prefix='control' col='name' text=tr_first_name %}
</th>
<th>
{% trans "First name" as tr_first_name %}
{% include 'buttons/sort.html' with prefix='control' col='surname' text=tr_first_name %}
{% trans "Surname" as tr_surname %}
{% include 'buttons/sort.html' with prefix='control' col='surname' text=tr_surname %}
</th>
<th>
{% trans "Invoice ID" as tr_invoice_id %}
@ -104,8 +104,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
</tr>
{% endfor %}
</table>
{% trans "Edit" as tr_edit %}
{% bootstrap_button tr_edit button_type='submit' icon='ok' button_class='btn-success' %}
{% trans "Confirm" as tr_confirm %}
{% bootstrap_button tr_confirm button_type='submit' icon='ok' button_class='btn-success' %}
</form>
{% endblock %}

View file

@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<form class="form" method="post">
{% csrf_token %}
<h4>
{% blocktrans %}Warning: are you sure you really want to delete this {{ object_name }} object ( {{ objet }} )?{% endblocktrans %}
{% blocktrans %}Warning: are you sure you really want to delete this {{ objet_name }} object ( {{ objet }} )?{% endblocktrans %}
</h4>
{% trans "Confirm" as tr_confirm %}
{% bootstrap_button tr_confirm button_type='submit' icon='trash' button_class='btn-danger' %}

View file

@ -6,17 +6,17 @@ Nous vous remercions pour votre achat auprès de {{asso_name}} et nous vous en j
En cas de question, nhésitez pas à nous contacter par mail à {{contact_mail}}.
Cordialement,
Léquipe de {{asso_name}}
Respectueusement,
Léquipe de {{asso_name}}.
=== English version ===
Dear {{name}},
Hello {{name}},
Thank you for your purchase. Here is your invoice.
Thank you for your purchase at {{asso_name}}. Here is your invoice.
Should you need extra information, you can email us at {{contact_mail}}.
Should you need extra information, do not hesitate to email us at {{contact_mail}}.
Best regards,
{{ asso_name }}'s team
Regards,
The {{ asso_name }} team.

View file

@ -6,17 +6,18 @@ Vous trouverez en pièce jointe un reçu.
Pour nous faire part de toute remarque, suggestion ou problème vous pouvez nous envoyer un mail à {{asso_email}}.
À bientôt,
Respectueusement,
L'équipe de {{asso_name}}.
---
Hello {{name}}!
Your subscription to {{asso_name}} has just been accepted. You are now a full member of {{asso_name}} until {{ date_end|date:"d/m/Y" }}.
You will find with this email a subscription voucher.
For any information, suggestion or problem, you can contact us via email at
{{asso_email}}.
To express any comment, suggestion or problem, you can send us an email to {{asso_email}}.
Regards,
The {{asso_name}} team.

View file

@ -30,14 +30,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block title %}{% trans "Articles" %}{% endblock %}
{% block content %}
<h2>{% trans "List of article types" %}</h2>
<h2>{% trans "List of articles" %}</h2>
{% can_create Article %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:add-article' %}">
<i class="fa fa-cart-plus"></i> {% trans "Add an article type" %}
<i class="fa fa-plus"></i> {% trans "Add an article" %}
</a>
{% acl_end %}
<a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:del-article' %}">
<i class="fa fa-trash"></i> {% trans "Delete one or several article types" %}
<i class="fa fa-trash"></i> {% trans "Delete one or several articles" %}
</a>
{% include 'cotisations/aff_article.html' with article_list=article_list %}
{% endblock %}

View file

@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<h2>{% trans "List of banks" %}</h2>
{% can_create Banque %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:add-banque' %}">
<i class="fa fa-cart-plus"></i> {% trans "Add a bank" %}
<i class="fa fa-plus"></i> {% trans "Add a bank" %}
</a>
{% acl_end %}
<a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:del-banque' %}">

View file

@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<h2>{% trans "List of payment methods" %}</h2>
{% can_create Paiement %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:add-paiement' %}">
<i class="fa fa-cart-plus"></i> {% trans "Add a payment method" %}
<i class="fa fa-plus"></i> {% trans "Add a payment method" %}
</a>
{% acl_end %}
<a class="btn btn-danger btn-sm" role="button" href="{% url 'cotisations:del-paiement' %}">

View file

@ -52,7 +52,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% acl_end %}
{% can_view_all Article %}
<a class="list-group-item list-group-item-info" href="{% url 'cotisations:index-article' %}">
<i class="fa fa-list-ul"></i> {% trans "Available articles" %}
<i class="fa fa-list-ul"></i> {% trans "Articles" %}
</a>
{% acl_end %}
{% can_view_all Banque %}

View file

@ -36,7 +36,6 @@ from django.template.loader import get_template
from django.http import HttpResponse
from django.conf import settings
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _
from re2o.mixins import AclMixin, RevMixin
from preferences.models import CotisationsOption

View file

@ -166,6 +166,7 @@ def new_facture(request, user, userid):
"articlelist": article_list,
"balance": balance,
"action_name": _("Confirm"),
"title": _("New invoice"),
},
"cotisations/facture.html",
request,
@ -222,7 +223,7 @@ def new_cost_estimate(request):
"articlesformset": articles_formset,
"articlelist": articles,
"discount_form": discount_form,
"title": _("Cost estimate"),
"title": _("New cost estimate"),
},
"cotisations/facture.html",
request,
@ -278,6 +279,7 @@ def new_custom_invoice(request):
"articlesformset": articles_formset,
"articlelist": articles,
"discount_form": discount_form,
"title": _("New custom invoice"),
},
"cotisations/facture.html",
request,
@ -373,7 +375,7 @@ def del_facture(request, facture, **_kwargs):
messages.success(request, _("The invoice was deleted."))
return redirect(reverse("cotisations:index"))
return form(
{"objet": facture, "objet_name": _("Invoice")},
{"objet": facture, "objet_name": _("invoice")},
"cotisations/delete.html",
request,
)
@ -437,7 +439,11 @@ def edit_custom_invoice(request, invoice, **kwargs):
return redirect(reverse("cotisations:index-custom-invoice"))
return form(
{"factureform": invoice_form, "venteform": purchase_form},
{
"factureform": invoice_form,
"venteform": purchase_form,
"title": _("Edit custom invoice"),
},
"cotisations/edit_facture.html",
request,
)
@ -501,7 +507,7 @@ def del_cost_estimate(request, estimate, **_kwargs):
messages.success(request, _("The cost estimate was deleted."))
return redirect(reverse("cotisations:index-cost-estimate"))
return form(
{"objet": estimate, "objet_name": _("Cost estimate")},
{"objet": estimate, "objet_name": _("cost estimate")},
"cotisations/delete.html",
request,
)
@ -564,7 +570,7 @@ def del_custom_invoice(request, invoice, **_kwargs):
messages.success(request, _("The invoice was deleted."))
return redirect(reverse("cotisations:index-custom-invoice"))
return form(
{"objet": invoice, "objet_name": _("Invoice")},
{"objet": invoice, "objet_name": _("invoice")},
"cotisations/delete.html",
request,
)
@ -588,7 +594,11 @@ def add_article(request):
messages.success(request, _("The article was created."))
return redirect(reverse("cotisations:index-article"))
return form(
{"factureform": article, "action_name": _("Add"), "title": _("New article")},
{
"factureform": article,
"action_name": _("Add"),
"title": _("New article"),
},
"cotisations/facture.html",
request,
)
@ -607,7 +617,11 @@ def edit_article(request, article_instance, **_kwargs):
messages.success(request, _("The article was edited."))
return redirect(reverse("cotisations:index-article"))
return form(
{"factureform": article, "action_name": _("Edit"), "title": _("Edit article")},
{
"factureform": article,
"action_name": _("Edit"),
"title": _("Edit article"),
},
"cotisations/facture.html",
request,
)
@ -718,8 +732,8 @@ def del_paiement(request, instances):
messages.error(
request,
_(
"The payment method %(method_name)s can't be deleted \
because there are invoices using it."
"The payment method %(method_name)s can't be deleted"
" because there are invoices using it."
)
% {"method_name": payment_del},
)
@ -748,7 +762,11 @@ def add_banque(request):
messages.success(request, _("The bank was created."))
return redirect(reverse("cotisations:index-banque"))
return form(
{"factureform": bank, "action_name": _("Add"), "title": _("New bank")},
{
"factureform": bank,
"action_name": _("Add"),
"title": _("New bank"),
},
"cotisations/facture.html",
request,
)
@ -768,7 +786,11 @@ def edit_banque(request, banque_instance, **_kwargs):
messages.success(request, _("The bank was edited."))
return redirect(reverse("cotisations:index-banque"))
return form(
{"factureform": bank, "action_name": _("Edit"), "title": _("Edit bank")},
{
"factureform": bank,
"action_name": _("Edit"),
"title": _("Edit bank"),
},
"cotisations/facture.html",
request,
)
@ -802,7 +824,11 @@ def del_banque(request, instances):
)
return redirect(reverse("cotisations:index-banque"))
return form(
{"factureform": bank, "action_name": _("Delete"), "title": _("Delete bank")},
{
"factureform": bank,
"action_name": _("Delete"),
"title": _("Delete bank"),
},
"cotisations/facture.html",
request,
)
@ -833,7 +859,7 @@ def control(request):
)
if control_invoices_form.is_valid():
control_invoices_form.save()
reversion.set_comment("Controle")
reversion.set_comment("Control")
messages.success(
request, _("Your changes have been properly taken into account.")
)

View file

@ -41,6 +41,7 @@ def can_view(user):
can = user.has_module_perms("admin")
return (
can,
None if can else _("You don't have the right to view this" " application."),
None if can else _("You don't have the right to view this"
" application."),
"admin",
)

View file

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-05 19:48+0200\n"
"POT-Creation-Date: 2019-11-19 23:43+0100\n"
"PO-Revision-Date: 2018-06-23 16:01+0200\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n"
@ -30,7 +30,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: logs/acl.py:42
#: logs/acl.py:44
msgid "You don't have the right to view this application."
msgstr "Vous n'avez pas le droit de voir cette application."
@ -159,7 +159,7 @@ msgid "Statistics"
msgstr "Statistiques"
#: logs/templates/logs/index.html:32 logs/templates/logs/stats_logs.html:32
#: logs/views.py:422
#: logs/views.py:400
msgid "Actions performed"
msgstr "Actions effectuées"
@ -183,7 +183,7 @@ msgstr "Base de données"
msgid "Wiring actions"
msgstr "Actions de câblage"
#: logs/templates/logs/sidebar.html:53 logs/views.py:344
#: logs/templates/logs/sidebar.html:53
msgid "Users"
msgstr "Utilisateurs"
@ -199,161 +199,126 @@ msgstr "Statistiques sur la base de données"
msgid "Statistics about users"
msgstr "Statistiques sur les utilisateurs"
#: logs/views.py:194
#: logs/views.py:175
msgid "Nonexistent revision."
msgstr "Révision inexistante."
#: logs/views.py:197
#: logs/views.py:178
msgid "The action was deleted."
msgstr "L'action a été supprimée."
#: logs/views.py:230
#: logs/views.py:219
msgid "Category"
msgstr "Catégorie"
#: logs/views.py:231
#: logs/views.py:220
msgid "Number of users (members and clubs)"
msgstr "Nombre d'utilisateurs (adhérents et clubs)"
#: logs/views.py:232
#: logs/views.py:221
msgid "Number of members"
msgstr "Nombre d'adhérents"
#: logs/views.py:233
#: logs/views.py:222
msgid "Number of clubs"
msgstr "Nombre de clubs"
#: logs/views.py:237
#: logs/views.py:226
msgid "Activated users"
msgstr "Utilisateurs activés"
#: logs/views.py:245
#: logs/views.py:232
msgid "Disabled users"
msgstr "Utilisateurs désactivés"
#: logs/views.py:253
#: logs/views.py:238
msgid "Archived users"
msgstr "Utilisateurs archivés"
#: logs/views.py:261
#, fuzzy
#| msgid "Archived users"
msgid "Full Archived users"
msgstr "Utilisateurs archivés"
#: logs/views.py:244
msgid "Fully archived users"
msgstr "Utilisateurs complètement archivés"
#: logs/views.py:269
#: logs/views.py:254
msgid "Not yet active users"
msgstr "Utilisateurs pas encore actifs"
#: logs/views.py:277
#: logs/views.py:264
msgid "Contributing members"
msgstr "Adhérents cotisants"
#: logs/views.py:283
#: logs/views.py:270
msgid "Users benefiting from a connection"
msgstr "Utilisateurs bénéficiant d'une connexion"
#: logs/views.py:289
#: logs/views.py:276
msgid "Banned users"
msgstr "Utilisateurs bannis"
#: logs/views.py:295
#: logs/views.py:282
msgid "Users benefiting from a free connection"
msgstr "Utilisateurs bénéficiant d'une connexion gratuite"
#: logs/views.py:301
#: logs/views.py:288
msgid "Active interfaces (with access to the network)"
msgstr "Interfaces actives (ayant accès au réseau)"
#: logs/views.py:311
#: logs/views.py:302
msgid "Active interfaces assigned IPv4"
msgstr "Interfaces actives assignées IPv4"
#: logs/views.py:324
#: logs/views.py:319
msgid "IP range"
msgstr "Plage d'IP"
#: logs/views.py:325
#: logs/views.py:320
msgid "VLAN"
msgstr "VLAN"
#: logs/views.py:326
#: logs/views.py:321
msgid "Total number of IP addresses"
msgstr "Nombre total d'adresses IP"
#: logs/views.py:327
#: logs/views.py:322
msgid "Number of assigned IP addresses"
msgstr "Nombre d'adresses IP non assignées"
msgstr "Nombre d'adresses IP assignées"
#: logs/views.py:328
#: logs/views.py:323
msgid "Number of IP address assigned to an activated machine"
msgstr "Nombre d'adresses IP assignées à une machine activée"
#: logs/views.py:329
msgid "Number of nonassigned IP addresses"
#: logs/views.py:324
msgid "Number of unassigned IP addresses"
msgstr "Nombre d'adresses IP non assignées"
#: logs/views.py:356
msgid "Subscriptions"
msgstr "Cotisations"
#: logs/views.py:339
msgid "Users (members and clubs)"
msgstr "Utilisateurs (adhérents et clubs)"
#: logs/views.py:378 logs/views.py:439
msgid "Machines"
msgstr "Machines"
#: logs/views.py:405
#: logs/views.py:385
msgid "Topology"
msgstr "Topologie"
#: logs/views.py:424
#: logs/views.py:401
msgid "Number of actions"
msgstr "Nombre d'actions"
#: logs/views.py:438 logs/views.py:456 logs/views.py:461 logs/views.py:466
#: logs/views.py:481
msgid "User"
msgstr "Utilisateur"
#: logs/views.py:442
msgid "Invoice"
msgstr "Facture"
#: logs/views.py:445
msgid "Ban"
msgstr "Bannissement"
#: logs/views.py:448
msgid "Whitelist"
msgstr "Accès gracieux"
#: logs/views.py:451
msgid "Rights"
msgstr "Droits"
#: logs/views.py:426
msgid "rights"
msgstr "droits"
#: logs/views.py:455
msgid "School"
msgstr "Établissement"
msgid "actions"
msgstr "actions"
#: logs/views.py:460
msgid "Payment method"
msgstr "Moyen de paiement"
#: logs/views.py:465
msgid "Bank"
msgstr "Banque"
#: logs/views.py:482
msgid "Action"
msgstr "Action"
#: logs/views.py:513
#: logs/views.py:486
msgid "No model found."
msgstr "Aucun modèle trouvé."
#: logs/views.py:519
#: logs/views.py:492
msgid "Nonexistent entry."
msgstr "Entrée inexistante."
#: logs/views.py:526
#: logs/views.py:499
msgid "You don't have the right to access this menu."
msgstr "Vous n'avez pas le droit d'accéder à ce menu."

View file

@ -241,7 +241,7 @@ def stats_general(request):
Club.objects.filter(state=Club.STATE_ARCHIVE).count(),
],
"full_archive_users": [
_("Full Archived users"),
_("Fully archived users"),
User.objects.filter(state=User.STATE_FULL_ARCHIVE).count(),
(
Adherent.objects.filter(
@ -321,7 +321,7 @@ def stats_general(request):
_("Total number of IP addresses"),
_("Number of assigned IP addresses"),
_("Number of IP address assigned to an activated machine"),
_("Number of nonassigned IP addresses"),
_("Number of unassigned IP addresses"),
],
ip_dict, # Data already prepared
],
@ -336,7 +336,7 @@ def stats_models(request):
nombre d'users, d'écoles, de droits, de bannissements,
de factures, de ventes, de banque, de machines, etc"""
stats = {
_("Users"): {
_("Users (members and clubs)"): {
"users": [User._meta.verbose_name, User.objects.count()],
"adherents": [Adherent._meta.verbose_name, Adherent.objects.count()],
"clubs": [Club._meta.verbose_name, Club.objects.count()],
@ -350,14 +350,14 @@ def stats_models(request):
"ban": [Ban._meta.verbose_name, Ban.objects.count()],
"whitelist": [Whitelist._meta.verbose_name, Whitelist.objects.count()],
},
_("Subscriptions"): {
Cotisation._meta.verbose_name_plural.title(): {
"factures": [Facture._meta.verbose_name, Facture.objects.count()],
"vente": [Vente._meta.verbose_name, Vente.objects.count()],
"cotisation": [Cotisation._meta.verbose_name, Cotisation.objects.count()],
"article": [Article._meta.verbose_name, Article.objects.count()],
"banque": [Banque._meta.verbose_name, Banque.objects.count()],
},
_("Machines"): {
Machine._meta.verbose_name_plural.title(): {
"machine": [Machine._meta.verbose_name, Machine.objects.count()],
"typemachine": [
MachineType._meta.verbose_name,
@ -412,31 +412,31 @@ def stats_users(request):
de moyens de paiements par user, de banque par user,
de bannissement par user, etc"""
stats = {
_("User"): {
_("Machines"): User.objects.annotate(num=Count("machine")).order_by("-num")[
User._meta.verbose_name: {
Machine._meta.verbose_name_plural: User.objects.annotate(num=Count("machine")).order_by("-num")[
:10
],
_("Invoice"): User.objects.annotate(num=Count("facture")).order_by("-num")[
Facture._meta.verbose_name_plural: User.objects.annotate(num=Count("facture")).order_by("-num")[
:10
],
_("Ban"): User.objects.annotate(num=Count("ban")).order_by("-num")[:10],
_("Whitelist"): User.objects.annotate(num=Count("whitelist")).order_by(
Ban._meta.verbose_name_plural: User.objects.annotate(num=Count("ban")).order_by("-num")[:10],
Whitelist._meta.verbose_name_plural: User.objects.annotate(num=Count("whitelist")).order_by(
"-num"
)[:10],
_("Rights"): User.objects.annotate(num=Count("groups")).order_by("-num")[
_("rights"): User.objects.annotate(num=Count("groups")).order_by("-num")[
:10
],
},
_("School"): {
_("User"): School.objects.annotate(num=Count("user")).order_by("-num")[:10]
School._meta.verbose_name: {
User._meta.verbose_name_plural: School.objects.annotate(num=Count("user")).order_by("-num")[:10]
},
_("Payment method"): {
_("User"): Paiement.objects.annotate(num=Count("facture")).order_by("-num")[
Paiement._meta.verbose_name: {
User._meta.verbose_name_plural: Paiement.objects.annotate(num=Count("facture")).order_by("-num")[
:10
]
},
_("Bank"): {
_("User"): Banque.objects.annotate(num=Count("facture")).order_by("-num")[
Banque._meta.verbose_name: {
User._meta.verbose_name_plural: Banque.objects.annotate(num=Count("facture")).order_by("-num")[
:10
]
},
@ -451,8 +451,8 @@ def stats_actions(request):
utilisateurs.
Affiche le nombre de modifications aggrégées par utilisateurs"""
stats = {
_("User"): {
_("Action"): User.objects.annotate(num=Count("revision")).order_by("-num")[
User._meta.verbose_name: {
_("actions"): User.objects.annotate(num=Count("revision")).order_by("-num")[
:40
]
}

View file

@ -41,6 +41,7 @@ def can_view(user):
can = user.has_module_perms("machines")
return (
can,
None if can else _("You don't have the right to view this" " application."),
None if can else _("You don't have the right to view this"
" application."),
("machines",),
)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,136 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.23 on 2019-11-20 00:59
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('machines', '0105_dname_ttl'),
]
operations = [
migrations.AlterModelOptions(
name='domain',
options={'permissions': (('view_domain', 'Can view a domain object'), ('change_ttl', 'Can change the TTL of a domain object')), 'verbose_name': 'domain', 'verbose_name_plural': 'domains'},
),
migrations.AlterField(
model_name='extension',
name='dnssec',
field=models.BooleanField(default=False, help_text='Should the zone be signed with DNSSEC.'),
),
migrations.AlterField(
model_name='extension',
name='name',
field=models.CharField(help_text='Zone name, must begin with a dot (.example.org).', max_length=255, unique=True),
),
migrations.AlterField(
model_name='extension',
name='origin',
field=models.ForeignKey(blank=True, help_text='A record associated with the zone.', null=True, on_delete=django.db.models.deletion.PROTECT, to='machines.IpList'),
),
migrations.AlterField(
model_name='extension',
name='origin_v6',
field=models.GenericIPAddressField(blank=True, help_text='AAAA record associated with the zone.', null=True, protocol='IPv6'),
),
migrations.AlterField(
model_name='iptype',
name='domaine_ip_netmask',
field=models.IntegerField(default=24, help_text="Netmask for the domain's IPv4 range.", validators=[django.core.validators.MaxValueValidator(31), django.core.validators.MinValueValidator(8)]),
),
migrations.AlterField(
model_name='iptype',
name='domaine_ip_network',
field=models.GenericIPAddressField(blank=True, help_text="Network containing the domain's IPv4 range (optional).", null=True, protocol='IPv4'),
),
migrations.AlterField(
model_name='iptype',
name='reverse_v4',
field=models.BooleanField(default=False, help_text='Enable reverse DNS for IPv4.'),
),
migrations.AlterField(
model_name='iptype',
name='reverse_v6',
field=models.BooleanField(default=False, help_text='Enable reverse DNS for IPv6.'),
),
migrations.AlterField(
model_name='machine',
name='name',
field=models.CharField(blank=True, help_text='Optional.', max_length=255, null=True),
),
migrations.AlterField(
model_name='soa',
name='expire',
field=models.PositiveIntegerField(default=3600000, help_text='Seconds before the secondary DNS stop answering requests in case of primary DNS timeout.'),
),
migrations.AlterField(
model_name='soa',
name='mail',
field=models.EmailField(help_text='Contact email address for the zone.', max_length=254),
),
migrations.AlterField(
model_name='soa',
name='refresh',
field=models.PositiveIntegerField(default=86400, help_text='Seconds before the secondary DNS have to ask the primary DNS serial to detect a modification.'),
),
migrations.AlterField(
model_name='soa',
name='retry',
field=models.PositiveIntegerField(default=7200, help_text='Seconds before the secondary DNS ask the serial again in case of a primary DNS timeout.'),
),
migrations.AlterField(
model_name='soa',
name='ttl',
field=models.PositiveIntegerField(default=172800, help_text='Time To Live.'),
),
migrations.AlterField(
model_name='srv',
name='port',
field=models.PositiveIntegerField(help_text='TCP/UDP port.', validators=[django.core.validators.MaxValueValidator(65535)]),
),
migrations.AlterField(
model_name='srv',
name='priority',
field=models.PositiveIntegerField(default=0, help_text='Priority of the target server (positive integer value, the lower it is, the more the server will be used if available).', validators=[django.core.validators.MaxValueValidator(65535)]),
),
migrations.AlterField(
model_name='srv',
name='target',
field=models.ForeignKey(help_text='Target server.', on_delete=django.db.models.deletion.PROTECT, to='machines.Domain'),
),
migrations.AlterField(
model_name='srv',
name='ttl',
field=models.PositiveIntegerField(default=172800, help_text='Time To Live.'),
),
migrations.AlterField(
model_name='srv',
name='weight',
field=models.PositiveIntegerField(default=0, help_text='Relative weight for records with the same priority (integer value between 0 and 65535).', validators=[django.core.validators.MaxValueValidator(65535)]),
),
migrations.AlterField(
model_name='sshfp',
name='comment',
field=models.CharField(blank=True, help_text='Comment.', max_length=255, null=True),
),
migrations.AlterField(
model_name='sshfp',
name='pub_key_entry',
field=models.TextField(help_text='SSH public key.', max_length=2048),
),
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.'),
),
]

View file

@ -68,7 +68,7 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
user = models.ForeignKey("users.User", on_delete=models.CASCADE)
name = models.CharField(
max_length=255, help_text=_("Optional"), blank=True, null=True
max_length=255, help_text=_("Optional."), blank=True, null=True
)
active = models.BooleanField(default=True)
@ -157,7 +157,8 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
if user != user_request:
return (
False,
_("You don't have the right to add a machine" " to another user."),
_("You don't have the right to add a machine to another"
" user."),
("machines.add_machine",),
)
if user.user_interfaces().count() >= max_lambdauser_interfaces:
@ -185,7 +186,8 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
if not (user_request.has_perm("machines.change_interface") and can_user):
return (
False,
_("You don't have the right to edit a machine" " of another user."),
_("You don't have the right to edit a machine of another"
" user."),
("machines.change_interface",) + permissions,
)
return True, None, None
@ -223,7 +225,8 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model):
):
return (
False,
_("You don't have the right to view other machines" " than yours."),
_("You don't have the right to view other machines than"
" yours."),
("machines.view_machine",),
)
return True, None, None
@ -358,22 +361,22 @@ class IpType(RevMixin, AclMixin, models.Model):
protocol="IPv4",
null=True,
blank=True,
help_text=_("Network containing the domain's IPv4 range (optional)"),
help_text=_("Network containing the domain's IPv4 range (optional)."),
)
domaine_ip_netmask = models.IntegerField(
default=24,
validators=[MaxValueValidator(31), MinValueValidator(8)],
help_text=_("Netmask for the domain's IPv4 range"),
help_text=_("Netmask for the domain's IPv4 range."),
)
reverse_v4 = models.BooleanField(
default=False, help_text=_("Enable reverse DNS for IPv4")
default=False, help_text=_("Enable reverse DNS for IPv4.")
)
prefix_v6 = models.GenericIPAddressField(protocol="IPv6", null=True, blank=True)
prefix_v6_length = models.IntegerField(
default=64, validators=[MaxValueValidator(128), MinValueValidator(0)]
)
reverse_v6 = models.BooleanField(
default=False, help_text=_("Enable reverse DNS for IPv6")
default=False, help_text=_("Enable reverse DNS for IPv6.")
)
vlan = models.ForeignKey("Vlan", on_delete=models.PROTECT, blank=True, null=True)
ouverture_ports = models.ForeignKey("OuverturePortList", blank=True, null=True)
@ -553,7 +556,8 @@ class IpType(RevMixin, AclMixin, models.Model):
for element in IpType.objects.all().exclude(pk=self.pk):
if not self.ip_set.isdisjoint(element.ip_set):
raise ValidationError(
_("The specified range is not disjoint" " from existing ranges.")
_("The specified range is not disjoint from existing"
" ranges.")
)
# On formate le prefix v6
if self.prefix_v6:
@ -604,8 +608,8 @@ class Vlan(RevMixin, AclMixin, models.Model):
arp_protect = models.BooleanField(default=False)
dhcp_snooping = models.BooleanField(default=False)
dhcpv6_snooping = models.BooleanField(default=False)
igmp = models.BooleanField(default=False, help_text=_("v4 multicast management"))
mld = models.BooleanField(default=False, help_text=_("v6 multicast management"))
igmp = models.BooleanField(default=False, help_text=_("v4 multicast management."))
mld = models.BooleanField(default=False, help_text=_("v6 multicast management."))
class Meta:
permissions = (("view_vlan", _("Can view a VLAN object")),)
@ -653,30 +657,30 @@ class SOA(RevMixin, AclMixin, models.Model):
"""
name = models.CharField(max_length=255)
mail = models.EmailField(help_text=_("Contact email address for the zone"))
mail = models.EmailField(help_text=_("Contact email address for the zone."))
refresh = models.PositiveIntegerField(
default=86400, # 24 hours
help_text=_(
"Seconds before the secondary DNS have to ask the primary"
" DNS serial to detect a modification"
" DNS serial to detect a modification."
),
)
retry = models.PositiveIntegerField(
default=7200, # 2 hours
help_text=_(
"Seconds before the secondary DNS ask the serial again in"
" case of a primary DNS timeout"
" case of a primary DNS timeout."
),
)
expire = models.PositiveIntegerField(
default=3600000, # 1000 hours
help_text=_(
"Seconds before the secondary DNS stop answering requests"
" in case of primary DNS timeout"
" in case of primary DNS timeout."
),
)
ttl = models.PositiveIntegerField(
default=172800, help_text=_("Time to Live") # 2 days
default=172800, help_text=_("Time To Live.") # 2 days
)
class Meta:
@ -732,7 +736,7 @@ class Extension(RevMixin, AclMixin, models.Model):
name = models.CharField(
max_length=255,
unique=True,
help_text=_("Zone name, must begin with a dot (.example.org)"),
help_text=_("Zone name, must begin with a dot (.example.org)."),
)
need_infra = models.BooleanField(default=False)
origin = models.ForeignKey(
@ -740,17 +744,17 @@ class Extension(RevMixin, AclMixin, models.Model):
on_delete=models.PROTECT,
blank=True,
null=True,
help_text=_("A record associated with the zone"),
help_text=_("A record associated with the zone."),
)
origin_v6 = models.GenericIPAddressField(
protocol="IPv6",
null=True,
blank=True,
help_text=_("AAAA record associated with the zone"),
help_text=_("AAAA record associated with the zone."),
)
soa = models.ForeignKey("SOA", on_delete=models.CASCADE)
dnssec = models.BooleanField(
default=False, help_text=_("Should the zone be signed with DNSSEC")
default=False, help_text=_("Should the zone be signed with DNSSEC.")
)
class Meta:
@ -819,7 +823,7 @@ class Extension(RevMixin, AclMixin, models.Model):
can = user_request.has_perm("machines.use_all_extension")
return (
can,
_("You cannot use all extensions.") if not can else None,
_("You don't have the right to use all extensions.") if not can else None,
("machines.use_all_extension",),
)
@ -943,7 +947,7 @@ class Srv(RevMixin, AclMixin, models.Model):
)
extension = models.ForeignKey("Extension", on_delete=models.PROTECT)
ttl = models.PositiveIntegerField(
default=172800, help_text=_("Time to Live") # 2 days
default=172800, help_text=_("Time To Live.") # 2 days
)
priority = models.PositiveIntegerField(
default=0,
@ -951,7 +955,7 @@ class Srv(RevMixin, AclMixin, models.Model):
help_text=_(
"Priority of the target server (positive integer value,"
" the lower it is, the more the server will be used if"
" available)"
" available)."
),
)
weight = models.PositiveIntegerField(
@ -959,14 +963,14 @@ class Srv(RevMixin, AclMixin, models.Model):
validators=[MaxValueValidator(65535)],
help_text=_(
"Relative weight for records with the same priority"
" (integer value between 0 and 65535)"
" (integer value between 0 and 65535)."
),
)
port = models.PositiveIntegerField(
validators=[MaxValueValidator(65535)], help_text=_("TCP/UDP port")
validators=[MaxValueValidator(65535)], help_text=_("TCP/UDP port.")
)
target = models.ForeignKey(
"Domain", on_delete=models.PROTECT, help_text=_("Target server")
"Domain", on_delete=models.PROTECT, help_text=_("Target server.")
)
class Meta:
@ -1023,10 +1027,10 @@ class SshFp(RevMixin, AclMixin, models.Model):
)
machine = models.ForeignKey("Machine", on_delete=models.CASCADE)
pub_key_entry = models.TextField(help_text=_("SSH public key"), max_length=2048)
pub_key_entry = models.TextField(help_text=_("SSH public key."), max_length=2048)
algo = models.CharField(choices=ALGO, max_length=32)
comment = models.CharField(
help_text=_("Comment"), max_length=255, null=True, blank=True
help_text=_("Comment."), max_length=255, null=True, blank=True
)
@cached_property
@ -1128,7 +1132,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
oui = mac.oui
vendor = oui.registration().org
except NotRegisteredError:
vendor = "Unknown vendor"
vendor = _("Unknown vendor.")
return vendor
def sync_ipv6_dhcpv6(self):
@ -1201,7 +1205,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
self.ipv4 = free_ips[0]
else:
raise ValidationError(
_("There is no IP address available in the" " slash.")
_("There are no IP addresses available in the slash.")
)
return
@ -1214,7 +1218,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
"""Unassign ipv4 to multiple interfaces"""
with transaction.atomic(), reversion.create_revision():
interface_list.update(ipv4=None)
reversion.set_comment(_("IPv4 unassigning"))
reversion.set_comment("IPv4 unassignment")
@classmethod
def mass_assign_ipv4(cls, interface_list):
@ -1222,7 +1226,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
with transaction.atomic(), reversion.create_revision():
interface.assign_ipv4()
interface.save()
reversion.set_comment(_("IPv4 assigning"))
reversion.set_comment("IPv4 assignment")
def update_type(self):
""" Lorsque le machinetype est changé de type d'ip, on réassigne"""
@ -1267,7 +1271,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
)
if interfaces_similar and interfaces_similar.first() != self:
raise ValidationError(
_("Mac address already registered in this Machine Type/Subnet")
_("MAC address already registered in this machine type/subnet.")
)
def save(self, *args, **kwargs):
@ -1276,7 +1280,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
if self.ipv4:
if self.machine_type.ip_type != self.ipv4.ip_type:
raise ValidationError(
_("The IPv4 address and the machine type" " don't match.")
_("The IPv4 address and the machine type don't match.")
)
self.validate_unique()
super(Interface, self).save(*args, **kwargs)
@ -1296,7 +1300,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
if not (
preferences.models.OptionalMachine.get_cached_value("create_machine")
):
return False, _("You can't add a machine."), ("machines.add_interface",)
return False, _("You don't have the right to add a machine."), ("machines.add_interface",)
max_lambdauser_interfaces = preferences.models.OptionalMachine.get_cached_value(
"max_lambdauser_interfaces"
)
@ -1328,7 +1332,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
can = user_request.has_perm("machines.change_interface_machine")
return (
can,
_("Permission required to edit the machine.") if not can else None,
_("You don't have the right to edit the machine.") if not can else None,
("machines.change_interface_machine",),
)
@ -1345,7 +1349,8 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
if not (user_request.has_perm("machines.change_interface") and can_user):
return (
False,
_("You don't have the right to edit a machine of" " another user."),
_("You don't have the right to edit a machine of another"
" user."),
("machines.change_interface",) + permissions,
)
return True, None, None
@ -1363,7 +1368,8 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
if not (user_request.has_perm("machines.change_interface") and can_user):
return (
False,
_("You don't have the right to edit a machine of" " another user."),
_("You don't have the right to edit a machine of another"
" user."),
("machines.change_interface",) + permissions,
)
return True, None, None
@ -1411,7 +1417,7 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
("view_ipv6list", _("Can view an IPv6 addresses list object")),
(
"change_ipv6list_slaac_ip",
_("Can change the SLAAC value of an" " IPv6 addresses list"),
_("Can change the SLAAC value of an IPv6 addresses list"),
),
)
verbose_name = _("IPv6 addresses list")
@ -1446,7 +1452,7 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
can = user_request.has_perm("machines.change_ipv6list_slaac_ip")
return (
can,
_("Permission required to change the SLAAC value of an IPv6" " address")
_("You don't have the right to change the SLAAC value of an IPv6 address.")
if not can
else None,
("machines.change_ipv6list_slaac_ip",),
@ -1465,7 +1471,7 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
if not (user_request.has_perm("machines.change_ipv6list") and can_user):
return (
False,
_("You don't have the right to edit a machine of" " another user."),
_("You don't have the right to edit a machine of another user."),
("machines.change_ipv6list",),
)
return True, None, None
@ -1483,7 +1489,7 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
if not (user_request.has_perm("machines.change_ipv6list") and can_user):
return (
False,
_("You don't have the right to edit a machine of" " another user."),
_("You don't have the right to edit a machine of another user."),
("machines.change_ipv6list",) + permissions,
)
return True, None, None
@ -1587,7 +1593,7 @@ class Domain(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
unique_together = (("name", "extension"),)
permissions = (
("view_domain", _("Can view a domain object")),
("change_ttl", _("Can change TTL of a domain object")),
("change_ttl", _("Can change the TTL of a domain object")),
)
verbose_name = _("domain")
verbose_name_plural = _("domains")
@ -1612,20 +1618,20 @@ class Domain(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
if self.get_extension():
self.extension = self.get_extension()
if self.interface_parent and self.cname:
raise ValidationError(_("You can't create a both A and CNAME" " record."))
raise ValidationError(_("You can't create a both A and CNAME record."))
if self.cname == self:
raise ValidationError(
_("You can't create a CNAME record pointing" " to itself.")
_("You can't create a CNAME record pointing to itself.")
)
HOSTNAME_LABEL_PATTERN = re.compile(r"(?!-)[A-Z\d-]+(?<!-)$", re.IGNORECASE)
dns = self.name.lower()
if len(dns) > 63:
raise ValidationError(
_("The domain name %s is too long (over 63" " characters).") % dns
_("The domain name %s is too long (over 63 characters).") % dns
)
if not HOSTNAME_LABEL_PATTERN.match(dns):
raise ValidationError(
_("The domain name %s contains forbidden" " characters.") % dns
_("The domain name %s contains forbidden characters.") % dns
)
self.validate_unique()
super(Domain, self).clean()
@ -1753,7 +1759,8 @@ class Domain(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
):
return (
False,
_("You don't have the right to view machines other than yours."),
_("You don't have the right to view other machines than"
" yours."),
("machines.view_domain",),
)
return True, None, None
@ -1794,7 +1801,7 @@ class IpList(RevMixin, AclMixin, models.Model):
""" Erreur si l'ip_type est incorrect"""
if not str(self.ipv4) in self.ip_type.ip_set_as_str:
raise ValidationError(
_("The IPv4 address and the range of the IP" " type don't match.")
_("The IPv4 address and the range of the IP type don't match.")
)
return
@ -1970,7 +1977,8 @@ class OuverturePortList(RevMixin, AclMixin, models.Model):
class Meta:
permissions = (
("view_ouvertureportlist", _("Can view a ports opening list" " object")),
("view_ouvertureportlist", _("Can view a ports opening list"
" object")),
)
verbose_name = _("ports opening list")
verbose_name_plural = _("ports opening lists")

View file

@ -32,7 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<thead>
<tr>
<th>{% trans "Extension" %}</th>
<th>{% trans "'infra' right required" %}</th>
<th>{% blocktrans %}"infra" right required{% endblocktrans %}</th>
<th>{% trans "SOA record" %}</th>
<th>{% trans "A record origin" %}</th>
{% if ipv6_enabled %}

View file

@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr>
<th>{% trans "IP type" %}</th>
<th>{% trans "Extension" %}</th>
<th>{% trans "'infra' right required" %}</th>
<th>{% blocktrans %}"infra" right required{% endblocktrans %}</th>
<th>{% trans "IPv4 range" %}</th>
<th>{% trans "v6 prefix" %}</th>
<th>{% trans "DNSSEC reverse v4/v6" %}</th>

View file

@ -31,8 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<th>{% trans "Service name" %}</th>
<th>{% trans "Server" %}</th>
<th>{% trans "Last regeneration" %}</th>
<th>{% trans "Regeneration required" %}</th>
<th>{% trans "Regeneration activated" %}</th>
<th>{% trans "Regeneration asked" %}</th>
<th>{% trans "Regeneration needed" %}</th>
</tr>
</thead>
{% for server in servers_list %}

View file

@ -47,11 +47,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
</div>
<p>
{% trans "Add a port" as value %}
<input class="btn btn-primary btn-sm" role="button" value="value" id="add_one">
<input class="btn btn-primary btn-sm" role="button" value="{% trans "Add a port" %}" id="add_one">
</p>
{% trans "Create or edit" as tr_create_or_edit %}
{% bootstrap_button tr_create_or_edit icon='ok' button_class='btn-success' %}
{% trans "Confirm" as tr_confirm %}
{% bootstrap_button tr_confirm icon='ok' button_class='btn-success' %}
</form>
<script type="text/javascript">
var template = `{{ports.empty_form}}`;

View file

@ -33,8 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<h2>{% trans "List of extensions" %}</h2>
{% can_create Extension %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'machines:add-extension' %}">
<i class="fa fa-plus"></i>
{% trans " Add an extension" %}</a>
<i class="fa fa-plus"></i> {% trans "Add an extension" %}</a>
{% acl_end %}
<a class="btn btn-danger btn-sm" role="button" href="{% url 'machines:del-extension' %}">
<i class="fa fa-trash"></i> {% trans "Delete one or several extensions" %}

View file

@ -250,7 +250,7 @@ def new_machine(request, user, **_kwargs):
"interfaceform": interface,
"domainform": domain,
"i_mbf_param": i_mbf_param,
"action_name": _("Create a machine"),
"action_name": _("Add"),
},
"machines/machine.html",
request,
@ -314,7 +314,7 @@ def del_machine(request, machine, **_kwargs):
reverse("users:profil", kwargs={"userid": str(machine.user.id)})
)
return form(
{"objet": machine, "objet_name": "machine"}, "machines/delete.html", request
{"objet": machine, "objet_name": _("machine")}, "machines/delete.html", request
)
@ -345,7 +345,7 @@ def new_interface(request, machine, **_kwargs):
"interfaceform": interface_form,
"domainform": domain_form,
"i_mbf_param": i_mbf_param,
"action_name": _("Create an interface"),
"action_name": _("Add"),
},
"machines/machine.html",
request,
@ -366,7 +366,7 @@ def del_interface(request, interface, **_kwargs):
reverse("users:profil", kwargs={"userid": str(request.user.id)})
)
return form(
{"objet": interface, "objet_name": "interface"}, "machines/delete.html", request
{"objet": interface, "objet_name": _("interface")}, "machines/delete.html", request
)
@ -386,7 +386,7 @@ def new_ipv6list(request, interface, **_kwargs):
reverse("machines:index-ipv6", kwargs={"interfaceid": str(interface.id)})
)
return form(
{"ipv6form": ipv6, "action_name": _("Create an IPv6 addresses list")},
{"ipv6form": ipv6, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -426,7 +426,7 @@ def del_ipv6list(request, ipv6list, **_kwargs):
reverse("machines:index-ipv6", kwargs={"interfaceid": str(interfaceid)})
)
return form(
{"objet": ipv6list, "objet_name": "ipv6"}, "machines/delete.html", request
{"objet": ipv6list, "objet_name": _("IPv6 addresses list")}, "machines/delete.html", request
)
@ -444,7 +444,7 @@ def new_sshfp(request, machine, **_kwargs):
reverse("machines:index-sshfp", kwargs={"machineid": str(machine.id)})
)
return form(
{"sshfpform": sshfp, "action_name": _("Create a SSHFP record")},
{"sshfpform": sshfp, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -482,7 +482,7 @@ def del_sshfp(request, sshfp, **_kwargs):
reverse("machines:index-sshfp", kwargs={"machineid": str(machineid)})
)
return form(
{"objet": sshfp, "objet_name": "sshfp"}, "machines/delete.html", request
{"objet": sshfp, "objet_name": _("SSHFP record")}, "machines/delete.html", request
)
@ -498,7 +498,7 @@ def add_iptype(request):
messages.success(request, _("The IP type was created."))
return redirect(reverse("machines:index-iptype"))
return form(
{"iptypeform": iptype, "action_name": _("Create an IP type")},
{"iptypeform": iptype, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -563,7 +563,7 @@ def add_machinetype(request):
messages.success(request, _("The machine type was created."))
return redirect(reverse("machines:index-machinetype"))
return form(
{"machinetypeform": machinetype, "action_name": _("Create a machine" " type")},
{"machinetypeform": machinetype, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -626,7 +626,7 @@ def add_extension(request):
messages.success(request, _("The extension was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"extensionform": extension, "action_name": _("Create an extension")},
{"extensionform": extension, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -688,7 +688,7 @@ def add_soa(request):
messages.success(request, _("The SOA record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"soaform": soa, "action_name": _("Create an SOA record")},
{"soaform": soa, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -740,7 +740,7 @@ def add_mx(request):
messages.success(request, _("The MX record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"mxform": mx, "action_name": _("Create an MX record")},
{"mxform": mx, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -792,7 +792,7 @@ def add_ns(request):
messages.success(request, _("The NS record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"nsform": ns, "action_name": _("Create an NS record")},
{"nsform": ns, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -844,7 +844,7 @@ def add_dname(request):
messages.success(request, _("The DNAME record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"dnameform": dname, "action_name": _("Create a DNAME record")},
{"dnameform": dname, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -899,7 +899,7 @@ def add_txt(request):
messages.success(request, _("The TXT record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"txtform": txt, "action_name": _("Create a TXT record")},
{"txtform": txt, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -951,7 +951,7 @@ def add_srv(request):
messages.success(request, _("The SRV record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"srvform": srv, "action_name": _("Create an SRV record")},
{"srvform": srv, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -1008,7 +1008,7 @@ def add_alias(request, interface, interfaceid):
reverse("machines:index-alias", kwargs={"interfaceid": str(interfaceid)})
)
return form(
{"aliasform": alias, "action_name": _("Create an alias")},
{"aliasform": alias, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -1069,7 +1069,7 @@ def add_role(request):
messages.success(request, _("The role was created."))
return redirect(reverse("machines:index-role"))
return form(
{"roleform": role, "action_name": _("Create a role")},
{"roleform": role, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -1121,7 +1121,7 @@ def add_service(request):
messages.success(request, _("The service was created."))
return redirect(reverse("machines:index-service"))
return form(
{"serviceform": service, "action_name": _("Create a service")},
{"serviceform": service, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -1187,7 +1187,7 @@ def add_vlan(request):
messages.success(request, _("The VLAN was created."))
return redirect(reverse("machines:index-vlan"))
return form(
{"vlanform": vlan, "action_name": _("Create a VLAN")},
{"vlanform": vlan, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -1239,7 +1239,7 @@ def add_nas(request):
messages.success(request, _("The NAS device was created."))
return redirect(reverse("machines:index-nas"))
return form(
{"nasform": nas, "action_name": _("Create a NAS device")},
{"nasform": nas, "action_name": _("Add")},
"machines/machine.html",
request,
)
@ -1558,8 +1558,8 @@ def configure_ports(request, interface_instance, **_kwargs):
request,
(
_(
"Warning: the IPv4 isn't public, the opening won't have effect"
" in v4."
"Warning: the IP address is not public, the opening won't"
" have any effect in v4."
)
),
)
@ -1572,7 +1572,7 @@ def configure_ports(request, interface_instance, **_kwargs):
messages.success(request, _("The ports configuration was edited."))
return redirect(reverse("machines:index"))
return form(
{"interfaceform": interface, "action_name": _("Edit the" " configuration")},
{"interfaceform": interface, "action_name": _("Edit")},
"machines/machine.html",
request,
)

View file

@ -0,0 +1,128 @@
# 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-11-20 01:24+0100\n"
"PO-Revision-Date: 2019-11-16 00:22+0100\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\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"
#: multi_op/forms.py:43
msgid "Dormitory"
msgstr "Résidence"
#: multi_op/preferences/models.py:37
msgid "enabled dorm"
msgstr "résidence activée"
#: multi_op/preferences/models.py:41
msgid "dormitories preferences"
msgstr "préférences de résidences"
#: multi_op/templates/multi_op/aff_room_state.html:36
msgid "Room"
msgstr "Chambre"
#: multi_op/templates/multi_op/aff_room_state.html:37
msgid "Building"
msgstr "Bâtiment"
#: multi_op/templates/multi_op/aff_room_state.html:40
msgid "Connnected to"
msgstr "Connectée à"
#: multi_op/templates/multi_op/aff_room_state.html:41
msgid "User"
msgstr "Utilisateur"
#: multi_op/templates/multi_op/aff_room_state.html:42
msgid "Details"
msgstr "Détails"
#: multi_op/templates/multi_op/aff_room_state.html:43
msgid "End of subscription on"
msgstr "Fin de cotisation le"
#: multi_op/templates/multi_op/aff_room_state.html:44
msgid "Internet access"
msgstr "Accès Internet"
#: multi_op/templates/multi_op/aff_room_state.html:45
msgid "Action"
msgstr "Action"
#: multi_op/templates/multi_op/aff_room_state.html:52
msgid "Other operator"
msgstr "Autre opérateur"
#: multi_op/templates/multi_op/aff_room_state.html:53
msgid "None"
msgstr "Aucun"
#: multi_op/templates/multi_op/aff_room_state.html:55
msgid "Non member"
msgstr "Non adhérent"
#: multi_op/templates/multi_op/aff_room_state.html:58
msgid "Active"
msgstr "Actif"
#: multi_op/templates/multi_op/aff_room_state.html:60
msgid "Disabled"
msgstr "Désactivé"
#: multi_op/templates/multi_op/index_room_state.html:30
msgid "Multiple operators"
msgstr "Opérateurs multiples"
#: multi_op/templates/multi_op/index_room_state.html:38
msgid "Room connections"
msgstr "Connexions de chambre"
#: multi_op/templates/multi_op/index_room_state.html:44
msgid "Select dormitory"
msgstr "Sélectionnez la résidence"
#: multi_op/templates/multi_op/navbar.html:2
msgid "Manage the operators"
msgstr "Gérer les opérateurs"
#: multi_op/templates/multi_op/sidebar.html:31
msgid "Room connections state"
msgstr "État des connexions de chambre"
#: multi_op/templates/multi_op/sidebar.html:35
msgid "Sockets to connect"
msgstr "Prises à connecter"
#: multi_op/templates/multi_op/sidebar.html:39
msgid "Sockets to disconnect"
msgstr "Prises à déconnecter"
#: multi_op/views.py:169
#, python-format
msgid "The room %s was disconnected."
msgstr "La chambre %s a été déconnectée."

View file

@ -34,8 +34,8 @@ class Preferences(models.Model):
"topologie.Dormitory",
related_name="vlan_tagged",
blank=True,
verbose_name=_("Enabled dorm"),
verbose_name=_("enabled dorm"),
)
class Meta:
verbose_name = _("Dormitory of connection settings")
verbose_name = _("dormitories preferences")

View file

@ -37,7 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% trans "Building" as tr_building %}
<th>{% include 'buttons/sort.html' with prefix='building' col='name' text=tr_building %}</th>
<th>{% include 'buttons/sort.html' with prefix='room' col='name' text=tr_room %}</th>
<th>{% trans "Connnected on" %}</th>
<th>{% trans "Connnected to" %}</th>
<th>{% trans "User" %}</th>
<th>{% trans "Details" %}</th>
<th>{% trans "End of subscription on" %}</th>
@ -49,10 +49,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr>
<td>{{ room.building }}</td>
<td>{{ room.name }}</td>
<td>{% if room.port_set.all %}<span class="label label-success">AURORE{% else %}<span class="label label-danger">{% trans "Other operator" %}{% endif %}</span></td>
<td>{% if room.adherent %}<a href="{% url 'users:profil' room.adherent.id%}">{{ room.adherent }}</a>{% else %} {% trans "Aucun" %}{% endif %}</td>
<td>{% if room.port_set.all %}<span class="label label-success">{{ asso_name }}{% else %}<span class="label label-danger">{% trans "Other operator" %}{% endif %}</span></td>
<td>{% if room.adherent %}<a href="{% url 'users:profil' room.adherent.id%}">{{ room.adherent }}</a>{% else %} {% trans "None" %}{% endif %}</td>
<td>{{ room.details }}</td>
<td>{% if room.adherent.is_adherent %}<i class="text-success">{% else %}<i class="text-danger">{% endif %}{% if room.adherent.end_adhesion %}{{ room.adherent.end_adhesion}}{% else %}{% trans "No member" %}{% endif %}</i></td>
<td>{% if room.adherent.is_adherent %}<i class="text-success">{% else %}<i class="text-danger">{% endif %}{% if room.adherent.end_adhesion %}{{ room.adherent.end_adhesion}}{% else %}{% trans "Non member" %}{% endif %}</i></td>
<td>
{% if room.adherent.has_access == True %}
<i class="text-success">{% trans "Active" %}</i>

View file

@ -1,48 +0,0 @@
{% 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
quelques clics.
Copyright © 2017 Gabriel Détraz
Copyright © 2017 Goulven Kermarec
Copyright © 2017 Augustin Lemesle
Copyright © 2017 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.
{% endcomment %}
{% load bootstrap3 %}
{% load i18n %}
{% block title %}{% trans "Ticket" %}{% endblock %}
{% block content %}
<h2> {% trans "Tickets settings modification" %}</h2>
{% for message in messages %}
<div class="{{ message| bootstrap_message_classes }} alert-dismissable">
<button type="button" class="close" data_dismiss="alert" aria-hidden="true">&#125;</button>
{{ message | safe }}
</div>
{% endfor %}
<form class="form" method="post">
{% csrf_token %}
{% bootstrap_field preferencesform.publish_address %}
{% bootstrap_field preferencesform.mail_language %}
{% bootstrap_button "Editer" button_type="submit" icon='ok' button_class='btn-success' %}
</form>
{% endblock %}

View file

@ -1,58 +0,0 @@
{% 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
quelques clics.
Copyright © 2017 Gabriel Détraz
Copyright © 2017 Goulven Kermarec
Copyright © 2017 Augustin Lemesle
Copyright © 2017 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.
{% endcomment %}
{% load bootstrap3 %}
{% load massive_bootstrap_form %}
{% load i18n %}
{% block title %}{% trans "Ticket" %}{% endblock %}
{% block content %}
<h2> Ouverture d'un Ticket </h2>
<form class="form" method="post">
{% csrf_token %}
{% if not user.is_authenticated %}
<p>{% trans "Vous n'êtes pas authentifié. Veuillez fournir une adresse mail afin que nous puissions vous recontacter." %}</p>
{% bootstrap_field ticketform.email %}
{% endif %}
{% bootstrap_field ticketform.title %}
<br>
<p>{% trans "Description de votre problème. Veuillez fournir le plus d'informations possible afin de faciliter la recherche de solution. Voici quelques informations dont nous pourions avoir besoin:" %}</p>
<ul class="list">
<li>
<p> {% trans "Le type de votre problème (adhesion, connexion, paiement ou autre)." %}</p>
</li>
<li>
<p> {% trans "Les conditions dans lesquelles vous rencontrez le problème (Wifi/filaire, sur tout les apareils ou sur un seul. Est-ce une nouvelle machine ?" %}</p>
</li>
<li>
<p> {% trans "Les endroits dans lequels le problème survient (chez vous, dans une partie commune, dans un batiment en particulier)." %}</p>
</ul>
{% bootstrap_field ticketform.description %}
{% bootstrap_button "Ouvrir le Ticket" button_type="submit" icon='ok' button_class='btn-success' %}
</form>
{% endblock %}

View file

@ -1,34 +0,0 @@
{% extends 'users/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 i18n %}
{% block title%}{% trans "Tickets" %}{% endblock %}
{% block content %}
<h2>{% trans "Tickets" %}</h2>
{% include 'tickets/aff_tickets.html' with tickets_list=tickets_list %}
{% endblock %}

View file

@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% load acl %}
{% load i18n %}
{% block title %}{% trans "Multi Operators" %}{% endblock %}
{% block title %}{% trans "Multiple operators" %}{% endblock %}
{% block content %}
@ -35,17 +35,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% bootstrap_form_errors dormitory_form %}
{% endif %}
<h2>{% trans "Rooms connections" %}</h2>
<h2>{% trans "Room connections" %}</h2>
{% if dormitory_form %}
<form class="form" method="post">
{% csrf_token %}
{% bootstrap_form dormitory_form %}
{% bootstrap_button "Select Dormitory" icon='ok' button_class='btn-success' %}
{% trans "Select dormitory" as tr_select_dorm %}
{% bootstrap_button tr_select_dorm icon='ok' button_class='btn-success' %}
</form>
{% endif %}
{% include 'multi_op/aff_room_state.html' with room_list=room_list %}
{% include 'multi_op/aff_room_state.html' with room_list=room_list asso_name=asso_name %}
<br />
<br />
<br />

View file

@ -1,2 +1,2 @@
{% load i18n %}
<li><a href="{% url 'multi_op:aff-state-global' %}"><i class="fa fa-random"></i> {% trans "Multi Operators" %}</a></li>
<li><a href="{% url 'multi_op:aff-state-global' %}"><i class="fa fa-random"></i> {% trans "Manage the operators" %}</a></li>

View file

@ -1,6 +0,0 @@
{% load i18n %}
<li>
<a href="{% url 'tickets:new-ticket' %}">
<i class="fa fa-ticket"></i> {% trans "Ouvrir un ticket" %}
</a>
</li>

View file

@ -1,36 +0,0 @@
{% load i18n %}
<div class="panel panel-default" id="tickets">
<div class="panel-heading" data-toggle="collapse" href="#collapse_tickets">
<h4 class="panel-title">
<a><i class="fa fa-ticket"></i> {% trans "Tickets" %}</a>
</h4>
</div>
<div id="collapse_tickets" class="panel-collapse panel-body collapse">
<a class="btn btn-primary btn-sm" role="button" href="{% url 'tickets:edit-preferences-tickets' %}">
<i class="fa fa-edit"></i>
{% trans "Edit" %}
</a>
<p></p>
<div class="table-responsive">
<table class="table">
<tr>
<th><p>{% trans "Publication email address"%}</p></th>
{% if preferences.publish_address %}
<td><p>{{ preferences.publish_address }}</p></td>
{% else %}
<td><p>{% trans "Pas d'adresse, les tickets ne sont pas annoncés" %}</p></td>
{% endif %}
</tr>
<tr>
<th><p>{% trans "Email language" %}</p></th>
<td><p>{{ language }}</p></th>
</tr>
<table class="table">
</table>
</div>
</div>
</div>

View file

@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block sidebar %}
<a class="list-group-item list-group-item-info" href="{% url 'multi_op:aff-state-global' %}">
<i class="fa fa-random"></i>
{% trans "Rooms connection state" %}
{% trans "Room connections state" %}
</a>
<a class="list-group-item list-group-item-info" href="{% url 'multi_op:aff-pending-connection' %}">
<i class="fa fa-compress"></i>

View file

@ -41,7 +41,7 @@ from re2o.base import re2o_paginator, SortTable
from re2o.acl import can_view, can_view_all, can_edit, can_create
from preferences.models import GeneralOption
from preferences.models import GeneralOption, AssoOption
from .forms import DormitoryForm
@ -67,7 +67,15 @@ def display_rooms_connection(request, dormitory=None):
)
pagination_number = GeneralOption.get_cached_value("pagination_number")
room_list = re2o_paginator(request, room_list, pagination_number)
return render(request, "multi_op/index_room_state.html", {"room_list": room_list})
asso_name = AssoOption.get_cached_value("pseudo")
return render(
request,
"multi_op/index_room_state.html",
{
"room_list": room_list,
"asso_name": asso_name,
},
)
@login_required
@ -105,10 +113,15 @@ def aff_pending_connection(request):
)
pagination_number = GeneralOption.get_cached_value("pagination_number")
room_list = re2o_paginator(request, room_list, pagination_number)
asso_name = AssoOption.get_cached_value("pseudo")
return render(
request,
"multi_op/index_room_state.html",
{"room_list": room_list, "dormitory_form": dormitory_form},
{
"room_list": room_list,
"dormitory_form": dormitory_form,
"asso_name": asso_name,
},
)
@ -135,10 +148,15 @@ def aff_pending_disconnection(request):
)
pagination_number = GeneralOption.get_cached_value("pagination_number")
room_list = re2o_paginator(request, room_list, pagination_number)
asso_name = AssoOption.get_cached_value("pseudo")
return render(
request,
"multi_op/index_room_state.html",
{"room_list": room_list, "dormitory_form": dormitory_form},
{
"room_list": room_list,
"dormitory_form": dormitory_form,
"asso_name": asso_name,
},
)
@ -148,7 +166,7 @@ def disconnect_room(request, room, roomid):
"""Action of disconnecting a room"""
room.port_set.clear()
room.save()
messages.success(request, "Room %s disconnected" % room)
messages.success(request, _("The room %s was disconnected.") % room)
return redirect(reverse("multi_op:aff-pending-disconnection"))

View file

@ -41,6 +41,7 @@ def can_view(user):
can = user.has_module_perms("preferences")
return (
can,
None if can else _("You don't have the right to view this" " application."),
None if can else _("You don't have the right to view this"
" application."),
("preferences",),
)

View file

@ -81,13 +81,13 @@ class EditOptionalMachineForm(ModelForm):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(EditOptionalMachineForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields["password_machine"].label = _(
"Possibility to set a" " password per machine"
"Possibility to set a password per machine"
)
self.fields["max_lambdauser_interfaces"].label = _(
"Maximum number of" " interfaces" " allowed for a" " standard user"
"Maximum number of interfaces allowed for a standard user"
)
self.fields["max_lambdauser_aliases"].label = _(
"Maximum number of DNS" " aliases allowed for" " a standard user"
"Maximum number of DNS aliases allowed for a standard user"
)
self.fields["ipv6_mode"].label = _("IPv6 mode")
self.fields["create_machine"].label = _("Can create a machine")
@ -136,20 +136,20 @@ class EditGeneralOptionForm(ModelForm):
self.fields["general_message_fr"].label = _("General message in French")
self.fields["general_message_en"].label = _("General message in English")
self.fields["search_display_page"].label = _(
"Number of results" " displayed when" " searching"
"Number of results displayed when searching"
)
self.fields["pagination_number"].label = _(
"Number of items per page," " standard size (e.g." " users)"
"Number of items per page, standard size (e.g. users)"
)
self.fields["pagination_large_number"].label = _(
"Number of items per" " page, large size" " (e.g. machines)"
"Number of items per page, large size (e.g. machines)"
)
self.fields["req_expire_hrs"].label = _(
"Time before expiration of the" " reset password link (in" " hours)"
"Time before expiration of the reset password link (in hours)"
)
self.fields["site_name"].label = _("Website name")
self.fields["email_from"].label = _("Email address for automatic" " emailing")
self.fields["GTU_sum_up"].label = _("Summary of the General Terms of" " Use")
self.fields["email_from"].label = _("Email address for automatic emailing")
self.fields["GTU_sum_up"].label = _("Summary of the General Terms of Use")
self.fields["GTU"].label = _("General Terms of Use")
@ -171,7 +171,7 @@ class EditAssoOptionForm(ModelForm):
self.fields["telephone"].label = _("Telephone number")
self.fields["pseudo"].label = _("Usual name")
self.fields["utilisateur_asso"].label = _(
"Account used for editing" " from /admin"
"Account used for editing from /admin"
)
self.fields["description"].label = _("Description")
@ -187,10 +187,10 @@ class EditMailMessageOptionForm(ModelForm):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(EditMailMessageOptionForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields["welcome_mail_fr"].label = _(
"Message for the French" " welcome email"
"Message for the French welcome email"
)
self.fields["welcome_mail_en"].label = _(
"Message for the English" " welcome email"
"Message for the English welcome email"
)
@ -451,7 +451,7 @@ class DelDocumentTemplateForm(FormRevMixin, Form):
document_templates = forms.ModelMultipleChoiceField(
queryset=DocumentTemplate.objects.none(),
label=_("Available document templates"),
label=_("Current document templates"),
widget=forms.CheckboxSelectMultiple,
)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,289 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.23 on 2019-11-20 00:59
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import preferences.models
import re2o.aes_field
class Migration(migrations.Migration):
dependencies = [
('preferences', '0066_optionalmachine_default_dns_ttl'),
]
operations = [
migrations.AlterModelOptions(
name='assooption',
options={'permissions': (('view_assooption', 'Can view the organisation preferences'),), 'verbose_name': 'organisation preferences'},
),
migrations.AlterModelOptions(
name='cotisationsoption',
options={'verbose_name': 'subscription preferences'},
),
migrations.AlterModelOptions(
name='generaloption',
options={'permissions': (('view_generaloption', 'Can view the general preferences'),), 'verbose_name': 'general preferences'},
),
migrations.AlterModelOptions(
name='homeoption',
options={'permissions': (('view_homeoption', 'Can view the homepage preferences'),), 'verbose_name': 'homepage preferences'},
),
migrations.AlterModelOptions(
name='mailmessageoption',
options={'permissions': (('view_mailmessageoption', 'Can view the email message preferences'),), 'verbose_name': 'email message preferences'},
),
migrations.AlterModelOptions(
name='mandate',
options={'permissions': (('view_mandate', 'Can view a mandate object'),), 'verbose_name': 'mandate', 'verbose_name_plural': 'mandates'},
),
migrations.AlterModelOptions(
name='optionalmachine',
options={'permissions': (('view_optionalmachine', 'Can view the machine preferences'),), 'verbose_name': 'machine preferences'},
),
migrations.AlterModelOptions(
name='optionaltopologie',
options={'permissions': (('view_optionaltopologie', 'Can view the topology preferences'),), 'verbose_name': 'topology preferences'},
),
migrations.AlterModelOptions(
name='optionaluser',
options={'permissions': (('view_optionaluser', 'Can view the user preferences'),), 'verbose_name': 'user preferences'},
),
migrations.AlterModelOptions(
name='service',
options={'permissions': (('view_service', 'Can view the service preferences'),), 'verbose_name': 'service', 'verbose_name_plural': 'services'},
),
migrations.AlterField(
model_name='cotisationsoption',
name='invoice_template',
field=models.OneToOneField(default=preferences.models.default_invoice, on_delete=django.db.models.deletion.PROTECT, related_name='invoice_template', to='preferences.DocumentTemplate', verbose_name='template for invoices'),
),
migrations.AlterField(
model_name='cotisationsoption',
name='send_voucher_mail',
field=models.BooleanField(default=False, help_text='Be careful, if no mandate is defined on the preferences page, errors will be triggered when generating vouchers.', verbose_name='send voucher by email when the invoice is controlled'),
),
migrations.AlterField(
model_name='cotisationsoption',
name='voucher_template',
field=models.OneToOneField(default=preferences.models.default_voucher, on_delete=django.db.models.deletion.PROTECT, related_name='voucher_template', to='preferences.DocumentTemplate', verbose_name='template for subscription vouchers'),
),
migrations.AlterField(
model_name='generaloption',
name='general_message_en',
field=models.TextField(blank=True, default='', help_text='General message displayed on the English version of the website (e.g. in case of maintenance).'),
),
migrations.AlterField(
model_name='generaloption',
name='general_message_fr',
field=models.TextField(blank=True, default='', help_text='General message displayed on the French version of the website (e.g. in case of maintenance).'),
),
migrations.AlterField(
model_name='mailcontact',
name='address',
field=models.EmailField(default='contact@example.org', help_text='Contact email address.', max_length=254),
),
migrations.AlterField(
model_name='mailmessageoption',
name='welcome_mail_en',
field=models.TextField(blank=True, default='', help_text='Welcome email in English.'),
),
migrations.AlterField(
model_name='mailmessageoption',
name='welcome_mail_fr',
field=models.TextField(blank=True, default='', help_text='Welcome email in French.'),
),
migrations.AlterField(
model_name='mandate',
name='president',
field=models.ForeignKey(blank=True, help_text='Displayed on subscription vouchers.', null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='president of the association'),
),
migrations.AlterField(
model_name='optionalmachine',
name='default_dns_ttl',
field=models.PositiveIntegerField(default=172800, verbose_name='default Time To Live (TTL) for CNAME, A and AAAA records'),
),
migrations.AlterField(
model_name='optionalmachine',
name='ipv6_mode',
field=models.CharField(choices=[('SLAAC', 'Automatic configuration by RA'), ('DHCPV6', 'IP addresses assignment by DHCPv6'), ('DISABLED', 'Disabled')], default='DISABLED', max_length=32),
),
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='local_email_domain',
field=models.CharField(default='@example.org', help_text='Domain to use for local email accounts.', max_length=32),
),
migrations.AlterField(
model_name='radiusattribute',
name='attribute',
field=models.CharField(help_text='See https://freeradius.org/rfc/attributes.html.', max_length=255, verbose_name='attribute'),
),
migrations.AlterField(
model_name='radiusattribute',
name='comment',
field=models.TextField(blank=True, default='', help_text='Use this field to document this attribute.', verbose_name='comment'),
),
migrations.AlterField(
model_name='radiusattribute',
name='value',
field=models.CharField(max_length=255, verbose_name='value'),
),
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=False, help_text='Default key for switches.'),
),
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_attributes',
field=models.ManyToManyField(blank=True, help_text='Answer attributes for banned users.', related_name='banned_attribute', to='preferences.RadiusAttribute', verbose_name='banned users attributes'),
),
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_attributes',
field=models.ManyToManyField(blank=True, help_text='Answer attributes for non members.', related_name='non_member_attribute', to='preferences.RadiusAttribute', verbose_name='non members attributes'),
),
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='ok_attributes',
field=models.ManyToManyField(blank=True, help_text='Answer attributes for accepted users.', related_name='ok_attribute', to='preferences.RadiusAttribute', verbose_name='accepted users attributes'),
),
migrations.AlterField(
model_name='radiusoption',
name='radius_general_policy',
field=models.CharField(choices=[('MACHINE', "On the IP range's VLAN of the machine"), ('DEFINED', 'Preset in "VLAN for machines accepted by RADIUS"')], default='DEFINED', max_length=32),
),
migrations.AlterField(
model_name='radiusoption',
name='unknown_machine',
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 machines'),
),
migrations.AlterField(
model_name='radiusoption',
name='unknown_machine_attributes',
field=models.ManyToManyField(blank=True, help_text='Answer attributes for unknown machines.', related_name='unknown_machine_attribute', to='preferences.RadiusAttribute', verbose_name='unknown machines attributes'),
),
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_attributes',
field=models.ManyToManyField(blank=True, help_text='Answer attributes for unknown ports.', related_name='unknown_port_attribute', to='preferences.RadiusAttribute', verbose_name='unknown ports attributes'),
),
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_attributes',
field=models.ManyToManyField(blank=True, help_text='Answer attributes for unknown rooms.', related_name='unknown_room_attribute', to='preferences.RadiusAttribute', verbose_name='unknown rooms attributes'),
),
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.TextField(blank=True, default='', help_text='Message displayed specifically for this reminder.', 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),
),
]

View file

@ -95,16 +95,16 @@ class OptionalUser(AclMixin, PreferencesModel):
local_email_domain = models.CharField(
max_length=32,
default="@example.org",
help_text=_("Domain to use for local email accounts"),
help_text=_("Domain to use for local email accounts."),
)
max_email_address = models.IntegerField(
default=15,
help_text=_("Maximum number of local email addresses for a standard" " user."),
help_text=_("Maximum number of local email addresses for a standard user."),
)
delete_notyetactive = models.IntegerField(
default=15,
help_text=_(
"Not yet active users will be deleted after this number of" " days."
"Not yet active users will be deleted after this number of days."
),
)
self_adhesion = models.BooleanField(
@ -122,15 +122,15 @@ class OptionalUser(AclMixin, PreferencesModel):
)
class Meta:
permissions = (("view_optionaluser", _("Can view the user options")),)
verbose_name = _("user options")
permissions = (("view_optionaluser", _("Can view the user preferences")),)
verbose_name = _("user preferences")
def clean(self):
"""Clean model:
Check the mail_extension
"""
if self.local_email_domain[0] != "@":
raise ValidationError(_("Email domain must begin with @"))
raise ValidationError(_("Email domain must begin with @."))
@receiver(post_save, sender=OptionalUser)
@ -148,8 +148,8 @@ class OptionalMachine(AclMixin, PreferencesModel):
DHCPV6 = "DHCPV6"
DISABLED = "DISABLED"
CHOICE_IPV6 = (
(SLAAC, _("Autoconfiguration by RA")),
(DHCPV6, _("IP addresses assigning by DHCPv6")),
(SLAAC, _("Automatic configuration by RA")),
(DHCPV6, _("IP addresses assignment by DHCPv6")),
(DISABLED, _("Disabled")),
)
@ -159,7 +159,7 @@ class OptionalMachine(AclMixin, PreferencesModel):
ipv6_mode = models.CharField(max_length=32, choices=CHOICE_IPV6, default="DISABLED")
create_machine = models.BooleanField(default=True)
default_dns_ttl = models.PositiveIntegerField(
verbose_name=_("Default Time To Live (TTL) for CNAME, A and AAA records."),
verbose_name=_("default Time To Live (TTL) for CNAME, A and AAAA records"),
default=172800, # 2 days
)
@ -169,8 +169,8 @@ class OptionalMachine(AclMixin, PreferencesModel):
return not self.get_cached_value("ipv6_mode") == "DISABLED"
class Meta:
permissions = (("view_optionalmachine", _("Can view the machine options")),)
verbose_name = _("machine options")
permissions = (("view_optionalmachine", _("Can view the machine preferences")),)
verbose_name = _("machine preferences")
@receiver(post_save, sender=OptionalMachine)
@ -191,43 +191,43 @@ class OptionalTopologie(AclMixin, PreferencesModel):
DEFINED = "DEFINED"
CHOICE_RADIUS = (
(MACHINE, _("On the IP range's VLAN of the machine")),
(DEFINED, _("Preset in 'VLAN for machines accepted by RADIUS'")),
(DEFINED, _("Preset in \"VLAN for machines accepted by RADIUS\"")),
)
CHOICE_PROVISION = (("sftp", "sftp"), ("tftp", "tftp"))
CHOICE_PROVISION = (("sftp", "SFTP"), ("tftp", "TFTP"))
switchs_web_management = models.BooleanField(
default=False,
help_text=_("Web management, activated in case of automatic provision"),
help_text=_("Web management, activated in case of automatic provision."),
)
switchs_web_management_ssl = models.BooleanField(
default=False,
help_text=_(
"SSL web management, make sure that a certificate is"
" installed on the switch"
" installed on the switch."
),
)
switchs_rest_management = models.BooleanField(
default=False,
help_text=_("REST management, activated in case of automatic provision"),
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=_("IP range for the management of switches"),
help_text=_("IP range for the management of switches."),
)
switchs_provision = models.CharField(
max_length=32,
choices=CHOICE_PROVISION,
default="tftp",
help_text=_("Provision of configuration mode for switches"),
help_text=_("Provision of configuration mode for switches."),
)
sftp_login = models.CharField(
max_length=32, null=True, blank=True, help_text=_("SFTP login for switches")
max_length=32, null=True, blank=True, help_text=_("SFTP login for switches.")
)
sftp_pass = AESEncryptedField(
max_length=63, null=True, blank=True, help_text=_("SFTP password")
max_length=63, null=True, blank=True, help_text=_("SFTP password.")
)
@cached_property
@ -331,8 +331,8 @@ class OptionalTopologie(AclMixin, PreferencesModel):
)
class Meta:
permissions = (("view_optionaltopologie", _("Can view the topology options")),)
verbose_name = _("topology options")
permissions = (("view_optionaltopologie", _("Can view the topology preferences")),)
verbose_name = _("topology preferences")
@receiver(post_save, sender=OptionalTopologie)
@ -345,12 +345,12 @@ def optionaltopologie_post_save(**kwargs):
class RadiusKey(AclMixin, models.Model):
"""Class of a radius key"""
radius_key = AESEncryptedField(max_length=255, help_text=_("RADIUS key"))
radius_key = AESEncryptedField(max_length=255, help_text=_("RADIUS key."))
comment = models.CharField(
max_length=255, null=True, blank=True, help_text=_("Comment for this key")
max_length=255, null=True, blank=True, help_text=_("Comment for this key.")
)
default_switch = models.BooleanField(
default=False, help_text=_("Default key for switches")
default=False, help_text=_("Default key for switches.")
)
class Meta:
@ -363,7 +363,7 @@ class RadiusKey(AclMixin, models.Model):
Check default switch is unique
"""
if RadiusKey.objects.filter(default_switch=True).count() > 1:
raise ValidationError(_("Default radiuskey for switchs already exist"))
raise ValidationError(_("Default RADIUS key for switches already exists."))
def __str__(self):
return _("RADIUS key ") + str(self.id) + " " + str(self.comment)
@ -372,17 +372,17 @@ class RadiusKey(AclMixin, models.Model):
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=_("Switch login"))
management_pass = AESEncryptedField(max_length=63, help_text=_("Password"))
management_id = models.CharField(max_length=63, help_text=_("Switch login."))
management_pass = AESEncryptedField(max_length=63, help_text=_("Password."))
default_switch = models.BooleanField(
default=True, unique=True, help_text=_("Default credentials for switches")
default=True, unique=True, help_text=_("Default credentials for switches.")
)
class Meta:
permissions = (
(
"view_switchmanagementcred",
_("Can view a switch management" " credentials object"),
_("Can view a switch management credentials object"),
),
)
verbose_name = _("switch management credentials")
@ -400,13 +400,13 @@ class Reminder(AclMixin, models.Model):
days = models.IntegerField(
default=7,
unique=True,
help_text=_("Delay between the email and the membership's end"),
help_text=_("Delay between the email and the membership's end."),
)
message = models.TextField(
default="",
null=True,
blank=True,
help_text=_("Message displayed specifically for this reminder"),
help_text=_("Message displayed specifically for this reminder."),
)
class Meta:
@ -434,7 +434,7 @@ class GeneralOption(AclMixin, PreferencesModel):
blank=True,
help_text=_(
"General message displayed on the French version of the"
" website (e.g. in case of maintenance)"
" website (e.g. in case of maintenance)."
),
)
general_message_en = models.TextField(
@ -442,7 +442,7 @@ class GeneralOption(AclMixin, PreferencesModel):
blank=True,
help_text=_(
"General message displayed on the English version of the"
" website (e.g. in case of maintenance)"
" website (e.g. in case of maintenance)."
),
)
search_display_page = models.IntegerField(default=15)
@ -456,8 +456,8 @@ class GeneralOption(AclMixin, PreferencesModel):
GTU = models.FileField(upload_to="", default="", null=True, blank=True)
class Meta:
permissions = (("view_generaloption", _("Can view the general options")),)
verbose_name = _("general options")
permissions = (("view_generaloption", _("Can view the general preferences")),)
verbose_name = _("general preferences")
@receiver(post_save, sender=GeneralOption)
@ -477,7 +477,7 @@ class Service(AclMixin, models.Model):
image = models.ImageField(upload_to="logo", blank=True)
class Meta:
permissions = (("view_service", _("Can view the service options")),)
permissions = (("view_service", _("Can view the service preferences")),)
verbose_name = _("service")
verbose_name_plural = _("services")
@ -489,7 +489,7 @@ class MailContact(AclMixin, models.Model):
"""Contact email adress with a commentary."""
address = models.EmailField(
default="contact@example.org", help_text=_("Contact email address")
default="contact@example.org", help_text=_("Contact email address.")
)
commentary = models.CharField(
@ -516,17 +516,17 @@ class MailContact(AclMixin, models.Model):
class Mandate(RevMixin, AclMixin, models.Model):
class Meta:
verbose_name = _("Mandate")
verbose_name_plural = _("Mandates")
permissions = (("view_mandate", _("Can view a mandate")),)
verbose_name = _("mandate")
verbose_name_plural = _("mandates")
permissions = (("view_mandate", _("Can view a mandate object")),)
president = models.ForeignKey(
"users.User",
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name=_("President of the association"),
help_text=_("Displayed on subscription vouchers"),
verbose_name=_("president of the association"),
help_text=_("Displayed on subscription vouchers."),
)
start_date = models.DateTimeField(verbose_name=_("start date"))
end_date = models.DateTimeField(verbose_name=_("end date"), blank=True, null=True)
@ -542,7 +542,7 @@ class Mandate(RevMixin, AclMixin, models.Model):
)
if not mandate:
raise cls.DoesNotExist(
"No mandate have been created. Please go to the preferences page to create one."
_("No mandates have been created. Please go to the preferences page to create one.")
)
return mandate
@ -571,8 +571,8 @@ class AssoOption(AclMixin, PreferencesModel):
description = models.TextField(null=True, blank=True)
class Meta:
permissions = (("view_assooption", _("Can view the organisation options")),)
verbose_name = _("organisation options")
permissions = (("view_assooption", _("Can view the organisation preferences")),)
verbose_name = _("organisation preferences")
@receiver(post_save, sender=AssoOption)
@ -590,8 +590,8 @@ class HomeOption(AclMixin, PreferencesModel):
twitter_account_name = models.CharField(max_length=32, null=True, blank=True)
class Meta:
permissions = (("view_homeoption", _("Can view the homepage options")),)
verbose_name = _("homepage options")
permissions = (("view_homeoption", _("Can view the homepage preferences")),)
verbose_name = _("homepage preferences")
@receiver(post_save, sender=HomeOption)
@ -605,17 +605,17 @@ class MailMessageOption(AclMixin, models.Model):
"""Reglages, mail de bienvenue et autre"""
welcome_mail_fr = models.TextField(
default="", blank=True, help_text=_("Welcome email in French")
default="", blank=True, help_text=_("Welcome email in French.")
)
welcome_mail_en = models.TextField(
default="", blank=True, help_text=_("Welcome email in English")
default="", blank=True, help_text=_("Welcome email in English.")
)
class Meta:
permissions = (
("view_mailmessageoption", _("Can view the email message" " options")),
("view_mailmessageoption", _("Can view the email message preferences")),
)
verbose_name = _("email message options")
verbose_name = _("email message preferences")
class RadiusAttribute(RevMixin, AclMixin, models.Model):
@ -625,12 +625,12 @@ class RadiusAttribute(RevMixin, AclMixin, models.Model):
attribute = models.CharField(
max_length=255,
verbose_name=_("Attribute"),
help_text=_("See http://freeradius.org/rfc/attributes.html"),
verbose_name=_("attribute"),
help_text=_("See https://freeradius.org/rfc/attributes.html."),
)
value = models.CharField(max_length=255, verbose_name=_("Value"))
value = models.CharField(max_length=255, verbose_name=_("value"))
comment = models.TextField(
verbose_name=_("Comment"),
verbose_name=_("comment"),
help_text=_("Use this field to document this attribute."),
blank=True,
default="",
@ -649,7 +649,7 @@ class RadiusOption(AclMixin, PreferencesModel):
DEFINED = "DEFINED"
CHOICE_RADIUS = (
(MACHINE, _("On the IP range's VLAN of the machine")),
(DEFINED, _("Preset in 'VLAN for machines accepted by RADIUS'")),
(DEFINED, _("Preset in \"VLAN for machines accepted by RADIUS\"")),
)
REJECT = "REJECT"
SET_VLAN = "SET_VLAN"
@ -664,7 +664,7 @@ class RadiusOption(AclMixin, PreferencesModel):
max_length=32,
choices=CHOICE_POLICY,
default=REJECT,
verbose_name=_("Policy for unknown machines"),
verbose_name=_("policy for unknown machines"),
)
unknown_machine_vlan = models.ForeignKey(
"machines.Vlan",
@ -672,21 +672,21 @@ class RadiusOption(AclMixin, PreferencesModel):
related_name="unknown_machine_vlan",
blank=True,
null=True,
verbose_name=_("Unknown machines 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_machine_attributes = models.ManyToManyField(
RadiusAttribute,
related_name="unknown_machine_attribute",
blank=True,
verbose_name=_("Unknown machines attributes."),
verbose_name=_("unknown machines attributes"),
help_text=_("Answer attributes for unknown machines."),
)
unknown_port = models.CharField(
max_length=32,
choices=CHOICE_POLICY,
default=REJECT,
verbose_name=_("Policy for unknown ports"),
verbose_name=_("policy for unknown ports"),
)
unknown_port_vlan = models.ForeignKey(
"machines.Vlan",
@ -694,14 +694,14 @@ class RadiusOption(AclMixin, PreferencesModel):
related_name="unknown_port_vlan",
blank=True,
null=True,
verbose_name=_("Unknown ports 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_port_attributes = models.ManyToManyField(
RadiusAttribute,
related_name="unknown_port_attribute",
blank=True,
verbose_name=_("Unknown ports attributes."),
verbose_name=_("unknown ports attributes"),
help_text=_("Answer attributes for unknown ports."),
)
unknown_room = models.CharField(
@ -719,21 +719,21 @@ class RadiusOption(AclMixin, PreferencesModel):
on_delete=models.PROTECT,
blank=True,
null=True,
verbose_name=_("Unknown rooms VLAN"),
help_text=_("VLAN for unknown rooms if not rejected"),
verbose_name=_("unknown rooms VLAN"),
help_text=_("VLAN for unknown rooms if not rejected."),
)
unknown_room_attributes = models.ManyToManyField(
RadiusAttribute,
related_name="unknown_room_attribute",
blank=True,
verbose_name=_("Unknown rooms attributes."),
verbose_name=_("unknown rooms attributes"),
help_text=_("Answer attributes for unknown rooms."),
)
non_member = models.CharField(
max_length=32,
choices=CHOICE_POLICY,
default=REJECT,
verbose_name=_("Policy for non members"),
verbose_name=_("policy for non members"),
)
non_member_vlan = models.ForeignKey(
"machines.Vlan",
@ -741,21 +741,21 @@ class RadiusOption(AclMixin, PreferencesModel):
on_delete=models.PROTECT,
blank=True,
null=True,
verbose_name=_("Non members VLAN"),
help_text=_("VLAN for non members if not rejected"),
verbose_name=_("non members VLAN"),
help_text=_("VLAN for non members if not rejected."),
)
non_member_attributes = models.ManyToManyField(
RadiusAttribute,
related_name="non_member_attribute",
blank=True,
verbose_name=_("Non member attributes."),
verbose_name=_("non members attributes"),
help_text=_("Answer attributes for non members."),
)
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",
@ -763,14 +763,14 @@ class RadiusOption(AclMixin, PreferencesModel):
on_delete=models.PROTECT,
blank=True,
null=True,
verbose_name=_("Banned users VLAN"),
help_text=_("VLAN for banned users if not rejected"),
verbose_name=_("banned users VLAN"),
help_text=_("VLAN for banned users if not rejected."),
)
banned_attributes = models.ManyToManyField(
RadiusAttribute,
related_name="banned_attribute",
blank=True,
verbose_name=_("Banned attributes."),
verbose_name=_("banned users attributes"),
help_text=_("Answer attributes for banned users."),
)
vlan_decision_ok = models.OneToOneField(
@ -784,7 +784,7 @@ class RadiusOption(AclMixin, PreferencesModel):
RadiusAttribute,
related_name="ok_attribute",
blank=True,
verbose_name=_("Accepted users attributes."),
verbose_name=_("accepted users attributes"),
help_text=_("Answer attributes for accepted users."),
)
@ -812,26 +812,27 @@ def default_voucher():
class CotisationsOption(AclMixin, PreferencesModel):
class Meta:
verbose_name = _("cotisations options")
verbose_name = _("subscription preferences")
invoice_template = models.OneToOneField(
"preferences.DocumentTemplate",
verbose_name=_("Template for invoices"),
verbose_name=_("template for invoices"),
related_name="invoice_template",
on_delete=models.PROTECT,
default=default_invoice,
)
voucher_template = models.OneToOneField(
"preferences.DocumentTemplate",
verbose_name=_("Template for subscription voucher"),
verbose_name=_("template for subscription vouchers"),
related_name="voucher_template",
on_delete=models.PROTECT,
default=default_voucher,
)
send_voucher_mail = models.BooleanField(
verbose_name=_("Send voucher by email when the invoice is controlled."),
verbose_name=_("send voucher by email when the invoice is controlled"),
help_text=_(
"Be carefull, if no mandate is defined on the preferences page, errors will be triggered when generating vouchers."
"Be careful, if no mandate is defined on the preferences page,"
" errors will be triggered when generating vouchers."
),
default=False,
)

View file

@ -35,7 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% for mandate in mandate_list %}
<tr>
<td>{{mandate.start_date|date:"d/m/Y"}}</td>
<td>{% if mandate.end_date %}{{mandate.end_date|date:"d/m/Y"}}{% else %}{% trans "In progress." %}{% endif %}</td>
<td>{% if mandate.end_date %}{{mandate.end_date|date:"d/m/Y"}}{% else %}{% trans "In progress" %}{% endif %}</td>
<td><a href="{% url 'users:profil' userid=mandate.president.id %}">{{mandate.president.name}} {{mandate.president.surname}}</a></td>
<td class="text-right">
{% can_edit mandate%}

View file

@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<th>{% trans "RADIUS key ID" %}</th>
<th>{% trans "Comment" %}</th>
<th>{% trans "Default RADIUS key for switches" %}</th>
<th>{% trans "RADIUS key used by the swithes" %}</th>
<th>{% trans "Switches using the RADIUS key" %}</th>
<th></th>
<th></th>
</tr>

View file

@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr>
<th>{% trans "General policy for VLAN setting" %}</th>
<td>{{ radiusoptions.radius_general_policy }}</td>
<td>{% trans "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 accepted by RADIUS'" %}</td>
<td>{% blocktrans %}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 accepted by RADIUS".{% endblocktrans %}</td>
</tr>
<tr>
<th>{% trans "VLAN for machines accepted by RADIUS" %}</th>

View file

@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr>
<th>{% trans "Switch login" %}</th>
<th>{% trans "Default switch management credentials" %}</th>
<th>{% trans "Management credentials used by the switches" %}</th>
<th>{% trans "Switches using the management credentials" %}</th>
<th></th>
<th></th>
</tr>

View file

@ -125,7 +125,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr>
<th>{% trans "All users are active by default" %}</th>
<td>{{ useroptions.all_users_active|tick }}</td>
<th>{% trans "Allow archived users to log-in" %}</th>
<th>{% trans "Allow archived users to log in" %}</th>
<td>{{ useroptions.allow_archived_connexion|tick }}</td>
</tr>
</table>
@ -156,7 +156,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="panel panel-default" id="machines">
<div class="panel-heading" data-toggle="collapse" href="#collapse_machines">
<h4 class ="panel-title">
<a><i class="fa fa-desktop"></i> {% trans "Machines preferences" %}</a>
<a><i class="fa fa-desktop"></i> {% trans "Machine preferences" %}</a>
</h4>
</div>
@ -177,7 +177,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr>
<th>{% trans "Maximum number of DNS aliases allowed for a standard user" %}</th>
<td>{{ machineoptions.max_lambdauser_aliases }}</td>
<th>{% trans "Default Time To Live (TTL) for CNAME, A and AAA records." %}</th>
<th>{% trans "Default Time To Live (TTL) for CNAME, A and AAAA records." %}</th>
<td>{{ machineoptions.default_dns_ttl }}</td>
</tr>
<tr>
@ -282,7 +282,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% trans "Edit" %}
</a>
{% include 'preferences/aff_radiusoptions.html' %}
<h5>{% trans "Available RADIUS attributes"%}</h5>
<h5>{% trans "Current RADIUS attributes"%}</h5>
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:add-radiusattribute' %}"><i class="fa fa-plus"></i>{% trans "Add an attribute" %}</a>
{% include 'preferences/aff_radiusattributes.html' %}
</div>
@ -346,7 +346,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div id="collapse_templates" class="panel-collapse panel-body collapse">
{% can_create DocumentTemplate %}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:add-document-template' %}">
<i class="fa fa-cart-plus"></i> {% trans "Add a document template" %}
<i class="fa fa-plus"></i> {% trans "Add a document template" %}
</a>
{% acl_end %}
<a class="btn btn-danger btn-sm" role="button" href="{% url 'preferences:del-document-template' %}">
@ -359,7 +359,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="panel panel-default" id="cotisation">
<div class="panel-heading" data-toggle="collapse" href="#collapse_cotisation">
<h4 class="panel-title">
<a><i class="fa fa-eur"></i> {% trans "Cotisation's options" %}</a>
<a><i class="fa fa-eur"></i> {% trans "Subscription preferences" %}</a>
</h4>
</div>
<div id="collapse_cotisation" class="panel-collapse panel-body collapse">
@ -414,7 +414,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="panel panel-default" id="rappels">
<div class="panel-heading" data-toggle="collapse" href="#collapse_rappels">
<h4 class="panel-title">
<a><i class="fa fa-bell"></i> {% trans "Options for the membership's end email" %}</a>
<a><i class="fa fa-bell"></i> {% trans "Preferences for the membership's end email" %}</a>
</h4>
</div>
<div id="collapse_rappels" class="panel-collapse panel-body collapse">
@ -465,7 +465,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="panel panel-default" id="social">
<div class="panel-heading" data-toggle="collapse" href="#collapse_social">
<h4 class="panel-title">
<i class="fa fa-twitter"></i> {% trans "Social networks" %}</a>
<a><i class="fa fa-twitter"></i> {% trans "Social networks" %}</a>
</h4>
</div>
<div id="collapse_social" class="panel-collapse panel-body collapse">

View file

@ -191,7 +191,7 @@ def add_service(request):
messages.success(request, _("The service was added."))
return redirect(reverse("preferences:display-options"))
return form(
{"preferenceform": service, "action_name": _("Add a service")},
{"preferenceform": service, "action_name": _("Add")},
"preferences/preferences.html",
request,
)
@ -224,7 +224,7 @@ def del_service(request, service_instance, **_kwargs):
messages.success(request, _("The service was deleted."))
return redirect(reverse("preferences:display-options"))
return form(
{"objet": service_instance, "objet_name": "service"},
{"objet": service_instance, "objet_name": _("service")},
"preferences/delete.html",
request,
)
@ -240,7 +240,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 reminder")},
{"preferenceform": reminder, "action_name": _("Add")},
"preferences/preferences.html",
request,
)
@ -273,7 +273,7 @@ def del_reminder(request, reminder_instance, **_kwargs):
messages.success(request, _("The reminder was deleted."))
return redirect(reverse("preferences:display-options"))
return form(
{"objet": reminder_instance, "objet_name": "reminder"},
{"objet": reminder_instance, "objet_name": _("reminder")},
"preferences/delete.html",
request,
)
@ -289,7 +289,7 @@ def add_radiuskey(request):
messages.success(request, _("The RADIUS key was added."))
return redirect(reverse("preferences:display-options"))
return form(
{"preferenceform": radiuskey, "action_name": _("Add a RADIUS key")},
{"preferenceform": radiuskey, "action_name": _("Add")},
"preferences/preferences.html",
request,
)
@ -328,7 +328,7 @@ def del_radiuskey(request, radiuskey_instance, **_kwargs):
)
return redirect(reverse("preferences:display-options"))
return form(
{"objet": radiuskey_instance, "objet_name": "radiuskey"},
{"objet": radiuskey_instance, "objet_name": _("RADIUS key")},
"preferences/delete.html",
request,
)
@ -346,7 +346,7 @@ def add_switchmanagementcred(request):
return form(
{
"preferenceform": switchmanagementcred,
"action_name": _("Add switch management credentials"),
"action_name": _("Add"),
},
"preferences/preferences.html",
request,
@ -391,7 +391,7 @@ def del_switchmanagementcred(request, switchmanagementcred_instance, **_kwargs):
)
return redirect(reverse("preferences:display-options"))
return form(
{"objet": switchmanagementcred_instance, "objet_name": "switchmanagementcred"},
{"objet": switchmanagementcred_instance, "objet_name": _("switch management credentials")},
"preferences/delete.html",
request,
)
@ -409,7 +409,7 @@ def add_mailcontact(request):
return form(
{
"preferenceform": mailcontact,
"action_name": _("Add a contact email address"),
"action_name": _("Add"),
},
"preferences/preferences.html",
request,
@ -524,8 +524,8 @@ def del_document_template(request, instances):
messages.error(
request,
_(
"The document template %(document_template)s can't be deleted \
because it is currently being used."
"The document template %(document_template)s can't be"
" deleted because it is currently being used."
)
% {"document_template": document_template},
)
@ -551,7 +551,7 @@ def add_radiusattribute(request):
messages.success(request, _("The attribute was added."))
return redirect(reverse("preferences:display-options"))
return form(
{"preferenceform": attribute, "action_name": _("Add a RADIUS attribute")},
{"preferenceform": attribute, "action_name": _("Add")},
"preferences/preferences.html",
request,
)
@ -584,7 +584,7 @@ def del_radiusattribute(request, radiusattribute_instance, **_kwargs):
messages.success(request, _("The attribute was deleted."))
return redirect(reverse("preferences:display-options"))
return form(
{"objet": radiusattribute_instance, "objet_name": "attribute"},
{"objet": radiusattribute_instance, "objet_name": _("attribute")},
"preferences/delete.html",
request,
)
@ -600,7 +600,7 @@ def add_mandate(request):
messages.success(request, _("The mandate was added."))
return redirect(reverse("preferences:display-options"))
return form(
{"preferenceform": mandate, "action_name": _("Add a mandate")},
{"preferenceform": mandate, "action_name": _("Add")},
"preferences/preferences.html",
request,
)
@ -631,7 +631,7 @@ def del_mandate(request, mandate_instance, **_kwargs):
messages.success(request, _("The mandate was deleted."))
return redirect(reverse("preferences:display-options"))
return form(
{"objet": mandate_instance, "objet_name": "attribute"},
{"objet": mandate_instance, "objet_name": _("mandate")},
"preferences/delete.html",
request,
)

View file

@ -44,14 +44,14 @@ def acl_error_message(msg, permissions):
if permissions is None:
return msg
groups = ", ".join([g.name for g in get_group_having_permission(*permissions)])
message = msg or _("You don't have the right to edit" " this option.")
message = msg or _("You don't have the right to edit this option.")
if groups:
return (
message
+ _(" You need to be a member of one of those" " groups : %s") % groups
+ _("You need to be a member of one of these groups: %s.") % groups
)
else:
return message + " No group have the %s permission(s) !" % " or ".join(
return message + _("No group has the %s permission(s)!") % " or ".join(
[",".join(permissions[:-1]), permissions[-1]]
if len(permissions) > 2
else permissions
@ -190,7 +190,7 @@ ModelC)
for msg in error_messages:
messages.error(
request,
msg or _("You don't have the right to access" " this menu."),
msg or _("You don't have the right to access this menu."),
)
if request.user.id is not None:
return redirect(

View file

@ -96,9 +96,9 @@ def convert_datetime_format(format):
def get_input_formats_help_text(input_formats):
"""Returns a help text about the possible input formats"""
if len(input_formats) > 1:
help_text_template = "Format: {main} {more}"
help_text_template = _("Format: {main} {more}")
else:
help_text_template = "Format: {main}"
help_text_template = _("Format: {main}")
more_text_template = '<i class="fa fa-question-circle" title="{}"></i>'
help_text = help_text_template.format(
main=convert_datetime_format(input_formats[0]),

View file

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-05 19:48+0200\n"
"POT-Creation-Date: 2019-11-20 01:24+0100\n"
"PO-Revision-Date: 2018-03-31 16:09+0002\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n"
@ -30,15 +30,29 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: re2o/acl.py:142
#: re2o/acl.py:47
msgid "You don't have the right to edit this option."
msgstr "Vous n'avez pas le droit de modifier cette option."
#: re2o/acl.py:51
#, python-format
msgid "You need to be a member of one of these groups: %s."
msgstr "Vous devez être membre de l'un de ces groupes : %s."
#: re2o/acl.py:54
#, python-format
msgid "No group has the %s permission(s)!"
msgstr "Aucun groupe ne possède la ou les permissions %s !"
#: re2o/acl.py:167
msgid "Nonexistent entry."
msgstr "Entrée inexistante."
#: re2o/acl.py:159 re2o/acl.py:229
#: re2o/acl.py:193 re2o/acl.py:264
msgid "You don't have the right to access this menu."
msgstr "Vous n'avez pas le droit d'accéder à ce menu."
#: re2o/acl.py:279
#: re2o/acl.py:314
msgid "You don't have the right to edit the history."
msgstr "Vous n'avez pas le droit de modifier l'historique."
@ -50,57 +64,94 @@ msgstr "Ce domaine est déjà pris."
msgid "SMTP unreachable."
msgstr "SMTP injoignable."
#: re2o/mixins.py:111
#: re2o/base.py:99
#, python-brace-format
msgid "Format: {main} {more}"
msgstr "Format : {main} {more}"
#: re2o/base.py:101
#, python-brace-format
msgid "Format: {main}"
msgstr "Format : {main}"
#: re2o/mixins.py:113
#, python-format
msgid "You don't have the right to create a %s object."
msgstr "Vous n'avez pas le droit de créer un objet %s."
#: re2o/mixins.py:125
#: re2o/mixins.py:129
#, python-format
msgid "You don't have the right to edit a %s object."
msgstr "Vous n'avez pas le droit de modifier un objet %s."
#: re2o/mixins.py:139
#: re2o/mixins.py:145
#, python-format
msgid "You don't have the right to delete a %s object."
msgstr "Vous n'avez pas le droit de supprimer un objet %s."
#: re2o/mixins.py:153
#: re2o/mixins.py:161
#, python-format
msgid "You don't have the right to view every %s object."
msgstr "Vous n'avez pas le droit de voir tous les objets %s."
#: re2o/mixins.py:167
#: re2o/mixins.py:177
#, python-format
msgid "You don't have the right to view a %s object."
msgstr "Vous n'avez pas le droit de voir un objet %s."
#: re2o/settings.py:158
#: re2o/settings.py:150
msgid "English"
msgstr "Anglais"
#: re2o/settings.py:159
#: re2o/settings.py:150
msgid "French"
msgstr "Français"
#: re2o/templates/re2o/about.html:29 re2o/templates/re2o/about.html:35
#: re2o/templates/re2o/about.html:29 re2o/templates/re2o/about.html:54
msgid "About Re2o"
msgstr "À propos de Re2o"
#: re2o/templates/re2o/about.html:32
#, python-format
msgid "About %(AssoName)s"
msgstr "À propos de %(AssoName)s"
msgid "Legal notes"
msgstr "Mentions légales"
#: re2o/templates/re2o/about.html:36
#: re2o/templates/re2o/about.html:34
msgid "Legal entity"
msgstr "Entité légale"
#: re2o/templates/re2o/about.html:37
msgid "Registered office"
msgstr "Siège enregistré"
#: re2o/templates/re2o/about.html:41
msgid "SIRET: "
msgstr "SIRET : "
#: re2o/templates/re2o/about.html:43
msgid "Publication manager"
msgstr "Gestionnaire de publication"
#: re2o/templates/re2o/about.html:44
msgid "President of "
msgstr "Président de "
#: re2o/templates/re2o/about.html:46
msgid "General Terms of Use"
msgstr "Conditions Générales d'Utilisation"
#: re2o/templates/re2o/about.html:50
msgid "Additional information"
msgstr "Informations supplémentaires"
#: re2o/templates/re2o/about.html:55
msgid ""
"Re2o is an administration tool initiated by <a href=\"https://rezometz.org/"
"\">Rezo Metz</a> and a few members of other <a href=\"https://federez.net"
"\">FedeRez</a> associations around the summer 2016.<br /> It is intended to "
"be a tool independant from any network infrastructure so it can be setup in "
"be a tool independent 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 <a href=\"https://gitlab.federez.net/federez/"
"re2o/\">FedeRez gitlab</a>.<br /> Re2o's mainteners are volunteers mainly "
"re2o/\">FedeRez gitlab</a>.<br /> Re2o's maintainers are volunteers mainly "
"from French schools. <br /> 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."
@ -109,7 +160,7 @@ msgstr ""
"\">Rézo Metz</a> et quelques membres d'autres associations de <a href="
"\"https://federez.net\">FedeRez</a> autour de l'été 2016.<br /> Il se veut "
"être un outil indépendant de toute infrastructure réseau pour pouvoir être "
"installé en \"quelques étapes\". Cet outil est entièrement gratuit et est "
"installé en « quelques étapes ». Cet outil est entièrement gratuit et est "
"disponible sous licence GNU Public Licence v2 (GPLv2) sur le <a href="
"\"https://gitlab.federez.net/federez/re2o/\">gitlab de FedeRez</a>.<br />\n"
"Les mainteneurs de Re2o sont de fiers bénévoles venant principalement "
@ -119,35 +170,35 @@ msgstr ""
"développement, nous serons heureux de vous accueillir donc n'hésitez pas à "
"nous contacter et à venir nous aider à construire le futur de Re2o."
#: re2o/templates/re2o/about.html:55
#: re2o/templates/re2o/about.html:74
msgid "Contributors list"
msgstr "Liste des contributeurs"
#: re2o/templates/re2o/about.html:64
#: re2o/templates/re2o/about.html:83
msgid "Version information"
msgstr "Informations de versions"
#: re2o/templates/re2o/about.html:66
#: re2o/templates/re2o/about.html:85
#, python-format
msgid "<b>Remote URL</b>: %(git_info_remote)s"
msgstr "<b>URL distante</b> : %(git_info_remote)s"
#: re2o/templates/re2o/about.html:69
#: re2o/templates/re2o/about.html:88
#, python-format
msgid "<b>Branch</b>: %(git_info_branch)s"
msgstr "<b>Branche</b> : %(git_info_branch)s"
#: re2o/templates/re2o/about.html:72
#: re2o/templates/re2o/about.html:91
#, python-format
msgid "<b>Commit</b>: %(git_info_commit)s"
msgstr "<b>Commit</b> : %(git_info_commit)s"
#: re2o/templates/re2o/about.html:75
#: re2o/templates/re2o/about.html:94
#, python-format
msgid "<b>Commit date</b>: %(git_info_commit_date)s"
msgstr "<b>Date du commit</b> : %(git_info_commit_date)s"
#: re2o/templates/re2o/about.html:80
#: re2o/templates/re2o/about.html:99
msgid "Dependencies"
msgstr "Dépendances"
@ -265,11 +316,9 @@ msgid "Follow @%(twitter_account_name)s"
msgstr "Suivre @%(twitter_account_name)s"
#: re2o/urls.py:57
#, fuzzy
#| msgid "Home"
msgid "Homepage"
msgstr "Accueil"
msgstr "Page d'accueil"
#: re2o/views.py:89
#: re2o/views.py:96
msgid "Unable to get the information."
msgstr "Impossible d'obtenir l'information."

View file

@ -80,21 +80,21 @@ def hash_password_salt(hashed_password):
try:
digest = b64decode(hashed_password[6:])
except TypeError as error:
raise ValueError("b64 error for `hashed_password` : %s" % error)
raise ValueError("b64 error for `hashed_password`: %s." % error)
if len(digest) < 20:
raise ValueError("`hashed_password` too short")
raise ValueError("`hashed_password` too short.")
return digest[20:]
elif hashed_password.upper().startswith("{SMD5}"):
try:
digest = b64decode(hashed_password[7:])
except TypeError as error:
raise ValueError("b64 error for `hashed_password` : %s" % error)
raise ValueError("b64 error for `hashed_password`: %s." % error)
if len(digest) < 16:
raise ValueError("`hashed_password` too short")
raise ValueError("`hashed_password` too short.")
return digest[16:]
else:
raise ValueError(
"`hashed_password` should start with '{SSHA}' or '{CRYPT}' or '{SMD5}'"
"`hashed_password` should start with '{SSHA}' or '{CRYPT}' or '{SMD5}'."
)

View file

@ -64,7 +64,7 @@ class Command(BaseCommand):
for item in os.popen("git shortlog -s -n").read().split("\n")
if "\t" in item
]
self.stdout.write(self.style.SUCCESS("Exportation Successful"))
self.stdout.write(self.style.SUCCESS("Exportation successful!"))
with open("re2o/contributors.py", "w") as contrib_file:
content = self._contrib_file_generator(contributors)
contrib_file.write(content)

View file

@ -61,7 +61,7 @@ class FormRevMixin(object):
)
elif self.changed_data:
reversion.set_comment(
"Field(s) altered : %s"
"Field(s) edited: %s"
% ", ".join(field for field in self.changed_data)
)
return super(FormRevMixin, self).save(*args, **kwargs)

View file

@ -53,7 +53,7 @@ def get_user(pseudo):
raise CommandError("Invalid user.")
if len(user) > 1:
raise CommandError(
"Several users match this username. This SHOULD" " NOT happen."
"Several users match this username. This SHOULD NOT happen."
)
return user[0]
@ -95,5 +95,5 @@ def form_cli(Form, user, action, *args, **kwargs):
reversion.set_comment(action)
sys.stdout.write(
"%s : done. The edit may take several minutes to" " apply.\n" % action
"%s: done. The edit may take several minutes to apply.\n" % action
)

View file

@ -38,16 +38,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<p>{{ option.adresse1 | safe }}</p>
<p>{{ option.adresse2 | safe }}</p>
<p>SIRET : {{ option.siret | safe }}</p>
<p>{% trans "SIRET: " %}{{ option.siret | safe }}</p>
<h4>{% trans "Publication manager" %}</h4>
<p>{{ president }} - {% trans "President of " %} {{ option.pseudo }}</p>
<h4>{% trans "General conditions of use" %}</h4>
<h4>{% trans "General Terms of Use" %}</h4>
<p><a href='{{ gtu.url }}' download='CGU'>{{ gtu }}</a></p>
{% if option.description %}
<h4>Extra informations</h4>
<h4>{% trans "Additional information" %}</h4>
<p>{{ option.description | safe }}</p>
{% endif %}
@ -57,11 +57,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<a href="https://rezometz.org/">Rezo Metz</a> and a few
members of other <a href="https://federez.net">FedeRez</a> associations
around the summer 2016.<br />
It is intended to be a tool independant from any network infrastructure
It is intended to be a tool independent 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
<a href="https://gitlab.federez.net/federez/re2o/">FedeRez gitlab</a>.<br />
Re2o's mainteners are volunteers mainly from French schools. <br />
Re2o's maintainers are volunteers mainly from French schools. <br />
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.

View file

@ -88,7 +88,7 @@ def get_model(model_name):
app_label, name = splitted
except ValueError:
raise template.TemplateSyntaxError(
"%r is an inconsistent model name" % model_name
"%r is an inconsistent model name." % model_name
)
else:
app_label, name = None, splitted[0]
@ -101,7 +101,7 @@ def get_model(model_name):
content_type = ContentType.objects.get(model=name.lower())
except ContentType.DoesNotExist:
raise template.TemplateSyntaxError(
"%r is not a valid model for an acl tag" % model_name
"%r is not a valid model for an acl tag." % model_name
)
except ContentType.MultipleObjectsReturned:
raise template.TemplateSyntaxError(
@ -178,7 +178,7 @@ def get_callback(tag_name, obj=None):
True,
)
raise template.TemplateSyntaxError("%r tag is not a valid can_xxx tag" % tag_name)
raise template.TemplateSyntaxError("%r tag is not a valid can_xxx tag." % tag_name)
def acl_fct(callback, reverse):
@ -264,7 +264,7 @@ def acl_change_filter(parser, token):
args = tag_content[3:]
except ValueError:
raise template.TemplateSyntaxError(
"%r tag require at least 2 argument: the model and the field"
"%r tag require at least 2 argument: the model and the field."
% token.contents.split()[0]
)
@ -306,7 +306,7 @@ def acl_model_filter(parser, token):
args = tag_content[2:]
except ValueError:
raise template.TemplateSyntaxError(
"%r tag require at least 1 argument: the model" % token.contents.split()[0]
"%r tag require at least 1 argument: the model." % token.contents.split()[0]
)
model = get_model(model_name)
@ -345,7 +345,7 @@ def acl_instance_filter(parser, token):
args = tag_content[2:]
except ValueError:
raise template.TemplateSyntaxError(
"%r tag require at least 1 argument: the instance"
"%r tag require at least 1 argument: the instance."
% token.contents.split()[0]
)

View file

@ -46,7 +46,7 @@ from __future__ import unicode_literals
from django.conf import settings
from django.conf.urls import include, url
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ugettext_lazy as _
from django.views.generic import RedirectView
from .settings_local import OPTIONNAL_APPS_RE2O

View file

@ -34,7 +34,7 @@ CHOICES_USER = (
("1", _("Disabled")),
("2", _("Archived")),
("3", _("Not yet active")),
("4", _("Full archived")),
("4", _("Fully archived")),
)
CHOICES_AFF = (

View file

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-05 19:48+0200\n"
"POT-Creation-Date: 2019-11-19 23:43+0100\n"
"PO-Revision-Date: 2018-06-24 20:10+0200\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n"
@ -47,10 +47,8 @@ msgid "Not yet active"
msgstr "Pas encore adhéré"
#: search/forms.py:37
#, fuzzy
#| msgid "Archived"
msgid "Full archived"
msgstr "Archivés"
msgid "Fully archived"
msgstr "Complètement archivés"
#: search/forms.py:41
msgid "Users"
@ -84,12 +82,12 @@ msgstr "Ports"
msgid "Switches"
msgstr "Commutateurs réseau"
#: search/forms.py:61 search/forms.py:73 search/templates/search/search.html:29
#: search/forms.py:62 search/forms.py:77 search/templates/search/search.html:29
#: search/templates/search/search.html:48
msgid "Search"
msgstr "Rechercher"
#: search/forms.py:63 search/forms.py:75
#: search/forms.py:65 search/forms.py:80
msgid ""
"Use « » and «,» to specify distinct words, «\"query\"» for an exact search "
"and «\\» to escape a character."
@ -97,19 +95,19 @@ msgstr ""
"Utilisez « » et «,» pour spécifier différents mots, «\"query\"» pour une "
"recherche exacte et «\\» pour échapper un caractère."
#: search/forms.py:82
#: search/forms.py:88
msgid "Users filter"
msgstr "Filtre utilisateurs"
#: search/forms.py:89
#: search/forms.py:95
msgid "Display filter"
msgstr "Filtre affichage"
#: search/forms.py:97
#: search/forms.py:101
msgid "Start date"
msgstr "Date de début"
#: search/forms.py:101
#: search/forms.py:102
msgid "End date"
msgstr "Date de fin"
@ -159,10 +157,10 @@ msgstr "Pas de résultat"
#: search/templates/search/index.html:71
#, python-format
msgid "(Only the first %(max_result)s results are displayed in each category)"
msgid "Only the first %(max_result)s results are displayed in each category."
msgstr ""
"(Seulement les %(max_result)s premiers résultats sont affichés dans chaque "
"catégorie)"
"Seulement les %(max_result)s premiers résultats sont affichés dans chaque "
"catégorie."
#: search/templates/search/sidebar.html:31
msgid "Simple search"

View file

@ -68,7 +68,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if not users and not machines and not factures and not whitelists and not bans and not rooms and not ports and not switches %}
<h3>{% trans "No result" %}</h3>
{% else %}
<h6>{% blocktrans %}(Only the first {{ max_result }} results are displayed in each category){% endblocktrans %}</h6>
<h6>{% blocktrans %}Only the first {{ max_result }} results are displayed in each category.{% endblocktrans %}</h6>
{% endif %}
<br />
<br />

View file

@ -14,8 +14,7 @@ Copyright © 2019 Alexandre Iooss
{% block content %}
<div id="content-main">
<p>
{% blocktrans %}You are on the operator interface. Here you will be able to manage the network and users
from the top left menu. You can also go read the developer documentation.{% endblocktrans %}
{% blocktrans %}You are on the operator interface. Here you will be able to manage the network and users from the top left menu. You can also go read the developer documentation.{% endblocktrans %}
</p>
<p>
{% blocktrans %}To go back to the main site, click "View site" button in top right menu.{% endblocktrans %}
@ -26,12 +25,12 @@ Copyright © 2019 Alexandre Iooss
{% block sidebar %}
<div id="content-related">
<div class="module" id="recent-actions-module">
<h2>{% trans 'My account' %}</h2>
<h3>{% trans 'My recent actions' %}</h3>
<h2>{% trans "My account" %}</h2>
<h3>{% trans "Recent actions" %}</h3>
{% load log %}
{% get_admin_log 10 as admin_log for_user user %}
{% if not admin_log %}
<p>{% trans 'None available' %}</p>
<p>{% trans "None available" %}</p>
{% else %}
<ul class="actionlist">
{% for entry in admin_log %}
@ -46,7 +45,7 @@ Copyright © 2019 Alexandre Iooss
<span class="mini quiet">{% filter capfirst %}
{{ entry.content_type }}{% endfilter %}</span>
{% else %}
<span class="mini quiet">{% trans 'Unknown content' %}</span>
<span class="mini quiet">{% trans "Unknown content" %}</span>
{% endif %}
</li>
{% endfor %}

View file

@ -40,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<meta property="og:image" content="{% static 'images/logo_re2o.svg' %}"/>
<meta property="og:image:type" content="image/svg"/>
<meta property="og:image:alt" content="The Re2o logo"/>
<meta property="og:description" content="{% trans "Networking managing website endorsed by FedeRez." %}" />
<meta property="og:description" content="Networking managing website endorsed by FedeRez." />
{# Preload JavaScript #}
{% bootstrap_javascript %}
@ -142,7 +142,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<li><a href="{% url 'about' %}"><i class="fa fa-info-circle"></i> {% trans "About" %}</a></li>
<li><a href="{% url 'contact' %}"><i class="fa fa-at"></i> {% trans "Contact" %}</a></li>
{% comment %}
<li><a href="{% url 'tickets:new-ticket' %}"><i class="fa fa-ticket"></i> {% trans "Ouvrir un ticket" %}</a><li>
<li><a href="{% url 'tickets:new-ticket' %}"><i class="fa fa-ticket"></i> {% trans "Open a ticket" %}</a><li>
{% endcomment %}
</ul>
</li>
@ -284,7 +284,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<p class="pull-right">
<a href="#">{% trans "Back to top" %}</a>
</p>
<p>{{ name_website }} {% trans "powered by" %} Re2o 2016&ndash;2018</p>
<p>{{ name_website }} {% trans "powered by" %} Re2o 2016&ndash;2019</p>
<p>
{% blocktrans trimmed %}
Brought to you with <i class="fa fa-heart text-danger"></i>.

View file

@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% endcomment %}
{% load i18n %}
<a {% if class%}class="btn btn-info btn-sm"{% endif %} role="button" title="{% trans 'History' %}" href="{% url 'logs:history' application name id %}">
<i class="fa fa-history"></i> {% if text %}{% trans 'History' %}{% endif %}
<a {% if class%}class="btn btn-info btn-sm"{% endif %} role="button" title="{% trans "History" %}" href="{% url 'logs:history' application name id %}">
<i class="fa fa-history"></i> {% if text %}{% trans "History" %}{% endif %}
</a>

View file

@ -32,7 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<meta property="og:image" content="{% static 'images/logo_re2o.svg' %}"/>
<meta property="og:image:type" content="image/svg"/>
<meta property="og:image:alt" content="The Re2o logo"/>
<meta property="og:description" content="{% trans "Networking managing website endorsed by FedeRez." %}" />
<meta property="og:description" content="Networking managing website endorsed by FedeRez." />
<meta charset="utf-8">
<link rel="shortcut icon" type="image/svg" href="{% static 'images/logo_re2o.svg' %}">

View file

@ -38,7 +38,7 @@
</p>
<p>
<b>{% blocktrans trimmed %}An email has been automatically sent to the site administrators. Please avoid
spamming them by trigerring the same issue multiple times.{% endblocktrans %}</b>{% blocktrans trimmed %} The mail should
spamming them by trigerring the same issue multiple times.{% endblocktrans %}</b>{% blocktrans trimmed %} The email should
contains all the details necessary to understand what went wrong but if your help were
needed, you will probably be contacted by them.{% endblocktrans %}
</p>

View file

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-05 19:48+0200\n"
"POT-Creation-Date: 2019-11-19 23:43+0100\n"
"PO-Revision-Date: 2018-03-31 16:09+0002\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n"
@ -30,11 +30,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: templates/admin/base_site.html:65 templates/base.html:281
#: templates/admin/base_site.html:65 templates/base.html:288
msgid "powered by"
msgstr "propulsé par"
#: templates/admin/base_site.html:69 templates/base.html:289
#: templates/admin/base_site.html:69 templates/base.html:296
msgid ""
"This software is under the terms of the <a href=\"http://www.gnu.org/"
"licenses/gpl-2.0.txt\" target=\"_blank\" rel=\"nofollow\">GPLv2</a> License."
@ -45,41 +45,41 @@ msgstr ""
#: templates/admin/custom_index.html:11
#, python-format
msgid "Welcome to %(name_website)s"
msgstr ""
msgstr "Bienvenue sur %(name_website)s"
#: templates/admin/custom_index.html:17
msgid ""
"You are on the operator interface. Here you will be able to manage the "
"network and users\n"
" from the top left menu. You can also go read the developer "
"network and users from the top left menu. You can also go read the developer "
"documentation."
msgstr ""
"Vous êtes dans l'interface opérateur. Ici vous pourrez gérer le réseau et "
"les utilisateurs depuis le menu en haut à gauche. Vous pouvez aussi lire la "
"documentation du développeur."
#: templates/admin/custom_index.html:21
#: templates/admin/custom_index.html:20
msgid ""
"To go back to the main site, click \"View site\" button in top right menu."
msgstr ""
"Pour revenir au site principal, cliquez sur le bouton « Voir le site » dans "
"le menu en haut à droite."
#: templates/admin/custom_index.html:28
msgid "My account"
msgstr "Mon compte"
#: templates/admin/custom_index.html:29
msgid "My account"
msgid "Recent actions"
msgstr ""
#: templates/admin/custom_index.html:30
msgid "My recent actions"
msgstr ""
#: templates/admin/custom_index.html:34
#: templates/admin/custom_index.html:33
msgid "None available"
msgstr ""
#: templates/admin/custom_index.html:49
#: templates/admin/custom_index.html:48
msgid "Unknown content"
msgstr ""
#: templates/base.html:43 templates/errors/404.html:35
msgid "Networking managing website endorsed by FedeRez."
msgstr "Site de gestion de réseau soutenu par FedeRez."
#: templates/base.html:70 templates/registration/logged_out.html:11
#: templates/registration/password_change_done.html:11
#: templates/registration/password_change_form.html:11
@ -88,7 +88,7 @@ msgstr "Site de gestion de réseau soutenu par FedeRez."
#: templates/registration/password_reset_done.html:11
#: templates/registration/password_reset_form.html:11
msgid "Home"
msgstr "Accueil"
msgstr ""
#: templates/base.html:91
msgid "Users"
@ -110,139 +110,139 @@ msgstr "Gérer les machines"
msgid "Manage the subscriptions"
msgstr "Gérer les cotisations"
#: templates/base.html:112
#: templates/base.html:114
msgid "Topology"
msgstr "Topologie"
#: templates/base.html:114
#: templates/base.html:116
msgid "Switches"
msgstr "Commutateurs réseau"
#: templates/base.html:115
#: templates/base.html:117
msgid "Access points"
msgstr "Points d'accès sans fil"
#: templates/base.html:116
#: templates/base.html:118
msgid "Rooms"
msgstr "Chambres"
#: templates/base.html:121
#: templates/base.html:128
msgid "Statistics"
msgstr "Statistiques"
#: templates/base.html:126
msgid "Administration"
msgstr "Administration"
#: templates/base.html:133
msgid "Information and contact"
msgid "Administration"
msgstr ""
#: templates/base.html:135
#: templates/base.html:140
msgid "Information and contact"
msgstr "Informations et contact"
#: templates/base.html:142
msgid "About"
msgstr "À propos"
#: templates/base.html:136
#: templates/base.html:143
msgid "Contact"
msgstr "Contact"
#: templates/base.html:150
#: templates/base.html:157
msgid "Sign up"
msgstr "S'inscrire"
#: templates/base.html:156 templates/registration/login.html:29
#: templates/base.html:163 templates/registration/login.html:29
#: templates/registration/login.html:36
msgid "Log in"
msgstr "Se connecter"
msgstr ""
#: templates/base.html:164
#: templates/base.html:171
msgid "Search"
msgstr "Rechercher"
msgstr ""
#: templates/base.html:178
#: templates/base.html:185
msgid "My profile"
msgstr "Mon profil"
#: templates/base.html:179
#: templates/base.html:186
msgid "Log out"
msgstr "Se déconnecter"
msgstr ""
#: templates/base.html:214
#: templates/base.html:221
msgid "Username"
msgstr "Pseudo"
#: templates/base.html:218
#: templates/base.html:225
msgid "Room"
msgstr "Chambre"
#: templates/base.html:222
#: templates/base.html:229
msgid "Internet access"
msgstr "Accès Internet"
#: templates/base.html:225
#: templates/base.html:232
#, python-format
msgid "Until %(end_access_date)s"
msgstr "Jusqu'au %(end_access_date)s"
#: templates/base.html:227
#: templates/base.html:234
msgid "Disabled"
msgstr "Désactivé"
#: templates/base.html:232
#: templates/base.html:239
msgid "Membership"
msgstr "Adhésion"
#: templates/base.html:235
#: templates/base.html:242
#, python-format
msgid "Until %(end_adhesion_date)s"
msgstr "Jusqu'au %(end_adhesion_date)s"
#: templates/base.html:237
#: templates/base.html:244
msgid "Non member"
msgstr "Non adhérent"
#: templates/base.html:245
#: templates/base.html:252
msgid "View my profile"
msgstr "Voir mon profil"
#: templates/base.html:250
#: templates/base.html:257
msgid "You are not logged in."
msgstr "Vous n'êtes pas connecté."
#: templates/base.html:257
#: templates/base.html:264
#, python-format
msgid "%(nb)s active machine"
msgid_plural "%(nb)s active machines"
msgstr[0] "%(nb)s machine active"
msgstr[1] "%(nb)s machines actives"
#: templates/base.html:266
#: templates/base.html:273
msgid "View my machines"
msgstr "Voir mes machines"
#: templates/base.html:279
#: templates/base.html:286
msgid "Back to top"
msgstr "Retour en haut"
#: templates/base.html:283
#: templates/base.html:290
msgid "Brought to you with <i class=\"fa fa-heart text-danger\"></i>."
msgstr "Codé avec <i class=\"fa fa-heart text-danger\"></i>."
#: templates/base.html:286
#: templates/base.html:293
msgid "About this website"
msgstr "À propos de ce site"
#: templates/buttons/add.html:27
msgid "Add"
msgstr "Ajouter"
msgstr ""
#: templates/buttons/edit.html:27 tickets/templates/tickets/preferences.html:14
#: templates/buttons/edit.html:27
msgid "Edit"
msgstr "Modifier"
#: templates/buttons/history.html:26 templates/buttons/history.html:27
msgid "History"
msgstr "Historique"
msgstr ""
#: templates/buttons/setlang.html:34
msgid "Translation in development"
@ -258,7 +258,7 @@ msgstr "Tri décroissant"
#: templates/buttons/suppr.html:27
msgid "Delete"
msgstr "Supprimer"
msgstr ""
#: templates/errors/404.html:39
msgid "404 error: page not found"
@ -312,7 +312,7 @@ msgstr ""
#: templates/errors/500.html:41
msgid ""
"The mail should contains all the details necessary to understand what went "
"The email should contains all the details necessary to understand what went "
"wrong but if your help were needed, you will probably be contacted by them."
msgstr ""
" Le courrier électronique devrait contenir tous les détails nécessaires à la "
@ -360,10 +360,8 @@ msgid "Thanks for spending some quality time with the Web site today."
msgstr ""
#: templates/registration/logged_out.html:17
#, fuzzy
#| msgid "Log in"
msgid "Log in again"
msgstr "Se connecter"
msgstr ""
#: templates/registration/login.html:40
msgid "Forgotten password?"
@ -381,10 +379,8 @@ msgid "Password reset"
msgstr ""
#: templates/registration/password_reset_confirm.html:11
#, fuzzy
#| msgid "More information"
msgid "Password reset confirmation"
msgstr "Plus d'informations"
msgstr ""
#: templates/registration/password_reset_email.html:2
#, python-format
@ -405,186 +401,3 @@ msgstr ""
#, python-format
msgid "The %(site_name)s team"
msgstr ""
#: tickets/models.py:27
msgid "Title of the ticket"
msgstr ""
#: tickets/models.py:32
msgid "Description of the ticket"
msgstr ""
#: tickets/models.py:37
msgid "An email address to get back to you"
msgstr ""
#: tickets/models.py:43 tickets/templates/tickets/form_preferences.html:30
#: tickets/templates/tickets/form_ticket.html:31
msgid "Ticket"
msgstr ""
#: tickets/models.py:44 tickets/templates/tickets/aff_ticket.html:30
#: tickets/templates/tickets/aff_tickets.html:35
#: tickets/templates/tickets/index.html:29
#: tickets/templates/tickets/index.html:32
#: tickets/templates/tickets/navbar.html:2
#: tickets/templates/tickets/preferences.html:6
msgid "Tickets"
msgstr ""
#: tickets/models.py:75
msgid "You don't have the right to view other tickets than yours."
msgstr ""
#: tickets/models.py:84
msgid "You don't have the right to view the list of tickets."
msgstr ""
#: tickets/preferences/models.py:8
msgid ""
"Email address to publish the new tickets (leave empty for no publications)"
msgstr ""
#: tickets/preferences/models.py:14
msgid "Français"
msgstr ""
#: tickets/preferences/models.py:15
msgid "English"
msgstr ""
#: tickets/preferences/models.py:19
msgid "Ticket's settings"
msgstr ""
#: tickets/templates/tickets/aff_ticket.html:36
msgid "Solved"
msgstr ""
#: tickets/templates/tickets/aff_ticket.html:38
msgid "Not Solved"
msgstr ""
#: tickets/templates/tickets/aff_ticket.html:44
#, fuzzy
#| msgid "powered by"
msgid "Opened by"
msgstr "propulsé par"
#: tickets/templates/tickets/aff_ticket.html:50
msgid "Anonymous User"
msgstr ""
#: tickets/templates/tickets/aff_ticket.html:54
msgid "Response address: "
msgstr ""
#: tickets/templates/tickets/aff_ticket.html:54
msgid "Response to your ticket"
msgstr ""
#: tickets/templates/tickets/aff_ticket.html:59
msgid "Title:"
msgstr ""
#: tickets/templates/tickets/aff_ticket.html:60
msgid "Description"
msgstr ""
#: tickets/templates/tickets/aff_ticket.html:79
msgid "Tous les tickets"
msgstr ""
#: tickets/templates/tickets/aff_tickets.html:38
msgid "Not Solved Tickets"
msgstr ""
#: tickets/templates/tickets/aff_tickets.html:41
msgid "Last Ticket:"
msgstr ""
#: tickets/templates/tickets/contact.html:8
#, python-format
msgid ""
"If you are experiencing issues with the services offered by %(asso_name)s, "
"you can open a ticket that will be taken care of. If you want to contact us "
"on any other topic, please choose one address below."
msgstr ""
#: tickets/templates/tickets/contact.html:10
#: tickets/templates/tickets/navbar_logout.html:4
msgid "Ouvrir un ticket"
msgstr ""
#: tickets/templates/tickets/form_preferences.html:33
msgid "Tickets settings modification"
msgstr ""
#: tickets/templates/tickets/form_ticket.html:39
msgid ""
"Vous n'êtes pas authentifié. Veuillez fournir une adresse mail afin que nous "
"puissions vous recontacter."
msgstr ""
#: tickets/templates/tickets/form_ticket.html:44
msgid ""
"Description de votre problème. Veuillez fournir le plus d'informations "
"possible afin de faciliter la recherche de solution. Voici quelques "
"informations dont nous pourions avoir besoin:"
msgstr ""
#: tickets/templates/tickets/form_ticket.html:47
msgid "Le type de votre problème (adhesion, connexion, paiement ou autre)."
msgstr ""
#: tickets/templates/tickets/form_ticket.html:50
msgid ""
"Les conditions dans lesquelles vous rencontrez le problème (Wifi/filaire, "
"sur tout les apareils ou sur un seul. Est-ce une nouvelle machine ?"
msgstr ""
#: tickets/templates/tickets/form_ticket.html:53
msgid ""
"Les endroits dans lequels le problème survient (chez vous, dans une partie "
"commune, dans un batiment en particulier)."
msgstr ""
#: tickets/templates/tickets/preferences.html:21
msgid "Publication email address"
msgstr ""
#: tickets/templates/tickets/preferences.html:25
msgid "Pas d'adresse, les tickets ne sont pas annoncés"
msgstr ""
#: tickets/templates/tickets/preferences.html:29
msgid "Email language"
msgstr ""
#: tickets/templates/tickets/profil.html:6
msgid " Tickets"
msgstr ""
#: tickets/templates/tickets/profil.html:12
msgid " Open a Ticket"
msgstr ""
#: tickets/templates/tickets/profil.html:19
msgid "No tickets"
msgstr ""
#: tickets/views.py:83 tickets/views.py:87
msgid ""
"Your ticket has been succesfully open. We will take care of it as soon as "
"possible."
msgstr ""
#: tickets/views.py:90
msgid ""
"You are not authenticated. Please login or provide an email address so we "
"can get back to you."
msgstr ""
#: tickets/views.py:117 tickets/views.py:163
msgid "Never"
msgstr ""

View file

@ -8,11 +8,11 @@ Copyright © 2019 Alexandre Iooss
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'index' %}">{% trans 'Home' %}</a>
<a href="{% url 'index' %}">{% trans "Home" %}</a>
</div>
{% endblock %}
{% block content %}
<p>{% trans "Thanks for spending some quality time with the Web site today." %}</p>
<p><a href="{% url 'login' %}">{% trans 'Log in again' %}</a></p>
<p><a href="{% url 'login' %}">{% trans "Log in again" %}</a></p>
{% endblock %}

View file

@ -8,6 +8,6 @@ Copyright © 2019 Alexandre Iooss
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'index' %}">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password change' %}
<a href="{% url 'index' %}">{% trans "Home" %}</a> &rsaquo; {% trans "Password change" %}
</div>
{% endblock %}

View file

@ -8,6 +8,6 @@ Copyright © 2019 Alexandre Iooss
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'index' %}">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password change' %}
<a href="{% url 'index' %}">{% trans "Home" %}</a> &rsaquo; {% trans "Password change" %}
</div>
{% endblock %}

View file

@ -8,6 +8,6 @@ Copyright © 2019 Alexandre Iooss
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'index' %}">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}
<a href="{% url 'index' %}">{% trans "Home" %}</a> &rsaquo; {% trans "Password reset" %}
</div>
{% endblock %}

View file

@ -8,6 +8,6 @@ Copyright © 2019 Alexandre Iooss
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'index' %}">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset confirmation' %}
<a href="{% url 'index' %}">{% trans "Home" %}</a> &rsaquo; {% trans "Password reset confirmation" %}
</div>
{% endblock %}

View file

@ -8,6 +8,6 @@ Copyright © 2019 Alexandre Iooss
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'index' %}">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}
<a href="{% url 'index' %}">{% trans "Home" %}</a> &rsaquo; {% trans "Password reset" %}
</div>
{% endblock %}

View file

@ -8,6 +8,6 @@ Copyright © 2019 Alexandre Iooss
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'index' %}">{% trans 'Home' %}</a> &rsaquo; {% trans 'Password reset' %}
<a href="{% url 'index' %}">{% trans "Home" %}</a> &rsaquo; {% trans "Password reset" %}
</div>
{% endblock %}

View file

@ -0,0 +1,300 @@
# 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-11-20 01:24+0100\n"
"PO-Revision-Date: 2019-11-16 00:35+0100\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\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"
#: tickets/models.py:28
msgid "Title of the ticket."
msgstr "Titre du ticket."
#: tickets/models.py:32
msgid "Description of the ticket."
msgstr "Description du ticket."
#: tickets/models.py:38
msgid "An email address to get back to you."
msgstr "Une adresse mail pour vous recontacter."
#: tickets/models.py:43
msgid "Can view a ticket object"
msgstr "Peut voir un objet ticket"
#: tickets/models.py:44
msgid "ticket"
msgstr "ticket"
#: tickets/models.py:45
msgid "tickets"
msgstr "tickets"
#: tickets/models.py:49
#, python-format
msgid "Ticket from %(name)s. Date: %(date)s."
msgstr "Ticket de %(name)s. Date : %(date)s."
#: tickets/models.py:51
#, python-format
msgid "Anonymous ticket. Date: %s."
msgstr "Ticket anonyme. Date : %s."
#: tickets/models.py:82
msgid "You don't have the right to view other tickets than yours."
msgstr "Vous n'avez pas le droit de voir d'autres tickets que les vôtres."
#: tickets/models.py:94
msgid "You don't have the right to view the list of tickets."
msgstr "Vous n'avez pas le droit de voir la liste des tickets."
#: tickets/preferences/models.py:10
msgid ""
"Email address to publish the new tickets (leave empty for no publication)."
msgstr ""
"Adresse mail où publier les nouveaux tickets (laissez vide pour ne pas "
"publier)."
#: tickets/preferences/models.py:17
msgid "French"
msgstr "Français"
#: tickets/preferences/models.py:17
msgid "English"
msgstr "Anglais"
#: tickets/preferences/models.py:21
msgid "tickets preferences"
msgstr "préférences de tickets"
#: tickets/templates/tickets/aff_ticket.html:30
#: tickets/templates/tickets/contact.html:4
#: tickets/templates/tickets/index.html:29
#: tickets/templates/tickets/preferences.html:6
#: tickets/templates/tickets/profil.html:6
msgid "Tickets"
msgstr "Tickets"
#: tickets/templates/tickets/aff_ticket.html:34
#, python-format
msgid "Ticket #%(id)s"
msgstr "Ticket #%(id)s"
#: tickets/templates/tickets/aff_ticket.html:36
#: tickets/templates/tickets/aff_tickets.html:58
msgid "Solved"
msgstr "Résolu"
#: tickets/templates/tickets/aff_ticket.html:38
msgid "Not solved"
msgstr "Non résolu"
#: tickets/templates/tickets/aff_ticket.html:44
msgid "Opened by"
msgstr "Ouvert par"
#: tickets/templates/tickets/aff_ticket.html:50
msgid "Anonymous user"
msgstr "Utilisateur anonyme"
#: tickets/templates/tickets/aff_ticket.html:54
msgid "Response address: "
msgstr "Adresse de réponse : "
#: tickets/templates/tickets/aff_ticket.html:54
msgid "Response to your ticket"
msgstr "Réponse à votre ticket"
#: tickets/templates/tickets/aff_ticket.html:59
msgid "Title:"
msgstr "Titre :"
#: tickets/templates/tickets/aff_ticket.html:60
msgid "Description:"
msgstr "Description :"
#: tickets/templates/tickets/aff_ticket.html:68
msgid "Mark as solved"
msgstr "Marquer comme résolu"
#: tickets/templates/tickets/aff_ticket.html:71
msgid "Mark as not solved"
msgstr "Marquer comme non résolu"
#: tickets/templates/tickets/aff_ticket.html:81
msgid "All tickets"
msgstr "Tous les tickets"
#: tickets/templates/tickets/aff_tickets.html:35
#: tickets/templates/tickets/form_preferences.html:30
#: tickets/templates/tickets/form_ticket.html:31
msgid "Ticket"
msgid_plural "Tickets"
msgstr[0] "Ticket"
msgstr[1] "Tickets"
#: tickets/templates/tickets/aff_tickets.html:38
msgid "Ticket not solved"
msgid_plural "Tickets not solved"
msgstr[0] "Ticket non résolu"
msgstr[1] "Tickets non résolus"
#: tickets/templates/tickets/aff_tickets.html:41
msgid "Last ticket:"
msgstr "Dernier ticket :"
#: tickets/templates/tickets/aff_tickets.html:55
msgid "User"
msgstr "Utilisateur"
#: tickets/templates/tickets/aff_tickets.html:56
msgid "Title"
msgstr "Titre"
#: tickets/templates/tickets/aff_tickets.html:57
msgid "Date"
msgstr "Date"
#: tickets/templates/tickets/aff_tickets.html:70
msgid "Anonymous"
msgstr "Anonyme"
#: tickets/templates/tickets/contact.html:8
#, python-format
msgid ""
"If you are experiencing issues with the services offered by %(asso_name)s, "
"you can open a ticket that will be taken care of. If you want to contact us "
"on any other topic, please choose one address below."
msgstr ""
"Si vous rencontrez des problèmes avec les services proposés par "
"%(asso_name)s, vous pouvez ouvrir un ticket qui sera pris en compte. Si vous "
"voulez nous contacter pour n'importe quel autre sujet, veuillez choisir une "
"adresse ci-dessous."
#: tickets/templates/tickets/contact.html:10
#: tickets/templates/tickets/navbar_logout.html:4
#: tickets/templates/tickets/profil.html:12
msgid "Open a ticket"
msgstr "Ouvrir un ticket"
#: tickets/templates/tickets/form_preferences.html:33
msgid "Editing of tickets preferences"
msgstr "Modification des préférences de tickets"
#: tickets/templates/tickets/form_preferences.html:46
#: tickets/templates/tickets/preferences.html:14
msgid "Edit"
msgstr "Modifier"
#: tickets/templates/tickets/form_ticket.html:34
msgid "Ticket opening"
msgstr "Ouverture de ticket"
#: tickets/templates/tickets/form_ticket.html:39 tickets/views.py:88
msgid ""
"You are not authenticated. Please log in or provide an email address so we "
"can get back to you."
msgstr ""
"Vous n'êtes pas authentifié. Veuillez vous connecter ou fournir une adresse "
"mail pour que nous puissions vous recontacter."
#: tickets/templates/tickets/form_ticket.html:44
msgid ""
"Description of your problem. Please give as much information as possible to "
"help us searching for a solution. Here is some information we might need:"
msgstr ""
"Description de votre problème. Veuillez donner le plus d'informations "
"possible pour nous aider à chercher une solution. Voici quelques "
"informations dont nous pourrions avoir besoin :"
#: tickets/templates/tickets/form_ticket.html:47
msgid "The type of your problem (membership, connection, payment etc.)."
msgstr "Le type de votre problème (adhésion, connexion, paiement etc.)."
#: tickets/templates/tickets/form_ticket.html:50
msgid ""
"The conditions in which you encounter the problem (Wi-Fi/wired connection, "
"on every machines or only one, on a new machine etc.)."
msgstr ""
"Les conditions dans lesquelles vous rencontrez le problème (connexion Wi-Fi/"
"filaire, sur toutes les machines ou une seule, sur une nouvelle machine "
"etc.)."
#: tickets/templates/tickets/form_ticket.html:53
msgid ""
"The locations where you encounter the problem (in your room, in a common "
"space, in a specific building etc.)."
msgstr ""
"Les lieux où vous rencontrez le problème (dans votre chambre, dans un espace "
"commun, dans un bâtiment en particulier etc.)."
#: tickets/templates/tickets/form_ticket.html:56
msgid "Open the ticket"
msgstr "Ouvrir le ticket"
#: tickets/templates/tickets/index.html:32
msgid "List of tickets"
msgstr "Liste des tickets"
#: tickets/templates/tickets/navbar.html:2
msgid "Manage the tickets"
msgstr "Gérer les tickets"
#: tickets/templates/tickets/preferences.html:21
msgid "Publication email address"
msgstr "Adresse mail de publication"
#: tickets/templates/tickets/preferences.html:25
msgid "No email address, the tickets will not be published."
msgstr "Pas d'adresse mail, les tickets ne seront pas publiés."
#: tickets/templates/tickets/preferences.html:29
msgid "Email language"
msgstr "Langue du mail"
#: tickets/templates/tickets/profil.html:19
msgid "No tickets"
msgstr "Pas de tickets"
#: tickets/views.py:69 tickets/views.py:80
msgid ""
"Your ticket has been succesfully opened. We will take care of it as soon as "
"possible."
msgstr ""
"Votre ticket a bien été ouvert. Nous nous en occuperons dès que possible."
#: tickets/views.py:125 tickets/views.py:175
msgid "Never"
msgstr "Jamais"
#: tickets/views.py:152
msgid "The tickets preferences were edited."
msgstr "Les préférences de tickets ont été modifiées."
#: tickets/views.py:155
msgid "Invalid form."
msgstr "Formulaire invalide."

View file

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.23 on 2019-11-20 00:59
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tickets', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='preferences',
options={'verbose_name': 'tickets preferences'},
),
migrations.AlterModelOptions(
name='ticket',
options={'permissions': (('view_tickets', 'Can view a ticket object'),), 'verbose_name': 'ticket', 'verbose_name_plural': 'tickets'},
),
migrations.AlterField(
model_name='preferences',
name='mail_language',
field=models.IntegerField(choices=[(0, 'French'), (1, 'English')], default=0),
),
migrations.AlterField(
model_name='preferences',
name='publish_address',
field=models.EmailField(help_text='Email address to publish the new tickets (leave empty for no publication).', max_length=1000, null=True),
),
migrations.AlterField(
model_name='ticket',
name='description',
field=models.TextField(help_text='Description of the ticket.', max_length=3000),
),
migrations.AlterField(
model_name='ticket',
name='email',
field=models.EmailField(help_text='An email address to get back to you.', max_length=100, null=True),
),
migrations.AlterField(
model_name='ticket',
name='title',
field=models.CharField(help_text='Title of the ticket.', max_length=255),
),
]

View file

@ -25,30 +25,30 @@ class Ticket(AclMixin, models.Model):
null=True,
)
title = models.CharField(
max_length=255, help_text=_("Title of the ticket"), blank=False, null=False
max_length=255, help_text=_("Title of the ticket."), blank=False, null=False
)
description = models.TextField(
max_length=3000,
help_text=_("Description of the ticket"),
help_text=_("Description of the ticket."),
blank=False,
null=False,
)
date = models.DateTimeField(auto_now_add=True)
email = models.EmailField(
help_text=_("An email address to get back to you"), max_length=100, null=True
help_text=_("An email address to get back to you."), max_length=100, null=True
)
solved = models.BooleanField(default=False)
class Meta:
permissions = (("view_tickets", _("Can view a ticket object")),)
verbose_name = _("Ticket")
verbose_name_plural = _("Tickets")
verbose_name = _("ticket")
verbose_name_plural = _("tickets")
def __str__(self):
if self.user:
return "Ticket from {}. Date: {}".format(self.user.surname, self.date)
return _("Ticket from %(name)s. Date: %(date)s.").format(name=self.user.surname, date=self.date)
else:
return "Anonymous Ticket. Date: {}".format(self.date)
return _("Anonymous ticket. Date: %s.") % (self.date)
def publish_mail(self):
site_url = GeneralOption.objects.first().main_site_url
@ -57,7 +57,7 @@ class Ticket(AclMixin, models.Model):
lang = Preferences.objects.first().mail_language
if lang == 0:
obj = "Nouvelle ouverture de ticket"
obj = "Nouveau ticket ouvert"
template = loader.get_template("tickets/publication_mail_fr")
else:
obj = "New ticket opened"

View file

@ -7,15 +7,15 @@ class Preferences(models.Model):
publish_address = models.EmailField(
help_text=_(
"Email address to publish the new tickets (leave empty for no publications)"
"Email address to publish the new tickets (leave empty for no publication)."
),
max_length=1000,
null=True,
)
LANG_FR = 0
LANG_EN = 1
LANGUES = ((0, _("Français")), (1, _("English")))
LANGUES = ((0, _("French")), (1, _("English")))
mail_language = models.IntegerField(choices=LANGUES, default=LANG_FR)
class Meta:
verbose_name = _("Ticket's settings")
verbose_name = _("tickets preferences")

View file

@ -31,11 +31,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block content %}
<h2> Ticket #{{ticket.id}}
<h2>{% blocktrans with id=ticket.id %}Ticket #{{id}}{% endblocktrans %}
{% if ticket.solved %}
<span class="badge badge-success">{% trans "Solved" %}</span>
{% else %}
<span class="badge badge-danger">{% trans "Not Solved" %}</span>
<span class="badge badge-danger">{% trans "Not solved" %}</span>
{% endif %}
</h2>
@ -47,7 +47,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{{ ticket.user.get_full_name }}
</a>
{% else %}
{% trans "Anonymous User" %}
{% trans "Anonymous user" %}
{% endif %}
{{ ticket.date | naturalday}}.
{% if not ticket.user %}
@ -57,7 +57,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="panel-body">
<p><b>{% trans "Title:" %}</b> {{ticket.title}}</p>
<p><b>{% trans "Description" %}</b> {{ ticket.description }}</p>
<p><b>{% trans "Description:" %}</b> {{ ticket.description }}</p>
<div class="text-right">
<form class="form" method="post">
@ -65,9 +65,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% bootstrap_form changestatusform %}
{% if not ticket.solved %}
{% bootstrap_button "Mark as Solved" button_type="submit" button_class='btn-info' %}
{% trans "Mark as solved" as tr_mark_solved %}
{% bootstrap_button tr_mark_solved button_type="submit" button_class='btn-info' %}
{% else %}
{% bootstrap_button "Mark as not Solved" button_type="submit" button_class='btn-warning' %}
{% trans "Mark as not solved" as tr_mark_not_solved %}
{% bootstrap_button tr_mark_not_solved button_type="submit" button_class='btn-warning' %}
{% endif %}
</form>
</div>
@ -76,7 +78,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<div class="text-right">
<a type="button" href="{% url 'tickets:aff-tickets' %}" class="btn btn-primary"><p>{% trans "Tous les tickets" %}</p></a>
<a type="button" href="{% url 'tickets:aff-tickets' %}" class="btn btn-primary"><p>{% trans "All tickets" %}</p></a>
</div>
{% endblock %}

View file

@ -32,13 +32,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<hr class="col-sm-12">
<div class="row justify-content-start">
<div class="col-sm-4">
<span class="badge badge-light">{{ nbr_tickets }}</span> {% trans "Tickets" %}
<span class="badge badge-light">{{ nbr_tickets }}</span> {% blocktrans count nb=nbr_tickets %}Ticket{% plural %}Tickets{% endblocktrans %}
</div>
<div class="col-sm-4">
<span class="badge badge-light"> {{ nbr_tickets_unsolved }}</span>{% trans "Not Solved Tickets" %}
<span class="badge badge-light"> {{ nbr_tickets_unsolved }}</span> {% blocktrans count nb=nbr_tickets_unsolved %}Ticket not solved{% plural %}Tickets not solved{% endblocktrans %}
</div>
<div class="col-sm-4">
<span>{% trans "Last Ticket:" %} {{ last_ticket_date }}</span>
<span>{% trans "Last ticket:" %} {{ last_ticket_date }}</span>
</div>
</div>
<hr class="col-sm-12">
@ -52,10 +52,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<thead>
<tr>
<th scope="col"></th>
<th scope="col">User</th>
<th scope="col">Titre</th>
<th scope="col">Date</th>
<th scope="col">Résolu</th>
<th scope="col">{% trans "User" %}</th>
<th scope="col">{% trans "Title" %}</th>
<th scope="col">{% trans "Date" %}</th>
<th scope="col">{% trans "Solved" %}</th>
</tr>
{% for ticket in tickets_list %}
<tr>
@ -67,7 +67,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% if ticket.user %}
<td><a href="{% url 'users:profil' ticket.user.id%}" role="button">{{ ticket.user.get_short_name }}</a></td>
{% else %}
<td> Anonyme </td>
<td>{% trans "Anonymous" %}</td>
{% endif %}
<td>{{ ticket.title }}</td>
<td>{{ ticket.date }}</td>

View file

@ -1,13 +1,13 @@
{% load i18n %}
<div class="panel panel-info">
<div class="panel-heading"><h4>Tickets</h4></div>
<div class="panel-heading"><h4>{% trans "Tickets" %}</h4></div>
<div class="panel-body">
<div class="row">
<div class="col-sm-9">
{% blocktrans %}If you are experiencing issues with the services offered by {{asso_name}}, you can open a ticket that will be taken care of. If you want to contact us on any other topic, please choose one address below.{% endblocktrans %}
</div>
<div class="col-sm-3"><a class="btn btn-primary" href="{% url 'tickets:new-ticket' %}"><i class="fa fa-ticket"></i> {% trans "Ouvrir un ticket" %}</a></div>
<div class="col-sm-3"><a class="btn btn-primary" href="{% url 'tickets:new-ticket' %}"><i class="fa fa-ticket"></i> {% trans "Open a ticket" %}</a></div>
</div>
</div>
</div>

View file

@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block title %}{% trans "Ticket" %}{% endblock %}
{% block content %}
<h2> {% trans "Tickets settings modification" %}</h2>
<h2> {% trans "Editing of tickets preferences" %}</h2>
{% for message in messages %}
<div class="{{ message| bootstrap_message_classes }} alert-dismissable">
@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% csrf_token %}
{% bootstrap_field preferencesform.publish_address %}
{% bootstrap_field preferencesform.mail_language %}
{% bootstrap_button "Editer" button_type="submit" icon='ok' button_class='btn-success' %}
{% trans "Edit" as tr_edit %}
{% bootstrap_button tr_edit button_type="submit" icon='ok' button_class='btn-success' %}
</form>
{% endblock %}

View file

@ -1,4 +1,4 @@
{% extends 'machines/sidebar.html' %}
{% extends 'users/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,28 +31,29 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block title %}{% trans "Ticket" %}{% endblock %}
{% block content %}
<h2> Ouverture d'un Ticket </h2>
<h2>{% trans "Ticket opening" %}</h2>
<form class="form" method="post">
{% csrf_token %}
{% if not user.is_authenticated %}
<p>{% trans "Vous n'êtes pas authentifié. Veuillez fournir une adresse mail afin que nous puissions vous recontacter." %}</p>
<p>{% trans "You are not authenticated. Please log in or provide an email address so we can get back to you." %}</p>
{% bootstrap_field ticketform.email %}
{% endif %}
{% bootstrap_field ticketform.title %}
<br>
<p>{% trans "Description de votre problème. Veuillez fournir le plus d'informations possible afin de faciliter la recherche de solution. Voici quelques informations dont nous pourions avoir besoin:" %}</p>
<p>{% trans "Description of your problem. Please give as much information as possible to help us searching for a solution. Here is some information we might need:" %}</p>
<ul class="list">
<li>
<p> {% trans "Le type de votre problème (adhesion, connexion, paiement ou autre)." %}</p>
<p> {% trans "The type of your problem (membership, connection, payment etc.)." %}</p>
</li>
<li>
<p> {% trans "Les conditions dans lesquelles vous rencontrez le problème (Wifi/filaire, sur tout les apareils ou sur un seul. Est-ce une nouvelle machine ?" %}</p>
<p> {% trans "The conditions in which you encounter the problem (Wi-Fi/wired connection, on every machines or only one, on a new machine etc.)." %}</p>
</li>
<li>
<p> {% trans "Les endroits dans lequels le problème survient (chez vous, dans une partie commune, dans un batiment en particulier)." %}</p>
<p> {% trans "The locations where you encounter the problem (in your room, in a common space, in a specific building etc.)." %}</p>
</ul>
{% bootstrap_field ticketform.description %}
{% bootstrap_button "Ouvrir le Ticket" button_type="submit" icon='ok' button_class='btn-success' %}
{% trans "Open the ticket" as tr_open %}
{% bootstrap_button tr_open button_type="submit" icon='ok' button_class='btn-success' %}
</form>
{% endblock %}

View file

@ -29,6 +29,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block title%}{% trans "Tickets" %}{% endblock %}
{% block content %}
<h2>{% trans "Tickets" %}</h2>
<h2>{% trans "List of tickets" %}</h2>
{% include 'tickets/aff_tickets.html' with tickets_list=tickets_list %}
{% endblock %}

View file

@ -1,2 +1,2 @@
{% load i18n %}
<li><a href="{% url 'tickets:aff-tickets' %}"><i class="fa fa-ticket"></i> {% trans "Tickets" %}</a></li>
<li><a href="{% url 'tickets:aff-tickets' %}"><i class="fa fa-ticket"></i> {% trans "Manage the tickets" %}</a></li>

View file

@ -1,6 +1,6 @@
{% load i18n %}
<li>
<a href="{% url 'tickets:new-ticket' %}">
<i class="fa fa-ticket"></i> {% trans "Ouvrir un ticket" %}
<i class="fa fa-ticket"></i> {% trans "Open a ticket" %}
</a>
</li>

View file

@ -22,7 +22,7 @@
{% if preferences.publish_address %}
<td><p>{{ preferences.publish_address }}</p></td>
{% else %}
<td><p>{% trans "Pas d'adresse, les tickets ne sont pas annoncés" %}</p></td>
<td><p>{% trans "No email address, the tickets will not be published." %}</p></td>
{% endif %}
</tr>
<tr>

View file

@ -9,7 +9,7 @@
<div id="ticket" class="panel-collapse collapse">
<div class="panel-body">
<a class="btn btn-primary btn-sm" role="button" href="{% url 'tickets:new-ticket' %}">
<i class="fa fa-ticket"></i>{% trans " Open a Ticket" %}
<i class="fa fa-ticket"></i> {% trans "Open a ticket" %}
</a>
</div>
<div class="panel-body">

View file

@ -1,5 +1,5 @@
{% if ticket.user %} {{ ticket.user.get_full_name }} opened a ticket.
Profil: {{site_url}}{% url 'users:profil' ticket.user.id%}
Profile: {{site_url}}{% url 'users:profil' ticket.user.id%}
Answer to the address: {{ticket.user.get_mail}}.
{% else %}

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