mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-12-26 08:53:46 +00:00
Merge branch 'search' into 'master'
Search See merge request rezo/re2o!28
This commit is contained in:
commit
8fbb1c5b04
11 changed files with 448 additions and 194 deletions
|
@ -36,7 +36,9 @@ def url_insert_param(url="", **kwargs):
|
||||||
Return the URL with some specific parameters inserted into the query
|
Return the URL with some specific parameters inserted into the query
|
||||||
part. If a URL has already some parameters, those requested will be
|
part. If a URL has already some parameters, those requested will be
|
||||||
modified if already exisiting or will be added and the other parameters
|
modified if already exisiting or will be added and the other parameters
|
||||||
will stay unmodified.
|
will stay unmodified. If parameters with the same name are already in the
|
||||||
|
URL and a value is specified for this parameter, it will replace all
|
||||||
|
existing parameters.
|
||||||
|
|
||||||
**Tag name**::
|
**Tag name**::
|
||||||
|
|
||||||
|
@ -82,18 +84,21 @@ def url_insert_param(url="", **kwargs):
|
||||||
# Get existing parameters in the url
|
# Get existing parameters in the url
|
||||||
params = {}
|
params = {}
|
||||||
if '?' in url:
|
if '?' in url:
|
||||||
url, params = url.split('?', maxsplit=1)
|
url, parameters = url.split('?', maxsplit=1)
|
||||||
params = {
|
for parameter in parameters.split('&'):
|
||||||
p[:p.find('=')]: p[p.find('=')+1:] for p in params.split('&')
|
p_name, p_value = parameter.split('=', maxsplit=1)
|
||||||
}
|
if p_name not in params:
|
||||||
|
params[p_name] = []
|
||||||
|
params[p_name].append(p_value)
|
||||||
|
|
||||||
# Add the request parameters to the list of parameters
|
# Add the request parameters to the list of parameters
|
||||||
for key, value in kwargs.items():
|
for key, value in kwargs.items():
|
||||||
params[key] = value
|
params[key] = [value]
|
||||||
|
|
||||||
# Write the url
|
# Write the url
|
||||||
url += '?'
|
url += '?'
|
||||||
for param, value in params.items():
|
for param, value_list in params.items():
|
||||||
|
for value in value_list:
|
||||||
url += str(param) + '=' + str(value) + '&'
|
url += str(param) + '=' + str(value) + '&'
|
||||||
|
|
||||||
# Remove the last '&' (or '?' if no parameters)
|
# Remove the last '&' (or '?' if no parameters)
|
||||||
|
|
|
@ -248,7 +248,7 @@ class SortTable:
|
||||||
if not fields:
|
if not fields:
|
||||||
fields = values.get('default', [])
|
fields = values.get('default', [])
|
||||||
request = request.order_by(*fields)
|
request = request.order_by(*fields)
|
||||||
if order == 'desc':
|
if values.get(col, None) and order == 'desc':
|
||||||
return request.reverse()
|
return request.reverse()
|
||||||
else:
|
else:
|
||||||
return request
|
return request
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""The field used in the admin view for the search app"""
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.contrib import admin
|
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
|
|
|
@ -20,21 +20,72 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""The forms used by the search app"""
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db.models import Q
|
from django import forms
|
||||||
from simple_search import BaseSearchForm
|
from django.forms import Form
|
||||||
|
|
||||||
from users.models import User, School
|
CHOICES_USER = (
|
||||||
|
('0', 'Actifs'),
|
||||||
|
('1', 'Désactivés'),
|
||||||
|
('2', 'Archivés'),
|
||||||
|
)
|
||||||
|
|
||||||
class UserSearchForm(BaseSearchForm):
|
CHOICES_AFF = (
|
||||||
class Meta:
|
('0', 'Utilisateurs'),
|
||||||
base_qs = User.objects
|
('1', 'Machines'),
|
||||||
search_fields = ('^name', 'description', 'specifications', '=id')
|
('2', 'Factures'),
|
||||||
|
('3', 'Bannissements'),
|
||||||
|
('4', 'Accès à titre gracieux'),
|
||||||
|
('5', 'Chambres'),
|
||||||
|
('6', 'Ports'),
|
||||||
|
('7', 'Switchs'),
|
||||||
|
)
|
||||||
|
|
||||||
# assumes a fulltext index has been defined on the fields
|
|
||||||
# 'name,description,specifications,id'
|
def initial_choices(c):
|
||||||
fulltext_indexes = (
|
"""Return the choices that should be activated by default for a
|
||||||
('name', 2), # name matches are weighted higher
|
given set of choices"""
|
||||||
('name,description,specifications,id', 1),
|
return [i[0] for i in c]
|
||||||
|
|
||||||
|
|
||||||
|
class SearchForm(Form):
|
||||||
|
"""The form for a simple search"""
|
||||||
|
q = forms.CharField(label='Search', max_length=100)
|
||||||
|
|
||||||
|
|
||||||
|
class SearchFormPlus(Form):
|
||||||
|
"""The form for an advanced search (with filters)"""
|
||||||
|
q = forms.CharField(
|
||||||
|
label='Search',
|
||||||
|
max_length=100,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
u = forms.MultipleChoiceField(
|
||||||
|
label="Filtre utilisateurs",
|
||||||
|
required=False,
|
||||||
|
widget=forms.CheckboxSelectMultiple,
|
||||||
|
choices=CHOICES_USER,
|
||||||
|
initial=initial_choices(CHOICES_USER)
|
||||||
|
)
|
||||||
|
a = forms.MultipleChoiceField(
|
||||||
|
label="Filtre affichage",
|
||||||
|
required=False,
|
||||||
|
widget=forms.CheckboxSelectMultiple,
|
||||||
|
choices=CHOICES_AFF,
|
||||||
|
initial=initial_choices(CHOICES_AFF)
|
||||||
|
)
|
||||||
|
s = forms.DateField(
|
||||||
|
required=False,
|
||||||
|
label="Date de début",
|
||||||
|
help_text='DD/MM/YYYY',
|
||||||
|
input_formats=['%d/%m/%Y']
|
||||||
|
)
|
||||||
|
e = forms.DateField(
|
||||||
|
required=False,
|
||||||
|
help_text='DD/MM/YYYY',
|
||||||
|
input_formats=['%d/%m/%Y'],
|
||||||
|
label="Date de fin"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
# -*- mode: python; coding: utf-8 -*-
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from django.db import models
|
|
||||||
from django import forms
|
|
||||||
from django.forms import Form
|
|
||||||
from django.forms import ModelForm
|
|
||||||
|
|
||||||
CHOICES = (
|
|
||||||
('0', 'Actifs'),
|
|
||||||
('1', 'Désactivés'),
|
|
||||||
('2', 'Archivés'),
|
|
||||||
)
|
|
||||||
|
|
||||||
CHOICES2 = (
|
|
||||||
(1, 'Active'),
|
|
||||||
("", 'Désactivée'),
|
|
||||||
)
|
|
||||||
|
|
||||||
CHOICES3 = (
|
|
||||||
('0', 'Utilisateurs'),
|
|
||||||
('1', 'Machines'),
|
|
||||||
('2', 'Factures'),
|
|
||||||
('3', 'Bannissements'),
|
|
||||||
('4', 'Accès à titre gracieux'),
|
|
||||||
('6', 'Switchs'),
|
|
||||||
('5', 'Ports'),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class SearchForm(Form):
|
|
||||||
search_field = forms.CharField(label = 'Search', max_length = 100)
|
|
||||||
|
|
||||||
class SearchFormPlus(Form):
|
|
||||||
search_field = forms.CharField(label = 'Search', max_length = 100, required=False)
|
|
||||||
filtre = forms.MultipleChoiceField(label="Filtre utilisateurs", required=False, widget =forms.CheckboxSelectMultiple,choices=CHOICES)
|
|
||||||
connexion = forms.MultipleChoiceField(label="Filtre connexion", required=False, widget =forms.CheckboxSelectMultiple,choices=CHOICES2)
|
|
||||||
affichage = forms.MultipleChoiceField(label="Filtre affichage", required=False, widget =forms.CheckboxSelectMultiple,choices=CHOICES3)
|
|
||||||
date_deb = forms.DateField(required=False, label="Date de début", help_text='DD/MM/YYYY', input_formats=['%d/%m/%Y'])
|
|
||||||
date_fin = forms.DateField(required=False, help_text='DD/MM/YYYY', input_formats=['%d/%m/%Y'], label="Date de fin")
|
|
|
@ -36,30 +36,35 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<h2>Résultats dans les machines : </h2>
|
<h2>Résultats dans les machines : </h2>
|
||||||
{% include "machines/aff_machines.html" with machines_list=machines_list %}
|
{% include "machines/aff_machines.html" with machines_list=machines_list %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if facture_list %}
|
{% if factures_list %}
|
||||||
<h2>Résultats dans les factures : </h2>
|
<h2>Résultats dans les factures : </h2>
|
||||||
{% include "cotisations/aff_cotisations.html" with facture_list=facture_list %}
|
{% include "cotisations/aff_cotisations.html" with facture_list=factures_list %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if white_list %}
|
{% if whitelists_list %}
|
||||||
<h2>Résultats dans les accès à titre gracieux : </h2>
|
<h2>Résultats dans les accès à titre gracieux : </h2>
|
||||||
{% include "users/aff_whitelists.html" with white_list=white_list %}
|
{% include "users/aff_whitelists.html" with white_list=whitelists_list %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if ban_list %}
|
{% if bans_list %}
|
||||||
<h2>Résultats dans les banissements : </h2>
|
<h2>Résultats dans les banissements : </h2>
|
||||||
{% include "users/aff_bans.html" with ban_list=ban_list %}
|
{% include "users/aff_bans.html" with ban_list=bans_list %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if switch_list %}
|
{% if rooms_list %}
|
||||||
<h2>Résultats dans les switchs : </h2>
|
<h2>Résultats dans les chambres : </h2>
|
||||||
{% include "topologie/aff_switch.html" with switch_list=switch_list %}
|
{% include "topologie/aff_chambres.html" with room_list=rooms_list %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if port_list %}
|
{% if switch_ports_list %}
|
||||||
<h2>Résultats dans les ports : </h2>
|
<h2>Résultats dans les ports : </h2>
|
||||||
{% include "topologie/aff_port.html" with port_list=port_list %}
|
{% include "topologie/aff_port.html" with port_list=switch_ports_list %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not ban_list and not interfaces_list and not users_list and not facture_list and not white_list and not port_list and not switch_list%}
|
{% if switches_list %}
|
||||||
|
<h2>Résultats dans les switchs : </h2>
|
||||||
|
{% include "topologie/aff_switch.html" with switch_list=switches_list %}
|
||||||
|
{% endif %}
|
||||||
|
{% if not users_list and not machines_list and not factures_list and not whitelists_list and not bans_list and not rooms_list and not switch_ports_list and not switches_list %}
|
||||||
<h3>Aucun résultat</h3>
|
<h3>Aucun résultat</h3>
|
||||||
{% endif %}
|
{% else %}
|
||||||
<h6>(Seulement les {{ max_result }} premiers résultats sont affichés dans chaque catégorie)</h6>
|
<h6>(Seulement les {{ max_result }} premiers résultats sont affichés dans chaque catégorie)</h6>
|
||||||
|
{% endif %}
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -28,11 +28,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
{% block title %}Recherche{% endblock %}
|
{% block title %}Recherche{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% bootstrap_form_errors searchform %}
|
{% bootstrap_form_errors search_form %}
|
||||||
|
|
||||||
<form class="form" method="post">
|
<form class="form">
|
||||||
{% csrf_token %}
|
{% bootstrap_field search_form.q %}
|
||||||
{% bootstrap_form searchform %}
|
{% include "buttons/multiple_checkbox_alt.html" with field=search_form.u %}
|
||||||
|
{% include "buttons/multiple_checkbox_alt.html" with field=search_form.a %}
|
||||||
|
{% bootstrap_field search_form.s %}
|
||||||
|
{% bootstrap_field search_form.e %}
|
||||||
{% bootstrap_button "Search" button_type="submit" icon="search" %}
|
{% bootstrap_button "Search" button_type="submit" icon="search" %}
|
||||||
</form>
|
</form>
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
"""The urls used by the search app"""
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
@ -28,5 +30,5 @@ from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.search, name='search'),
|
url(r'^$', views.search, name='search'),
|
||||||
url(r'^avance/$', views.searchp, name='searchp'),
|
url(r'^advanced/$', views.searchp, name='searchp'),
|
||||||
]
|
]
|
||||||
|
|
381
search/views.py
381
search/views.py
|
@ -20,115 +20,326 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
# App de recherche pour re2o
|
"""The views for the search app, responsible for finding the matches
|
||||||
# Augustin lemesle, Gabriel Détraz, Goulven Kermarec
|
Augustin lemesle, Gabriel Détraz, Goulven Kermarec, Maël Kervella
|
||||||
# Gplv2
|
Gplv2"""
|
||||||
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.shortcuts import render
|
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 django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from users.models import User, Ban, Whitelist
|
from users.models import User, Ban, Whitelist
|
||||||
from machines.models import Machine, Interface
|
from machines.models import Machine
|
||||||
from topologie.models import Port, Switch
|
from topologie.models import Port, Switch, Room
|
||||||
from cotisations.models import Facture
|
from cotisations.models import Facture
|
||||||
from search.models import SearchForm, SearchFormPlus
|
|
||||||
from preferences.models import GeneralOption
|
from preferences.models import GeneralOption
|
||||||
|
from search.forms import (
|
||||||
|
SearchForm,
|
||||||
|
SearchFormPlus,
|
||||||
|
CHOICES_USER,
|
||||||
|
CHOICES_AFF,
|
||||||
|
initial_choices
|
||||||
|
)
|
||||||
|
from re2o.utils import SortTable
|
||||||
|
|
||||||
def form(ctx, template, request):
|
|
||||||
c = ctx
|
|
||||||
c.update(csrf(request))
|
|
||||||
return render(request, template, c)
|
|
||||||
|
|
||||||
def search_result(search, type, request):
|
def is_int(variable):
|
||||||
date_deb = None
|
""" Check if the variable can be casted to an integer """
|
||||||
date_fin = None
|
|
||||||
states=[]
|
|
||||||
co=[]
|
|
||||||
aff=[]
|
|
||||||
if(type):
|
|
||||||
aff = search.cleaned_data['affichage']
|
|
||||||
co = search.cleaned_data['connexion']
|
|
||||||
states = search.cleaned_data['filtre']
|
|
||||||
date_deb = search.cleaned_data['date_deb']
|
|
||||||
date_fin = search.cleaned_data['date_fin']
|
|
||||||
date_query = Q()
|
|
||||||
if aff==[]:
|
|
||||||
aff = ['0','1','2','3','4','5','6']
|
|
||||||
if date_deb != None:
|
|
||||||
date_query = date_query & Q(date__gte=date_deb)
|
|
||||||
if date_fin != None:
|
|
||||||
date_query = date_query & Q(date__lte=date_fin)
|
|
||||||
search = search.cleaned_data['search_field']
|
|
||||||
query1 = Q()
|
|
||||||
for s in states:
|
|
||||||
query1 = query1 | Q(state = s)
|
|
||||||
|
|
||||||
connexion = []
|
try:
|
||||||
|
int(variable)
|
||||||
recherche = {'users_list': None, 'machines_list' : [], 'facture_list' : None, 'ban_list' : None, 'white_list': None, 'port_list': None, 'switch_list': None}
|
except ValueError:
|
||||||
|
return False
|
||||||
if request.user.has_perms(('cableur',)):
|
|
||||||
query = Q(user__pseudo__icontains = search) | Q(user__adherent__name__icontains = search) | Q(user__surname__icontains = search)
|
|
||||||
else:
|
else:
|
||||||
query = (Q(user__pseudo__icontains = search) | Q(user__adherent__name__icontains = search) | Q(user__surname__icontains = search)) & Q(user = request.user)
|
return True
|
||||||
|
|
||||||
|
|
||||||
for i in aff:
|
def get_results(query, request, filters={}):
|
||||||
if i == '0':
|
""" Construct the correct filters to match differents fields of some models
|
||||||
query_user_list = Q(adherent__room__name__icontains = search) | Q(club__room__name__icontains = search) | Q(pseudo__icontains = search) | Q(adherent__name__icontains = search) | Q(surname__icontains = search) & query1
|
with the given query according to the given filters.
|
||||||
if request.user.has_perms(('cableur',)):
|
The match field are either CharField or IntegerField that will be displayed
|
||||||
recherche['users_list'] = User.objects.filter(query_user_list).order_by('state', 'surname').distinct()
|
on the results page (else, one might not see why a result has matched the
|
||||||
else :
|
query). IntegerField are matched against the query only if it can be casted
|
||||||
recherche['users_list'] = User.objects.filter(query_user_list & Q(id=request.user.id)).order_by('state', 'surname').distinct()
|
to an int."""
|
||||||
if i == '1':
|
|
||||||
query_machine_list = Q(machine__user__pseudo__icontains = search) | Q(machine__user__adherent__name__icontains = search) | Q(machine__user__surname__icontains = search) | Q(mac_address__icontains = search) | Q(ipv4__ipv4__icontains = search) | Q(domain__name__icontains = search) | Q(domain__related_domain__name__icontains = search)
|
start = filters.get('s', None)
|
||||||
if request.user.has_perms(('cableur',)):
|
end = filters.get('e', None)
|
||||||
data = Interface.objects.filter(query_machine_list).distinct()
|
user_state = filters.get('u', initial_choices(CHOICES_USER))
|
||||||
else:
|
aff = filters.get('a', initial_choices(CHOICES_AFF))
|
||||||
data = Interface.objects.filter(query_machine_list & Q(machine__user__id = request.user.id)).distinct()
|
|
||||||
for d in data:
|
options, _ = GeneralOption.objects.get_or_create()
|
||||||
recherche['machines_list'].append(d.machine)
|
max_result = options.search_display_page
|
||||||
if i == '2':
|
|
||||||
recherche['facture_list'] = Facture.objects.filter(query & date_query).distinct()
|
results = {
|
||||||
if i == '3':
|
'users_list': User.objects.none(),
|
||||||
recherche['ban_list'] = Ban.objects.filter(query).distinct()
|
'machines_list': Machine.objects.none(),
|
||||||
if i == '4':
|
'factures_list': Facture.objects.none(),
|
||||||
recherche['white_list'] = Whitelist.objects.filter(query).distinct()
|
'bans_list': Ban.objects.none(),
|
||||||
if i == '5':
|
'whitelists_list': Whitelist.objects.none(),
|
||||||
recherche['port_list'] = Port.objects.filter(details__icontains = search).distinct()
|
'rooms_list': Room.objects.none(),
|
||||||
|
'switch_ports_list': Port.objects.none(),
|
||||||
|
'switches_list': Switch.objects.none()
|
||||||
|
}
|
||||||
|
|
||||||
|
# Users
|
||||||
|
if '0' in aff:
|
||||||
|
filter_user_list = (
|
||||||
|
Q(
|
||||||
|
surname__icontains=query
|
||||||
|
) | Q(
|
||||||
|
adherent__name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
pseudo__icontains=query
|
||||||
|
) | Q(
|
||||||
|
club__room__name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
adherent__room__name__icontains=query
|
||||||
|
)
|
||||||
|
) & Q(state__in=user_state)
|
||||||
if not request.user.has_perms(('cableur',)):
|
if not request.user.has_perms(('cableur',)):
|
||||||
recherche['port_list'] = None
|
filter_user_list &= Q(id=request.user.id)
|
||||||
if i == '6':
|
results['users_list'] = User.objects.filter(filter_user_list)
|
||||||
recherche['switch_list'] = Switch.objects.filter(details__icontains = search).distinct()
|
results['users_list'] = SortTable.sort(
|
||||||
|
results['users_list'],
|
||||||
|
request.GET.get('col'),
|
||||||
|
request.GET.get('order'),
|
||||||
|
SortTable.USERS_INDEX
|
||||||
|
)
|
||||||
|
|
||||||
|
# Machines
|
||||||
|
if '1' in aff:
|
||||||
|
filter_machine_list = Q(
|
||||||
|
name__icontains=query
|
||||||
|
) | (
|
||||||
|
Q(
|
||||||
|
user__pseudo__icontains=query
|
||||||
|
) & Q(
|
||||||
|
user__state__in=user_state
|
||||||
|
)
|
||||||
|
) | Q(
|
||||||
|
interface__domain__name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
interface__domain__related_domain__name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
interface__mac_address__icontains=query
|
||||||
|
) | Q(
|
||||||
|
interface__ipv4__ipv4__icontains=query
|
||||||
|
)
|
||||||
if not request.user.has_perms(('cableur',)):
|
if not request.user.has_perms(('cableur',)):
|
||||||
recherche['switch_list'] = None
|
filter_machine_list &= Q(user__id=request.user.id)
|
||||||
options, created = GeneralOption.objects.get_or_create()
|
results['machines_list'] = Machine.objects.filter(filter_machine_list)
|
||||||
search_display_page = options.search_display_page
|
results['machines_list'] = SortTable.sort(
|
||||||
|
results['machines_list'],
|
||||||
|
request.GET.get('col'),
|
||||||
|
request.GET.get('order'),
|
||||||
|
SortTable.MACHINES_INDEX
|
||||||
|
)
|
||||||
|
|
||||||
for r in recherche:
|
# Factures
|
||||||
if recherche[r] != None:
|
if '2' in aff:
|
||||||
recherche[r] = recherche[r][:search_display_page]
|
filter_facture_list = Q(
|
||||||
|
user__pseudo__icontains=query
|
||||||
|
) & Q(
|
||||||
|
user__state__in=user_state
|
||||||
|
)
|
||||||
|
if start is not None:
|
||||||
|
filter_facture_list &= Q(date__gte=start)
|
||||||
|
if end is not None:
|
||||||
|
filter_facture_list &= Q(date__lte=end)
|
||||||
|
results['factures_list'] = Facture.objects.filter(filter_facture_list)
|
||||||
|
results['factures_list'] = SortTable.sort(
|
||||||
|
results['factures_list'],
|
||||||
|
request.GET.get('col'),
|
||||||
|
request.GET.get('order'),
|
||||||
|
SortTable.COTISATIONS_INDEX
|
||||||
|
)
|
||||||
|
|
||||||
recherche.update({'max_result': search_display_page})
|
# Bans
|
||||||
|
if '3' in aff:
|
||||||
|
date_filter = (
|
||||||
|
Q(
|
||||||
|
user__pseudo__icontains=query
|
||||||
|
) & Q(
|
||||||
|
user__state__in=user_state
|
||||||
|
)
|
||||||
|
) | Q(
|
||||||
|
raison__icontains=query
|
||||||
|
)
|
||||||
|
if start is not None:
|
||||||
|
date_filter &= (
|
||||||
|
Q(date_start__gte=start) & Q(date_end__gte=start)
|
||||||
|
) | (
|
||||||
|
Q(date_start__lte=start) & Q(date_end__gte=start)
|
||||||
|
) | (
|
||||||
|
Q(date_start__gte=start) & Q(date_end__lte=start)
|
||||||
|
)
|
||||||
|
if end is not None:
|
||||||
|
date_filter &= (
|
||||||
|
Q(date_start__lte=end) & Q(date_end__lte=end)
|
||||||
|
) | (
|
||||||
|
Q(date_start__lte=end) & Q(date_end__gte=end)
|
||||||
|
) | (
|
||||||
|
Q(date_start__gte=end) & Q(date_end__lte=end)
|
||||||
|
)
|
||||||
|
results['bans_list'] = Ban.objects.filter(date_filter)
|
||||||
|
results['bans_list'] = SortTable.sort(
|
||||||
|
results['bans_list'],
|
||||||
|
request.GET.get('col'),
|
||||||
|
request.GET.get('order'),
|
||||||
|
SortTable.USERS_INDEX_BAN
|
||||||
|
)
|
||||||
|
|
||||||
|
# Whitelists
|
||||||
|
if '4' in aff:
|
||||||
|
date_filter = (
|
||||||
|
Q(
|
||||||
|
user__pseudo__icontains=query
|
||||||
|
) & Q(
|
||||||
|
user__state__in=user_state
|
||||||
|
)
|
||||||
|
) | Q(
|
||||||
|
raison__icontains=query
|
||||||
|
)
|
||||||
|
if start is not None:
|
||||||
|
date_filter &= (
|
||||||
|
Q(date_start__gte=start) & Q(date_end__gte=start)
|
||||||
|
) | (
|
||||||
|
Q(date_start__lte=start) & Q(date_end__gte=start)
|
||||||
|
) | (
|
||||||
|
Q(date_start__gte=start) & Q(date_end__lte=start)
|
||||||
|
)
|
||||||
|
if end is not None:
|
||||||
|
date_filter &= (
|
||||||
|
Q(date_start__lte=end) & Q(date_end__lte=end)
|
||||||
|
) | (
|
||||||
|
Q(date_start__lte=end) & Q(date_end__gte=end)
|
||||||
|
) | (
|
||||||
|
Q(date_start__gte=end) & Q(date_end__lte=end)
|
||||||
|
)
|
||||||
|
results['whitelists_list'] = Whitelist.objects.filter(date_filter)
|
||||||
|
results['whitelists_list'] = SortTable.sort(
|
||||||
|
results['whitelists_list'],
|
||||||
|
request.GET.get('col'),
|
||||||
|
request.GET.get('order'),
|
||||||
|
SortTable.USERS_INDEX_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
# Rooms
|
||||||
|
if '5' in aff and request.user.has_perms(('cableur',)):
|
||||||
|
filter_rooms_list = Q(
|
||||||
|
details__icontains=query
|
||||||
|
) | Q(
|
||||||
|
name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
port__details=query
|
||||||
|
)
|
||||||
|
results['rooms_list'] = Room.objects.filter(filter_rooms_list)
|
||||||
|
results['rooms_list'] = SortTable.sort(
|
||||||
|
results['rooms_list'],
|
||||||
|
request.GET.get('col'),
|
||||||
|
request.GET.get('order'),
|
||||||
|
SortTable.TOPOLOGIE_INDEX_ROOM
|
||||||
|
)
|
||||||
|
|
||||||
|
# Switch ports
|
||||||
|
if '6' in aff and request.user.has_perms(('cableur',)):
|
||||||
|
filter_ports_list = Q(
|
||||||
|
room__name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
machine_interface__domain__name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
related__switch__switch_interface__domain__name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
radius__icontains=query
|
||||||
|
) | Q(
|
||||||
|
vlan_force__name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
details__icontains=query
|
||||||
|
)
|
||||||
|
if is_int(query):
|
||||||
|
filter_ports_list |= Q(
|
||||||
|
port=query
|
||||||
|
)
|
||||||
|
results['switch_ports_list'] = Port.objects.filter(filter_ports_list)
|
||||||
|
results['switch_ports_list'] = SortTable.sort(
|
||||||
|
results['switch_ports_list'],
|
||||||
|
request.GET.get('col'),
|
||||||
|
request.GET.get('order'),
|
||||||
|
SortTable.TOPOLOGIE_INDEX_PORT
|
||||||
|
)
|
||||||
|
|
||||||
|
# Switches
|
||||||
|
if '7' in aff and request.user.has_perms(('cableur',)):
|
||||||
|
filter_switches_list = Q(
|
||||||
|
switch_interface__domain__name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
switch_interface__ipv4__ipv4__icontains=query
|
||||||
|
) | Q(
|
||||||
|
location__icontains=query
|
||||||
|
) | Q(
|
||||||
|
stack__name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
model__reference__icontains=query
|
||||||
|
) | Q(
|
||||||
|
model__constructor__name__icontains=query
|
||||||
|
) | Q(
|
||||||
|
details__icontains=query
|
||||||
|
)
|
||||||
|
if is_int(query):
|
||||||
|
filter_switches_list |= Q(
|
||||||
|
number=query
|
||||||
|
) | Q(
|
||||||
|
stack_member_id=query
|
||||||
|
)
|
||||||
|
results['switches_list'] = Switch.objects.filter(filter_switches_list)
|
||||||
|
results['switches_list'] = SortTable.sort(
|
||||||
|
results['switches_list'],
|
||||||
|
request.GET.get('col'),
|
||||||
|
request.GET.get('order'),
|
||||||
|
SortTable.TOPOLOGIE_INDEX
|
||||||
|
)
|
||||||
|
|
||||||
|
for name, val in results.items():
|
||||||
|
results[name] = val.distinct()[:max_result]
|
||||||
|
|
||||||
|
results.update({'max_result': max_result})
|
||||||
|
results.update({'search_term': query})
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
return recherche
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def search(request):
|
def search(request):
|
||||||
search = SearchForm(request.POST or None)
|
""" La page de recherche standard """
|
||||||
if search.is_valid():
|
search_form = SearchForm(request.GET or None)
|
||||||
return form(search_result(search, False, request), 'search/index.html',request)
|
if search_form.is_valid():
|
||||||
return form({'searchform' : search}, 'search/search.html', request)
|
return render(
|
||||||
|
request,
|
||||||
|
'search/index.html',
|
||||||
|
get_results(
|
||||||
|
search_form.cleaned_data.get('q', ''),
|
||||||
|
request,
|
||||||
|
search_form.cleaned_data
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return render(request, 'search/search.html', {'search_form': search_form})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def searchp(request):
|
def searchp(request):
|
||||||
search = SearchFormPlus(request.POST or None)
|
""" La page de recherche avancée """
|
||||||
if search.is_valid():
|
search_form = SearchFormPlus(request.GET or None)
|
||||||
return form(search_result(search, True, request), 'search/index.html',request)
|
if search_form.is_valid():
|
||||||
return form({'searchform' : search}, 'search/search.html', request)
|
return render(
|
||||||
|
request,
|
||||||
|
'search/index.html',
|
||||||
|
get_results(
|
||||||
|
search_form.cleaned_data.get('q', ''),
|
||||||
|
request,
|
||||||
|
search_form.cleaned_data
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return render(request, 'search/search.html', {'search_form': search_form})
|
||||||
|
|
|
@ -73,10 +73,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
<div class="col-sm-3 col-md-3 navbar-right">
|
<div class="col-sm-3 col-md-3 navbar-right">
|
||||||
<form action="{% url "search:search"%}" method="POST" class="navbar-form" role="search">
|
<form action="{% url "search:search"%}" class="navbar-form" role="search">
|
||||||
{% csrf_token %}
|
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="text" class="form-control" placeholder="Search" name="search_field" id="search-term">
|
<input type="text" class="form-control" placeholder="Search" name="q" id="search-term" {% if search_term %}value="{{ search_term }}"{% endif %}>
|
||||||
<div class="input-group-btn">
|
<div class="input-group-btn">
|
||||||
<button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
|
<button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
|
||||||
<a href="{% url "search:searchp" %}" class="btn btn-default" role="button"><i class="glyphicon glyphicon-plus"></i></a>
|
<a href="{% url "search:searchp" %}" class="btn btn-default" role="button"><i class="glyphicon glyphicon-plus"></i></a>
|
||||||
|
|
40
templates/buttons/multiple_checkbox_alt.html
Normal file
40
templates/buttons/multiple_checkbox_alt.html
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{% 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 %}
|
||||||
|
|
||||||
|
<div class="form-group {% if field.form.errors %}{% if field.errors %}has-error{% else %}has-success{% endif %}{% endif %}">
|
||||||
|
<label class="control-label" for="{{ field.id_for_label }}">
|
||||||
|
{{ field.label }}
|
||||||
|
</label>
|
||||||
|
<div id="{{ field.auto_id }}" data-toggle="buttons">
|
||||||
|
{% for val in field.field.choices %}
|
||||||
|
<label for="id_u_{{ val.0 }}" class="btn btn-default{% if val.0 in field.initial %} active{% endif %}">
|
||||||
|
<input {% if val.0 in field.initial %}checked="checked" {% endif %}class="" id="id_u_{{ val.0 }}" name="{{ field.name }}" title="" type="checkbox" value="{{ val.0 }}" /> {{ val.1 }}
|
||||||
|
</label>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<div class="help-block">{{ error }}</div>
|
||||||
|
{% endfor %}
|
||||||
|
<div class="help-block">{{ field.help_text }}</div>
|
||||||
|
</div>
|
Loading…
Reference in a new issue