From 38edf3b0ebc262c66c313e949179a0365e11ef4b Mon Sep 17 00:00:00 2001 From: grisel-davy Date: Sat, 30 Jun 2018 19:19:40 +0200 Subject: [PATCH 01/14] =?UTF-8?q?Cr=C3=A9ation,=20modification,=20suppress?= =?UTF-8?q?ion=20d'adresses=20mail=20de=20contact?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- preferences/admin.py | 7 ++ preferences/forms.py | 30 ++++++- preferences/models.py | 23 +++++ .../preferences/aff_mailcontact.html | 45 ++++++++++ .../preferences/display_preferences.html | 9 ++ preferences/urls.py | 15 +++- preferences/views.py | 83 ++++++++++++++++++- re2o/templatetags/acl.py | 1 - 8 files changed, 206 insertions(+), 7 deletions(-) create mode 100644 preferences/templates/preferences/aff_mailcontact.html diff --git a/preferences/admin.py b/preferences/admin.py index 296dc57c..043370db 100644 --- a/preferences/admin.py +++ b/preferences/admin.py @@ -34,6 +34,7 @@ from .models import ( OptionalTopologie, GeneralOption, Service, + MailContact, AssoOption, MailMessageOption, HomeOption @@ -65,6 +66,11 @@ class ServiceAdmin(VersionAdmin): pass +class MailContactAdmin(VersionAdmin): + """Class admin gestion des adresses mail de contact""" + pass + + class AssoOptionAdmin(VersionAdmin): """Class admin options de l'asso""" pass @@ -86,5 +92,6 @@ admin.site.register(OptionalTopologie, OptionalTopologieAdmin) admin.site.register(GeneralOption, GeneralOptionAdmin) admin.site.register(HomeOption, HomeOptionAdmin) admin.site.register(Service, ServiceAdmin) +admin.site.register(MailContact, MailContactAdmin) admin.site.register(AssoOption, AssoOptionAdmin) admin.site.register(MailMessageOption, MailMessageOptionAdmin) diff --git a/preferences/forms.py b/preferences/forms.py index 477d4d57..193beca8 100644 --- a/preferences/forms.py +++ b/preferences/forms.py @@ -35,7 +35,8 @@ from .models import ( AssoOption, MailMessageOption, HomeOption, - Service + Service, + MailContact ) @@ -227,3 +228,30 @@ class DelServiceForm(Form): self.fields['services'].queryset = instances else: self.fields['services'].queryset = Service.objects.all() + +class MailContactForm(ModelForm): + """Edition, ajout d'adresse de contact""" + class Meta: + model = MailContact + fields = '__all__' + + def __init__(self, *args, **kwargs): + prefix = kwargs.pop('prefix', self.Meta.model.__name__) + super(MailContactForm, self).__init__(*args, prefix=prefix, **kwargs) + + +class DelMailContactForm(Form): + """Suppression d'adresse de contact""" + mailcontacts = forms.ModelMultipleChoiceField( + queryset=MailContact.objects.none(), + label="Enregistrements adresses actuels", + widget=forms.CheckboxSelectMultiple + ) + + def __init__(self, *args, **kwargs): + instances = kwargs.pop('instances', None) + super(DelMailContactForm, self).__init__(*args, **kwargs) + if instances: + self.fields['mailcontacts'].queryset = instances + else: + self.fields['mailcontacts'].queryset = MailContact.objects.all() diff --git a/preferences/models.py b/preferences/models.py index c2d6aa74..d6a1c6b6 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -267,6 +267,29 @@ class Service(AclMixin, models.Model): def __str__(self): return str(self.name) +class MailContact(AclMixin, models.Model): + """Addresse mail de contact associée à un commentaire descriptif""" + + address = models.EmailField( + default = "contact@example.org", + help_text = "Adresse mail de contact" + ) + + commentary = models.CharField( + blank = True, + null = True, + help_text = "Description de l'utilisation de l'adresse mail associée", + max_length = 256 + ) + + class Meta: + permissions = ( + ("view_mailcontact", "Peut voir les mails de contact"), + ) + + def __str__(self): + return(self.address) + class AssoOption(AclMixin, PreferencesModel): """Options générales de l'asso : siret, addresse, nom, etc""" diff --git a/preferences/templates/preferences/aff_mailcontact.html b/preferences/templates/preferences/aff_mailcontact.html new file mode 100644 index 00000000..55d268f0 --- /dev/null +++ b/preferences/templates/preferences/aff_mailcontact.html @@ -0,0 +1,45 @@ +{% comment %} +Re2o est un logiciel d'administration développé initiallement au rezometz. Il +se veut agnostique au réseau considéré, de manière à être installable en +quelques clics. + +Copyright © 2017 Gabriel Détraz +Copyright © 2017 Goulven Kermarec +Copyright © 2017 Augustin Lemesle + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +{% endcomment %} +{% load acl %} + + + + + + + + + {% for mailcontact in mailcontact_list %} + + + + + + {% endfor %} +
AdresseCommentaire
{{ mailcontact.address }}{{ mailcontact.commentary }} + {% can_edit mailcontact %} + {% include 'buttons/edit.html' with href='preferences:edit-mailcontact' id=mailcontact.id %} + {% acl_end %} + {% include 'buttons/history.html' with href='preferences:history' name='mailcontact' id=mailcontact.id %} +
diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html index a3f2dbc3..eb2fcea8 100644 --- a/preferences/templates/preferences/display_preferences.html +++ b/preferences/templates/preferences/display_preferences.html @@ -220,6 +220,15 @@ with this program; if not, write to the Free Software Foundation, Inc., Editer + +

Liste des adresses mail de contact

+ {% can_create preferences.MailContact%} + Ajouter une adresse + {% acl_end %} + Supprimer une ou plusieurs adresses + {% include "preferences/aff_mailcontact.html" with mailcontact_list=mailcontact_list %} +

+ diff --git a/preferences/urls.py b/preferences/urls.py index ec35cc41..896dc45f 100644 --- a/preferences/urls.py +++ b/preferences/urls.py @@ -72,6 +72,19 @@ urlpatterns = [ views.edit_service, name='edit-service' ), - url(r'^del_services/$', views.del_services, name='del-services'), + url(r'^del_service/$', views.del_service, name='del-service'), + url(r'^add_mailcontact/$', views.add_mailcontact, name='add-mailcontact'), + url( + r'^edit_mailcontact/(?P[0-9]+)$', + views.edit_mailcontact, + name='edit-mailcontact' + ), + url(r'^del_mailcontact/$', views.del_mailcontact, name='del-mailcontact'), + url( + r'^history/(?P\w+)/(?P[0-9]+)$', + re2o.views.history, + name='history', + kwargs={'application': 'preferences'}, + ), url(r'^$', views.display_options, name='display-options'), ] diff --git a/preferences/views.py b/preferences/views.py index b8ca39d2..1ad0b42d 100644 --- a/preferences/views.py +++ b/preferences/views.py @@ -42,9 +42,10 @@ from reversion import revisions as reversion from re2o.views import form from re2o.acl import can_create, can_edit, can_delete_set, can_view_all -from .forms import ServiceForm, DelServiceForm +from .forms import ServiceForm, DelServiceForm, MailContactForm, DelMailContactForm from .models import ( Service, + MailContact, OptionalUser, OptionalMachine, AssoOption, @@ -71,6 +72,7 @@ def display_options(request): homeoptions, _created = HomeOption.objects.get_or_create() mailmessageoptions, _created = MailMessageOption.objects.get_or_create() service_list = Service.objects.all() + mailcontact_list = MailContact.objects.all() return form({ 'useroptions': useroptions, 'machineoptions': machineoptions, @@ -79,7 +81,8 @@ def display_options(request): 'assooptions': assooptions, 'homeoptions': homeoptions, 'mailmessageoptions': mailmessageoptions, - 'service_list': service_list + 'service_list': service_list, + 'mailcontact_list': mailcontact_list }, 'preferences/display_preferences.html', request) @@ -169,7 +172,7 @@ def edit_service(request, service_instance, **_kwargs): @login_required @can_delete_set(Service) -def del_services(request, instances): +def del_service(request, instances): """Suppression d'un service de la page d'accueil""" services = DelServiceForm(request.POST or None, instances=instances) if services.is_valid(): @@ -179,7 +182,7 @@ def del_services(request, instances): with transaction.atomic(), reversion.create_revision(): services_del.delete() reversion.set_user(request.user) - messages.success(request, "Le service a été supprimée") + messages.success(request, "Le service a été supprimé") except ProtectedError: messages.error(request, "Erreur le service\ suivant %s ne peut être supprimé" % services_del) @@ -189,3 +192,75 @@ def del_services(request, instances): 'preferences/preferences.html', request ) + + +@login_required +@can_create(MailContact) +def add_mailcontact(request): + """Ajout d'une adresse de contact""" + mailcontact = MailContactForm( + request.POST or None, + request.FILES or None + ) + if mailcontact.is_valid(): + with transaction.atomic(), reversion.create_revision(): + mailcontact.save() + reversion.set_user(request.user) + reversion.set_comment("Création") + messages.success(request, "Cette adresse a été ajoutée") + return redirect(reverse('preferences:display-options')) + return form( + {'preferenceform': mailcontact, 'action_name': 'Ajouter'}, + 'preferences/preferences.html', + request + ) + + +@login_required +@can_edit(MailContact) +def edit_mailcontact(request, mailcontact_instance, **_kwargs): + """Edition des adresses de contacte affichées""" + mailcontact = MailContactForm( + request.POST or None, + request.FILES or None, + instance=mailcontact_instance + ) + if mailcontact.is_valid(): + with transaction.atomic(), reversion.create_revision(): + mailcontact.save() + reversion.set_user(request.user) + reversion.set_comment("Modification") + messages.success(request, "Adresse modifiée") + return redirect(reverse('preferences:display-options')) + return form( + {'preferenceform': mailcontact, 'action_name': 'Editer'}, + 'preferences/preferences.html', + request + ) + + +@login_required +@can_delete_set(MailContact) +def del_mailcontact(request, instances): + """Suppression d'une adresse de contact""" + mailcontacts = DelMailContactForm( + request.POST or None, + instances=instances + ) + if mailcontacts.is_valid(): + mailcontacts_dels = mailcontacts.cleaned_data['mailcontacts'] + for mailcontacts_del in mailcontacts_dels: + try: + with transaction.atomic(), reversion.create_revision(): + mailcontacts_del.delete() + reversion.set_user(request.user) + messages.success(request, "L'adresse a été supprimée") + except ProtectedError: + messages.error(request, "Erreur le service\ + suivant %s ne peut être supprimé" % mailcontacts_del) + return redirect(reverse('preferences:display-options')) + return form( + {'preferenceform': mailcontacts, 'action_name': 'Supprimer'}, + 'preferences/preferences.html', + request + ) diff --git a/re2o/templatetags/acl.py b/re2o/templatetags/acl.py index fe13c5ac..9a439f88 100644 --- a/re2o/templatetags/acl.py +++ b/re2o/templatetags/acl.py @@ -79,7 +79,6 @@ from django.contrib.contenttypes.models import ContentType register = template.Library() - def get_model(model_name): """Retrieve the model object from its name""" splitted = model_name.split('.') From 5c1d2a6b900c17fc9fe1b1eb9ede9b4fea3957c0 Mon Sep 17 00:00:00 2001 From: grisel-davy Date: Sun, 1 Jul 2018 10:49:47 +0200 Subject: [PATCH 02/14] =?UTF-8?q?Page=20de=20contact=20cot=C3=A9=20utilisa?= =?UTF-8?q?teur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- preferences/models.py | 4 + re2o/templates/re2o/contact.html | 52 +++++++++++ re2o/views.py | 142 +++++++++++++++++++++++++++++-- 3 files changed, 192 insertions(+), 6 deletions(-) create mode 100644 re2o/templates/re2o/contact.html diff --git a/preferences/models.py b/preferences/models.py index d6a1c6b6..f7d42c10 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -282,6 +282,10 @@ class MailContact(AclMixin, models.Model): max_length = 256 ) + @cached_property + def get_name(self): + return self.address.split("@")[0] + class Meta: permissions = ( ("view_mailcontact", "Peut voir les mails de contact"), diff --git a/re2o/templates/re2o/contact.html b/re2o/templates/re2o/contact.html new file mode 100644 index 00000000..474ac7e8 --- /dev/null +++ b/re2o/templates/re2o/contact.html @@ -0,0 +1,52 @@ +{% extends "re2o/sidebar.html" %} +{% comment %} +Re2o est un logiciel d'administration développé initiallement au rezometz. Il +se veut agnostique au réseau considéré, de manière à être installable en +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 "Contact" %}{% endblock %} + +{% block content %} +

{% blocktrans %}Contacter l'association {{asso_name}}{% endblocktrans %}

+
+ +{% for contact in contacts %} + +
+

{{ contact.get_name }}

+
+
+
{{ contact.commentary}}
+ +
+
+
+ +{% endfor %} + + + +{% endblock %} + diff --git a/re2o/views.py b/re2o/views.py index 9a9dec78..aaf69602 100644 --- a/re2o/views.py +++ b/re2o/views.py @@ -36,6 +36,8 @@ from django.views.decorators.cache import cache_page from preferences.models import ( Service, + MailContact, + GeneralOption, AssoOption, HomeOption ) @@ -60,12 +62,125 @@ def index(request): twitter_account_name = HomeOption.get_cached_value('twitter_account_name') asso_name = AssoOption.get_cached_value('pseudo') return form({ - 'services_urls': services, - 'twitter_url': twitter_url, - 'twitter_account_name': twitter_account_name, - 'facebook_url': facebook_url, - 'asso_name': asso_name - }, 're2o/index.html', request) + 'services_urls': services, + 'twitter_url': twitter_url, + 'twitter_account_name' : twitter_account_name, + 'facebook_url': facebook_url, + 'asso_name': asso_name + }, 're2o/index.html', request) + + +#: Binding the corresponding char sequence of history url to re2o models. +HISTORY_BIND = { + 'users': { + 'user': users.models.User, + 'ban': users.models.Ban, + 'mailalias': users.models.MailAlias, + 'whitelist': users.models.Whitelist, + 'school': users.models.School, + 'listright': users.models.ListRight, + 'serviceuser': users.models.ServiceUser, + 'listshell': users.models.ListShell, + }, + 'preferences': { + 'service': preferences.models.Service, + 'mailcontact': preferences.models.MailContact, + }, + 'cotisations': { + 'facture': cotisations.models.Facture, + 'article': cotisations.models.Article, + 'paiement': cotisations.models.Paiement, + 'banque': cotisations.models.Banque, + }, + 'topologie': { + 'switch': topologie.models.Switch, + 'port': topologie.models.Port, + 'room': topologie.models.Room, + 'stack': topologie.models.Stack, + 'modelswitch': topologie.models.ModelSwitch, + 'constructorswitch': topologie.models.ConstructorSwitch, + 'accesspoint': topologie.models.AccessPoint, + 'switchbay': topologie.models.SwitchBay, + 'building': topologie.models.Building, + }, + 'machines': { + 'machine': machines.models.Machine, + 'interface': machines.models.Interface, + 'domain': machines.models.Domain, + 'machinetype': machines.models.MachineType, + 'iptype': machines.models.IpType, + 'extension': machines.models.Extension, + 'soa': machines.models.SOA, + 'mx': machines.models.Mx, + 'txt': machines.models.Txt, + 'dname': machines.models.DName, + 'srv': machines.models.Srv, + 'ns': machines.models.Ns, + 'service': machines.models.Service, + 'role': machines.models.Role, + 'vlan': machines.models.Vlan, + 'nas': machines.models.Nas, + 'ipv6list': machines.models.Ipv6List, + 'sshfingerprint': machines.models.SshFingerprint, + 'sshfpralgo': machines.models.SshFprAlgo, + }, +} + + +@login_required +def history(request, application, object_name, object_id): + """Render history for a model. + + The model is determined using the `HISTORY_BIND` dictionnary if none is + found, raises a Http404. The view checks if the user is allowed to see the + history using the `can_view` method of the model. + + Args: + request: The request sent by the user. + object_name: Name of the model. + object_id: Id of the object you want to acces history. + + Returns: + The rendered page of history if access is granted, else the user is + redirected to their profile page, with an error message. + + Raises: + Http404: This kind of models doesn't have history. + """ + try: + model = HISTORY_BIND[application][object_name] + except KeyError: + raise Http404(u"Il n'existe pas d'historique pour ce modèle.") + object_name_id = object_name + 'id' + kwargs = {object_name_id: object_id} + try: + instance = model.get_instance(**kwargs) + except model.DoesNotExist: + messages.error(request, u"Entrée inexistante") + return redirect(reverse( + 'users:profil', + kwargs={'userid': str(request.user.id)} + )) + can, msg = instance.can_view(request.user) + if not can: + messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu") + return redirect(reverse( + 'users:profil', + kwargs={'userid': str(request.user.id)} + )) + pagination_number = GeneralOption.get_cached_value('pagination_number') + reversions = Version.objects.get_for_object(instance) + if hasattr(instance, 'linked_objects'): + for related_object in chain(instance.linked_objects()): + reversions = (reversions | + Version.objects.get_for_object(related_object)) + reversions = re2o_paginator(request, reversions, pagination_number) + return render( + request, + 're2o/history.html', + {'reversions': reversions, 'object': instance} + ) +>>>>>>> e42b8f9... Page de contact coté utilisateur @cache_page(7 * 24 * 60 * 60) @@ -106,6 +221,21 @@ def about_page(request): } ) +def contact_page(request): + """The view for the contact page + Send all the objects MailContact + """ + address = MailContact.objects.all() + + return render( + request, + "re2o/contact.html", + { + 'contacts': address, + 'asso_name': AssoOption.objects.first().name + } + ) + def handler500(request): """The handler view for a 500 error""" From 15571e79a1c8a600329c3d835346ca76306b82fd Mon Sep 17 00:00:00 2001 From: Grizzly Date: Sun, 1 Jul 2018 16:41:03 +0000 Subject: [PATCH 03/14] oubli du fichier urls --- re2o/urls.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/re2o/urls.py b/re2o/urls.py index 87a5b346..d1e11d52 100644 --- a/re2o/urls.py +++ b/re2o/urls.py @@ -47,7 +47,7 @@ from django.conf.urls import include, url from django.contrib import admin from django.contrib.auth import views as auth_views -from .views import index, about_page +from .views import index, about_page, contact_page handler500 = 're2o.views.handler500' handler404 = 're2o.views.handler404' @@ -55,6 +55,7 @@ handler404 = 're2o.views.handler404' urlpatterns = [ url(r'^$', index, name='index'), url(r'^about/$', about_page, name='about'), + url(r'^contact/$', contact_page, name='contact'), url('^logout/', auth_views.logout, {'next_page': '/'}), url('^', include('django.contrib.auth.urls')), url(r'^i18n/', include('django.conf.urls.i18n')), From 5c8957ca5329b2c3af17812ab3ee611f678c131b Mon Sep 17 00:00:00 2001 From: grisel-davy Date: Sun, 1 Jul 2018 15:51:18 +0200 Subject: [PATCH 04/14] migration --- preferences/migrations/0038_mailcontact.py | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 preferences/migrations/0038_mailcontact.py diff --git a/preferences/migrations/0038_mailcontact.py b/preferences/migrations/0038_mailcontact.py new file mode 100644 index 00000000..6165b98a --- /dev/null +++ b/preferences/migrations/0038_mailcontact.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-06-30 15:27 +from __future__ import unicode_literals + +from django.db import migrations, models +import re2o.mixins + + +class Migration(migrations.Migration): + + dependencies = [ + ('preferences', '0037_optionaluser_max_mail_alias'), + ] + + operations = [ + migrations.CreateModel( + name='MailContact', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('address', models.EmailField(default='contact@example.org', help_text='Adresse mail de contact', max_length=254)), + ('commentary', models.CharField(blank=True, help_text="Description de l'utilisation de l'adresse mail associée", max_length=256, null=True)), + ], + options={ + 'permissions': (('view_mailcontact', 'Peut voir les mails de contact'),), + }, + bases=(re2o.mixins.AclMixin, models.Model), + ), + ] From f6971e9fba681d2489ab5b924e7a3a0b9e618531 Mon Sep 17 00:00:00 2001 From: chirac Date: Mon, 23 Jul 2018 23:18:58 +0200 Subject: [PATCH 05/14] Update urls.py --- preferences/urls.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/preferences/urls.py b/preferences/urls.py index 896dc45f..a89fcdf3 100644 --- a/preferences/urls.py +++ b/preferences/urls.py @@ -80,11 +80,5 @@ urlpatterns = [ name='edit-mailcontact' ), url(r'^del_mailcontact/$', views.del_mailcontact, name='del-mailcontact'), - url( - r'^history/(?P\w+)/(?P[0-9]+)$', - re2o.views.history, - name='history', - kwargs={'application': 'preferences'}, - ), url(r'^$', views.display_options, name='display-options'), ] From d9d919f8fe83683ca73020bdf27667aba60ef0c7 Mon Sep 17 00:00:00 2001 From: chirac Date: Mon, 23 Jul 2018 23:23:09 +0200 Subject: [PATCH 06/14] Update aff_mailcontact.html --- preferences/templates/preferences/aff_mailcontact.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/preferences/templates/preferences/aff_mailcontact.html b/preferences/templates/preferences/aff_mailcontact.html index 55d268f0..76e11d70 100644 --- a/preferences/templates/preferences/aff_mailcontact.html +++ b/preferences/templates/preferences/aff_mailcontact.html @@ -38,7 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% can_edit mailcontact %} {% include 'buttons/edit.html' with href='preferences:edit-mailcontact' id=mailcontact.id %} {% acl_end %} - {% include 'buttons/history.html' with href='preferences:history' name='mailcontact' id=mailcontact.id %} + {% history_button mailcontact %}
{% endfor %} From 5b61d8991e7091ebb730b4e5e6dbc6a095ff2611 Mon Sep 17 00:00:00 2001 From: chirac Date: Mon, 23 Jul 2018 23:24:13 +0200 Subject: [PATCH 07/14] Update views.py --- re2o/views.py | 113 -------------------------------------------------- 1 file changed, 113 deletions(-) diff --git a/re2o/views.py b/re2o/views.py index aaf69602..ff34d726 100644 --- a/re2o/views.py +++ b/re2o/views.py @@ -70,119 +70,6 @@ def index(request): }, 're2o/index.html', request) -#: Binding the corresponding char sequence of history url to re2o models. -HISTORY_BIND = { - 'users': { - 'user': users.models.User, - 'ban': users.models.Ban, - 'mailalias': users.models.MailAlias, - 'whitelist': users.models.Whitelist, - 'school': users.models.School, - 'listright': users.models.ListRight, - 'serviceuser': users.models.ServiceUser, - 'listshell': users.models.ListShell, - }, - 'preferences': { - 'service': preferences.models.Service, - 'mailcontact': preferences.models.MailContact, - }, - 'cotisations': { - 'facture': cotisations.models.Facture, - 'article': cotisations.models.Article, - 'paiement': cotisations.models.Paiement, - 'banque': cotisations.models.Banque, - }, - 'topologie': { - 'switch': topologie.models.Switch, - 'port': topologie.models.Port, - 'room': topologie.models.Room, - 'stack': topologie.models.Stack, - 'modelswitch': topologie.models.ModelSwitch, - 'constructorswitch': topologie.models.ConstructorSwitch, - 'accesspoint': topologie.models.AccessPoint, - 'switchbay': topologie.models.SwitchBay, - 'building': topologie.models.Building, - }, - 'machines': { - 'machine': machines.models.Machine, - 'interface': machines.models.Interface, - 'domain': machines.models.Domain, - 'machinetype': machines.models.MachineType, - 'iptype': machines.models.IpType, - 'extension': machines.models.Extension, - 'soa': machines.models.SOA, - 'mx': machines.models.Mx, - 'txt': machines.models.Txt, - 'dname': machines.models.DName, - 'srv': machines.models.Srv, - 'ns': machines.models.Ns, - 'service': machines.models.Service, - 'role': machines.models.Role, - 'vlan': machines.models.Vlan, - 'nas': machines.models.Nas, - 'ipv6list': machines.models.Ipv6List, - 'sshfingerprint': machines.models.SshFingerprint, - 'sshfpralgo': machines.models.SshFprAlgo, - }, -} - - -@login_required -def history(request, application, object_name, object_id): - """Render history for a model. - - The model is determined using the `HISTORY_BIND` dictionnary if none is - found, raises a Http404. The view checks if the user is allowed to see the - history using the `can_view` method of the model. - - Args: - request: The request sent by the user. - object_name: Name of the model. - object_id: Id of the object you want to acces history. - - Returns: - The rendered page of history if access is granted, else the user is - redirected to their profile page, with an error message. - - Raises: - Http404: This kind of models doesn't have history. - """ - try: - model = HISTORY_BIND[application][object_name] - except KeyError: - raise Http404(u"Il n'existe pas d'historique pour ce modèle.") - object_name_id = object_name + 'id' - kwargs = {object_name_id: object_id} - try: - instance = model.get_instance(**kwargs) - except model.DoesNotExist: - messages.error(request, u"Entrée inexistante") - return redirect(reverse( - 'users:profil', - kwargs={'userid': str(request.user.id)} - )) - can, msg = instance.can_view(request.user) - if not can: - messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu") - return redirect(reverse( - 'users:profil', - kwargs={'userid': str(request.user.id)} - )) - pagination_number = GeneralOption.get_cached_value('pagination_number') - reversions = Version.objects.get_for_object(instance) - if hasattr(instance, 'linked_objects'): - for related_object in chain(instance.linked_objects()): - reversions = (reversions | - Version.objects.get_for_object(related_object)) - reversions = re2o_paginator(request, reversions, pagination_number) - return render( - request, - 're2o/history.html', - {'reversions': reversions, 'object': instance} - ) ->>>>>>> e42b8f9... Page de contact coté utilisateur - - @cache_page(7 * 24 * 60 * 60) def about_page(request): """ The view for the about page. From 2599a503ac76136915d41b1d6f73c1a4504e647e Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Thu, 26 Jul 2018 20:34:39 +0200 Subject: [PATCH 08/14] Fix les migrations. --- .../migrations/{0038_mailcontact.py => 0046_mailcontact.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename preferences/migrations/{0038_mailcontact.py => 0046_mailcontact.py} (93%) diff --git a/preferences/migrations/0038_mailcontact.py b/preferences/migrations/0046_mailcontact.py similarity index 93% rename from preferences/migrations/0038_mailcontact.py rename to preferences/migrations/0046_mailcontact.py index 6165b98a..0c6705e7 100644 --- a/preferences/migrations/0038_mailcontact.py +++ b/preferences/migrations/0046_mailcontact.py @@ -9,7 +9,7 @@ import re2o.mixins class Migration(migrations.Migration): dependencies = [ - ('preferences', '0037_optionaluser_max_mail_alias'), + ('preferences', '0045_remove_unused_payment_fields'), ] operations = [ From 0cc15d63c869f41edbe374a4ba979448021940fb Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Thu, 26 Jul 2018 21:53:32 +0200 Subject: [PATCH 09/14] Traduction + utilisation du mixin de revision --- preferences/admin.py | 2 +- preferences/forms.py | 8 +- preferences/locale/fr/LC_MESSAGES/django.mo | Bin 0 -> 1245 bytes preferences/locale/fr/LC_MESSAGES/django.po | 70 ++++++++++++++++++ preferences/migrations/0046_mailcontact.py | 6 +- preferences/models.py | 10 ++- .../preferences/aff_mailcontact.html | 6 +- .../preferences/display_preferences.html | 6 +- preferences/views.py | 39 ++++------ 9 files changed, 108 insertions(+), 39 deletions(-) create mode 100644 preferences/locale/fr/LC_MESSAGES/django.mo create mode 100644 preferences/locale/fr/LC_MESSAGES/django.po diff --git a/preferences/admin.py b/preferences/admin.py index 043370db..5ca90095 100644 --- a/preferences/admin.py +++ b/preferences/admin.py @@ -67,7 +67,7 @@ class ServiceAdmin(VersionAdmin): class MailContactAdmin(VersionAdmin): - """Class admin gestion des adresses mail de contact""" + """Admin class for contact email adresses""" pass diff --git a/preferences/forms.py b/preferences/forms.py index 193beca8..99910f9c 100644 --- a/preferences/forms.py +++ b/preferences/forms.py @@ -27,6 +27,8 @@ from __future__ import unicode_literals from django.forms import ModelForm, Form from django import forms + +from re2o.mixins import FormRevMixin from .models import ( OptionalUser, OptionalMachine, @@ -229,8 +231,8 @@ class DelServiceForm(Form): else: self.fields['services'].queryset = Service.objects.all() -class MailContactForm(ModelForm): - """Edition, ajout d'adresse de contact""" +class MailContactForm(FormRevMixin, ModelForm): + """Edit and add contact email adress""" class Meta: model = MailContact fields = '__all__' @@ -241,7 +243,7 @@ class MailContactForm(ModelForm): class DelMailContactForm(Form): - """Suppression d'adresse de contact""" + """Delete contact email adress""" mailcontacts = forms.ModelMultipleChoiceField( queryset=MailContact.objects.none(), label="Enregistrements adresses actuels", diff --git a/preferences/locale/fr/LC_MESSAGES/django.mo b/preferences/locale/fr/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..21ed01a47b5f1f12bd59e566a77fbaba297530be GIT binary patch literal 1245 zcmZ{jO=}ZD7{^DgZ_#?NN~J13Afi$>CPB1rZE>TVRYy$QZ zX4cX^#>T-KcnEv|o(3O-r$7y!1-Ekld+-AGAHiwx3pfV;08QL4(Bzre&)6h51)c{h z;39l2(A0l(fU(2i2hjBO2|NRS1uuf%!K2_flAHY`cmc^_zIi?--1T} z8AQ44ZU;e=%PbRXmg&*_CTNEpfkB?-IS!(9whB2jI6**OL|!1dQp_1)0Vj%c^5aN* zz9!!HM93EQ?zSWTb;uQkLTOgzA=f+y#Sy1iQa=r~NJ5?`;0k`_OOa?1M-;D-UWZSq z*cYDW!KijFE;2U|nz^Q({D{&dFuEdZqf7aebxnA74SMD&@+BX+&3Sf@z1|?}5Wy`O zZ*X5*wZK~CQlS-_TF%0K=blTeZo5-!E*IK7iKVt0swV>LZrW2;H@2zJYIdy!Qw2d* z6~%0-l*%(!>84e=L6x$7{nm7;QYt}cwfUwn$#dO9*J)dgrd4%lscAQA(~p|VZlUfe zZFQv=snFB0v}tjrUZ-WJ;nHol;neDPoNBf0b~^KrM!nSQp=6;^Yq-0;my4x>c^V!e z)r$lI&7bRQN$81ami%>3Dz4{Nx{KD#uFjNPdea>BpXr9VfXA8{Ph*QlarFiSnBk+8tIBW4#(`GD;m$DZOb|!3Fl)um( zM;(L2DZohO`PAQ, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-07-26 21:49+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: models.py:256 +msgid "Contact email adress" +msgstr "Adresse email de contact" + +#: models.py:263 +msgid "Description of the associated email adress." +msgstr "Description de l'adresse mail associée." + +#: models.py:273 +msgid "Can see contact email" +msgstr "Peut voir un mail de contact" + +#: templates/preferences/aff_mailcontact.html:30 +msgid "Adress" +msgstr "Adresse" + +#: templates/preferences/aff_mailcontact.html:31 +msgid "Remark" +msgstr "Commentaire" + +#: templates/preferences/display_preferences.html:205 +msgid "Contact email adresses list" +msgstr "Liste des adresses email de contact" + +#: templates/preferences/display_preferences.html:207 +msgid "Add an adress" +msgstr "Ajouter une adresse" + +#: templates/preferences/display_preferences.html:209 +msgid "Delete one or multiple adresses" +msgstr "Supprimer une ou plusieurs adresses" + +#: views.py:210 +msgid "The adress was created." +msgstr "L'adresse a été créée." + +#: views.py:230 +msgid "Email adress updated." +msgstr "L'adresse email a été mise à jour." + +#: views.py:233 +msgid "Edit" +msgstr "Éditer" + +#: views.py:251 +msgid "The email adress was deleted." +msgstr "L'adresse email a été supprimée." + +#: views.py:254 +msgid "Delete" +msgstr "Supprimer" diff --git a/preferences/migrations/0046_mailcontact.py b/preferences/migrations/0046_mailcontact.py index 0c6705e7..1364ff66 100644 --- a/preferences/migrations/0046_mailcontact.py +++ b/preferences/migrations/0046_mailcontact.py @@ -17,11 +17,11 @@ class Migration(migrations.Migration): name='MailContact', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('address', models.EmailField(default='contact@example.org', help_text='Adresse mail de contact', max_length=254)), - ('commentary', models.CharField(blank=True, help_text="Description de l'utilisation de l'adresse mail associée", max_length=256, null=True)), + ('address', models.EmailField(default='contact@example.org', help_text="Contact email adress", max_length=254)), + ('commentary', models.CharField(blank=True, help_text="Description of the associated email adress.", max_length=256, null=True)), ], options={ - 'permissions': (('view_mailcontact', 'Peut voir les mails de contact'),), + 'permissions': (('view_mailcontact', "Can see contact email"),), }, bases=(re2o.mixins.AclMixin, models.Model), ), diff --git a/preferences/models.py b/preferences/models.py index f7d42c10..9226bd4a 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -31,6 +31,7 @@ from django.db.models.signals import post_save from django.dispatch import receiver from django.core.cache import cache from django.forms import ValidationError +from django.utils.translation import ugettext_lazy as _ import machines.models from re2o.mixins import AclMixin @@ -268,17 +269,18 @@ class Service(AclMixin, models.Model): return str(self.name) class MailContact(AclMixin, models.Model): - """Addresse mail de contact associée à un commentaire descriptif""" + """Contact email adress with a commentary.""" address = models.EmailField( default = "contact@example.org", - help_text = "Adresse mail de contact" + help_text = _("Contact email adress") ) commentary = models.CharField( blank = True, null = True, - help_text = "Description de l'utilisation de l'adresse mail associée", + help_text = _( + "Description of the associated email adress."), max_length = 256 ) @@ -288,7 +290,7 @@ class MailContact(AclMixin, models.Model): class Meta: permissions = ( - ("view_mailcontact", "Peut voir les mails de contact"), + ("view_mailcontact", _("Can see contact email")), ) def __str__(self): diff --git a/preferences/templates/preferences/aff_mailcontact.html b/preferences/templates/preferences/aff_mailcontact.html index 76e11d70..a87e03bb 100644 --- a/preferences/templates/preferences/aff_mailcontact.html +++ b/preferences/templates/preferences/aff_mailcontact.html @@ -21,12 +21,14 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. {% endcomment %} +{% load i18n %} {% load acl %} +{% load logs_extra %}
Url du compte twitter
- - + + diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html index eb2fcea8..5d2e2dd0 100644 --- a/preferences/templates/preferences/display_preferences.html +++ b/preferences/templates/preferences/display_preferences.html @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load bootstrap3 %} {% load acl %} {% load design %} +{% load i18n %} {% block title %}Création et modification des préférences{% endblock %} @@ -222,10 +223,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,

Liste des adresses mail de contact

+

{% trans "Contact email adresses list" %}

{% can_create preferences.MailContact%} - Ajouter une adresse + {% trans "Add an adress" %} {% acl_end %} - Supprimer une ou plusieurs adresses + {% trans "Delete one or multiple adresses" %} {% include "preferences/aff_mailcontact.html" with mailcontact_list=mailcontact_list %}

diff --git a/preferences/views.py b/preferences/views.py index 1ad0b42d..3c0c4879 100644 --- a/preferences/views.py +++ b/preferences/views.py @@ -36,13 +36,16 @@ from django.contrib import messages from django.contrib.auth.decorators import login_required from django.db.models import ProtectedError from django.db import transaction +from django.utils.translation import ugettext as _ from reversion import revisions as reversion from re2o.views import form from re2o.acl import can_create, can_edit, can_delete_set, can_view_all -from .forms import ServiceForm, DelServiceForm, MailContactForm, DelMailContactForm +from .forms import ( + ServiceForm, DelServiceForm, MailContactForm, DelMailContactForm +) from .models import ( Service, MailContact, @@ -197,17 +200,14 @@ def del_service(request, instances): @login_required @can_create(MailContact) def add_mailcontact(request): - """Ajout d'une adresse de contact""" + """Add a contact email adress.""" mailcontact = MailContactForm( request.POST or None, request.FILES or None ) if mailcontact.is_valid(): - with transaction.atomic(), reversion.create_revision(): - mailcontact.save() - reversion.set_user(request.user) - reversion.set_comment("Création") - messages.success(request, "Cette adresse a été ajoutée") + mailcontact.save() + messages.success(request, _("The adress was created.")) return redirect(reverse('preferences:display-options')) return form( {'preferenceform': mailcontact, 'action_name': 'Ajouter'}, @@ -219,21 +219,18 @@ def add_mailcontact(request): @login_required @can_edit(MailContact) def edit_mailcontact(request, mailcontact_instance, **_kwargs): - """Edition des adresses de contacte affichées""" + """Edit contact email adress.""" mailcontact = MailContactForm( request.POST or None, request.FILES or None, instance=mailcontact_instance ) if mailcontact.is_valid(): - with transaction.atomic(), reversion.create_revision(): - mailcontact.save() - reversion.set_user(request.user) - reversion.set_comment("Modification") - messages.success(request, "Adresse modifiée") + mailcontact.save() + messages.success(request, _("Email adress updated.")) return redirect(reverse('preferences:display-options')) return form( - {'preferenceform': mailcontact, 'action_name': 'Editer'}, + {'preferenceform': mailcontact, 'action_name': _('Edit')}, 'preferences/preferences.html', request ) @@ -242,7 +239,7 @@ def edit_mailcontact(request, mailcontact_instance, **_kwargs): @login_required @can_delete_set(MailContact) def del_mailcontact(request, instances): - """Suppression d'une adresse de contact""" + """Delete an email adress""" mailcontacts = DelMailContactForm( request.POST or None, instances=instances @@ -250,17 +247,11 @@ def del_mailcontact(request, instances): if mailcontacts.is_valid(): mailcontacts_dels = mailcontacts.cleaned_data['mailcontacts'] for mailcontacts_del in mailcontacts_dels: - try: - with transaction.atomic(), reversion.create_revision(): - mailcontacts_del.delete() - reversion.set_user(request.user) - messages.success(request, "L'adresse a été supprimée") - except ProtectedError: - messages.error(request, "Erreur le service\ - suivant %s ne peut être supprimé" % mailcontacts_del) + mailcontacts_del.delete() + messages.success(request, _("The email adress was deleted.")) return redirect(reverse('preferences:display-options')) return form( - {'preferenceform': mailcontacts, 'action_name': 'Supprimer'}, + {'preferenceform': mailcontacts, 'action_name': _('Delete')}, 'preferences/preferences.html', request ) From 0338b58a6c1bda28bc06498a8592dab1fae37d3a Mon Sep 17 00:00:00 2001 From: grisel-davy Date: Sun, 1 Jul 2018 15:33:16 +0200 Subject: [PATCH 10/14] =?UTF-8?q?fichiers=20oubli=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/base.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/templates/base.html b/templates/base.html index d6b03798..8a21a612 100644 --- a/templates/base.html +++ b/templates/base.html @@ -124,8 +124,12 @@ with this program; if not, write to the Free Software Foundation, Inc., {% acl_end %} -

  • - {% trans "About" %} +
  • {% if not request.user.is_authenticated %} {% if var_sa %} From 8abff4c35c4596e77780bdcd6969c57f14eee4fe Mon Sep 17 00:00:00 2001 From: chirac Date: Sun, 29 Jul 2018 17:12:37 +0200 Subject: [PATCH 11/14] Update contact.html --- re2o/templates/re2o/contact.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/re2o/templates/re2o/contact.html b/re2o/templates/re2o/contact.html index 474ac7e8..f2de696d 100644 --- a/re2o/templates/re2o/contact.html +++ b/re2o/templates/re2o/contact.html @@ -38,9 +38,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,

    {{ contact.get_name }}

    -
    {{ contact.commentary}}
    - -
    +
    {{ contact.commentary}}
    + +
    From 98c1e8cfe162cf6ea25445b944f0644f76a510eb Mon Sep 17 00:00:00 2001 From: chirac Date: Sun, 29 Jul 2018 17:13:36 +0200 Subject: [PATCH 12/14] Remove 5 indentation views.py --- re2o/views.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/re2o/views.py b/re2o/views.py index ff34d726..47826541 100644 --- a/re2o/views.py +++ b/re2o/views.py @@ -62,12 +62,12 @@ def index(request): twitter_account_name = HomeOption.get_cached_value('twitter_account_name') asso_name = AssoOption.get_cached_value('pseudo') return form({ - 'services_urls': services, - 'twitter_url': twitter_url, - 'twitter_account_name' : twitter_account_name, - 'facebook_url': facebook_url, - 'asso_name': asso_name - }, 're2o/index.html', request) + 'services_urls': services, + 'twitter_url': twitter_url, + 'twitter_account_name' : twitter_account_name, + 'facebook_url': facebook_url, + 'asso_name': asso_name + }, 're2o/index.html', request) @cache_page(7 * 24 * 60 * 60) From 19da3ce341dff82f54a7d4cd38ecf6b8824291e2 Mon Sep 17 00:00:00 2001 From: "David_5.1" Date: Sun, 29 Jul 2018 23:38:29 +0200 Subject: [PATCH 13/14] Remove useless space. --- re2o/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/re2o/views.py b/re2o/views.py index 47826541..fb00b98e 100644 --- a/re2o/views.py +++ b/re2o/views.py @@ -64,7 +64,7 @@ def index(request): return form({ 'services_urls': services, 'twitter_url': twitter_url, - 'twitter_account_name' : twitter_account_name, + 'twitter_account_name': twitter_account_name, 'facebook_url': facebook_url, 'asso_name': asso_name }, 're2o/index.html', request) From 7b7227332ddf6d269fd1cde9416041b87a100180 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Wed, 1 Aug 2018 19:07:01 +0200 Subject: [PATCH 14/14] Reconstruction des migrations dans l'ordre pour preference + fix display --- .../migrations/{0046_mailcontact.py => 0047_mailcontact.py} | 2 +- preferences/templates/preferences/display_preferences.html | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) rename preferences/migrations/{0046_mailcontact.py => 0047_mailcontact.py} (93%) diff --git a/preferences/migrations/0046_mailcontact.py b/preferences/migrations/0047_mailcontact.py similarity index 93% rename from preferences/migrations/0046_mailcontact.py rename to preferences/migrations/0047_mailcontact.py index 1364ff66..c7b7eda5 100644 --- a/preferences/migrations/0046_mailcontact.py +++ b/preferences/migrations/0047_mailcontact.py @@ -9,7 +9,7 @@ import re2o.mixins class Migration(migrations.Migration): dependencies = [ - ('preferences', '0045_remove_unused_payment_fields'), + ('preferences', '0046_optionaluser_mail_extension'), ] operations = [ diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html index 5d2e2dd0..2e34db5a 100644 --- a/preferences/templates/preferences/display_preferences.html +++ b/preferences/templates/preferences/display_preferences.html @@ -213,7 +213,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Ajouter un service {% acl_end %} - + Supprimer un ou plusieurs service {% include "preferences/aff_service.html" with service_list=service_list %} @@ -222,8 +222,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Editer -

    Liste des adresses mail de contact

    -

    {% trans "Contact email adresses list" %}

    +

    {% trans "Contact email adresses list" %}

    {% can_create preferences.MailContact%} {% trans "Add an adress" %} {% acl_end %}
    AdresseCommentaire{% trans "Adress" %}{% trans "Remark" %}