mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-27 07:02:26 +00:00
Pep8 compliance on re2o
This commit is contained in:
parent
287ce23d1c
commit
48d904b6de
19 changed files with 313 additions and 224 deletions
|
@ -26,6 +26,7 @@
|
||||||
Here are defined some functions to check acl on the application.
|
Here are defined some functions to check acl on the application.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def can_view(user):
|
def can_view(user):
|
||||||
"""Check if an user can view the application.
|
"""Check if an user can view the application.
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,16 @@ class EditOptionalUserForm(ModelForm):
|
||||||
prefix=prefix,
|
prefix=prefix,
|
||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
self.fields['is_tel_mandatory'].label = 'Exiger un numéro de\
|
self.fields['is_tel_mandatory'].label = (
|
||||||
téléphone'
|
'Exiger un numéro de téléphone'
|
||||||
self.fields['user_solde'].label = 'Activation du solde pour\
|
)
|
||||||
les utilisateurs'
|
self.fields['user_solde'].label = (
|
||||||
|
'Activation du solde pour les utilisateurs'
|
||||||
|
)
|
||||||
self.fields['max_solde'].label = 'Solde maximum'
|
self.fields['max_solde'].label = 'Solde maximum'
|
||||||
self.fields['min_online_payment'].label = 'Montant de rechargement minimum en ligne'
|
self.fields['min_online_payment'].label = (
|
||||||
|
'Montant de rechargement minimum en ligne'
|
||||||
|
)
|
||||||
self.fields['self_adhesion'].label = 'Auto inscription'
|
self.fields['self_adhesion'].label = 'Auto inscription'
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,7 +166,6 @@ class EditAssoOptionForm(ModelForm):
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EditMailMessageOptionForm(ModelForm):
|
class EditMailMessageOptionForm(ModelForm):
|
||||||
"""Formulaire d'edition des messages de bienvenue personnalisés"""
|
"""Formulaire d'edition des messages de bienvenue personnalisés"""
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -36,6 +36,7 @@ from django.core.cache import cache
|
||||||
from .aes_field import AESEncryptedField
|
from .aes_field import AESEncryptedField
|
||||||
from re2o.mixins import AclMixin
|
from re2o.mixins import AclMixin
|
||||||
|
|
||||||
|
|
||||||
class PreferencesModel(models.Model):
|
class PreferencesModel(models.Model):
|
||||||
@classmethod
|
@classmethod
|
||||||
def set_in_cache(cls):
|
def set_in_cache(cls):
|
||||||
|
@ -46,7 +47,7 @@ class PreferencesModel(models.Model):
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_cached_value(cls, key):
|
def get_cached_value(cls, key):
|
||||||
instance = cache.get(cls().__class__.__name__.lower())
|
instance = cache.get(cls().__class__.__name__.lower())
|
||||||
if instance == None:
|
if instance is None:
|
||||||
instance = cls.set_in_cache()
|
instance = cls.set_in_cache()
|
||||||
return getattr(instance, key)
|
return getattr(instance, key)
|
||||||
|
|
||||||
|
@ -146,7 +147,7 @@ class OptionalMachine(AclMixin, PreferencesModel):
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def ipv6(self):
|
def ipv6(self):
|
||||||
return not self.get_cached_value('ipv6_mode') == 'DISABLED'
|
return not self.get_cached_value('ipv6_mode') == 'DISABLED'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
permissions = (
|
permissions = (
|
||||||
|
@ -230,7 +231,7 @@ class GeneralOption(AclMixin, PreferencesModel):
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
GTU = models.FileField(
|
GTU = models.FileField(
|
||||||
upload_to = '',
|
upload_to='',
|
||||||
default="",
|
default="",
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
|
|
@ -73,7 +73,7 @@ urlpatterns = [
|
||||||
r'^history/(?P<object_name>\w+)/(?P<object_id>[0-9]+)$',
|
r'^history/(?P<object_name>\w+)/(?P<object_id>[0-9]+)$',
|
||||||
re2o.views.history,
|
re2o.views.history,
|
||||||
name='history',
|
name='history',
|
||||||
kwargs={'application':'preferences'},
|
kwargs={'application': 'preferences'},
|
||||||
),
|
),
|
||||||
url(r'^$', views.display_options, name='display-options'),
|
url(r'^$', views.display_options, name='display-options'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -128,7 +128,7 @@ def add_service(request):
|
||||||
messages.success(request, "Ce service a été ajouté")
|
messages.success(request, "Ce service a été ajouté")
|
||||||
return redirect(reverse('preferences:display-options'))
|
return redirect(reverse('preferences:display-options'))
|
||||||
return form(
|
return form(
|
||||||
{'preferenceform': service, 'action_name' : 'Ajouter'},
|
{'preferenceform': service, 'action_name': 'Ajouter'},
|
||||||
'preferences/preferences.html',
|
'preferences/preferences.html',
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
@ -151,7 +151,7 @@ def edit_service(request, service_instance, serviceid):
|
||||||
messages.success(request, "Service modifié")
|
messages.success(request, "Service modifié")
|
||||||
return redirect(reverse('preferences:display-options'))
|
return redirect(reverse('preferences:display-options'))
|
||||||
return form(
|
return form(
|
||||||
{'preferenceform': service, 'action_name' : 'Editer'},
|
{'preferenceform': service, 'action_name': 'Editer'},
|
||||||
'preferences/preferences.html',
|
'preferences/preferences.html',
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
@ -175,7 +175,7 @@ def del_services(request, instances):
|
||||||
suivant %s ne peut être supprimé" % services_del)
|
suivant %s ne peut être supprimé" % services_del)
|
||||||
return redirect(reverse('preferences:display-options'))
|
return redirect(reverse('preferences:display-options'))
|
||||||
return form(
|
return form(
|
||||||
{'preferenceform': services, 'action_name' : 'Supprimer'},
|
{'preferenceform': services, 'action_name': 'Supprimer'},
|
||||||
'preferences/preferences.html',
|
'preferences/preferences.html',
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,4 +20,3 @@
|
||||||
# You should have received a copy of the GNU General Public License along
|
# 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.,
|
# 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.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,28 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
CONTRIBUTORS = ['Gabriel "Chirac" Détraz', 'Maël "MoaMoaK" Kervella', 'Hugo "Klafyvel" Levy--Falk', 'Augustin "Dahlaro" Lemesle', 'Goulven "Lhark" Kermarec', 'Guillaume "Guimoz" Goessel', 'Yoann "Nanoy" Pietri', 'Matthieu "Lebanni" Michelet', 'Arthur "Grizzly" Grisel-Davy', 'Simon "Rezatoune" Brélivet', 'Sellem Lev-Arcady', 'David "5-1" Sinquin', 'Pierre "Redstorm" Cadart', 'Éloi "Goslig" Alain', 'Laouen "Volgarr" Fernet', 'Joanne Steiner', '"Krokmou"', 'Thibault "Tipunchetrhum" de Boutray', 'Baptiste "B" Fournier', 'Daniel "Dstan" Stan', 'Hugo "Shaka" Hervieux', '"Mikachu"', 'Thomas "Nymous" Gaudin', '"Esum"']
|
CONTRIBUTORS = [
|
||||||
|
'Gabriel "Chirac" Détraz',
|
||||||
|
'Maël "MoaMoaK" Kervella',
|
||||||
|
'Hugo "Klafyvel" Levy--Falk',
|
||||||
|
'Augustin "Dahlaro" Lemesle',
|
||||||
|
'Goulven "Lhark" Kermarec',
|
||||||
|
'Guillaume "Guimoz" Goessel',
|
||||||
|
'Yoann "Nanoy" Pietri',
|
||||||
|
'Matthieu "Lebanni" Michelet',
|
||||||
|
'Arthur "Grizzly" Grisel-Davy',
|
||||||
|
'Simon "Rezatoune" Brélivet',
|
||||||
|
'Sellem Lev-Arcady',
|
||||||
|
'David "5-1" Sinquin',
|
||||||
|
'Pierre "Redstorm" Cadart',
|
||||||
|
'Éloi "Goslig" Alain',
|
||||||
|
'Laouen "Volgarr" Fernet',
|
||||||
|
'Joanne Steiner',
|
||||||
|
'"Krokmou"',
|
||||||
|
'Thibault "Tipunchetrhum" de Boutray',
|
||||||
|
'Baptiste "B" Fournier',
|
||||||
|
'Daniel "Dstan" Stan',
|
||||||
|
'Hugo "Shaka" Hervieux',
|
||||||
|
'"Mikachu"',
|
||||||
|
'Thomas "Nymous" Gaudin',
|
||||||
|
'"Esum"'
|
||||||
|
]
|
||||||
|
|
|
@ -43,13 +43,15 @@ class FieldPermissionModelMixin:
|
||||||
if result is not None:
|
if result is not None:
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
result = user.has_perm(perm) # Don't supply 'obj', or else infinite recursion.
|
# Don't supply 'obj', or else infinite recursion.
|
||||||
|
result = user.has_perm(perm)
|
||||||
if result:
|
if result:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# If no requirement can be met, then permission is denied.
|
# If no requirement can be met, then permission is denied.
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class FieldPermissionModel(FieldPermissionModelMixin, models.Model):
|
class FieldPermissionModel(FieldPermissionModelMixin, models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
@ -76,4 +78,3 @@ class FieldPermissionFormMixin:
|
||||||
|
|
||||||
class FieldPermissionForm(FieldPermissionFormMixin, forms.ModelForm):
|
class FieldPermissionForm(FieldPermissionFormMixin, forms.ModelForm):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -20,18 +20,23 @@
|
||||||
# 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.
|
||||||
"""
|
"""
|
||||||
Write in a python file the list of all contributors sorted by number of commits.
|
Write in a python file the list of all contributors sorted by number of
|
||||||
This list is extracted from the FedeRez gitlab repository.
|
commits. This list is extracted from the current gitlab repository.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Update contributors list'
|
help = 'Update contributors list'
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
contributeurs = [item.split('\t')[1] for item in os.popen("git shortlog -s -n").read().split("\n") if '\t' in item]
|
contributeurs = [
|
||||||
|
item.split('\t')[1]
|
||||||
|
for item in os.popen("git shortlog -s -n").read().split("\n")
|
||||||
|
if '\t' in item
|
||||||
|
]
|
||||||
self.stdout.write(self.style.SUCCESS("Exportation Sucessfull"))
|
self.stdout.write(self.style.SUCCESS("Exportation Sucessfull"))
|
||||||
with open("re2o/contributors.py", "w") as contrib_file:
|
with open("re2o/contributors.py", "w") as contrib_file:
|
||||||
contrib_file.write("#!/usr/bin/env python3\n")
|
contrib_file.write("#!/usr/bin/env python3\n")
|
||||||
|
|
|
@ -37,9 +37,15 @@ class RevMixin(object):
|
||||||
class FormRevMixin(object):
|
class FormRevMixin(object):
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if reversion.get_comment() != "" and self.changed_data != []:
|
if reversion.get_comment() != "" and self.changed_data != []:
|
||||||
reversion.set_comment(reversion.get_comment() + ",%s" % ', '.join(field for field in self.changed_data))
|
reversion.set_comment(
|
||||||
|
reversion.get_comment() + ",%s"
|
||||||
|
% ', '.join(field for field in self.changed_data)
|
||||||
|
)
|
||||||
elif self.changed_data:
|
elif self.changed_data:
|
||||||
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in self.changed_data))
|
reversion.set_comment(
|
||||||
|
"Champs modifié(s) : %s"
|
||||||
|
% ', '.join(field for field in self.changed_data)
|
||||||
|
)
|
||||||
return super(FormRevMixin, self).save(*args, **kwargs)
|
return super(FormRevMixin, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,12 +53,16 @@ class AclMixin(object):
|
||||||
"""This mixin is used in nearly every class/models defined in re2o apps.
|
"""This mixin is used in nearly every class/models defined in re2o apps.
|
||||||
It is used by acl, in models (decorators can_...) and in templates tags
|
It is used by acl, in models (decorators can_...) and in templates tags
|
||||||
:get_instance: Applied on a class, take an id argument, return an instance
|
:get_instance: Applied on a class, take an id argument, return an instance
|
||||||
:can_create: Applied on a class, take the requested user, return if the user
|
:can_create: Applied on a class, take the requested user, return if the
|
||||||
can do the creation
|
user can do the creation
|
||||||
:can_edit: Applied on an instance, return if the user can edit the instance
|
:can_edit: Applied on an instance, return if the user can edit the
|
||||||
:can_delete: Applied on an instance, return if the user can delete the instance
|
instance
|
||||||
:can_view: Applied on an instance, return if the user can view the instance
|
:can_delete: Applied on an instance, return if the user can delete the
|
||||||
:can_view_all: Applied on a class, return if the user can view all instances"""
|
instance
|
||||||
|
:can_view: Applied on an instance, return if the user can view the
|
||||||
|
instance
|
||||||
|
:can_view_all: Applied on a class, return if the user can view all
|
||||||
|
instances"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_classname(cls):
|
def get_classname(cls):
|
||||||
|
@ -76,8 +86,12 @@ class AclMixin(object):
|
||||||
un object
|
un object
|
||||||
:param user_request: instance utilisateur qui fait la requête
|
:param user_request: instance utilisateur qui fait la requête
|
||||||
:return: soit True, soit False avec la raison de l'échec"""
|
:return: soit True, soit False avec la raison de l'échec"""
|
||||||
return user_request.has_perm(cls.get_modulename() + '.add_' + cls.get_classname()), u"Vous n'avez pas le droit\
|
return (
|
||||||
de créer un " + cls.get_classname()
|
user_request.has_perm(
|
||||||
|
cls.get_modulename() + '.add_' + cls.get_classname()
|
||||||
|
),
|
||||||
|
u"Vous n'avez pas le droit de créer un " + cls.get_classname()
|
||||||
|
)
|
||||||
|
|
||||||
def can_edit(self, user_request, *args, **kwargs):
|
def can_edit(self, user_request, *args, **kwargs):
|
||||||
"""Verifie que l'user a les bons droits pour editer
|
"""Verifie que l'user a les bons droits pour editer
|
||||||
|
@ -85,7 +99,12 @@ class AclMixin(object):
|
||||||
:param self: Instance à editer
|
:param self: Instance à editer
|
||||||
:param user_request: Utilisateur qui fait la requête
|
:param user_request: Utilisateur qui fait la requête
|
||||||
:return: soit True, soit False avec la raison de l'échec"""
|
:return: soit True, soit False avec la raison de l'échec"""
|
||||||
return user_request.has_perm(self.get_modulename() + '.change_' + self.get_classname()), u"Vous n'avez pas le droit d'éditer des " + self.get_classname()
|
return (
|
||||||
|
user_request.has_perm(
|
||||||
|
self.get_modulename() + '.change_' + self.get_classname()
|
||||||
|
),
|
||||||
|
u"Vous n'avez pas le droit d'éditer des " + self.get_classname()
|
||||||
|
)
|
||||||
|
|
||||||
def can_delete(self, user_request, *args, **kwargs):
|
def can_delete(self, user_request, *args, **kwargs):
|
||||||
"""Verifie que l'user a les bons droits pour delete
|
"""Verifie que l'user a les bons droits pour delete
|
||||||
|
@ -93,7 +112,12 @@ class AclMixin(object):
|
||||||
:param self: Instance à delete
|
:param self: Instance à delete
|
||||||
:param user_request: Utilisateur qui fait la requête
|
:param user_request: Utilisateur qui fait la requête
|
||||||
:return: soit True, soit False avec la raison de l'échec"""
|
:return: soit True, soit False avec la raison de l'échec"""
|
||||||
return user_request.has_perm(self.get_modulename() + '.delete_' + self.get_classname()), u"Vous n'avez pas le droit d'éditer des " + self.get_classname()
|
return (
|
||||||
|
user_request.has_perm(
|
||||||
|
self.get_modulename() + '.delete_' + self.get_classname()
|
||||||
|
),
|
||||||
|
u"Vous n'avez pas le droit d'éditer des " + self.get_classname()
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def can_view_all(cls, user_request, *args, **kwargs):
|
def can_view_all(cls, user_request, *args, **kwargs):
|
||||||
|
@ -101,7 +125,12 @@ class AclMixin(object):
|
||||||
droit particulier view objet correspondant
|
droit particulier view objet correspondant
|
||||||
:param user_request: instance user qui fait l'edition
|
:param user_request: instance user qui fait l'edition
|
||||||
:return: True ou False avec la raison de l'échec le cas échéant"""
|
:return: True ou False avec la raison de l'échec le cas échéant"""
|
||||||
return user_request.has_perm(cls.get_modulename() + '.view_' + cls.get_classname()), u"Vous n'avez pas le droit de voir des " + cls.get_classname()
|
return (
|
||||||
|
user_request.has_perm(
|
||||||
|
cls.get_modulename() + '.view_' + cls.get_classname()
|
||||||
|
),
|
||||||
|
u"Vous n'avez pas le droit de voir des " + cls.get_classname()
|
||||||
|
)
|
||||||
|
|
||||||
def can_view(self, user_request, *args, **kwargs):
|
def can_view(self, user_request, *args, **kwargs):
|
||||||
"""Vérifie qu'on peut bien voir cette instance particulière avec
|
"""Vérifie qu'on peut bien voir cette instance particulière avec
|
||||||
|
@ -109,4 +138,9 @@ class AclMixin(object):
|
||||||
:param self: instance à voir
|
:param self: instance à voir
|
||||||
:param user_request: instance user qui fait l'edition
|
:param user_request: instance user qui fait l'edition
|
||||||
:return: True ou False avec la raison de l'échec le cas échéant"""
|
:return: True ou False avec la raison de l'échec le cas échéant"""
|
||||||
return user_request.has_perm(self.get_modulename() + '.view_' + self.get_classname()), u"Vous n'avez pas le droit de voir des " + self.get_classname()
|
return (
|
||||||
|
user_request.has_perm(
|
||||||
|
self.get_modulename() + '.view_' + self.get_classname()
|
||||||
|
),
|
||||||
|
u"Vous n'avez pas le droit de voir des " + self.get_classname()
|
||||||
|
)
|
||||||
|
|
|
@ -19,15 +19,11 @@
|
||||||
# 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.
|
||||||
|
|
||||||
import os, sys, pwd
|
import os
|
||||||
|
import sys
|
||||||
|
import pwd
|
||||||
|
|
||||||
proj_path="/var/www/re2o"
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE","re2o.settings")
|
|
||||||
sys.path.append(proj_path)
|
|
||||||
os.chdir(proj_path)
|
|
||||||
from django.core.wsgi import get_wsgi_application
|
from django.core.wsgi import get_wsgi_application
|
||||||
application = get_wsgi_application()
|
|
||||||
|
|
||||||
|
|
||||||
from django.core.management.base import CommandError
|
from django.core.management.base import CommandError
|
||||||
from users.models import User
|
from users.models import User
|
||||||
|
@ -37,14 +33,22 @@ from reversion import revisions as reversion
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from getpass import getpass
|
from getpass import getpass
|
||||||
|
|
||||||
|
proj_path = "/var/www/re2o"
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "re2o.settings")
|
||||||
|
sys.path.append(proj_path)
|
||||||
|
os.chdir(proj_path)
|
||||||
|
|
||||||
|
application = get_wsgi_application()
|
||||||
|
|
||||||
|
|
||||||
def get_user(pseudo):
|
def get_user(pseudo):
|
||||||
"""Cherche un utilisateur re2o à partir de son pseudo"""
|
"""Cherche un utilisateur re2o à partir de son pseudo"""
|
||||||
user = User.objects.filter(pseudo=pseudo)
|
user = User.objects.filter(pseudo=pseudo)
|
||||||
if len(user)==0:
|
if len(user) == 0:
|
||||||
raise CommandError("Utilisateur invalide")
|
raise CommandError("Utilisateur invalide")
|
||||||
if len(user)>1:
|
if len(user) > 1:
|
||||||
raise CommandError("Plusieurs utilisateurs correspondant à ce pseudo. Ceci NE DEVRAIT PAS arriver")
|
raise CommandError("Plusieurs utilisateurs correspondant à ce "
|
||||||
|
"pseudo. Ceci NE DEVRAIT PAS arriver")
|
||||||
return user[0]
|
return user[0]
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,7 +57,7 @@ def get_system_user():
|
||||||
return pwd.getpwuid(int(os.getenv("SUDO_UID") or os.getuid())).pw_name
|
return pwd.getpwuid(int(os.getenv("SUDO_UID") or os.getuid())).pw_name
|
||||||
|
|
||||||
|
|
||||||
def form_cli(Form,user,action,*args,**kwargs):
|
def form_cli(Form, user, action, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Remplit un formulaire à partir de la ligne de commande
|
Remplit un formulaire à partir de la ligne de commande
|
||||||
Form : le formulaire (sous forme de classe) à remplir
|
Form : le formulaire (sous forme de classe) à remplir
|
||||||
|
@ -61,26 +65,30 @@ def form_cli(Form,user,action,*args,**kwargs):
|
||||||
action : l'action réalisée par le formulaire (pour les logs)
|
action : l'action réalisée par le formulaire (pour les logs)
|
||||||
Les arguments suivants sont transmis tels quels au formulaire.
|
Les arguments suivants sont transmis tels quels au formulaire.
|
||||||
"""
|
"""
|
||||||
data={}
|
data = {}
|
||||||
dumb_form = Form(user=user,*args,**kwargs)
|
dumb_form = Form(user=user, *args, **kwargs)
|
||||||
for key in dumb_form.fields:
|
for key in dumb_form.fields:
|
||||||
if not dumb_form.fields[key].widget.input_type=='hidden':
|
if not dumb_form.fields[key].widget.input_type == 'hidden':
|
||||||
if dumb_form.fields[key].widget.input_type=='password':
|
if dumb_form.fields[key].widget.input_type == 'password':
|
||||||
data[key]=getpass("%s : " % dumb_form.fields[key].label)
|
data[key] = getpass("%s : " % dumb_form.fields[key].label)
|
||||||
else:
|
else:
|
||||||
data[key]=input("%s : " % dumb_form.fields[key].label)
|
data[key] = input("%s : " % dumb_form.fields[key].label)
|
||||||
|
|
||||||
form = Form(data,user=user,*args,**kwargs)
|
form = Form(data, user=user, *args, **kwargs)
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
sys.stderr.write("Erreurs : \n")
|
sys.stderr.write("Erreurs : \n")
|
||||||
for err in form.errors:
|
for err in form.errors:
|
||||||
#Oui, oui, on gère du HTML là où d'autres ont eu la lumineuse idée de le mettre
|
# Oui, oui, on gère du HTML là où d'autres ont eu la
|
||||||
sys.stderr.write("\t%s : %s\n" % (err,strip_tags(form.errors[err])))
|
# lumineuse idée de le mettre
|
||||||
|
sys.stderr.write(
|
||||||
|
"\t%s : %s\n" % (err, strip_tags(form.errors[err]))
|
||||||
|
)
|
||||||
raise CommandError("Formulaire invalide")
|
raise CommandError("Formulaire invalide")
|
||||||
|
|
||||||
with transaction.atomic(), reversion.create_revision():
|
with transaction.atomic(), reversion.create_revision():
|
||||||
form.save()
|
form.save()
|
||||||
reversion.set_user(user)
|
reversion.set_user(user)
|
||||||
reversion.set_comment(action)
|
reversion.set_comment(action)
|
||||||
|
|
||||||
sys.stdout.write("%s : effectué. La modification peut prendre quelques minutes pour s'appliquer.\n" % action)
|
sys.stdout.write("%s : effectué. La modification peut prendre "
|
||||||
|
"quelques minutes pour s'appliquer.\n" % action)
|
||||||
|
|
|
@ -126,7 +126,7 @@ LANGUAGE_CODE = 'en'
|
||||||
# Proritary location search for translations
|
# Proritary location search for translations
|
||||||
# then searches in {app}/locale/ for app in INSTALLED_APPS
|
# then searches in {app}/locale/ for app in INSTALLED_APPS
|
||||||
LOCALE_PATHS = [
|
LOCALE_PATHS = [
|
||||||
BASE_DIR + '/templates/locale/' # to define translations outside of apps
|
BASE_DIR + '/templates/locale/' # For translations outside of apps
|
||||||
]
|
]
|
||||||
|
|
||||||
TIME_ZONE = 'Europe/Paris'
|
TIME_ZONE = 'Europe/Paris'
|
||||||
|
|
|
@ -73,23 +73,22 @@ EMAIL_PORT = MY_EMAIL_PORT
|
||||||
|
|
||||||
# Reglages pour la bdd ldap
|
# Reglages pour la bdd ldap
|
||||||
LDAP = {
|
LDAP = {
|
||||||
'base_user_dn' : 'cn=Utilisateurs,dc=example,dc=org',
|
'base_user_dn': 'cn=Utilisateurs,dc=example,dc=org',
|
||||||
'base_userservice_dn' : 'ou=service-users,dc=example,dc=org',
|
'base_userservice_dn': 'ou=service-users,dc=example,dc=org',
|
||||||
'base_usergroup_dn' : 'ou=posix,ou=groups,dc=example,dc=org',
|
'base_usergroup_dn': 'ou=posix,ou=groups,dc=example,dc=org',
|
||||||
'base_userservicegroup_dn' : 'ou=services,ou=groups,dc=example,dc=org',
|
'base_userservicegroup_dn': 'ou=services,ou=groups,dc=example,dc=org',
|
||||||
'user_gid' : 500,
|
'user_gid': 500,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
UID_RANGES = {
|
UID_RANGES = {
|
||||||
'users' : [21001,30000],
|
'users': [21001, 30000],
|
||||||
'service-users' : [20000,21000],
|
'service-users': [20000, 21000],
|
||||||
}
|
}
|
||||||
|
|
||||||
# Chaque groupe a un gid assigné, voici la place libre pour assignation
|
# Chaque groupe a un gid assigné, voici la place libre pour assignation
|
||||||
GID_RANGES = {
|
GID_RANGES = {
|
||||||
'posix' : [501, 600],
|
'posix': [501, 600],
|
||||||
}
|
}
|
||||||
|
|
||||||
OPTIONNAL_APPS = ()
|
OPTIONNAL_APPS = ()
|
||||||
|
|
||||||
|
|
|
@ -18,4 +18,3 @@
|
||||||
# You should have received a copy of the GNU General Public License along
|
# 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.,
|
# 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.
|
||||||
|
|
||||||
|
|
|
@ -85,32 +85,32 @@ register = template.Library()
|
||||||
|
|
||||||
MODEL_NAME = {
|
MODEL_NAME = {
|
||||||
# cotisations
|
# cotisations
|
||||||
'Facture' : cotisations.models.Facture,
|
'Facture': cotisations.models.Facture,
|
||||||
'Vente' : cotisations.models.Vente,
|
'Vente': cotisations.models.Vente,
|
||||||
'Article' : cotisations.models.Article,
|
'Article': cotisations.models.Article,
|
||||||
'Banque' : cotisations.models.Banque,
|
'Banque': cotisations.models.Banque,
|
||||||
'Paiement' : cotisations.models.Paiement,
|
'Paiement': cotisations.models.Paiement,
|
||||||
'Cotisation' : cotisations.models.Cotisation,
|
'Cotisation': cotisations.models.Cotisation,
|
||||||
# machines
|
# machines
|
||||||
'Machine' : machines.models.Machine,
|
'Machine': machines.models.Machine,
|
||||||
'MachineType' : machines.models.MachineType,
|
'MachineType': machines.models.MachineType,
|
||||||
'IpType' : machines.models.IpType,
|
'IpType': machines.models.IpType,
|
||||||
'Vlan' : machines.models.Vlan,
|
'Vlan': machines.models.Vlan,
|
||||||
'Nas' : machines.models.Nas,
|
'Nas': machines.models.Nas,
|
||||||
'SOA' : machines.models.SOA,
|
'SOA': machines.models.SOA,
|
||||||
'Extension' : machines.models.Extension,
|
'Extension': machines.models.Extension,
|
||||||
'Mx' : machines.models.Mx,
|
'Mx': machines.models.Mx,
|
||||||
'Ns' : machines.models.Ns,
|
'Ns': machines.models.Ns,
|
||||||
'Txt' : machines.models.Txt,
|
'Txt': machines.models.Txt,
|
||||||
'Srv' : machines.models.Srv,
|
'Srv': machines.models.Srv,
|
||||||
'Interface' : machines.models.Interface,
|
'Interface': machines.models.Interface,
|
||||||
'Domain' : machines.models.Domain,
|
'Domain': machines.models.Domain,
|
||||||
'IpList' : machines.models.IpList,
|
'IpList': machines.models.IpList,
|
||||||
'Ipv6List' : machines.models.Ipv6List,
|
'Ipv6List': machines.models.Ipv6List,
|
||||||
'machines.Service' : machines.models.Service,
|
'machines.Service': machines.models.Service,
|
||||||
'Service_link' : machines.models.Service_link,
|
'Service_link': machines.models.Service_link,
|
||||||
'OuverturePortList' : machines.models.OuverturePortList,
|
'OuverturePortList': machines.models.OuverturePortList,
|
||||||
'OuverturePort' : machines.models.OuverturePort,
|
'OuverturePort': machines.models.OuverturePort,
|
||||||
# preferences
|
# preferences
|
||||||
'OptionalUser': preferences.models.OptionalUser,
|
'OptionalUser': preferences.models.OptionalUser,
|
||||||
'OptionalMachine': preferences.models.OptionalMachine,
|
'OptionalMachine': preferences.models.OptionalMachine,
|
||||||
|
@ -120,25 +120,25 @@ MODEL_NAME = {
|
||||||
'AssoOption': preferences.models.AssoOption,
|
'AssoOption': preferences.models.AssoOption,
|
||||||
'MailMessageOption': preferences.models.MailMessageOption,
|
'MailMessageOption': preferences.models.MailMessageOption,
|
||||||
# topologie
|
# topologie
|
||||||
'Stack' : topologie.models.Stack,
|
'Stack': topologie.models.Stack,
|
||||||
'Switch' : topologie.models.Switch,
|
'Switch': topologie.models.Switch,
|
||||||
'AccessPoint' : topologie.models.AccessPoint,
|
'AccessPoint': topologie.models.AccessPoint,
|
||||||
'ModelSwitch' : topologie.models.ModelSwitch,
|
'ModelSwitch': topologie.models.ModelSwitch,
|
||||||
'ConstructorSwitch' : topologie.models.ConstructorSwitch,
|
'ConstructorSwitch': topologie.models.ConstructorSwitch,
|
||||||
'Port' : topologie.models.Port,
|
'Port': topologie.models.Port,
|
||||||
'Room' : topologie.models.Room,
|
'Room': topologie.models.Room,
|
||||||
'Building' : topologie.models.Building,
|
'Building': topologie.models.Building,
|
||||||
'SwitchBay' : topologie.models.SwitchBay,
|
'SwitchBay': topologie.models.SwitchBay,
|
||||||
# users
|
# users
|
||||||
'User' : users.models.User,
|
'User': users.models.User,
|
||||||
'Adherent' : users.models.Adherent,
|
'Adherent': users.models.Adherent,
|
||||||
'Club' : users.models.Club,
|
'Club': users.models.Club,
|
||||||
'ServiceUser' : users.models.ServiceUser,
|
'ServiceUser': users.models.ServiceUser,
|
||||||
'School' : users.models.School,
|
'School': users.models.School,
|
||||||
'ListRight' : users.models.ListRight,
|
'ListRight': users.models.ListRight,
|
||||||
'ListShell' : users.models.ListShell,
|
'ListShell': users.models.ListShell,
|
||||||
'Ban' : users.models.Ban,
|
'Ban': users.models.Ban,
|
||||||
'Whitelist' : users.models.Whitelist,
|
'Whitelist': users.models.Whitelist,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -184,17 +184,41 @@ def get_callback(tag_name, obj=None):
|
||||||
if tag_name == 'cannot_view_all':
|
if tag_name == 'cannot_view_all':
|
||||||
return acl_fct(obj.can_view_all, True)
|
return acl_fct(obj.can_view_all, True)
|
||||||
if tag_name == 'can_view_app':
|
if tag_name == 'can_view_app':
|
||||||
return acl_fct(lambda x : (not any(not sys.modules[o].can_view(x) for o in obj), None), False)
|
return acl_fct(
|
||||||
|
lambda x: (
|
||||||
|
not any(not sys.modules[o].can_view(x) for o in obj),
|
||||||
|
None
|
||||||
|
),
|
||||||
|
False
|
||||||
|
)
|
||||||
if tag_name == 'cannot_view_app':
|
if tag_name == 'cannot_view_app':
|
||||||
return acl_fct(lambda x : (not any(not sys.modules[o].can_view(x) for o in obj), None), True)
|
return acl_fct(
|
||||||
|
lambda x: (
|
||||||
|
not any(not sys.modules[o].can_view(x) for o in obj),
|
||||||
|
None
|
||||||
|
),
|
||||||
|
True
|
||||||
|
)
|
||||||
if tag_name == 'can_edit_history':
|
if tag_name == 'can_edit_history':
|
||||||
return acl_fct(lambda user:(user.has_perm('admin.change_logentry'),None),False)
|
return acl_fct(
|
||||||
|
lambda user: (user.has_perm('admin.change_logentry'), None),
|
||||||
|
False
|
||||||
|
)
|
||||||
if tag_name == 'cannot_edit_history':
|
if tag_name == 'cannot_edit_history':
|
||||||
return acl_fct(lambda user:(user.has_perm('admin.change_logentry'),None),True)
|
return acl_fct(
|
||||||
|
lambda user: (user.has_perm('admin.change_logentry'), None),
|
||||||
|
True
|
||||||
|
)
|
||||||
if tag_name == 'can_view_any_app':
|
if tag_name == 'can_view_any_app':
|
||||||
return acl_fct(lambda x : (any(sys.modules[o].can_view(x) for o in obj), None), False)
|
return acl_fct(
|
||||||
|
lambda x: (any(sys.modules[o].can_view(x) for o in obj), None),
|
||||||
|
False
|
||||||
|
)
|
||||||
if tag_name == 'cannot_view_any_app':
|
if tag_name == 'cannot_view_any_app':
|
||||||
return acl_fct(lambda x : (any(sys.modules[o].can_view(x) for o in obj), None), True)
|
return acl_fct(
|
||||||
|
lambda x: (any(sys.modules[o].can_view(x) for o in obj), None),
|
||||||
|
True
|
||||||
|
)
|
||||||
|
|
||||||
raise template.TemplateSyntaxError(
|
raise template.TemplateSyntaxError(
|
||||||
"%r tag is not a valid can_xxx tag" % tag_name
|
"%r tag is not a valid can_xxx tag" % tag_name
|
||||||
|
@ -246,11 +270,11 @@ def acl_app_filter(parser, token):
|
||||||
tag_name, *app_name = token.split_contents()
|
tag_name, *app_name = token.split_contents()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise template.TemplateSyntaxError(
|
raise template.TemplateSyntaxError(
|
||||||
"%r tag require 1 argument : an application"
|
"%r tag require 1 argument: an application"
|
||||||
% token.contents.split()[0]
|
% token.contents.split()[0]
|
||||||
)
|
)
|
||||||
for name in app_name:
|
for name in app_name:
|
||||||
if not name in sys.modules.keys():
|
if name not in sys.modules.keys():
|
||||||
raise template.TemplateSyntaxError(
|
raise template.TemplateSyntaxError(
|
||||||
"%r is not a registered application for acl."
|
"%r is not a registered application for acl."
|
||||||
% name
|
% name
|
||||||
|
@ -270,6 +294,7 @@ def acl_app_filter(parser, token):
|
||||||
|
|
||||||
return AclNode(callback, oknodes, konodes)
|
return AclNode(callback, oknodes, konodes)
|
||||||
|
|
||||||
|
|
||||||
@register.tag('can_change')
|
@register.tag('can_change')
|
||||||
@register.tag('cannot_change')
|
@register.tag('cannot_change')
|
||||||
def acl_change_filter(parser, token):
|
def acl_change_filter(parser, token):
|
||||||
|
@ -283,7 +308,7 @@ def acl_change_filter(parser, token):
|
||||||
args = tag_content[3:]
|
args = tag_content[3:]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise template.TemplateSyntaxError(
|
raise template.TemplateSyntaxError(
|
||||||
"%r tag require at least 2 argument : the model and the field"
|
"%r tag require at least 2 argument: the model and the field"
|
||||||
% token.contents.split()[0]
|
% token.contents.split()[0]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -306,6 +331,7 @@ def acl_change_filter(parser, token):
|
||||||
|
|
||||||
return AclNode(callback, oknodes, konodes, *args)
|
return AclNode(callback, oknodes, konodes, *args)
|
||||||
|
|
||||||
|
|
||||||
@register.tag('can_create')
|
@register.tag('can_create')
|
||||||
@register.tag('cannot_create')
|
@register.tag('cannot_create')
|
||||||
@register.tag('can_edit_all')
|
@register.tag('can_edit_all')
|
||||||
|
@ -324,7 +350,7 @@ def acl_model_filter(parser, token):
|
||||||
args = tag_content[2:]
|
args = tag_content[2:]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise template.TemplateSyntaxError(
|
raise template.TemplateSyntaxError(
|
||||||
"%r tag require at least 1 argument : the model"
|
"%r tag require at least 1 argument: the model"
|
||||||
% token.contents.split()[0]
|
% token.contents.split()[0]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -364,7 +390,7 @@ def acl_instance_filter(parser, token):
|
||||||
args = tag_content[2:]
|
args = tag_content[2:]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise template.TemplateSyntaxError(
|
raise template.TemplateSyntaxError(
|
||||||
"%r tag require at least 1 argument : the instance"
|
"%r tag require at least 1 argument: the instance"
|
||||||
% token.contents.split()[0]
|
% token.contents.split()[0]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -36,13 +36,14 @@ from bootstrap3.forms import render_field
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def massive_bootstrap_form(form, mbf_fields, *args, **kwargs):
|
def massive_bootstrap_form(form, mbf_fields, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Render a form where some specific fields are rendered using Twitter
|
Render a form where some specific fields are rendered using Twitter
|
||||||
Typeahead and/or splitree's Bootstrap Tokenfield to improve the performance, the
|
Typeahead and/or splitree's Bootstrap Tokenfield to improve the
|
||||||
speed and UX when dealing with very large datasets (select with 50k+ elts
|
performance, the speed and UX when dealing with very large datasets
|
||||||
for instance).
|
(select with 50k+ elts for instance).
|
||||||
When the fields specified should normally be rendered as a select with
|
When the fields specified should normally be rendered as a select with
|
||||||
single selectable option, Twitter Typeahead is used for a better display
|
single selectable option, Twitter Typeahead is used for a better display
|
||||||
and the matching query engine. When dealing with multiple selectable
|
and the matching query engine. When dealing with multiple selectable
|
||||||
|
@ -189,8 +190,6 @@ def massive_bootstrap_form(form, mbf_fields, *args, **kwargs):
|
||||||
return mbf_form.render()
|
return mbf_form.render()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MBFForm():
|
class MBFForm():
|
||||||
""" An object to hold all the information and useful methods needed to
|
""" An object to hold all the information and useful methods needed to
|
||||||
create and render a massive django form into an actual HTML and JS
|
create and render a massive django form into an actual HTML and JS
|
||||||
|
@ -198,7 +197,6 @@ class MBFForm():
|
||||||
Every field that is not listed is rendered as a normal bootstrap_field.
|
Every field that is not listed is rendered as a normal bootstrap_field.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, form, mbf_fields, *args, **kwargs):
|
def __init__(self, form, mbf_fields, *args, **kwargs):
|
||||||
# The django form object
|
# The django form object
|
||||||
self.form = form
|
self.form = form
|
||||||
|
@ -224,14 +222,13 @@ class MBFForm():
|
||||||
# HTML code to insert inside a template
|
# HTML code to insert inside a template
|
||||||
self.html = ""
|
self.html = ""
|
||||||
|
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
""" HTML code for the fully rendered form with all the necessary form
|
""" HTML code for the fully rendered form with all the necessary form
|
||||||
"""
|
"""
|
||||||
for name, field in self.form.fields.items():
|
for name, field in self.form.fields.items():
|
||||||
if not name in self.exclude:
|
if name not in self.exclude:
|
||||||
|
|
||||||
if name in self.fields and not name in self.hidden_fields:
|
if name in self.fields and name not in self.hidden_fields:
|
||||||
mbf_field = MBFField(
|
mbf_field = MBFField(
|
||||||
name,
|
name,
|
||||||
field,
|
field,
|
||||||
|
@ -256,9 +253,6 @@ class MBFForm():
|
||||||
return mark_safe(self.html)
|
return mark_safe(self.html)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MBFField():
|
class MBFField():
|
||||||
""" An object to hold all the information and useful methods needed to
|
""" An object to hold all the information and useful methods needed to
|
||||||
create and render a massive django form field into an actual HTML and JS
|
create and render a massive django form field into an actual HTML and JS
|
||||||
|
@ -270,7 +264,6 @@ class MBFField():
|
||||||
the displayed input. It's used to store the actual data that will be sent
|
the displayed input. It's used to store the actual data that will be sent
|
||||||
to the server """
|
to the server """
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, name_, field_, bound_, choices_, engine_, match_func_,
|
def __init__(self, name_, field_, bound_, choices_, engine_, match_func_,
|
||||||
update_on_, gen_select_, *args_, **kwargs_):
|
update_on_, gen_select_, *args_, **kwargs_):
|
||||||
|
|
||||||
|
@ -278,8 +271,8 @@ class MBFField():
|
||||||
if not isinstance(field_.widget, Select):
|
if not isinstance(field_.widget, Select):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
('Field named {f_name} is not a Select and'
|
('Field named {f_name} is not a Select and'
|
||||||
'can\'t be rendered with massive_bootstrap_form.'
|
'can\'t be rendered with massive_bootstrap_form.')
|
||||||
).format(
|
.format(
|
||||||
f_name=name_
|
f_name=name_
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -324,7 +317,6 @@ class MBFField():
|
||||||
self.args = args_
|
self.args = args_
|
||||||
self.kwargs = kwargs_
|
self.kwargs = kwargs_
|
||||||
|
|
||||||
|
|
||||||
def default_choices(self):
|
def default_choices(self):
|
||||||
""" JS code of the variable choices_<fieldname> """
|
""" JS code of the variable choices_<fieldname> """
|
||||||
|
|
||||||
|
@ -351,7 +343,6 @@ class MBFField():
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def default_engine(self):
|
def default_engine(self):
|
||||||
""" Default JS code of the variable engine_<field_name> """
|
""" Default JS code of the variable engine_<field_name> """
|
||||||
return (
|
return (
|
||||||
|
@ -365,7 +356,6 @@ class MBFField():
|
||||||
name=self.name
|
name=self.name
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def default_datasets(self):
|
def default_datasets(self):
|
||||||
""" Default JS script of the datasets to use with typeahead """
|
""" Default JS script of the datasets to use with typeahead """
|
||||||
return (
|
return (
|
||||||
|
@ -384,7 +374,6 @@ class MBFField():
|
||||||
match_func=self.match_func
|
match_func=self.match_func
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def default_match_func(self):
|
def default_match_func(self):
|
||||||
""" Default JS code of the matching function to use with typeahed """
|
""" Default JS code of the matching function to use with typeahed """
|
||||||
return (
|
return (
|
||||||
|
@ -402,14 +391,12 @@ class MBFField():
|
||||||
name=self.name
|
name=self.name
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
""" HTML code for the fully rendered field """
|
""" HTML code for the fully rendered field """
|
||||||
self.gen_displayed_div()
|
self.gen_displayed_div()
|
||||||
self.gen_hidden_div()
|
self.gen_hidden_div()
|
||||||
return mark_safe(self.html)
|
return mark_safe(self.html)
|
||||||
|
|
||||||
|
|
||||||
def gen_displayed_div(self):
|
def gen_displayed_div(self):
|
||||||
""" Generate HTML code for the div that contains displayed tags """
|
""" Generate HTML code for the div that contains displayed tags """
|
||||||
if self.gen_select:
|
if self.gen_select:
|
||||||
|
@ -434,7 +421,6 @@ class MBFField():
|
||||||
if not self.gen_select:
|
if not self.gen_select:
|
||||||
self.html += self.replace_input
|
self.html += self.replace_input
|
||||||
|
|
||||||
|
|
||||||
def gen_hidden_div(self):
|
def gen_hidden_div(self):
|
||||||
""" Generate HTML code for the div that contains hidden tags """
|
""" Generate HTML code for the div that contains hidden tags """
|
||||||
self.gen_full_js()
|
self.gen_full_js()
|
||||||
|
@ -449,7 +435,6 @@ class MBFField():
|
||||||
attrs={'id': self.div2_id}
|
attrs={'id': self.div2_id}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def hidden_input(self):
|
def hidden_input(self):
|
||||||
""" HTML for the hidden input element """
|
""" HTML for the hidden input element """
|
||||||
return render_tag(
|
return render_tag(
|
||||||
|
@ -462,14 +447,12 @@ class MBFField():
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def gen_full_js(self):
|
def gen_full_js(self):
|
||||||
""" Generate the full script tag containing the JS code """
|
""" Generate the full script tag containing the JS code """
|
||||||
self.create_js()
|
self.create_js()
|
||||||
self.fill_js()
|
self.fill_js()
|
||||||
self.get_script()
|
self.get_script()
|
||||||
|
|
||||||
|
|
||||||
def create_js(self):
|
def create_js(self):
|
||||||
""" Generate a template for the whole script to use depending on
|
""" Generate a template for the whole script to use depending on
|
||||||
gen_select and multiple """
|
gen_select and multiple """
|
||||||
|
@ -549,7 +532,6 @@ class MBFField():
|
||||||
'}} );'
|
'}} );'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def fill_js(self):
|
def fill_js(self):
|
||||||
""" Fill the template with the correct values """
|
""" Fill the template with the correct values """
|
||||||
self.js_script = self.js_script.format(
|
self.js_script = self.js_script.format(
|
||||||
|
@ -571,11 +553,12 @@ class MBFField():
|
||||||
typ_init_input=self.typeahead_init_input()
|
typ_init_input=self.typeahead_init_input()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_script(self):
|
def get_script(self):
|
||||||
""" Insert the JS code inside a script tag """
|
""" Insert the JS code inside a script tag """
|
||||||
self.js_script = render_tag('script', content=mark_safe(self.js_script))
|
self.js_script = render_tag(
|
||||||
|
'script',
|
||||||
|
content=mark_safe(self.js_script)
|
||||||
|
)
|
||||||
|
|
||||||
def del_select(self):
|
def del_select(self):
|
||||||
""" JS code to delete the select if it has been generated and replace
|
""" JS code to delete the select if it has been generated and replace
|
||||||
|
@ -589,7 +572,6 @@ class MBFField():
|
||||||
replace_input=self.replace_input
|
replace_input=self.replace_input
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def gen_hidden(self):
|
def gen_hidden(self):
|
||||||
""" JS code to add a hidden tag to store the value. """
|
""" JS code to add a hidden tag to store the value. """
|
||||||
return (
|
return (
|
||||||
|
@ -606,7 +588,6 @@ class MBFField():
|
||||||
html_name=self.bound.html_name
|
html_name=self.bound.html_name
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def typeahead_init_input(self):
|
def typeahead_init_input(self):
|
||||||
""" JS code to init the fields values """
|
""" JS code to init the fields values """
|
||||||
init_key = self.bound.value() or '""'
|
init_key = self.bound.value() or '""'
|
||||||
|
@ -624,7 +605,6 @@ class MBFField():
|
||||||
hidden_id=self.hidden_id
|
hidden_id=self.hidden_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def typeahead_reset_input(self):
|
def typeahead_reset_input(self):
|
||||||
""" JS code to reset the fields values """
|
""" JS code to reset the fields values """
|
||||||
return (
|
return (
|
||||||
|
@ -635,7 +615,6 @@ class MBFField():
|
||||||
hidden_id=self.hidden_id
|
hidden_id=self.hidden_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def typeahead_select(self):
|
def typeahead_select(self):
|
||||||
""" JS code to create the function triggered when an item is selected
|
""" JS code to create the function triggered when an item is selected
|
||||||
through typeahead """
|
through typeahead """
|
||||||
|
@ -649,7 +628,6 @@ class MBFField():
|
||||||
hidden_id=self.hidden_id
|
hidden_id=self.hidden_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def typeahead_change(self):
|
def typeahead_change(self):
|
||||||
""" JS code of the function triggered when an item is changed (i.e.
|
""" JS code of the function triggered when an item is changed (i.e.
|
||||||
looses focus and value has changed since the moment it gained focus )
|
looses focus and value has changed since the moment it gained focus )
|
||||||
|
@ -666,7 +644,6 @@ class MBFField():
|
||||||
hidden_id=self.hidden_id
|
hidden_id=self.hidden_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def typeahead_updates(self):
|
def typeahead_updates(self):
|
||||||
""" JS code for binding external fields changes with a reset """
|
""" JS code for binding external fields changes with a reset """
|
||||||
reset_input = self.typeahead_reset_input()
|
reset_input = self.typeahead_reset_input()
|
||||||
|
@ -683,7 +660,6 @@ class MBFField():
|
||||||
) for u_id in self.update_on]
|
) for u_id in self.update_on]
|
||||||
return ''.join(updates)
|
return ''.join(updates)
|
||||||
|
|
||||||
|
|
||||||
def tokenfield_init_input(self):
|
def tokenfield_init_input(self):
|
||||||
""" JS code to init the fields values """
|
""" JS code to init the fields values """
|
||||||
init_key = self.bound.value() or '""'
|
init_key = self.bound.value() or '""'
|
||||||
|
@ -700,7 +676,6 @@ class MBFField():
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def tokenfield_reset_input(self):
|
def tokenfield_reset_input(self):
|
||||||
""" JS code to reset the fields values """
|
""" JS code to reset the fields values """
|
||||||
return (
|
return (
|
||||||
|
@ -709,7 +684,6 @@ class MBFField():
|
||||||
input_id=self.input_id
|
input_id=self.input_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def tokenfield_create(self):
|
def tokenfield_create(self):
|
||||||
""" JS code triggered when a new token is created in tokenfield. """
|
""" JS code triggered when a new token is created in tokenfield. """
|
||||||
return (
|
return (
|
||||||
|
@ -739,7 +713,6 @@ class MBFField():
|
||||||
div2_id=self.div2_id
|
div2_id=self.div2_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def tokenfield_edit(self):
|
def tokenfield_edit(self):
|
||||||
""" JS code triggered when a token is edited in tokenfield. """
|
""" JS code triggered when a token is edited in tokenfield. """
|
||||||
return (
|
return (
|
||||||
|
@ -765,7 +738,6 @@ class MBFField():
|
||||||
hidden_id=self.hidden_id
|
hidden_id=self.hidden_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def tokenfield_remove(self):
|
def tokenfield_remove(self):
|
||||||
""" JS code trigggered when a token is removed from tokenfield. """
|
""" JS code trigggered when a token is removed from tokenfield. """
|
||||||
return (
|
return (
|
||||||
|
@ -791,7 +763,6 @@ class MBFField():
|
||||||
hidden_id=self.hidden_id
|
hidden_id=self.hidden_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def tokenfield_updates(self):
|
def tokenfield_updates(self):
|
||||||
""" JS code for binding external fields changes with a reset """
|
""" JS code for binding external fields changes with a reset """
|
||||||
reset_input = self.tokenfield_reset_input()
|
reset_input = self.tokenfield_reset_input()
|
||||||
|
|
|
@ -24,6 +24,7 @@ from preferences.models import OptionalUser, GeneralOption
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def self_adhesion():
|
def self_adhesion():
|
||||||
options, _created = OptionalUser.objects.get_or_create()
|
options, _created = OptionalUser.objects.get_or_create()
|
||||||
|
|
|
@ -118,14 +118,18 @@ def all_has_access(search_time=None):
|
||||||
|
|
||||||
def filter_active_interfaces(interface_set):
|
def filter_active_interfaces(interface_set):
|
||||||
"""Filtre les machines autorisées à sortir sur internet dans une requête"""
|
"""Filtre les machines autorisées à sortir sur internet dans une requête"""
|
||||||
return interface_set.filter(
|
return (interface_set
|
||||||
machine__in=Machine.objects.filter(
|
.filter(
|
||||||
user__in=all_has_access()
|
machine__in=Machine.objects.filter(
|
||||||
).filter(active=True)
|
user__in=all_has_access()
|
||||||
).select_related('domain').select_related('machine')\
|
).filter(active=True)
|
||||||
.select_related('type').select_related('ipv4')\
|
).select_related('domain')
|
||||||
.select_related('domain__extension').select_related('ipv4__ip_type')\
|
.select_related('machine')
|
||||||
.distinct()
|
.select_related('type')
|
||||||
|
.select_related('ipv4')
|
||||||
|
.select_related('domain__extension')
|
||||||
|
.select_related('ipv4__ip_type')
|
||||||
|
.distinct())
|
||||||
|
|
||||||
|
|
||||||
def filter_complete_interfaces(interface_set):
|
def filter_complete_interfaces(interface_set):
|
||||||
|
@ -160,6 +164,7 @@ def all_active_assigned_interfaces_count():
|
||||||
""" Version light seulement pour compter"""
|
""" Version light seulement pour compter"""
|
||||||
return all_active_interfaces_count().filter(ipv4__isnull=False)
|
return all_active_interfaces_count().filter(ipv4__isnull=False)
|
||||||
|
|
||||||
|
|
||||||
class SortTable:
|
class SortTable:
|
||||||
""" Class gathering uselful stuff to sort the colums of a table, according
|
""" 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
|
to the column and order requested. It's used with a dict of possible
|
||||||
|
@ -171,7 +176,8 @@ class SortTable:
|
||||||
# the url value and the values are a list of model field name to use to
|
# 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.
|
# 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
|
# A 'default' might be provided to specify what to do if the requested col
|
||||||
# doesn't match any keys.
|
# doesn't match any keys.
|
||||||
|
|
||||||
USERS_INDEX = {
|
USERS_INDEX = {
|
||||||
'user_name': ['name'],
|
'user_name': ['name'],
|
||||||
'user_surname': ['surname'],
|
'user_surname': ['surname'],
|
||||||
|
@ -255,7 +261,7 @@ class SortTable:
|
||||||
}
|
}
|
||||||
TOPOLOGIE_INDEX_MODEL_SWITCH = {
|
TOPOLOGIE_INDEX_MODEL_SWITCH = {
|
||||||
'model-switch_name': ['reference'],
|
'model-switch_name': ['reference'],
|
||||||
'model-switch_contructor' : ['constructor__name'],
|
'model-switch_contructor': ['constructor__name'],
|
||||||
'default': ['reference'],
|
'default': ['reference'],
|
||||||
}
|
}
|
||||||
TOPOLOGIE_INDEX_SWITCH_BAY = {
|
TOPOLOGIE_INDEX_SWITCH_BAY = {
|
||||||
|
@ -290,6 +296,7 @@ class SortTable:
|
||||||
else:
|
else:
|
||||||
return request
|
return request
|
||||||
|
|
||||||
|
|
||||||
def re2o_paginator(request, query_set, pagination_number):
|
def re2o_paginator(request, query_set, pagination_number):
|
||||||
"""Paginator script for list display in re2o.
|
"""Paginator script for list display in re2o.
|
||||||
:request:
|
:request:
|
||||||
|
@ -307,6 +314,7 @@ def re2o_paginator(request, query_set, pagination_number):
|
||||||
results = paginator.page(paginator.num_pages)
|
results = paginator.page(paginator.num_pages)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
def remove_user_room(room):
|
def remove_user_room(room):
|
||||||
""" Déménage de force l'ancien locataire de la chambre """
|
""" Déménage de force l'ancien locataire de la chambre """
|
||||||
try:
|
try:
|
||||||
|
|
106
re2o/views.py
106
re2o/views.py
|
@ -44,12 +44,17 @@ from itertools import chain
|
||||||
|
|
||||||
from preferences.models import Service
|
from preferences.models import Service
|
||||||
from preferences.models import OptionalUser, GeneralOption, AssoOption
|
from preferences.models import OptionalUser, GeneralOption, AssoOption
|
||||||
import users, preferences, cotisations, topologie, machines
|
import users
|
||||||
|
import preferences
|
||||||
|
import cotisations
|
||||||
|
import topologie
|
||||||
|
import machines
|
||||||
|
|
||||||
from .utils import re2o_paginator
|
from .utils import re2o_paginator
|
||||||
from .settings import BASE_DIR, INSTALLED_APPS, MIDDLEWARE_CLASSES
|
from .settings import BASE_DIR, INSTALLED_APPS, MIDDLEWARE_CLASSES
|
||||||
from .contributors import CONTRIBUTORS
|
from .contributors import CONTRIBUTORS
|
||||||
|
|
||||||
|
|
||||||
def form(ctx, template, request):
|
def form(ctx, template, request):
|
||||||
"""Form générique, raccourci importé par les fonctions views du site"""
|
"""Form générique, raccourci importé par les fonctions views du site"""
|
||||||
context = ctx
|
context = ctx
|
||||||
|
@ -64,56 +69,58 @@ def index(request):
|
||||||
services[indice % 3].append(serv)
|
services[indice % 3].append(serv)
|
||||||
return form({'services_urls': services}, 're2o/index.html', request)
|
return form({'services_urls': services}, 're2o/index.html', request)
|
||||||
|
|
||||||
|
|
||||||
#: Binding the corresponding char sequence of history url to re2o models.
|
#: Binding the corresponding char sequence of history url to re2o models.
|
||||||
HISTORY_BIND = {
|
HISTORY_BIND = {
|
||||||
'users' : {
|
'users': {
|
||||||
'user' : users.models.User,
|
'user': users.models.User,
|
||||||
'ban' : users.models.Ban,
|
'ban': users.models.Ban,
|
||||||
'whitelist' : users.models.Whitelist,
|
'whitelist': users.models.Whitelist,
|
||||||
'school' : users.models.School,
|
'school': users.models.School,
|
||||||
'listright' : users.models.ListRight,
|
'listright': users.models.ListRight,
|
||||||
'serviceuser' : users.models.ServiceUser,
|
'serviceuser': users.models.ServiceUser,
|
||||||
'listshell' : users.models.ListShell,
|
'listshell': users.models.ListShell,
|
||||||
},
|
},
|
||||||
'preferences' : {
|
'preferences': {
|
||||||
'service' : preferences.models.Service,
|
'service': preferences.models.Service,
|
||||||
},
|
},
|
||||||
'cotisations' : {
|
'cotisations': {
|
||||||
'facture' : cotisations.models.Facture,
|
'facture': cotisations.models.Facture,
|
||||||
'article' : cotisations.models.Article,
|
'article': cotisations.models.Article,
|
||||||
'paiement' : cotisations.models.Paiement,
|
'paiement': cotisations.models.Paiement,
|
||||||
'banque' : cotisations.models.Banque,
|
'banque': cotisations.models.Banque,
|
||||||
},
|
},
|
||||||
'topologie' : {
|
'topologie': {
|
||||||
'switch' : topologie.models.Switch,
|
'switch': topologie.models.Switch,
|
||||||
'port' : topologie.models.Port,
|
'port': topologie.models.Port,
|
||||||
'room' : topologie.models.Room,
|
'room': topologie.models.Room,
|
||||||
'stack' : topologie.models.Stack,
|
'stack': topologie.models.Stack,
|
||||||
'modelswitch' : topologie.models.ModelSwitch,
|
'modelswitch': topologie.models.ModelSwitch,
|
||||||
'constructorswitch' : topologie.models.ConstructorSwitch,
|
'constructorswitch': topologie.models.ConstructorSwitch,
|
||||||
'accesspoint' : topologie.models.AccessPoint,
|
'accesspoint': topologie.models.AccessPoint,
|
||||||
'switchbay' : topologie.models.SwitchBay,
|
'switchbay': topologie.models.SwitchBay,
|
||||||
'building' : topologie.models.Building,
|
'building': topologie.models.Building,
|
||||||
},
|
},
|
||||||
'machines' : {
|
'machines': {
|
||||||
'machine' : machines.models.Machine,
|
'machine': machines.models.Machine,
|
||||||
'interface' : machines.models.Interface,
|
'interface': machines.models.Interface,
|
||||||
'domain' : machines.models.Domain,
|
'domain': machines.models.Domain,
|
||||||
'machinetype' : machines.models.MachineType,
|
'machinetype': machines.models.MachineType,
|
||||||
'iptype' : machines.models.IpType,
|
'iptype': machines.models.IpType,
|
||||||
'extension' : machines.models.Extension,
|
'extension': machines.models.Extension,
|
||||||
'soa' : machines.models.SOA,
|
'soa': machines.models.SOA,
|
||||||
'mx' : machines.models.Mx,
|
'mx': machines.models.Mx,
|
||||||
'txt' : machines.models.Txt,
|
'txt': machines.models.Txt,
|
||||||
'srv' : machines.models.Srv,
|
'srv': machines.models.Srv,
|
||||||
'ns' : machines.models.Ns,
|
'ns': machines.models.Ns,
|
||||||
'service' : machines.models.Service,
|
'service': machines.models.Service,
|
||||||
'vlan' : machines.models.Vlan,
|
'vlan': machines.models.Vlan,
|
||||||
'nas' : machines.models.Nas,
|
'nas': machines.models.Nas,
|
||||||
'ipv6list' : machines.models.Ipv6List,
|
'ipv6list': machines.models.Ipv6List,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def history(request, application, object_name, object_id):
|
def history(request, application, object_name, object_id):
|
||||||
"""Render history for a model.
|
"""Render history for a model.
|
||||||
|
@ -144,21 +151,23 @@ def history(request, application, object_name, object_id):
|
||||||
instance = model.get_instance(**kwargs)
|
instance = model.get_instance(**kwargs)
|
||||||
except model.DoesNotExist:
|
except model.DoesNotExist:
|
||||||
messages.error(request, u"Entrée inexistante")
|
messages.error(request, u"Entrée inexistante")
|
||||||
return redirect(reverse('users:profil',
|
return redirect(reverse(
|
||||||
kwargs={'userid':str(request.user.id)}
|
'users:profil',
|
||||||
|
kwargs={'userid': str(request.user.id)}
|
||||||
))
|
))
|
||||||
can, msg = instance.can_view(request.user)
|
can, msg = instance.can_view(request.user)
|
||||||
if not can:
|
if not can:
|
||||||
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
|
||||||
return redirect(reverse(
|
return redirect(reverse(
|
||||||
'users:profil',
|
'users:profil',
|
||||||
kwargs={'userid':str(request.user.id)}
|
kwargs={'userid': str(request.user.id)}
|
||||||
))
|
))
|
||||||
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
pagination_number = GeneralOption.get_cached_value('pagination_number')
|
||||||
reversions = Version.objects.get_for_object(instance)
|
reversions = Version.objects.get_for_object(instance)
|
||||||
if hasattr(instance, 'linked_objects'):
|
if hasattr(instance, 'linked_objects'):
|
||||||
for related_object in chain(instance.linked_objects()):
|
for related_object in chain(instance.linked_objects()):
|
||||||
reversions = reversions | Version.objects.get_for_object(related_object)
|
reversions = (reversions |
|
||||||
|
Version.objects.get_for_object(related_object))
|
||||||
reversions = re2o_paginator(request, reversions, pagination_number)
|
reversions = re2o_paginator(request, reversions, pagination_number)
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
|
@ -191,8 +200,8 @@ def about_page(request):
|
||||||
request,
|
request,
|
||||||
"re2o/about.html",
|
"re2o/about.html",
|
||||||
{
|
{
|
||||||
'description': option.description ,
|
'description': option.description,
|
||||||
'AssoName' : option.name ,
|
'AssoName': option.name,
|
||||||
'git_info_contributors': git_info_contributors,
|
'git_info_contributors': git_info_contributors,
|
||||||
'git_info_remote': git_info_remote,
|
'git_info_remote': git_info_remote,
|
||||||
'git_info_branch': git_info_branch,
|
'git_info_branch': git_info_branch,
|
||||||
|
@ -201,4 +210,3 @@ def about_page(request):
|
||||||
'dependencies': dependencies
|
'dependencies': dependencies
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue