mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-08-19 21:53:41 +00:00
Crée des statistiques générales de la bdd + model alias
This commit is contained in:
parent
6af40d9e6c
commit
a4d3100512
15 changed files with 206 additions and 4 deletions
|
@ -6,6 +6,8 @@ from dateutil.relativedelta import relativedelta
|
|||
from django.core.validators import MinValueValidator
|
||||
|
||||
class Facture(models.Model):
|
||||
PRETTY_NAME = "Factures émises"
|
||||
|
||||
user = models.ForeignKey('users.User', on_delete=models.PROTECT)
|
||||
paiement = models.ForeignKey('Paiement', on_delete=models.PROTECT)
|
||||
banque = models.ForeignKey('Banque', on_delete=models.PROTECT, blank=True, null=True)
|
||||
|
@ -40,6 +42,8 @@ def facture_post_delete(sender, **kwargs):
|
|||
#user.ldap_sync(base=False, access_refresh=True, mac_refresh=False)
|
||||
|
||||
class Vente(models.Model):
|
||||
PRETTY_NAME = "Ventes effectuées"
|
||||
|
||||
facture = models.ForeignKey('Facture', on_delete=models.CASCADE)
|
||||
number = models.IntegerField(validators=[MinValueValidator(1)])
|
||||
name = models.CharField(max_length=255)
|
||||
|
@ -74,6 +78,8 @@ def vente_post_delete(sender, **kwargs):
|
|||
#user.ldap_sync(base=False, access_refresh=True, mac_refresh=False)
|
||||
|
||||
class Article(models.Model):
|
||||
PRETTY_NAME = "Articles en vente"
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
prix = models.DecimalField(max_digits=5, decimal_places=2)
|
||||
iscotisation = models.BooleanField()
|
||||
|
@ -83,18 +89,24 @@ class Article(models.Model):
|
|||
return self.name
|
||||
|
||||
class Banque(models.Model):
|
||||
PRETTY_NAME = "Banques enregistrées"
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Paiement(models.Model):
|
||||
PRETTY_NAME = "Moyens de paiement"
|
||||
|
||||
moyen = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return self.moyen
|
||||
|
||||
class Cotisation(models.Model):
|
||||
PRETTY_NAME = "Cotisations"
|
||||
|
||||
vente = models.OneToOneField('Vente', on_delete=models.CASCADE, null=True)
|
||||
date_start = models.DateTimeField()
|
||||
date_end = models.DateTimeField()
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<th>Modification par</th>
|
||||
<th>Date de modification</th>
|
||||
<th>Commentaire</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for revision in revisions_list %}
|
||||
|
@ -21,6 +22,7 @@
|
|||
<td>{{ revision.user }}</td>
|
||||
<td>{{ revision.date_created }}</td>
|
||||
<td>{{ revision.comment }}</td>
|
||||
</tr>
|
||||
{% if is_bureau %}<td><a class="btn btn-info btn-sm" role="button" href="{% url 'logs:revert-action' revision.id %}"><i class="glyphicon glyphicon-repeat"></i>Annuler</a></p></td>{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
|
17
logs/templates/logs/aff_stats_models.html
Normal file
17
logs/templates/logs/aff_stats_models.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
{% for key, stats in stats_list.items %}
|
||||
<table class="table table-striped">
|
||||
<h4>Statistiques de l'ensemble {{ key }}</h4>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Type d'objet</th>
|
||||
<th>Nombre d'entrée stockées</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for key, stat in stats.items %}
|
||||
<tr>
|
||||
<td>{{ stat.0 }}</td>
|
||||
<td>{{ stat.1 }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endfor %}
|
16
logs/templates/logs/delete.html
Normal file
16
logs/templates/logs/delete.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
{% extends "logs/sidebar.html" %}
|
||||
{% load bootstrap3 %}
|
||||
|
||||
{% block title %}Supression d'action{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<form class="form" method="post">
|
||||
{% csrf_token %}
|
||||
<h4>Attention, voulez-vous vraiment annuler cette action {{ objet_name }} ( {{ objet }} ) ?</h4>
|
||||
{% bootstrap_button "Confirmer" button_type="submit" icon="trash" %}
|
||||
</form>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
{% endblock %}
|
|
@ -2,5 +2,6 @@
|
|||
|
||||
{% block sidebar %}
|
||||
{% if is_cableur %}
|
||||
<p><a href="{% url "logs:stats-models" %}">Statistiques base de donnée</a></p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
12
logs/templates/logs/stats_models.html
Normal file
12
logs/templates/logs/stats_models.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
{% extends "logs/sidebar.html" %}
|
||||
{% load bootstrap3 %}
|
||||
|
||||
{% block title %}Statistiques des objets base de données{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Statistiques bdd</h2>
|
||||
{% include "logs/aff_stats_models.html" with stats_list=stats_list %}
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
{% endblock %}
|
|
@ -4,4 +4,6 @@ from . import views
|
|||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.index, name='index'),
|
||||
url(r'^revert_action/(?P<revision_id>[0-9]+)$', views.revert_action, name='revert-action'),
|
||||
url(r'^stats_models/$', views.stats_models, name='stats-models'),
|
||||
]
|
||||
|
|
|
@ -16,8 +16,18 @@ from django.db import transaction
|
|||
from reversion.models import Revision
|
||||
from reversion.models import Version
|
||||
|
||||
from users.models import User, ServiceUser, Right, School, ListRight, ListShell, Ban, Whitelist
|
||||
from cotisations.models import Facture, Vente, Article, Banque, Paiement, Cotisation
|
||||
from machines.models import Machine, MachineType, IpType, Extension, Interface, Alias, IpList
|
||||
from topologie.models import Switch, Port, Room
|
||||
|
||||
from re2o.settings import PAGINATION_NUMBER, PAGINATION_LARGE_NUMBER
|
||||
|
||||
def form(ctx, template, request):
|
||||
c = ctx
|
||||
c.update(csrf(request))
|
||||
return render_to_response(template, c, context_instance=RequestContext(request))
|
||||
|
||||
@login_required
|
||||
@permission_required('cableur')
|
||||
def index(request):
|
||||
|
@ -34,3 +44,55 @@ def index(request):
|
|||
revisions = paginator.page(paginator.num_pages)
|
||||
return render(request, 'logs/index.html', {'revisions_list': revisions})
|
||||
|
||||
@login_required
|
||||
@permission_required('bureau')
|
||||
def revert_action(request, revision_id):
|
||||
""" Annule l'action en question """
|
||||
try:
|
||||
revision = Revision.objects.get(id=revision_id)
|
||||
except Revision.DoesNotExist:
|
||||
messages.error(request, u"Revision inexistante" )
|
||||
if request.method == "POST":
|
||||
revision.revert()
|
||||
messages.success(request, "L'action a été supprimée")
|
||||
return redirect("/logs/")
|
||||
return form({'objet': revision, 'objet_name': revision.__class__.__name__ }, 'logs/delete.html', request)
|
||||
|
||||
@login_required
|
||||
@permission_required('cableur')
|
||||
def stats_models(request):
|
||||
stats = {
|
||||
'Users' : {
|
||||
'users' : [User.PRETTY_NAME, User.objects.count()],
|
||||
'serviceuser' : [ServiceUser.PRETTY_NAME, ServiceUser.objects.count()],
|
||||
'right' : [Right.PRETTY_NAME, Right.objects.count()],
|
||||
'school' : [School.PRETTY_NAME, School.objects.count()],
|
||||
'listright' : [ListRight.PRETTY_NAME, ListRight.objects.count()],
|
||||
'listshell' : [ListShell.PRETTY_NAME, ListShell.objects.count()],
|
||||
'ban' : [Ban.PRETTY_NAME, Ban.objects.count()],
|
||||
'whitelist' : [Whitelist.PRETTY_NAME, Whitelist.objects.count()]
|
||||
},
|
||||
'Cotisations' : {
|
||||
'factures' : [Facture.PRETTY_NAME, Facture.objects.count()],
|
||||
'vente' : [Vente.PRETTY_NAME, Vente.objects.count()],
|
||||
'cotisation' : [Cotisation.PRETTY_NAME, Cotisation.objects.count()],
|
||||
'article' : [Article.PRETTY_NAME, Article.objects.count()],
|
||||
'banque' : [Banque.PRETTY_NAME, Banque.objects.count()],
|
||||
'cotisation' : [Cotisation.PRETTY_NAME, Cotisation.objects.count()],
|
||||
},
|
||||
'Machines' : {
|
||||
'machine' : [Machine.PRETTY_NAME, Machine.objects.count()],
|
||||
'typemachine' : [MachineType.PRETTY_NAME, MachineType.objects.count()],
|
||||
'typeip' : [IpType.PRETTY_NAME, IpType.objects.count()],
|
||||
'extension' : [Extension.PRETTY_NAME, Extension.objects.count()],
|
||||
'interface' : [Interface.PRETTY_NAME, Interface.objects.count()],
|
||||
'alias' : [Alias.PRETTY_NAME, Alias.objects.count()],
|
||||
'iplist' : [IpList.PRETTY_NAME, IpList.objects.count()],
|
||||
},
|
||||
'Topologie' : {
|
||||
'switch' : [Switch.PRETTY_NAME, Switch.objects.count()],
|
||||
'port' : [Port.PRETTY_NAME, Port.objects.count()],
|
||||
'chambre' : [Room.PRETTY_NAME, Room.objects.count()],
|
||||
},
|
||||
}
|
||||
return render(request, 'logs/stats_models.html', {'stats_list': stats})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from django.contrib import admin
|
||||
from reversion.admin import VersionAdmin
|
||||
|
||||
from .models import IpType, Machine, MachineType, IpList, Interface, Extension
|
||||
from .models import IpType, Machine, MachineType, Alias, IpList, Interface, Extension
|
||||
|
||||
class MachineAdmin(VersionAdmin):
|
||||
list_display = ('user','name','active')
|
||||
|
@ -22,9 +22,13 @@ class IpListAdmin(VersionAdmin):
|
|||
class InterfaceAdmin(VersionAdmin):
|
||||
list_display = ('machine','type','dns','mac_address','ipv4','details')
|
||||
|
||||
class AliasAdmin(VersionAdmin):
|
||||
list_display = ('interface_parent', 'alias')
|
||||
|
||||
admin.site.register(Machine, MachineAdmin)
|
||||
admin.site.register(MachineType, MachineTypeAdmin)
|
||||
admin.site.register(IpType, IpTypeAdmin)
|
||||
admin.site.register(Extension, ExtensionAdmin)
|
||||
admin.site.register(IpList, IpListAdmin)
|
||||
admin.site.register(Interface, InterfaceAdmin)
|
||||
admin.site.register(Alias, AliasAdmin)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from django.forms import ModelForm, Form, ValidationError
|
||||
from django import forms
|
||||
from .models import Machine, Interface, IpList, MachineType, Extension, IpType
|
||||
from .models import Alias, Machine, Interface, IpList, MachineType, Extension, IpType
|
||||
|
||||
class EditMachineForm(ModelForm):
|
||||
class Meta:
|
||||
|
@ -59,6 +59,15 @@ class BaseEditInterfaceForm(EditInterfaceForm):
|
|||
self.fields['type'].queryset = MachineType.objects.filter(ip_type=IpType.objects.filter(need_infra=False))
|
||||
self.fields['ipv4'].queryset = IpList.objects.filter(ip_type=IpType.objects.filter(need_infra=False))
|
||||
|
||||
class NewAliasForm(ModelForm):
|
||||
class Meta:
|
||||
model = Alias
|
||||
fields = ['alias']
|
||||
|
||||
class EditAliasFullForm(NewAliasForm):
|
||||
class Meta(NewAliasForm.Meta):
|
||||
fields = '__all__'
|
||||
|
||||
class MachineTypeForm(ModelForm):
|
||||
class Meta:
|
||||
model = MachineType
|
||||
|
|
22
machines/migrations/0027_alias.py
Normal file
22
machines/migrations/0027_alias.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('machines', '0026_auto_20161026_1348'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Alias',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False, auto_created=True, verbose_name='ID')),
|
||||
('alias', models.CharField(max_length=255, help_text='Obligatoire et unique, ne doit pas comporter de points', unique=True)),
|
||||
('interface_parent', models.ForeignKey(to='machines.Interface')),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -8,6 +8,8 @@ from re2o.settings import MAIN_EXTENSION
|
|||
|
||||
|
||||
class Machine(models.Model):
|
||||
PRETTY_NAME = "Machine"
|
||||
|
||||
user = models.ForeignKey('users.User', on_delete=models.PROTECT)
|
||||
name = models.CharField(max_length=255, help_text="Optionnel", blank=True, null=True)
|
||||
active = models.BooleanField(default=True)
|
||||
|
@ -16,6 +18,8 @@ class Machine(models.Model):
|
|||
return str(self.user) + ' - ' + str(self.id) + ' - ' + str(self.name)
|
||||
|
||||
class MachineType(models.Model):
|
||||
PRETTY_NAME = "Type de machine"
|
||||
|
||||
type = models.CharField(max_length=255)
|
||||
ip_type = models.ForeignKey('IpType', on_delete=models.PROTECT, blank=True, null=True)
|
||||
|
||||
|
@ -23,6 +27,8 @@ class MachineType(models.Model):
|
|||
return self.type
|
||||
|
||||
class IpType(models.Model):
|
||||
PRETTY_NAME = "Type d'ip"
|
||||
|
||||
type = models.CharField(max_length=255)
|
||||
extension = models.ForeignKey('Extension', on_delete=models.PROTECT)
|
||||
need_infra = models.BooleanField(default=False)
|
||||
|
@ -31,12 +37,16 @@ class IpType(models.Model):
|
|||
return self.type
|
||||
|
||||
class Extension(models.Model):
|
||||
PRETTY_NAME = "Extensions dns"
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Interface(models.Model):
|
||||
PRETTY_NAME = "Interface"
|
||||
|
||||
ipv4 = models.OneToOneField('IpList', on_delete=models.PROTECT, blank=True, null=True)
|
||||
#ipv6 = models.GenericIPAddressField(protocol='IPv6', null=True)
|
||||
mac_address = MACAddressField(integer=False, unique=True)
|
||||
|
@ -54,7 +64,18 @@ class Interface(models.Model):
|
|||
def __str__(self):
|
||||
return self.dns
|
||||
|
||||
class Alias(models.Model):
|
||||
PRETTY_NAME = "Alias dns"
|
||||
|
||||
interface_parent = models.ForeignKey('Interface', on_delete=models.CASCADE)
|
||||
alias = models.CharField(help_text="Obligatoire et unique, ne doit pas comporter de points", max_length=255, unique=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.alias
|
||||
|
||||
class IpList(models.Model):
|
||||
PRETTY_NAME = "Addresses ipv4"
|
||||
|
||||
ipv4 = models.GenericIPAddressField(protocol='IPv4', unique=True)
|
||||
ip_type = models.ForeignKey('IpType', on_delete=models.PROTECT)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ from reversion import revisions as reversion
|
|||
|
||||
import re
|
||||
from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm
|
||||
from .forms import IpTypeForm, DelIpTypeForm
|
||||
from .forms import IpTypeForm, DelIpTypeForm, NewAliasForm, EditAliasFullForm
|
||||
from .models import IpType, Machine, Interface, IpList, MachineType, Extension
|
||||
from users.models import User
|
||||
from re2o.settings import PAGINATION_NUMBER, PAGINATION_LARGE_NUMBER
|
||||
|
|
|
@ -16,6 +16,8 @@ def clean_port_related(port):
|
|||
related_port.save()
|
||||
|
||||
class Switch(models.Model):
|
||||
PRETTY_NAME = "Switch / Commutateur"
|
||||
|
||||
switch_interface = models.OneToOneField('machines.Interface', on_delete=models.CASCADE)
|
||||
location = models.CharField(max_length=255)
|
||||
number = models.IntegerField()
|
||||
|
@ -25,6 +27,8 @@ class Switch(models.Model):
|
|||
return str(self.location)
|
||||
|
||||
class Port(models.Model):
|
||||
PRETTY_NAME = "Port de switch"
|
||||
|
||||
switch = models.ForeignKey('Switch', related_name="ports")
|
||||
port = models.IntegerField()
|
||||
room = models.ForeignKey('Room', on_delete=models.PROTECT, blank=True, null=True)
|
||||
|
@ -36,6 +40,8 @@ class Port(models.Model):
|
|||
unique_together = ('switch', 'port')
|
||||
|
||||
def clean(self):
|
||||
if self.port > self.switch.number:
|
||||
raise ValidationError("Ce port ne peut exister, numero trop élevé")
|
||||
if self.room and self.machine_interface or self.room and self.related or self.machine_interface and self.related:
|
||||
raise ValidationError("Chambre, interface et related_port sont mutuellement exclusifs")
|
||||
if self.related==self:
|
||||
|
@ -52,6 +58,8 @@ class Port(models.Model):
|
|||
return str(self.switch) + " - " + str(self.port)
|
||||
|
||||
class Room(models.Model):
|
||||
PRETTY_NAME = "Chambre/ Prise murale"
|
||||
|
||||
name = models.CharField(max_length=255, unique=True)
|
||||
details = models.CharField(max_length=255, blank=True)
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ class UserManager(BaseUserManager):
|
|||
|
||||
|
||||
class User(AbstractBaseUser):
|
||||
PRETTY_NAME = "Utilisateurs"
|
||||
STATE_ACTIVE = 0
|
||||
STATE_DISABLED = 1
|
||||
STATE_ARCHIVE = 2
|
||||
|
@ -287,6 +288,7 @@ def user_post_delete(sender, **kwargs):
|
|||
#user.ldap_del()
|
||||
|
||||
class ServiceUser(AbstractBaseUser):
|
||||
PRETTY_NAME = "Utilisateurs de service"
|
||||
|
||||
pseudo = models.CharField(max_length=32, unique=True, help_text="Doit contenir uniquement des lettres, chiffres, ou tirets", validators=[linux_user_validator])
|
||||
|
||||
|
@ -323,6 +325,8 @@ def service_user_post_delete(sender, **kwargs):
|
|||
service_user.ldap_del()
|
||||
|
||||
class Right(models.Model):
|
||||
PRETTY_NAME = "Droits affectés à des users"
|
||||
|
||||
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
||||
right = models.ForeignKey('ListRight', on_delete=models.PROTECT)
|
||||
|
||||
|
@ -343,6 +347,8 @@ def right_post_delete(sender, **kwargs):
|
|||
right.ldap_sync()
|
||||
|
||||
class School(models.Model):
|
||||
PRETTY_NAME = "Etablissements enregistrés"
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
|
@ -350,6 +356,8 @@ class School(models.Model):
|
|||
|
||||
|
||||
class ListRight(models.Model):
|
||||
PRETTY_NAME = "Liste des droits existants"
|
||||
|
||||
listright = models.CharField(max_length=255, unique=True)
|
||||
gid = models.IntegerField(unique=True, null=True)
|
||||
|
||||
|
@ -383,12 +391,16 @@ def listright_post_delete(sender, **kwargs):
|
|||
right.ldap_del()
|
||||
|
||||
class ListShell(models.Model):
|
||||
PRETTY_NAME = "Liste des shells disponibles"
|
||||
|
||||
shell = models.CharField(max_length=255, unique=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.shell
|
||||
|
||||
class Ban(models.Model):
|
||||
PRETTY_NAME = "Liste des bannissements"
|
||||
|
||||
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
||||
raison = models.CharField(max_length=255)
|
||||
date_start = models.DateTimeField(auto_now_add=True)
|
||||
|
@ -399,6 +411,8 @@ class Ban(models.Model):
|
|||
|
||||
|
||||
class Whitelist(models.Model):
|
||||
PRETTY_NAME = "Liste des accès gracieux"
|
||||
|
||||
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
||||
raison = models.CharField(max_length=255)
|
||||
date_start = models.DateTimeField(auto_now_add=True)
|
||||
|
|
Loading…
Reference in a new issue