diff --git a/preferences/forms.py b/preferences/forms.py index 0bdee00c..4c9024d6 100644 --- a/preferences/forms.py +++ b/preferences/forms.py @@ -63,7 +63,10 @@ class EditAssoOptionForm(ModelForm): model = AssoOption fields = '__all__' -class Service(ModelForm): +class ServiceForm(ModelForm): class Meta: model = Service fields = '__all__' + +class DelServiceForm(Form): + services = forms.ModelMultipleChoiceField(queryset=Service.objects.all(), label="Enregistrements service actuels", widget=forms.CheckboxSelectMultiple) diff --git a/preferences/models.py b/preferences/models.py index 47ab7381..d87c1eb4 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -59,6 +59,9 @@ class Service(models.Model): description = models.TextField() image = models.ImageField(upload_to='logo', blank=True) + def __str__(self): + return str(self.name) + class AssoOption(models.Model): PRETTY_NAME = "Options de l'association" diff --git a/preferences/templates/preferences/aff_service.html b/preferences/templates/preferences/aff_service.html new file mode 100644 index 00000000..e5f8aecf --- /dev/null +++ b/preferences/templates/preferences/aff_service.html @@ -0,0 +1,51 @@ +{% 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 %} + + + + + + + + + + + + + {% for service in service_list %} + + + + + + + + {% endfor %} +
NomUrlDescriptionImage
{{ service.name }}{{ service.url }}{{ service.description }}{{ service.image }} + {% if is_admin %} + {% include 'buttons/edit.html' with href='preferences:edit-services' id=service.id %} + {% endif %} + {% include 'buttons/history.html' with href='preferences:history' name='service' id=service.id %} +
+ diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html index ffb0091e..dd6f6996 100644 --- a/preferences/templates/preferences/display_preferences.html +++ b/preferences/templates/preferences/display_preferences.html @@ -124,6 +124,12 @@ with this program; if not, write to the Free Software Foundation, Inc., {{ assooptions.utilisateur_asso }} +

Liste des services page d'accueil

+ {% if is_infra %} + Ajouter un service + Supprimer un ou plusieurs service + {% endif %} + {% include "preferences/aff_service.html" with service_list=service_list %}


diff --git a/preferences/templates/preferences/preferences.html b/preferences/templates/preferences/preferences.html new file mode 100644 index 00000000..6184bfb3 --- /dev/null +++ b/preferences/templates/preferences/preferences.html @@ -0,0 +1,46 @@ +{% extends "preferences/sidebar.html" %} +{% comment %} +Re2o est un logiciel d'administration développé initiallement au rezometz. Il +se veut agnostique au réseau considéré, de manière à être installable en +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 %} + +{% block title %}Création et modification des preferences{% endblock %} + +{% block content %} +{% if preferenceform %} +{% bootstrap_form_errors preferenceform %} +{% endif %} + + +
+ {% csrf_token %} + {% if preferenceform %} + {% bootstrap_form preferenceform %} + {% endif %} + {% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %} +
+
+
+
+{% endblock %} diff --git a/preferences/urls.py b/preferences/urls.py index 0f1ba560..17119d4e 100644 --- a/preferences/urls.py +++ b/preferences/urls.py @@ -30,5 +30,9 @@ urlpatterns = [ url(r'^edit_options/(?P
OptionalMachine)$', views.edit_options, name='edit-options'), url(r'^edit_options/(?P
GeneralOption)$', views.edit_options, name='edit-options'), url(r'^edit_options/(?P
AssoOption)$', views.edit_options, name='edit-options'), + url(r'^add_services/$', views.add_services, name='add-services'), + url(r'^edit_services/(?P[0-9]+)$', views.edit_services, name='edit-services'), + url(r'^del_services/$', views.del_services, name='del-services'), + url(r'^history/(?Pservice)/(?P[0-9]+)$', views.history, name='history'), url(r'^$', views.display_options, name='display-options'), ] diff --git a/preferences/views.py b/preferences/views.py index 5c0384cd..8176ba9b 100644 --- a/preferences/views.py +++ b/preferences/views.py @@ -42,7 +42,8 @@ from django.db import transaction from reversion.models import Version from reversion import revisions as reversion -from .models import OptionalUser, OptionalMachine, AssoOption, GeneralOption +from .forms import ServiceForm, DelServiceForm +from .models import Service, OptionalUser, OptionalMachine, AssoOption, GeneralOption from . import models from . import forms @@ -59,7 +60,8 @@ def display_options(request): machineoptions, created = OptionalMachine.objects.get_or_create() generaloptions, created = GeneralOption.objects.get_or_create() assooptions, crated = AssoOption.objects.get_or_create() - return form({'useroptions': useroptions, 'machineoptions': machineoptions, 'generaloptions': generaloptions, 'assooptions' : assooptions}, 'preferences/display_preferences.html', request) + service_list = Service.objects.all() + return form({'useroptions': useroptions, 'machineoptions': machineoptions, 'generaloptions': generaloptions, 'assooptions' : assooptions, 'service_list':service_list}, 'preferences/display_preferences.html', request) @login_required @permission_required('admin') @@ -82,3 +84,74 @@ def edit_options(request, section): messages.error(request, "Objet inconnu") return redirect("/preferences/") +@login_required +@permission_required('admin') +def add_services(request): + services = ServiceForm(request.POST or None) + if services.is_valid(): + with transaction.atomic(), reversion.create_revision(): + services.save() + reversion.set_user(request.user) + reversion.set_comment("Création") + messages.success(request, "Cet enregistrement ns a été ajouté") + return redirect("/preferences/") + return form({'preferenceform': services}, 'preferences/preferences.html', request) + +@login_required +@permission_required('admin') +def edit_services(request, servicesid): + try: + services_instance = Service.objects.get(pk=servicesid) + except Service.DoesNotExist: + messages.error(request, u"Entrée inexistante" ) + return redirect("/preferences/") + services = ServiceForm(request.POST or None, instance=services_instance) + if services.is_valid(): + with transaction.atomic(), reversion.create_revision(): + services.save() + reversion.set_user(request.user) + reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in services.changed_data)) + messages.success(request, "Service modifié") + return redirect("/preferences/") + return form({'preferenceform': services}, 'preferences/preferences.html', request) + +@login_required +@permission_required('admin') +def del_services(request): + services = DelServiceForm(request.POST or None) + if services.is_valid(): + services_dels = services.cleaned_data['services'] + for services_del in services_dels: + try: + with transaction.atomic(), reversion.create_revision(): + services_del.delete() + reversion.set_user(request.user) + messages.success(request, "Le services a été supprimée") + except ProtectedError: + messages.error(request, "Erreur le service suivant %s ne peut être supprimé" % services_del) + return redirect("/preferences/") + return form({'preferenceform': services}, 'preferences/preferences.html', request) + +@login_required +@permission_required('cableur') +def history(request, object, id): + if object == 'service': + try: + object_instance = Service.objects.get(pk=id) + except Service.DoesNotExist: + messages.error(request, "Service inexistant") + return redirect("/preferences/") + options, created = GeneralOption.objects.get_or_create() + pagination_number = options.pagination_number + reversions = Version.objects.get_for_object(object_instance) + paginator = Paginator(reversions, pagination_number) + page = request.GET.get('page') + try: + reversions = paginator.page(page) + except PageNotAnInteger: + # If page is not an integer, deliver first page. + reversions = paginator.page(1) + except EmptyPage: + # If page is out of range (e.g. 9999), deliver last page of results. + reversions = paginator.page(paginator.num_pages) + return render(request, 're2o/history.html', {'reversions': reversions, 'object': object_instance}) diff --git a/re2o/context_processors.py b/re2o/context_processors.py index d1a216f0..8b34425c 100644 --- a/re2o/context_processors.py +++ b/re2o/context_processors.py @@ -32,6 +32,7 @@ def context_user(request): is_bofh = user.is_bofh is_trez = user.is_trez is_infra = user.is_infra + is_admin = user.is_admin else: interfaces = None is_cableur = False @@ -39,6 +40,7 @@ def context_user(request): is_bofh = False is_trez = False is_infra = False + is_admin = False return { 'request_user': user, 'is_cableur': is_cableur, @@ -46,6 +48,7 @@ def context_user(request): 'is_bofh': is_bofh, 'is_trez': is_trez, 'is_infra': is_infra, + 'is_admin' : is_admin, 'interfaces': interfaces, 'site_name': SITE_NAME, } diff --git a/re2o/settings_local.example.py b/re2o/settings_local.example.py index 766c37fc..0d684310 100644 --- a/re2o/settings_local.example.py +++ b/re2o/settings_local.example.py @@ -67,20 +67,6 @@ SITE_NAME = "Re2o.rez" MAIN_EXTENSION = ".rez" LOGO_PATH = "static_files/logo.png" -ASSO_NAME = "Asso reseau" -ASSO_ADDRESS_LINE1 = "2, rue Edouard Belin" -ASSO_ADDRESS_LINE2 = "57070 Metz" -ASSO_SIRET = "" -ASSO_EMAIL = "tresorier@ecole.fr" -ASSO_PHONE = "01 02 03 04 05" -ASSO_PSEUDO = "rezo" - -services_urls = { -#Fill IT : ex : 'gitlab': { -# 'url': 'https://gitlab.rezometz.org', -# 'logo': 'gitlab.png', -# 'description': 'Gitlab is cool 8-)'}, - } # Number of hours a token remains valid after having been created. Numeric and string # versions should have the same meaning. diff --git a/re2o/templates/re2o/index.html b/re2o/templates/re2o/index.html index ac51eee8..477c64e2 100644 --- a/re2o/templates/re2o/index.html +++ b/re2o/templates/re2o/index.html @@ -32,20 +32,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,

Bienvenue sur {{ site_name }} !

-{% for col in services_urls %} +{% for service_list in services_urls %}
- {% for key, s in col.items %} + {% for service in service_list %}
- {{ key }} + {{ service.name }}
-

{{ key }}

-

{{ s.description }}

-

Accéder

+

{{ service.name }}

+

{{ service.description }}

+

Accéder

- {% endfor %} + {% endfor %}
{% endfor %}
diff --git a/re2o/views.py b/re2o/views.py index 8db3f288..df975634 100644 --- a/re2o/views.py +++ b/re2o/views.py @@ -24,7 +24,7 @@ from django.shortcuts import render from django.shortcuts import get_object_or_404 from django.template.context_processors import csrf from django.template import Context, RequestContext, loader -from re2o.settings import services_urls +from preferences.models import Service def form(ctx, template, request): c = ctx @@ -34,11 +34,8 @@ def form(ctx, template, request): def index(request): i = 0 - services = [{}] - for key, s in services_urls.items(): - if len(services) <= i: - services += [{}] - services[i][key] = s - i = i + 1 if i < 2 else 0 + services = [[], [], []] + for indice, serv in enumerate(Service.objects.all()): + services[indice % 3].append(serv) return form({'services_urls': services}, 're2o/index.html', request) diff --git a/topologie/views.py b/topologie/views.py index 4602845f..721e1d3e 100644 --- a/topologie/views.py +++ b/topologie/views.py @@ -35,9 +35,8 @@ from users.views import form from users.models import User from machines.forms import AliasForm, NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm -from preferences.models import GeneralOption +from preferences.models import AssoOption, GeneralOption -from re2o.settings import ASSO_PSEUDO @login_required @permission_required('cableur') @@ -150,10 +149,10 @@ def new_switch(request): interface = AddInterfaceForm(request.POST or None, infra=request.user.has_perms(('infra',))) domain = AliasForm(request.POST or None, infra=request.user.has_perms(('infra',))) if switch.is_valid() and machine.is_valid() and interface.is_valid(): - try: - user = User.objects.get(pseudo=ASSO_PSEUDO) - except User.DoesNotExist: - messages.error(request, "L'user %s n'existe pas encore, veuillez le créer" % ASSO_PSEUDO) + options, created = AssoOption.objects.get_or_create() + user = options.utilisateur_asso + if not user: + messages.error(request, "L'user association n'existe pas encore, veuillez le créer ou le linker dans preferences") return redirect("/topologie/") new_machine = machine.save(commit=False) new_machine.user = user