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

Merge branch 'improve_user_history' into 'dev'

Improve user history

See merge request re2o/re2o!516
This commit is contained in:
klafyvel 2020-04-23 17:06:12 +02:00
commit 5b42ca8cbe
17 changed files with 516 additions and 168 deletions

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-22 19:00+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2019-01-07 01:37+0100\n" "PO-Revision-Date: 2019-01-07 01:37+0100\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n" "Language-Team: \n"

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-22 19:00+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2018-03-31 16:09+0002\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language: fr_FR\n" "Language: fr_FR\n"

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-22 19:00+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2018-06-23 16:01+0200\n" "PO-Revision-Date: 2018-06-23 16:01+0200\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n" "Language-Team: \n"
@ -58,6 +58,20 @@ msgstr "Date de début"
msgid "End date" msgid "End date"
msgstr "Date de fin" msgstr "Date de fin"
#: logs/models.py:238 logs/models.py:263
msgid "None"
msgstr "Aucun(e)"
#: logs/models.py:248
msgid "Deleted"
msgstr "Supprimé(e)"
#: logs/models.py:255 logs/models.py:260
#: logs/templates/logs/machine_history.html:55
#: logs/templates/logs/user_history.html:51
msgid "Unknown"
msgstr "Inconnu(e)"
#: logs/templates/logs/aff_stats_logs.html:36 #: logs/templates/logs/aff_stats_logs.html:36
msgid "Edited object" msgid "Edited object"
msgstr "Objet modifié" msgstr "Objet modifié"
@ -77,6 +91,7 @@ msgstr "Date de modification"
#: logs/templates/logs/aff_stats_logs.html:42 #: logs/templates/logs/aff_stats_logs.html:42
#: logs/templates/logs/machine_history.html:39 #: logs/templates/logs/machine_history.html:39
#: logs/templates/logs/user_history.html:39
msgid "Comment" msgid "Comment"
msgstr "Commentaire" msgstr "Commentaire"
@ -113,6 +128,7 @@ msgid "Rank"
msgstr "Rang" msgstr "Rang"
#: logs/templates/logs/aff_summary.html:37 #: logs/templates/logs/aff_summary.html:37
#: logs/templates/logs/user_history.html:36
msgid "Date" msgid "Date"
msgstr "Date" msgstr "Date"
@ -196,15 +212,11 @@ msgstr "Résultats de la recherche"
msgid "User" msgid "User"
msgstr "Utilisateur" msgstr "Utilisateur"
#: logs/templates/logs/machine_history.html:55
msgid "Unknown"
msgstr "Inconnu(e)"
#: logs/templates/logs/machine_history.html:62 #: logs/templates/logs/machine_history.html:62
msgid "Now" msgid "Now"
msgstr "Maintenant" msgstr "Maintenant"
#: logs/templates/logs/machine_history.html:70 #: logs/templates/logs/machine_history.html:71
msgid "No result" msgid "No result"
msgstr "Aucun résultat" msgstr "Aucun résultat"
@ -253,6 +265,27 @@ msgstr "Statistiques sur la base de données"
msgid "Statistics about users" msgid "Statistics about users"
msgstr "Statistiques sur les utilisateurs" msgstr "Statistiques sur les utilisateurs"
#: logs/templates/logs/user_history.html:27
msgid "History"
msgstr "Historique"
#: logs/templates/logs/user_history.html:30
#, python-format
msgid "History of %(user)s"
msgstr "Historique de %(user)s"
#: logs/templates/logs/user_history.html:37
msgid "Performed by"
msgstr "Effectué(e) par"
#: logs/templates/logs/user_history.html:38
msgid "Edited"
msgstr "Modifié"
#: logs/templates/logs/user_history.html:74
msgid "No event"
msgstr "Aucun évènement"
#: logs/views.py:178 #: logs/views.py:178
msgid "Nonexistent revision." msgid "Nonexistent revision."
msgstr "Révision inexistante." msgstr "Révision inexistante."
@ -377,14 +410,14 @@ msgstr "droits"
msgid "actions" msgid "actions"
msgstr "actions" msgstr "actions"
#: logs/views.py:529 #: logs/views.py:554
msgid "No model found." msgid "No model found."
msgstr "Aucun modèle trouvé." msgstr "Aucun modèle trouvé."
#: logs/views.py:535 #: logs/views.py:560
msgid "Nonexistent entry." msgid "Nonexistent entry."
msgstr "Entrée inexistante." msgstr "Entrée inexistante."
#: logs/views.py:542 #: logs/views.py:567
msgid "You don't have the right to access this menu." msgid "You don't have the right to access this menu."
msgstr "Vous n'avez pas le droit d'accéder à ce menu." msgstr "Vous n'avez pas le droit d'accéder à ce menu."

View file

@ -22,14 +22,19 @@
The models definitions for the logs app The models definitions for the logs app
""" """
from reversion.models import Version from reversion.models import Version
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import Group
from machines.models import IpList from machines.models import IpList
from machines.models import Interface from machines.models import Interface
from machines.models import Machine from machines.models import Machine
from users.models import User from users.models import User
from users.models import Adherent
from users.models import Club
from topologie.models import Room
class HistoryEvent: class MachineHistoryEvent:
def __init__(self, user, machine, interface, start=None, end=None): def __init__(self, user, machine, interface, start=None, end=None):
""" """
:param user: User, The user owning the maching at the time of the event :param user: User, The user owning the maching at the time of the event
@ -80,7 +85,7 @@ class MachineHistory:
""" """
:param search: ip or mac to lookup :param search: ip or mac to lookup
:param params: dict built by the search view :param params: dict built by the search view
:return: list or None, a list of HistoryEvent :return: list or None, a list of MachineHistoryEvent
""" """
self.start = params.get("s", None) self.start = params.get("s", None)
self.end = params.get("e", None) self.end = params.get("e", None)
@ -101,7 +106,7 @@ class MachineHistory:
:param machine: Version, the machine version related to the interface :param machine: Version, the machine version related to the interface
:param interface: Version, the interface targeted by this event :param interface: Version, the interface targeted by this event
""" """
evt = HistoryEvent(user, machine, interface) evt = MachineHistoryEvent(user, machine, interface)
evt.start_date = interface.revision.date_created evt.start_date = interface.revision.date_created
# Try not to recreate events if it's unnecessary # Try not to recreate events if it's unnecessary
@ -177,7 +182,7 @@ class MachineHistory:
def __get_by_ip(self, ip): def __get_by_ip(self, ip):
""" """
:param ip: str, The IP to lookup :param ip: str, The IP to lookup
:returns: list, a list of HistoryEvent :returns: list, a list of MachineHistoryEvent
""" """
interfaces = self.__get_interfaces_for_ip(ip) interfaces = self.__get_interfaces_for_ip(ip)
@ -193,7 +198,7 @@ class MachineHistory:
def __get_by_mac(self, mac): def __get_by_mac(self, mac):
""" """
:param mac: str, The MAC address to lookup :param mac: str, The MAC address to lookup
:returns: list, a list of HistoryEvent :returns: list, a list of MachineHistoryEvent
""" """
interfaces = self.__get_interfaces_for_mac(mac) interfaces = self.__get_interfaces_for_mac(mac)
@ -205,3 +210,205 @@ class MachineHistory:
self.__add_revision(user, machine, interface) self.__add_revision(user, machine, interface)
return self.events return self.events
class UserHistoryEvent:
def __init__(self, user, version, previous_version=None, edited_fields=None):
"""
:param user: User, The user who's history is being built
:param version: Version, the version of the user for this event
:param previous_version: Version, the version of the user before this event
:param edited_fields: list, The list of modified fields by this event
"""
self.user = user
self.version = version
self.previous_version = previous_version
self.edited_fields = edited_fields
self.date = version.revision.date_created
self.performed_by = version.revision.user
self.comment = version.revision.get_comment() or None
def __repr(self, name, value):
"""
Returns the best representation of the given field
:param name: the name of the field
:param value: the value of the field
:return: object
"""
if name == "groups":
if len(value) == 0:
# Removed all the user's groups
return _("None")
# value is a list of ints
groups = []
for gid in value:
# Try to get the group name, if it's not deleted
try:
groups.append(Group.objects.get(id=gid).name)
except Group.DoesNotExist:
# TODO: Find the group name in the versions?
groups.append("{} ({})".format(_("Deleted"), gid))
return ", ".join(groups)
elif name == "state":
if value is not None:
return User.STATES[value][1]
else:
return _("Unknown")
elif name == "email_state":
if value is not None:
return User.EMAIL_STATES[value][1]
else:
return _("Unknown")
elif name == "room_id" and value is not None:
# Try to get the room name, if it's not deleted
try:
return Room.objects.get(id=value)
except Room.DoesNotExist:
# TODO: Find the room name in the versions?
return "{} ({})".format(_("Deleted"), value)
elif name == "members" or name == "administrators":
if len(value) == 0:
# Removed all the club's members
return _("None")
# value is a list of ints
users = []
for uid in value:
# Try to get the user's name, if theyr're not deleted
try:
users.append(User.objects.get(id=uid).pseudo)
except User.DoesNotExist:
# TODO: Find the user's name in the versions?
users.append("{} ({})".format(_("Deleted"), uid))
return ", ".join(users)
if value is None:
return _("None")
return value
def edits(self, hide=["password", "pwd_ntlm", "gpg_fingerprint"]):
"""
Build a list of the changes performed during this event
:param hide: list, the list of fields for which not to show details
:return: str
"""
edits = []
for field in self.edited_fields:
if field in hide:
# Don't show sensitive information
edits.append((field, None, None))
else:
edits.append((
field,
self.__repr(field, self.previous_version.field_dict[field]),
self.__repr(field, self.version.field_dict[field])
))
return edits
def __eq__(self, other):
return (
self.user.id == other.user.id
and self.edited_fields == other.edited_fields
and self.date == other.date
and self.performed_by == other.performed_by
and self.comment == other.comment
)
def __hash__(self):
return hash((self.user.id, frozenset(self.edited_fields), self.date, self.performed_by, self.comment))
def __repr__(self):
return "{} edited fields {} of {} ({})".format(
self.performed_by,
self.edited_fields or "nothing",
self.user,
self.comment or "No comment"
)
class UserHistory:
def __init__(self):
self.events = []
self.__last_version = None
def get(self, user):
"""
:param user: User, the user to lookup
:return: list or None, a list of UserHistoryEvent, in reverse chronological order
"""
self.events = []
# Find whether this is a Club or an Adherent
try:
obj = Adherent.objects.get(user_ptr_id=user.id)
except Adherent.DoesNotExist:
obj = Club.objects.get(user_ptr_id=user.id)
# Get all the versions for this user, with the oldest first
self.__last_version = None
user_versions = filter(
lambda x: x.field_dict["id"] == user.id,
Version.objects.get_for_model(User).order_by("revision__date_created")
)
for version in user_versions:
self.__add_revision(user, version)
# Do the same thing for the Adherent of Club
self.__last_version = None
obj_versions = filter(
lambda x: x.field_dict["id"] == obj.id,
Version.objects.get_for_model(type(obj)).order_by("revision__date_created")
)
for version in obj_versions:
self.__add_revision(user, version)
# Remove duplicates and sort
self.events = list(dict.fromkeys(self.events))
return sorted(
self.events,
key=lambda e: e.date,
reverse=True
)
def __compute_diff(self, v1, v2, ignoring=["last_login", "pwd_ntlm", "email_change_date"]):
"""
Find the edited field between two versions
:param v1: Version
:param v2: Version
:param ignoring: List, a list of fields to ignore
:return: List of field names
"""
fields = []
for key in v1.field_dict.keys():
if key not in ignoring and v1.field_dict[key] != v2.field_dict[key]:
fields.append(key)
return fields
def __add_revision(self, user, version):
"""
Add a new revision to the chronological order
:param user: User, The user displayed in this history
:param version: Version, The version of the user for this event
"""
diff = None
if self.__last_version is not None:
diff = self.__compute_diff(version, self.__last_version)
# Ignore "empty" events like login
if not diff:
self.__last_version = version
return
evt = UserHistoryEvent(user, version, self.__last_version, diff)
self.events.append(evt)
self.__last_version = version

View file

@ -0,0 +1,80 @@
{% extends 'logs/sidebar.html' %}
{% comment %}
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en
quelques clics.
Copyright © 2020 Jean-Romain Garnier
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 "History" %}{% endblock %}
{% block content %}
<h2>{% blocktrans %}History of {{ user }}{% endblocktrans %}</h2>
{% if events %}
<table class="table table-striped">
<thead>
<tr>
<th>{% trans "Date" %}</th>
<th>{% trans "Performed by" %}</th>
<th>{% trans "Edited" %}</th>
<th>{% trans "Comment" %}</th>
</tr>
</thead>
{% for event in events %}
<tr>
<td>{{ event.date }}</td>
<td>
{% if event.performed_by %}
<a href="{% url 'users:profil' userid=event.performed_by.id %}" title=tr_view_the_profile>
{{ event.performed_by }}
</a>
{% else %}
{% trans "Unknown" %}
{% endif %}
</td>
<td>
{% for edit in event.edits %}
{% if edit.1 is None and edit.2 is None %}
<strong>{{ edit.0 }}</strong><br/>
{% elif edit.1 is None %}
<strong>{{ edit.0 }}:</strong>
<i class="text-success"> {{ edit.2 }}</i><br/>
{% else %}
<strong>{{ edit.0 }}:</strong>
<i class="text-danger"> {{ edit.1 }} </i>
<i class="text-success">{{ edit.2 }}</i><br/>
{% endif %}
{% endfor %}
</td>
<td>{{ event.comment }}</td>
</tr>
{% endfor %}
</table>
{% include 'pagination.html' with list=events %}
{% else %}
<h3>{% trans "No event" %}</h3>
{% endif %}
<br />
<br />
<br />
{% endblock %}

View file

@ -47,4 +47,5 @@ urlpatterns = [
name="history", name="history",
), ),
url(r"^stats_search_machine/$", views.stats_search_machine_history, name="stats-search-machine"), url(r"^stats_search_machine/$", views.stats_search_machine_history, name="stats-search-machine"),
url(r"^user/(?P<userid>[0-9]+)$", views.user_history, name="user-history"),
] ]

View file

@ -99,9 +99,9 @@ from re2o.utils import (
all_active_interfaces_count, all_active_interfaces_count,
) )
from re2o.base import re2o_paginator, SortTable from re2o.base import re2o_paginator, SortTable
from re2o.acl import can_view_all, can_view_app, can_edit_history from re2o.acl import can_view_all, can_view_app, can_edit_history, can_view
from .models import MachineHistory from .models import MachineHistory, UserHistory
from .forms import MachineHistoryForm from .forms import MachineHistoryForm
@ -508,6 +508,26 @@ def stats_search_machine_history(request):
return render(request, "logs/search_machine_history.html", {"history_form": history_form}) return render(request, "logs/search_machine_history.html", {"history_form": history_form})
@login_required
@can_view(User)
def user_history(request, users, **_kwargs):
history = UserHistory()
events = history.get(users)
max_result = GeneralOption.get_cached_value("pagination_number")
events = re2o_paginator(
request,
events,
max_result
)
return render(
request,
"logs/user_history.html",
{ "user": users, "events": events },
)
def history(request, application, object_name, object_id): def history(request, application, object_name, object_id):
"""Render history for a model. """Render history for a model.

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-22 19:00+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2018-06-23 16:35+0200\n" "PO-Revision-Date: 2018-06-23 16:35+0200\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n" "Language-Team: \n"

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-22 19:00+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2019-11-16 00:22+0100\n" "PO-Revision-Date: 2019-11-16 00:22+0100\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n" "Language-Team: \n"

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-23 11:55+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2018-06-24 15:54+0200\n" "PO-Revision-Date: 2018-06-24 15:54+0200\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n" "Language-Team: \n"
@ -342,13 +342,13 @@ msgid "Maximum number of local email addresses for a standard user."
msgstr "" msgstr ""
"Nombre maximum d'adresses mail locales autorisé pour un utilisateur standard." "Nombre maximum d'adresses mail locales autorisé pour un utilisateur standard."
#: preferences/models.py:125 #: preferences/models.py:122
msgid "Not yet active users will be deleted after this number of days." msgid "Not yet active users will be deleted after this number of days."
msgstr "" msgstr ""
"Les utilisateurs n'ayant jamais adhéré seront supprimés après ce nombre de " "Les utilisateurs n'ayant jamais adhéré seront supprimés après ce nombre de "
"jours." "jours."
#: preferences/models.py:130 #: preferences/models.py:127
msgid "" msgid ""
"Users with an email address not yet confirmed will be disabled after this " "Users with an email address not yet confirmed will be disabled after this "
"number of days." "number of days."
@ -356,11 +356,11 @@ msgstr ""
"Les utilisateurs n'ayant pas confirmé leur addresse mail seront désactivés " "Les utilisateurs n'ayant pas confirmé leur addresse mail seront désactivés "
"après ce nombre de jours" "après ce nombre de jours"
#: preferences/models.py:134 #: preferences/models.py:131
msgid "A new user can create their account on Re2o." msgid "A new user can create their account on Re2o."
msgstr "Un nouvel utilisateur peut créer son compte sur Re2o." msgstr "Un nouvel utilisateur peut créer son compte sur Re2o."
#: preferences/models.py:139 #: preferences/models.py:136
msgid "" msgid ""
"If True, all new created and connected users are active. If False, only when " "If True, all new created and connected users are active. If False, only when "
"a valid registration has been paid." "a valid registration has been paid."
@ -368,7 +368,7 @@ msgstr ""
"Si True, tous les nouveaux utilisations créés et connectés sont actifs. Si " "Si True, tous les nouveaux utilisations créés et connectés sont actifs. Si "
"False, seulement quand une inscription validée a été payée." "False, seulement quand une inscription validée a été payée."
#: preferences/models.py:146 #: preferences/models.py:143
msgid "" msgid ""
"If True, users have the choice to receive an email containing a link to " "If True, users have the choice to receive an email containing a link to "
"reset their password during creation, or to directly set their password in " "reset their password during creation, or to directly set their password in "
@ -379,172 +379,172 @@ msgstr ""
"de choisir leur mot de passe immédiatement. Si False, un mail est toujours " "de choisir leur mot de passe immédiatement. Si False, un mail est toujours "
"envoyé." "envoyé."
#: preferences/models.py:153 #: preferences/models.py:150
msgid "If True, archived users are allowed to connect." msgid "If True, archived users are allowed to connect."
msgstr "Si True, les utilisateurs archivés sont autorisés à se connecter." msgstr "Si True, les utilisateurs archivés sont autorisés à se connecter."
#: preferences/models.py:157 #: preferences/models.py:154
msgid "Can view the user preferences" msgid "Can view the user preferences"
msgstr "Peut voir les préférences d'utilisateur" msgstr "Peut voir les préférences d'utilisateur"
#: preferences/models.py:158 #: preferences/models.py:155
msgid "user preferences" msgid "user preferences"
msgstr "Préférences d'utilisateur" msgstr "Préférences d'utilisateur"
#: preferences/models.py:165 #: preferences/models.py:162
msgid "Email domain must begin with @." msgid "Email domain must begin with @."
msgstr "Un domaine mail doit commencer par @." msgstr "Un domaine mail doit commencer par @."
#: preferences/models.py:183 #: preferences/models.py:180
msgid "Automatic configuration by RA" msgid "Automatic configuration by RA"
msgstr "Configuration automatique par RA" msgstr "Configuration automatique par RA"
#: preferences/models.py:184 #: preferences/models.py:181
msgid "IP addresses assignment by DHCPv6" msgid "IP addresses assignment by DHCPv6"
msgstr "Attribution d'adresses IP par DHCPv6" msgstr "Attribution d'adresses IP par DHCPv6"
#: preferences/models.py:185 #: preferences/models.py:182
msgid "Disabled" msgid "Disabled"
msgstr "Désactivé" msgstr "Désactivé"
#: preferences/models.py:194 #: preferences/models.py:191
msgid "default Time To Live (TTL) for CNAME, A and AAAA records" msgid "default Time To Live (TTL) for CNAME, A and AAAA records"
msgstr "" msgstr ""
"Temps de vie (TTL) par défault pour des enregistrements CNAME, A et AAAA" "Temps de vie (TTL) par défault pour des enregistrements CNAME, A et AAAA"
#: preferences/models.py:204 #: preferences/models.py:201
msgid "Can view the machine preferences" msgid "Can view the machine preferences"
msgstr "Peut voir les préférences de machine" msgstr "Peut voir les préférences de machine"
#: preferences/models.py:205 #: preferences/models.py:202
msgid "machine preferences" msgid "machine preferences"
msgstr "Préférences de machine" msgstr "Préférences de machine"
#: preferences/models.py:225 preferences/models.py:687 #: preferences/models.py:222 preferences/models.py:684
msgid "On the IP range's VLAN of the machine" msgid "On the IP range's VLAN of the machine"
msgstr "Sur le VLAN de la plage d'IP de la machine" msgstr "Sur le VLAN de la plage d'IP de la machine"
#: preferences/models.py:226 preferences/models.py:688 #: preferences/models.py:223 preferences/models.py:685
msgid "Preset in \"VLAN for machines accepted by RADIUS\"" msgid "Preset in \"VLAN for machines accepted by RADIUS\""
msgstr "Prédéfinie dans « VLAN pour les machines acceptées par RADIUS »" msgstr "Prédéfinie dans « VLAN pour les machines acceptées par RADIUS »"
#: preferences/models.py:232 #: preferences/models.py:229
msgid "Web management, activated in case of automatic provision." msgid "Web management, activated in case of automatic provision."
msgstr "Gestion web, activée en cas de provision automatique." msgstr "Gestion web, activée en cas de provision automatique."
#: preferences/models.py:237 #: preferences/models.py:234
msgid "" msgid ""
"SSL web management, make sure that a certificate is installed on the switch." "SSL web management, make sure that a certificate is installed on the switch."
msgstr "" msgstr ""
"Gestion web SSL, vérifiez qu'un certificat est installé sur le commutateur " "Gestion web SSL, vérifiez qu'un certificat est installé sur le commutateur "
"réseau." "réseau."
#: preferences/models.py:243 #: preferences/models.py:240
msgid "REST management, activated in case of automatic provision." msgid "REST management, activated in case of automatic provision."
msgstr "Gestion REST, activée en cas de provision automatique." msgstr "Gestion REST, activée en cas de provision automatique."
#: preferences/models.py:250 #: preferences/models.py:247
msgid "IP range for the management of switches." msgid "IP range for the management of switches."
msgstr "Plage d'IP pour la gestion des commutateurs réseau." msgstr "Plage d'IP pour la gestion des commutateurs réseau."
#: preferences/models.py:256 #: preferences/models.py:253
msgid "Provision of configuration mode for switches." msgid "Provision of configuration mode for switches."
msgstr "Mode de provision de configuration pour les commutateurs réseau." msgstr "Mode de provision de configuration pour les commutateurs réseau."
#: preferences/models.py:259 #: preferences/models.py:256
msgid "SFTP login for switches." msgid "SFTP login for switches."
msgstr "Identifiant SFTP pour les commutateurs réseau." msgstr "Identifiant SFTP pour les commutateurs réseau."
#: preferences/models.py:262 #: preferences/models.py:259
msgid "SFTP password." msgid "SFTP password."
msgstr "Mot de passe SFTP." msgstr "Mot de passe SFTP."
#: preferences/models.py:367 #: preferences/models.py:364
msgid "Can view the topology preferences" msgid "Can view the topology preferences"
msgstr "Peut voir les préférences de topologie" msgstr "Peut voir les préférences de topologie"
#: preferences/models.py:369 #: preferences/models.py:366
msgid "topology preferences" msgid "topology preferences"
msgstr "préférences de topologie" msgstr "préférences de topologie"
#: preferences/models.py:382 #: preferences/models.py:379
msgid "RADIUS key." msgid "RADIUS key."
msgstr "Clé RADIUS." msgstr "Clé RADIUS."
#: preferences/models.py:384 #: preferences/models.py:381
msgid "Comment for this key." msgid "Comment for this key."
msgstr "Commentaire pour cette clé." msgstr "Commentaire pour cette clé."
#: preferences/models.py:387 #: preferences/models.py:384
msgid "Default key for switches." msgid "Default key for switches."
msgstr "Clé par défaut pour les commutateurs réseau." msgstr "Clé par défaut pour les commutateurs réseau."
#: preferences/models.py:391 #: preferences/models.py:388
msgid "Can view a RADIUS key object" msgid "Can view a RADIUS key object"
msgstr "Peut voir un objet clé RADIUS" msgstr "Peut voir un objet clé RADIUS"
#: preferences/models.py:392 preferences/views.py:335 #: preferences/models.py:389 preferences/views.py:335
msgid "RADIUS key" msgid "RADIUS key"
msgstr "Clé RADIUS" msgstr "Clé RADIUS"
#: preferences/models.py:393 #: preferences/models.py:390
#: preferences/templates/preferences/display_preferences.html:223 #: preferences/templates/preferences/display_preferences.html:221
msgid "RADIUS keys" msgid "RADIUS keys"
msgstr "clés RADIUS" msgstr "clés RADIUS"
#: preferences/models.py:400 #: preferences/models.py:397
msgid "Default RADIUS key for switches already exists." msgid "Default RADIUS key for switches already exists."
msgstr "Clé par défaut pour les commutateurs réseau." msgstr "Clé par défaut pour les commutateurs réseau."
#: preferences/models.py:403 #: preferences/models.py:400
msgid "RADIUS key " msgid "RADIUS key "
msgstr "clé RADIUS " msgstr "clé RADIUS "
#: preferences/models.py:409 #: preferences/models.py:406
msgid "Switch login." msgid "Switch login."
msgstr "Identifiant du commutateur réseau." msgstr "Identifiant du commutateur réseau."
#: preferences/models.py:410 #: preferences/models.py:407
msgid "Password." msgid "Password."
msgstr "Mot de passe." msgstr "Mot de passe."
#: preferences/models.py:412 #: preferences/models.py:409
msgid "Default credentials for switches." msgid "Default credentials for switches."
msgstr "Identifiants par défaut pour les commutateurs réseau." msgstr "Identifiants par défaut pour les commutateurs réseau."
#: preferences/models.py:419 #: preferences/models.py:416
msgid "Can view a switch management credentials object" msgid "Can view a switch management credentials object"
msgstr "Peut voir un objet identifiants de gestion de commutateur réseau" msgstr "Peut voir un objet identifiants de gestion de commutateur réseau"
#: preferences/models.py:422 preferences/views.py:397 #: preferences/models.py:419 preferences/views.py:397
msgid "switch management credentials" msgid "switch management credentials"
msgstr "identifiants de gestion de commutateur réseau" msgstr "identifiants de gestion de commutateur réseau"
#: preferences/models.py:425 #: preferences/models.py:422
msgid "Switch login " msgid "Switch login "
msgstr "Identifiant du commutateur réseau " msgstr "Identifiant du commutateur réseau "
#: preferences/models.py:437 #: preferences/models.py:434
msgid "Delay between the email and the membership's end." msgid "Delay between the email and the membership's end."
msgstr "Délai entre le mail et la fin d'adhésion." msgstr "Délai entre le mail et la fin d'adhésion."
#: preferences/models.py:443 #: preferences/models.py:440
msgid "Message displayed specifically for this reminder." msgid "Message displayed specifically for this reminder."
msgstr "Message affiché spécifiquement pour ce rappel." msgstr "Message affiché spécifiquement pour ce rappel."
#: preferences/models.py:447 #: preferences/models.py:444
msgid "Can view a reminder object" msgid "Can view a reminder object"
msgstr "Peut voir un objet rappel" msgstr "Peut voir un objet rappel"
#: preferences/models.py:448 preferences/views.py:280 #: preferences/models.py:445 preferences/views.py:280
msgid "reminder" msgid "reminder"
msgstr "rappel" msgstr "rappel"
#: preferences/models.py:449 #: preferences/models.py:446
msgid "reminders" msgid "reminders"
msgstr "rappels" msgstr "rappels"
#: preferences/models.py:470 #: preferences/models.py:467
msgid "" msgid ""
"General message displayed on the French version of the website (e.g. in case " "General message displayed on the French version of the website (e.g. in case "
"of maintenance)." "of maintenance)."
@ -552,7 +552,7 @@ msgstr ""
"Message général affiché sur la version française du site (ex : en cas de " "Message général affiché sur la version française du site (ex : en cas de "
"maintenance)." "maintenance)."
#: preferences/models.py:478 #: preferences/models.py:475
msgid "" msgid ""
"General message displayed on the English version of the website (e.g. in " "General message displayed on the English version of the website (e.g. in "
"case of maintenance)." "case of maintenance)."
@ -560,75 +560,75 @@ msgstr ""
"Message général affiché sur la version anglaise du site (ex : en cas de " "Message général affiché sur la version anglaise du site (ex : en cas de "
"maintenance)." "maintenance)."
#: preferences/models.py:493 #: preferences/models.py:490
msgid "Can view the general preferences" msgid "Can view the general preferences"
msgstr "Peut voir les préférences générales" msgstr "Peut voir les préférences générales"
#: preferences/models.py:494 #: preferences/models.py:491
msgid "general preferences" msgid "general preferences"
msgstr "préférences générales" msgstr "préférences générales"
#: preferences/models.py:514 #: preferences/models.py:511
msgid "Can view the service preferences" msgid "Can view the service preferences"
msgstr "Peut voir les préférences de service" msgstr "Peut voir les préférences de service"
#: preferences/models.py:515 preferences/views.py:231 #: preferences/models.py:512 preferences/views.py:231
msgid "service" msgid "service"
msgstr "service" msgstr "service"
#: preferences/models.py:516 #: preferences/models.py:513
msgid "services" msgid "services"
msgstr "services" msgstr "services"
#: preferences/models.py:526 #: preferences/models.py:523
msgid "Contact email address." msgid "Contact email address."
msgstr "Adresse mail de contact." msgstr "Adresse mail de contact."
#: preferences/models.py:532 #: preferences/models.py:529
msgid "Description of the associated email address." msgid "Description of the associated email address."
msgstr "Description de l'adresse mail associée." msgstr "Description de l'adresse mail associée."
#: preferences/models.py:542 #: preferences/models.py:539
msgid "Can view a contact email address object" msgid "Can view a contact email address object"
msgstr "Peut voir un objet adresse mail de contact" msgstr "Peut voir un objet adresse mail de contact"
#: preferences/models.py:544 #: preferences/models.py:541
msgid "contact email address" msgid "contact email address"
msgstr "adresse mail de contact" msgstr "adresse mail de contact"
#: preferences/models.py:545 #: preferences/models.py:542
msgid "contact email addresses" msgid "contact email addresses"
msgstr "adresses mail de contact" msgstr "adresses mail de contact"
#: preferences/models.py:553 preferences/views.py:635 #: preferences/models.py:550 preferences/views.py:635
msgid "mandate" msgid "mandate"
msgstr "mandat" msgstr "mandat"
#: preferences/models.py:554 #: preferences/models.py:551
msgid "mandates" msgid "mandates"
msgstr "mandats" msgstr "mandats"
#: preferences/models.py:555 #: preferences/models.py:552
msgid "Can view a mandate object" msgid "Can view a mandate object"
msgstr "Peut voir un objet mandat" msgstr "Peut voir un objet mandat"
#: preferences/models.py:562 #: preferences/models.py:559
msgid "president of the association" msgid "president of the association"
msgstr "président de l'association" msgstr "président de l'association"
#: preferences/models.py:563 #: preferences/models.py:560
msgid "Displayed on subscription vouchers." msgid "Displayed on subscription vouchers."
msgstr "Affiché sur les reçus de cotisation." msgstr "Affiché sur les reçus de cotisation."
#: preferences/models.py:565 #: preferences/models.py:562
msgid "start date" msgid "start date"
msgstr "date de début" msgstr "date de début"
#: preferences/models.py:566 #: preferences/models.py:563
msgid "end date" msgid "end date"
msgstr "date de fin" msgstr "date de fin"
#: preferences/models.py:580 #: preferences/models.py:577
msgid "" msgid ""
"No mandates have been created. Please go to the preferences page to create " "No mandates have been created. Please go to the preferences page to create "
"one." "one."
@ -636,140 +636,140 @@ msgstr ""
"Aucun mandat n'a été créé. Veuillez vous rendre sur la page de préférences " "Aucun mandat n'a été créé. Veuillez vous rendre sur la page de préférences "
"pour en créer un." "pour en créer un."
#: preferences/models.py:596 #: preferences/models.py:593
msgid "Networking organisation school Something" msgid "Networking organisation school Something"
msgstr "Association de réseau de l'école Machin" msgstr "Association de réseau de l'école Machin"
#: preferences/models.py:599 #: preferences/models.py:596
msgid "Threadneedle Street" msgid "Threadneedle Street"
msgstr "1 rue de la Vrillière" msgstr "1 rue de la Vrillière"
#: preferences/models.py:600 #: preferences/models.py:597
msgid "London EC2R 8AH" msgid "London EC2R 8AH"
msgstr "75001 Paris" msgstr "75001 Paris"
#: preferences/models.py:603 #: preferences/models.py:600
msgid "Organisation" msgid "Organisation"
msgstr "Association" msgstr "Association"
#: preferences/models.py:610 #: preferences/models.py:607
msgid "Can view the organisation preferences" msgid "Can view the organisation preferences"
msgstr "Peut voir les préférences d'association" msgstr "Peut voir les préférences d'association"
#: preferences/models.py:611 #: preferences/models.py:608
msgid "organisation preferences" msgid "organisation preferences"
msgstr "préférences d'association" msgstr "préférences d'association"
#: preferences/models.py:629 #: preferences/models.py:626
msgid "Can view the homepage preferences" msgid "Can view the homepage preferences"
msgstr "Peut voir les préférences de page d'accueil" msgstr "Peut voir les préférences de page d'accueil"
#: preferences/models.py:630 #: preferences/models.py:627
msgid "homepage preferences" msgid "homepage preferences"
msgstr "Préférences de page d'accueil" msgstr "Préférences de page d'accueil"
#: preferences/models.py:644 #: preferences/models.py:641
msgid "Welcome email in French." msgid "Welcome email in French."
msgstr "Mail de bienvenue en français." msgstr "Mail de bienvenue en français."
#: preferences/models.py:647 #: preferences/models.py:644
msgid "Welcome email in English." msgid "Welcome email in English."
msgstr "Mail de bienvenue en anglais." msgstr "Mail de bienvenue en anglais."
#: preferences/models.py:652 #: preferences/models.py:649
msgid "Can view the email message preferences" msgid "Can view the email message preferences"
msgstr "Peut voir les préférences de message pour les mails" msgstr "Peut voir les préférences de message pour les mails"
#: preferences/models.py:654 #: preferences/models.py:651
msgid "email message preferences" msgid "email message preferences"
msgstr "préférences de messages pour les mails" msgstr "préférences de messages pour les mails"
#: preferences/models.py:659 #: preferences/models.py:656
msgid "RADIUS attribute" msgid "RADIUS attribute"
msgstr "attribut RADIUS" msgstr "attribut RADIUS"
#: preferences/models.py:660 #: preferences/models.py:657
msgid "RADIUS attributes" msgid "RADIUS attributes"
msgstr "attributs RADIUS" msgstr "attributs RADIUS"
#: preferences/models.py:664 preferences/views.py:588 #: preferences/models.py:661 preferences/views.py:588
msgid "attribute" msgid "attribute"
msgstr "attribut" msgstr "attribut"
#: preferences/models.py:665 #: preferences/models.py:662
msgid "See https://freeradius.org/rfc/attributes.html." msgid "See https://freeradius.org/rfc/attributes.html."
msgstr "Voir https://freeradius.org/rfc/attributes.html." msgstr "Voir https://freeradius.org/rfc/attributes.html."
#: preferences/models.py:667 #: preferences/models.py:664
msgid "value" msgid "value"
msgstr "valeur" msgstr "valeur"
#: preferences/models.py:669 #: preferences/models.py:666
msgid "comment" msgid "comment"
msgstr "commentaire" msgstr "commentaire"
#: preferences/models.py:670 #: preferences/models.py:667
msgid "Use this field to document this attribute." msgid "Use this field to document this attribute."
msgstr "Utilisez ce champ pour documenter cet attribut." msgstr "Utilisez ce champ pour documenter cet attribut."
#: preferences/models.py:681 #: preferences/models.py:678
msgid "RADIUS policy" msgid "RADIUS policy"
msgstr "politique de RADIUS" msgstr "politique de RADIUS"
#: preferences/models.py:682 #: preferences/models.py:679
#: preferences/templates/preferences/display_preferences.html:301 #: preferences/templates/preferences/display_preferences.html:299
msgid "RADIUS policies" msgid "RADIUS policies"
msgstr "politiques de RADIUS" msgstr "politiques de RADIUS"
#: preferences/models.py:693 #: preferences/models.py:690
msgid "Reject the machine" msgid "Reject the machine"
msgstr "Rejeter la machine" msgstr "Rejeter la machine"
#: preferences/models.py:694 #: preferences/models.py:691
msgid "Place the machine on the VLAN" msgid "Place the machine on the VLAN"
msgstr "Placer la machine sur le VLAN" msgstr "Placer la machine sur le VLAN"
#: preferences/models.py:703 #: preferences/models.py:700
msgid "policy for unknown machines" msgid "policy for unknown machines"
msgstr "politique pour les machines inconnues" msgstr "politique pour les machines inconnues"
#: preferences/models.py:711 #: preferences/models.py:708
msgid "unknown machines VLAN" msgid "unknown machines VLAN"
msgstr "VLAN pour les machines inconnues" msgstr "VLAN pour les machines inconnues"
#: preferences/models.py:712 #: preferences/models.py:709
msgid "VLAN for unknown machines if not rejected." msgid "VLAN for unknown machines if not rejected."
msgstr "VLAN pour les machines inconnues si non rejeté." msgstr "VLAN pour les machines inconnues si non rejeté."
#: preferences/models.py:718 #: preferences/models.py:715
msgid "unknown machines attributes" msgid "unknown machines attributes"
msgstr "attributs pour les machines inconnues" msgstr "attributs pour les machines inconnues"
#: preferences/models.py:719 #: preferences/models.py:716
msgid "Answer attributes for unknown machines." msgid "Answer attributes for unknown machines."
msgstr "Attributs de réponse pour les machines inconnues." msgstr "Attributs de réponse pour les machines inconnues."
#: preferences/models.py:725 #: preferences/models.py:722
msgid "policy for unknown ports" msgid "policy for unknown ports"
msgstr "politique pour les ports inconnus" msgstr "politique pour les ports inconnus"
#: preferences/models.py:733 #: preferences/models.py:730
msgid "unknown ports VLAN" msgid "unknown ports VLAN"
msgstr "VLAN pour les ports inconnus" msgstr "VLAN pour les ports inconnus"
#: preferences/models.py:734 #: preferences/models.py:731
msgid "VLAN for unknown ports if not rejected." msgid "VLAN for unknown ports if not rejected."
msgstr "VLAN pour les ports inconnus si non rejeté." msgstr "VLAN pour les ports inconnus si non rejeté."
#: preferences/models.py:740 #: preferences/models.py:737
msgid "unknown ports attributes" msgid "unknown ports attributes"
msgstr "attributs pour les ports inconnus" msgstr "attributs pour les ports inconnus"
#: preferences/models.py:741 #: preferences/models.py:738
msgid "Answer attributes for unknown ports." msgid "Answer attributes for unknown ports."
msgstr "Attributs de réponse pour les ports inconnus." msgstr "Attributs de réponse pour les ports inconnus."
#: preferences/models.py:748 #: preferences/models.py:745
msgid "" msgid ""
"Policy for machines connecting from unregistered rooms (relevant on ports " "Policy for machines connecting from unregistered rooms (relevant on ports "
"with STRICT RADIUS mode)" "with STRICT RADIUS mode)"
@ -777,87 +777,87 @@ msgstr ""
"Politique pour les machines se connectant depuis des chambre non " "Politique pour les machines se connectant depuis des chambre non "
"enregistrées (pertinent pour les ports avec le mode de RADIUS STRICT)" "enregistrées (pertinent pour les ports avec le mode de RADIUS STRICT)"
#: preferences/models.py:758 #: preferences/models.py:755
msgid "unknown rooms VLAN" msgid "unknown rooms VLAN"
msgstr "VLAN pour les chambres inconnues" msgstr "VLAN pour les chambres inconnues"
#: preferences/models.py:759 #: preferences/models.py:756
msgid "VLAN for unknown rooms if not rejected." msgid "VLAN for unknown rooms if not rejected."
msgstr "VLAN pour les chambres inconnues si non rejeté." msgstr "VLAN pour les chambres inconnues si non rejeté."
#: preferences/models.py:765 #: preferences/models.py:762
msgid "unknown rooms attributes" msgid "unknown rooms attributes"
msgstr "attributs pour les chambres inconnues" msgstr "attributs pour les chambres inconnues"
#: preferences/models.py:766 #: preferences/models.py:763
msgid "Answer attributes for unknown rooms." msgid "Answer attributes for unknown rooms."
msgstr "Attributs de réponse pour les chambres inconnues." msgstr "Attributs de réponse pour les chambres inconnues."
#: preferences/models.py:772 #: preferences/models.py:769
msgid "policy for non members" msgid "policy for non members"
msgstr "politique pour les non adhérents" msgstr "politique pour les non adhérents"
#: preferences/models.py:780 #: preferences/models.py:777
msgid "non members VLAN" msgid "non members VLAN"
msgstr "VLAN pour les non adhérents" msgstr "VLAN pour les non adhérents"
#: preferences/models.py:781 #: preferences/models.py:778
msgid "VLAN for non members if not rejected." msgid "VLAN for non members if not rejected."
msgstr "VLAN pour les non adhérents si non rejeté." msgstr "VLAN pour les non adhérents si non rejeté."
#: preferences/models.py:787 #: preferences/models.py:784
msgid "non members attributes" msgid "non members attributes"
msgstr "attributs pour les non adhérents" msgstr "attributs pour les non adhérents"
#: preferences/models.py:788 #: preferences/models.py:785
msgid "Answer attributes for non members." msgid "Answer attributes for non members."
msgstr "Attributs de réponse pour les non adhérents." msgstr "Attributs de réponse pour les non adhérents."
#: preferences/models.py:794 #: preferences/models.py:791
msgid "policy for banned users" msgid "policy for banned users"
msgstr "politique pour les utilisateurs bannis" msgstr "politique pour les utilisateurs bannis"
#: preferences/models.py:802 #: preferences/models.py:799
msgid "banned users VLAN" msgid "banned users VLAN"
msgstr "VLAN pour les utilisateurs bannis" msgstr "VLAN pour les utilisateurs bannis"
#: preferences/models.py:803 #: preferences/models.py:800
msgid "VLAN for banned users if not rejected." msgid "VLAN for banned users if not rejected."
msgstr "VLAN pour les utilisateurs bannis si non rejeté." msgstr "VLAN pour les utilisateurs bannis si non rejeté."
#: preferences/models.py:809 #: preferences/models.py:806
msgid "banned users attributes" msgid "banned users attributes"
msgstr "attributs pour les utilisateurs bannis" msgstr "attributs pour les utilisateurs bannis"
#: preferences/models.py:810 #: preferences/models.py:807
msgid "Answer attributes for banned users." msgid "Answer attributes for banned users."
msgstr "Attributs de réponse pour les utilisateurs bannis." msgstr "Attributs de réponse pour les utilisateurs bannis."
#: preferences/models.py:823 #: preferences/models.py:820
msgid "accepted users attributes" msgid "accepted users attributes"
msgstr "attributs pour les utilisateurs acceptés" msgstr "attributs pour les utilisateurs acceptés"
#: preferences/models.py:824 #: preferences/models.py:821
msgid "Answer attributes for accepted users." msgid "Answer attributes for accepted users."
msgstr "Attributs de réponse pour les utilisateurs acceptés." msgstr "Attributs de réponse pour les utilisateurs acceptés."
#: preferences/models.py:851 #: preferences/models.py:848
msgid "subscription preferences" msgid "subscription preferences"
msgstr "préférences de cotisation" msgstr "préférences de cotisation"
#: preferences/models.py:855 #: preferences/models.py:852
msgid "template for invoices" msgid "template for invoices"
msgstr "modèle pour les factures" msgstr "modèle pour les factures"
#: preferences/models.py:862 #: preferences/models.py:859
msgid "template for subscription vouchers" msgid "template for subscription vouchers"
msgstr "modèle pour les reçus de cotisation" msgstr "modèle pour les reçus de cotisation"
#: preferences/models.py:868 #: preferences/models.py:865
msgid "send voucher by email when the invoice is controlled" msgid "send voucher by email when the invoice is controlled"
msgstr "envoyer le reçu par mail quand la facture est contrôlée" msgstr "envoyer le reçu par mail quand la facture est contrôlée"
#: preferences/models.py:870 #: preferences/models.py:867
msgid "" msgid ""
"Be careful, if no mandate is defined on the preferences page, errors will be " "Be careful, if no mandate is defined on the preferences page, errors will be "
"triggered when generating vouchers." "triggered when generating vouchers."
@ -865,19 +865,19 @@ msgstr ""
"Faites attention, si aucun mandat n'est défini sur la page de préférences, " "Faites attention, si aucun mandat n'est défini sur la page de préférences, "
"des erreurs seront déclenchées en générant des reçus." "des erreurs seront déclenchées en générant des reçus."
#: preferences/models.py:882 #: preferences/models.py:879
msgid "template" msgid "template"
msgstr "modèle" msgstr "modèle"
#: preferences/models.py:883 #: preferences/models.py:880
msgid "name" msgid "name"
msgstr "nom" msgstr "nom"
#: preferences/models.py:886 #: preferences/models.py:883
msgid "document template" msgid "document template"
msgstr "modèle de document" msgstr "modèle de document"
#: preferences/models.py:887 #: preferences/models.py:884
msgid "document templates" msgid "document templates"
msgstr "modèles de document" msgstr "modèles de document"

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-22 19:00+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2018-03-31 16:09+0002\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n" "Language-Team: \n"

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-22 19:00+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2018-06-24 20:10+0200\n" "PO-Revision-Date: 2018-06-24 20:10+0200\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n" "Language-Team: \n"

View file

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

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-22 19:00+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2018-03-31 16:09+0002\n" "PO-Revision-Date: 2018-03-31 16:09+0002\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n" "Language-Team: \n"

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-23 03:10+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2019-11-16 00:35+0100\n" "PO-Revision-Date: 2019-11-16 00:35+0100\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n" "Language-Team: \n"
@ -30,65 +30,65 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: tickets/forms.py:76 #: tickets/forms.py:78
msgid "comment" msgid "comment"
msgstr "commentaire" msgstr "commentaire"
#: tickets/models.py:57 #: tickets/models.py:58
msgid "Title of the ticket." msgid "Title of the ticket."
msgstr "Titre du ticket." msgstr "Titre du ticket."
#: tickets/models.py:66 #: tickets/models.py:67
msgid "An email address to get back to you." msgid "An email address to get back to you."
msgstr "Une adresse mail pour vous recontacter." msgstr "Une adresse mail pour vous recontacter."
#: tickets/models.py:70 #: tickets/models.py:71
msgid "Language of the ticket." msgid "Language of the ticket."
msgstr "Langue des tickets" msgstr "Langue des tickets"
#: tickets/models.py:74 tickets/models.py:170 #: tickets/models.py:76 tickets/models.py:173
msgid "Can view a ticket object" msgid "Can view a ticket object"
msgstr "Peut voir un objet ticket" msgstr "Peut voir un objet ticket"
#: tickets/models.py:75 tickets/models.py:171 #: tickets/models.py:77 tickets/models.py:174
msgid "ticket" msgid "ticket"
msgstr "ticket" msgstr "ticket"
#: tickets/models.py:76 tickets/models.py:172 #: tickets/models.py:78 tickets/models.py:175
msgid "tickets" msgid "tickets"
msgstr "tickets" msgstr "tickets"
#: tickets/models.py:80 #: tickets/models.py:82
#, python-format #, python-format
msgid "Ticket from %(name)s. Date: %(date)s." msgid "Ticket from %(name)s. Date: %(date)s."
msgstr "Ticket de %(name)s. Date : %(date)s." msgstr "Ticket de %(name)s. Date : %(date)s."
#: tickets/models.py:82 #: tickets/models.py:84
#, python-format #, python-format
msgid "Anonymous ticket. Date: %s." msgid "Anonymous ticket. Date: %s."
msgstr "Ticket anonyme. Date : %s." msgstr "Ticket anonyme. Date : %s."
#: tickets/models.py:90 tickets/templates/tickets/aff_ticket.html:52 #: tickets/models.py:92 tickets/templates/tickets/aff_ticket.html:52
msgid "Anonymous user" msgid "Anonymous user"
msgstr "Utilisateur anonyme" msgstr "Utilisateur anonyme"
#: tickets/models.py:128 #: tickets/models.py:130
msgid "You don't have the right to view other tickets than yours." 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." msgstr "Vous n'avez pas le droit de voir d'autres tickets que les vôtres."
#: tickets/models.py:140 tickets/models.py:214 #: tickets/models.py:142 tickets/models.py:217
msgid "You don't have the right to view the list of tickets." 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." msgstr "Vous n'avez pas le droit de voir la liste des tickets."
#: tickets/models.py:187 #: tickets/models.py:190
msgid "You don't have the right to view other tickets comments than yours." msgid "You don't have the right to view other tickets comments than yours."
msgstr "Vous n'avez pas le droit de voir d'autres tickets que les vôtres." msgstr "Vous n'avez pas le droit de voir d'autres tickets que les vôtres."
#: tickets/models.py:202 #: tickets/models.py:205
msgid "You don't have the right to edit other tickets comments than yours." msgid "You don't have the right to edit other tickets comments than yours."
msgstr "Vous n'avez pas le droit d'éditer d'autres tickets que les vôtres." msgstr "Vous n'avez pas le droit d'éditer d'autres tickets que les vôtres."
#: tickets/models.py:232 #: tickets/models.py:236
msgid "Update of your ticket" msgid "Update of your ticket"
msgstr "Mise à jour de votre ticket" msgstr "Mise à jour de votre ticket"

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-22 19:00+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2018-06-25 14:53+0200\n" "PO-Revision-Date: 2018-06-25 14:53+0200\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n" "Language-Team: \n"

View file

@ -21,7 +21,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 2.5\n" "Project-Id-Version: 2.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-22 19:00+0200\n" "POT-Creation-Date: 2020-04-23 14:44+0200\n"
"PO-Revision-Date: 2018-06-27 23:35+0200\n" "PO-Revision-Date: 2018-06-27 23:35+0200\n"
"Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n" "Last-Translator: Laouen Fernet <laouen.fernet@supelec.fr>\n"
"Language-Team: \n" "Language-Team: \n"