diff --git a/cotisations/views.py b/cotisations/views.py
index 4cd76f93..68118711 100644
--- a/cotisations/views.py
+++ b/cotisations/views.py
@@ -47,7 +47,10 @@ from users.models import User
from re2o.settings import LOGO_PATH
from re2o import settings
from re2o.views import form
-from re2o.utils import SortTable, re2o_paginator
+from re2o.base import (
+ SortTable,
+ re2o_paginator,
+)
from re2o.acl import (
can_create,
can_edit,
diff --git a/logs/views.py b/logs/views.py
index 21e3c470..a54edd56 100644
--- a/logs/views.py
+++ b/logs/views.py
@@ -102,15 +102,18 @@ from re2o.utils import (
all_baned,
all_has_access,
all_adherent,
+ all_active_assigned_interfaces_count,
+ all_active_interfaces_count,
+)
+from re2o.base import (
re2o_paginator,
+ SortTable
)
from re2o.acl import (
can_view_all,
can_view_app,
can_edit_history,
)
-from re2o.utils import all_active_assigned_interfaces_count
-from re2o.utils import all_active_interfaces_count, SortTable
@login_required
diff --git a/machines/views.py b/machines/views.py
index 8d395749..59d4bd5a 100644
--- a/machines/views.py
+++ b/machines/views.py
@@ -55,6 +55,8 @@ from re2o.acl import (
from re2o.utils import (
all_active_assigned_interfaces,
filter_active_interfaces,
+)
+from re2o.base import (
SortTable,
re2o_paginator,
)
diff --git a/re2o/base.py b/re2o/base.py
index 539cc30f..023a16ff 100644
--- a/re2o/base.py
+++ b/re2o/base.py
@@ -29,10 +29,41 @@ Et non corrélées/dépendantes des autres applications
import smtplib
from django.utils.translation import ugettext_lazy as _
+from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from re2o.settings import EMAIL_HOST
+# Mapping of srtftime format for better understanding
+# https://docs.python.org/3.6/library/datetime.html#strftime-strptime-behavior
+datetime_mapping={
+ '%a': '%a',
+ '%A': '%A',
+ '%w': '%w',
+ '%d': 'dd',
+ '%b': '%b',
+ '%B': '%B',
+ '%m': 'mm',
+ '%y': 'yy',
+ '%Y': 'yyyy',
+ '%H': 'HH',
+ '%I': 'HH(12h)',
+ '%p': 'AMPM',
+ '%M': 'MM',
+ '%S': 'SS',
+ '%f': 'µµ',
+ '%z': 'UTC(+/-HHMM)',
+ '%Z': 'UTC(TZ)',
+ '%j': '%j',
+ '%U': 'ww',
+ '%W': 'ww',
+ '%c': '%c',
+ '%x': '%x',
+ '%X': '%X',
+ '%%': '%%',
+}
+
+
def smtp_check(local_part):
"""Return True if the local_part is already taken
False if available"""
@@ -46,3 +77,191 @@ def smtp_check(local_part):
except:
return True, _("Smtp unreachable")
return False, None
+
+
+def convert_datetime_format(format):
+ i=0
+ new_format = ""
+ while i < len(format):
+ if format[i] == '%':
+ char = format[i:i+2]
+ new_format += datetime_mapping.get(char, char)
+ i += 2
+ else:
+ new_format += format[i]
+ i += 1
+ return new_format
+
+
+def get_input_formats_help_text(input_formats):
+ """Returns a help text about the possible input formats"""
+ if len(input_formats) > 1:
+ help_text_template="Format: {main} {more}"
+ else:
+ help_text_template="Format: {main}"
+ more_text_template=""
+ help_text = help_text_template.format(
+ main=convert_datetime_format(input_formats[0]),
+ more=more_text_template.format(
+ '\n'.join(map(convert_datetime_format, input_formats))
+ )
+ )
+ return help_text
+
+
+class SortTable:
+ """ Class gathering uselful stuff to sort the colums of a table, according
+ to the column and order requested. It's used with a dict of possible
+ values and associated model_fields """
+
+ # All the possible possible values
+ # The naming convention is based on the URL or the views function
+ # The syntax to describe the sort to apply is a dict where the keys are
+ # the url value and the values are a list of model field name to use to
+ # order the request. They are applied in the order they are given.
+ # A 'default' might be provided to specify what to do if the requested col
+ # doesn't match any keys.
+
+ USERS_INDEX = {
+ 'user_name': ['name'],
+ 'user_surname': ['surname'],
+ 'user_pseudo': ['pseudo'],
+ 'user_room': ['room'],
+ 'default': ['state', 'pseudo']
+ }
+ USERS_INDEX_BAN = {
+ 'ban_user': ['user__pseudo'],
+ 'ban_start': ['date_start'],
+ 'ban_end': ['date_end'],
+ 'default': ['-date_end']
+ }
+ USERS_INDEX_WHITE = {
+ 'white_user': ['user__pseudo'],
+ 'white_start': ['date_start'],
+ 'white_end': ['date_end'],
+ 'default': ['-date_end']
+ }
+ USERS_INDEX_SCHOOL = {
+ 'school_name': ['name'],
+ 'default': ['name']
+ }
+ MACHINES_INDEX = {
+ 'machine_name': ['name'],
+ 'default': ['pk']
+ }
+ COTISATIONS_INDEX = {
+ 'cotis_user': ['user__pseudo'],
+ 'cotis_paiement': ['paiement__moyen'],
+ 'cotis_date': ['date'],
+ 'cotis_id': ['id'],
+ 'default': ['-date']
+ }
+ COTISATIONS_CUSTOM = {
+ 'invoice_date': ['date'],
+ 'invoice_id': ['id'],
+ 'invoice_recipient': ['recipient'],
+ 'invoice_address': ['address'],
+ 'invoice_payment': ['payment'],
+ 'default': ['-date']
+ }
+ COTISATIONS_CONTROL = {
+ 'control_name': ['user__adherent__name'],
+ 'control_surname': ['user__surname'],
+ 'control_paiement': ['paiement'],
+ 'control_date': ['date'],
+ 'control_valid': ['valid'],
+ 'control_control': ['control'],
+ 'control_id': ['id'],
+ 'control_user-id': ['user__id'],
+ 'default': ['-date']
+ }
+ TOPOLOGIE_INDEX = {
+ 'switch_dns': ['interface__domain__name'],
+ 'switch_ip': ['interface__ipv4__ipv4'],
+ 'switch_loc': ['switchbay__name'],
+ 'switch_ports': ['number'],
+ 'switch_stack': ['stack__name'],
+ 'default': ['switchbay', 'stack', 'stack_member_id']
+ }
+ TOPOLOGIE_INDEX_PORT = {
+ 'port_port': ['port'],
+ 'port_room': ['room__name'],
+ 'port_interface': ['machine_interface__domain__name'],
+ 'port_related': ['related__switch__name'],
+ 'port_radius': ['radius'],
+ 'port_vlan': ['vlan_force__name'],
+ 'default': ['port']
+ }
+ TOPOLOGIE_INDEX_ROOM = {
+ 'room_name': ['name'],
+ 'default': ['name']
+ }
+ TOPOLOGIE_INDEX_BUILDING = {
+ 'building_name': ['name'],
+ 'default': ['name']
+ }
+ TOPOLOGIE_INDEX_BORNE = {
+ 'ap_name': ['interface__domain__name'],
+ 'ap_ip': ['interface__ipv4__ipv4'],
+ 'ap_mac': ['interface__mac_address'],
+ 'default': ['interface__domain__name']
+ }
+ TOPOLOGIE_INDEX_STACK = {
+ 'stack_name': ['name'],
+ 'stack_id': ['stack_id'],
+ 'default': ['stack_id'],
+ }
+ TOPOLOGIE_INDEX_MODEL_SWITCH = {
+ 'model-switch_name': ['reference'],
+ 'model-switch_contructor': ['constructor__name'],
+ 'default': ['reference'],
+ }
+ TOPOLOGIE_INDEX_SWITCH_BAY = {
+ 'switch-bay_name': ['name'],
+ 'switch-bay_building': ['building__name'],
+ 'default': ['name'],
+ }
+ TOPOLOGIE_INDEX_CONSTRUCTOR_SWITCH = {
+ 'constructor-switch_name': ['name'],
+ 'default': ['name'],
+ }
+ LOGS_INDEX = {
+ 'sum_date': ['revision__date_created'],
+ 'default': ['-revision__date_created'],
+ }
+ LOGS_STATS_LOGS = {
+ 'logs_author': ['user__name'],
+ 'logs_date': ['date_created'],
+ 'default': ['-date_created']
+ }
+
+ @staticmethod
+ def sort(request, col, order, values):
+ """ Check if the given values are possible and add .order_by() and
+ a .reverse() as specified according to those values """
+ fields = values.get(col, None)
+ if not fields:
+ fields = values.get('default', [])
+ request = request.order_by(*fields)
+ if values.get(col, None) and order == 'desc':
+ return request.reverse()
+ else:
+ return request
+
+
+def re2o_paginator(request, query_set, pagination_number):
+ """Paginator script for list display in re2o.
+ :request:
+ :query_set: Query_set to paginate
+ :pagination_number: Number of entries to display"""
+ paginator = Paginator(query_set, pagination_number)
+ page = request.GET.get('page')
+ try:
+ results = paginator.page(page)
+ except PageNotAnInteger:
+ # If page is not an integer, deliver first page.
+ results = paginator.page(1)
+ except EmptyPage:
+ # If page is out of range (e.g. 9999), deliver last page of results.
+ results = paginator.page(paginator.num_pages)
+ return results
diff --git a/re2o/utils.py b/re2o/utils.py
index 6f7870f0..9836a98c 100644
--- a/re2o/utils.py
+++ b/re2o/utils.py
@@ -38,55 +38,11 @@ from __future__ import unicode_literals
from django.utils import timezone
from django.db.models import Q
-from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from cotisations.models import Cotisation, Facture, Vente
from machines.models import Interface, Machine
from users.models import Adherent, User, Ban, Whitelist
-# Mapping of srtftime format for better understanding
-# https://docs.python.org/3.6/library/datetime.html#strftime-strptime-behavior
-datetime_mapping={
- '%a': '%a',
- '%A': '%A',
- '%w': '%w',
- '%d': 'dd',
- '%b': '%b',
- '%B': '%B',
- '%m': 'mm',
- '%y': 'yy',
- '%Y': 'yyyy',
- '%H': 'HH',
- '%I': 'HH(12h)',
- '%p': 'AMPM',
- '%M': 'MM',
- '%S': 'SS',
- '%f': 'µµ',
- '%z': 'UTC(+/-HHMM)',
- '%Z': 'UTC(TZ)',
- '%j': '%j',
- '%U': 'ww',
- '%W': 'ww',
- '%c': '%c',
- '%x': '%x',
- '%X': '%X',
- '%%': '%%',
-}
-
-
-def convert_datetime_format(format):
- i=0
- new_format = ""
- while i < len(format):
- if format[i] == '%':
- char = format[i:i+2]
- new_format += datetime_mapping.get(char, char)
- i += 2
- else:
- new_format += format[i]
- i += 1
- return new_format
-
def all_adherent(search_time=None):
""" Fonction renvoyant tous les users adherents. Optimisee pour n'est
@@ -203,164 +159,6 @@ def all_active_assigned_interfaces_count():
return all_active_interfaces_count().filter(ipv4__isnull=False)
-class SortTable:
- """ Class gathering uselful stuff to sort the colums of a table, according
- to the column and order requested. It's used with a dict of possible
- values and associated model_fields """
-
- # All the possible possible values
- # The naming convention is based on the URL or the views function
- # The syntax to describe the sort to apply is a dict where the keys are
- # the url value and the values are a list of model field name to use to
- # order the request. They are applied in the order they are given.
- # A 'default' might be provided to specify what to do if the requested col
- # doesn't match any keys.
-
- USERS_INDEX = {
- 'user_name': ['name'],
- 'user_surname': ['surname'],
- 'user_pseudo': ['pseudo'],
- 'user_room': ['room'],
- 'default': ['state', 'pseudo']
- }
- USERS_INDEX_BAN = {
- 'ban_user': ['user__pseudo'],
- 'ban_start': ['date_start'],
- 'ban_end': ['date_end'],
- 'default': ['-date_end']
- }
- USERS_INDEX_WHITE = {
- 'white_user': ['user__pseudo'],
- 'white_start': ['date_start'],
- 'white_end': ['date_end'],
- 'default': ['-date_end']
- }
- USERS_INDEX_SCHOOL = {
- 'school_name': ['name'],
- 'default': ['name']
- }
- MACHINES_INDEX = {
- 'machine_name': ['name'],
- 'default': ['pk']
- }
- COTISATIONS_INDEX = {
- 'cotis_user': ['user__pseudo'],
- 'cotis_paiement': ['paiement__moyen'],
- 'cotis_date': ['date'],
- 'cotis_id': ['id'],
- 'default': ['-date']
- }
- COTISATIONS_CUSTOM = {
- 'invoice_date': ['date'],
- 'invoice_id': ['id'],
- 'invoice_recipient': ['recipient'],
- 'invoice_address': ['address'],
- 'invoice_payment': ['payment'],
- 'default': ['-date']
- }
- COTISATIONS_CONTROL = {
- 'control_name': ['user__adherent__name'],
- 'control_surname': ['user__surname'],
- 'control_paiement': ['paiement'],
- 'control_date': ['date'],
- 'control_valid': ['valid'],
- 'control_control': ['control'],
- 'control_id': ['id'],
- 'control_user-id': ['user__id'],
- 'default': ['-date']
- }
- TOPOLOGIE_INDEX = {
- 'switch_dns': ['interface__domain__name'],
- 'switch_ip': ['interface__ipv4__ipv4'],
- 'switch_loc': ['switchbay__name'],
- 'switch_ports': ['number'],
- 'switch_stack': ['stack__name'],
- 'default': ['switchbay', 'stack', 'stack_member_id']
- }
- TOPOLOGIE_INDEX_PORT = {
- 'port_port': ['port'],
- 'port_room': ['room__name'],
- 'port_interface': ['machine_interface__domain__name'],
- 'port_related': ['related__switch__name'],
- 'port_radius': ['radius'],
- 'port_vlan': ['vlan_force__name'],
- 'default': ['port']
- }
- TOPOLOGIE_INDEX_ROOM = {
- 'room_name': ['name'],
- 'default': ['name']
- }
- TOPOLOGIE_INDEX_BUILDING = {
- 'building_name': ['name'],
- 'default': ['name']
- }
- TOPOLOGIE_INDEX_BORNE = {
- 'ap_name': ['interface__domain__name'],
- 'ap_ip': ['interface__ipv4__ipv4'],
- 'ap_mac': ['interface__mac_address'],
- 'default': ['interface__domain__name']
- }
- TOPOLOGIE_INDEX_STACK = {
- 'stack_name': ['name'],
- 'stack_id': ['stack_id'],
- 'default': ['stack_id'],
- }
- TOPOLOGIE_INDEX_MODEL_SWITCH = {
- 'model-switch_name': ['reference'],
- 'model-switch_contructor': ['constructor__name'],
- 'default': ['reference'],
- }
- TOPOLOGIE_INDEX_SWITCH_BAY = {
- 'switch-bay_name': ['name'],
- 'switch-bay_building': ['building__name'],
- 'default': ['name'],
- }
- TOPOLOGIE_INDEX_CONSTRUCTOR_SWITCH = {
- 'constructor-switch_name': ['name'],
- 'default': ['name'],
- }
- LOGS_INDEX = {
- 'sum_date': ['revision__date_created'],
- 'default': ['-revision__date_created'],
- }
- LOGS_STATS_LOGS = {
- 'logs_author': ['user__name'],
- 'logs_date': ['date_created'],
- 'default': ['-date_created']
- }
-
- @staticmethod
- def sort(request, col, order, values):
- """ Check if the given values are possible and add .order_by() and
- a .reverse() as specified according to those values """
- fields = values.get(col, None)
- if not fields:
- fields = values.get('default', [])
- request = request.order_by(*fields)
- if values.get(col, None) and order == 'desc':
- return request.reverse()
- else:
- return request
-
-
-def re2o_paginator(request, query_set, pagination_number):
- """Paginator script for list display in re2o.
- :request:
- :query_set: Query_set to paginate
- :pagination_number: Number of entries to display"""
- paginator = Paginator(query_set, pagination_number)
- page = request.GET.get('page')
- try:
- results = paginator.page(page)
- except PageNotAnInteger:
- # If page is not an integer, deliver first page.
- results = paginator.page(1)
- except EmptyPage:
- # If page is out of range (e.g. 9999), deliver last page of results.
- results = paginator.page(paginator.num_pages)
- return results
-
-
def remove_user_room(room):
""" Déménage de force l'ancien locataire de la chambre """
try:
@@ -370,18 +168,3 @@ def remove_user_room(room):
user.room = None
user.save()
-
-def get_input_formats_help_text(input_formats):
- """Returns a help text about the possible input formats"""
- if len(input_formats) > 1:
- help_text_template="Format: {main} {more}"
- else:
- help_text_template="Format: {main}"
- more_text_template=""
- help_text = help_text_template.format(
- main=convert_datetime_format(input_formats[0]),
- more=more_text_template.format(
- '\n'.join(map(convert_datetime_format, input_formats))
- )
- )
- return help_text
diff --git a/search/forms.py b/search/forms.py
index 5c98415f..5fa5fca8 100644
--- a/search/forms.py
+++ b/search/forms.py
@@ -27,7 +27,7 @@ from __future__ import unicode_literals
from django import forms
from django.forms import Form
from django.utils.translation import ugettext_lazy as _
-from re2o.utils import get_input_formats_help_text
+from re2o.base import get_input_formats_help_text
CHOICES_USER = (
('0', _("Active")),
diff --git a/search/views.py b/search/views.py
index a92b0105..eb0027ec 100644
--- a/search/views.py
+++ b/search/views.py
@@ -46,7 +46,7 @@ from search.forms import (
CHOICES_AFF,
initial_choices
)
-from re2o.utils import SortTable
+from re2o.base import SortTable
from re2o.acl import can_view_all
diff --git a/topologie/views.py b/topologie/views.py
index 0bd0f6c2..a4db2dc6 100644
--- a/topologie/views.py
+++ b/topologie/views.py
@@ -48,7 +48,10 @@ from django.utils.translation import ugettext as _
import tempfile
from users.views import form
-from re2o.utils import re2o_paginator, SortTable
+from re2o.base import (
+ re2o_paginator,
+ SortTable,
+)
from re2o.acl import (
can_create,
can_edit,
diff --git a/users/forms.py b/users/forms.py
index 7695e6fc..b96e3ad3 100644
--- a/users/forms.py
+++ b/users/forms.py
@@ -45,7 +45,8 @@ from django.utils.safestring import mark_safe
from machines.models import Interface, Machine, Nas
from topologie.models import Port
from preferences.models import OptionalUser
-from re2o.utils import remove_user_room, get_input_formats_help_text
+from re2o.utils import remove_user_room
+from re2o.base import get_input_formats_help_text
from re2o.mixins import FormRevMixin
from re2o.field_permissions import FieldPermissionFormMixin
diff --git a/users/views.py b/users/views.py
index a94a7927..060610f8 100644
--- a/users/views.py
+++ b/users/views.py
@@ -57,8 +57,10 @@ from preferences.models import OptionalUser, GeneralOption, AssoOption
from re2o.views import form
from re2o.utils import (
all_has_access,
- SortTable,
- re2o_paginator
+)
+from re2o.base import (
+ re2o_paginator,
+ SortTable
)
from re2o.acl import (
can_create,