[gestion] Ajout d'un début de gest_crans utilisant lc_ldap
This commit is contained in:
parent
8962c3b33d
commit
21341577a5
1 changed files with 305 additions and 0 deletions
305
gestion/gest_crans_lc.py
Executable file
305
gestion/gest_crans_lc.py
Executable file
|
@ -0,0 +1,305 @@
|
||||||
|
#!/bin/bash /usr/scripts/python.sh
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
u"""
|
||||||
|
Interface utilisateur du système de gestion des machines
|
||||||
|
et adhérents du crans
|
||||||
|
|
||||||
|
Copyright (C) Valentin Samir
|
||||||
|
Licence : GPLv3
|
||||||
|
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import signal
|
||||||
|
from pythondialog import Dialog
|
||||||
|
|
||||||
|
from gestion.affich_tools import get_screen_size, coul
|
||||||
|
|
||||||
|
import lc_ldap.shortcuts
|
||||||
|
import lc_ldap.printing as printing
|
||||||
|
|
||||||
|
def handle_exit_code(d, code):
|
||||||
|
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
|
||||||
|
if code == d.DIALOG_CANCEL:
|
||||||
|
msg = "Vous avez choisi Annuler dans la dernière fenêtre de dialogue.\n\n" \
|
||||||
|
"Voulez vous quitter le programme ?"
|
||||||
|
os.system('clear')
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
msg = "Vous avez appuyer sur ESC dans la dernière fenêtre de dialogue.\n\n" \
|
||||||
|
"Voulez vous quitter le programme ?"
|
||||||
|
if d.yesno(msg, width=60) == d.DIALOG_OK:
|
||||||
|
os.system('clear')
|
||||||
|
sys.exit(0)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True # code est d.DIALOG_OK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def search(dialog, objectClassS, title, values={}):
|
||||||
|
"""
|
||||||
|
Rechercher des adhérents ou des machines dans la base ldap
|
||||||
|
retourne le tuple (code de retour dialog, valeurs entrée par l'utilisateur, liste d'objets trouvés)
|
||||||
|
La fonction est découpé en trois partie :
|
||||||
|
* affichage dialog et récupération du résultat
|
||||||
|
* construction de filtres de recherche ldap et recherches ldap
|
||||||
|
* filtre sur les résultats des recherches ldap
|
||||||
|
"""
|
||||||
|
select_dict = {
|
||||||
|
#label attribut ldap search for substring param dialog: line col valeur input-line icol len max-chars
|
||||||
|
'Nom' : {'ldap':'nom', 'sub':True, 'params' : [ 1, 1, values.get('nom', ""), 1, 13, 20, 20]},
|
||||||
|
'Prenom' : {'ldap':'prenom', 'sub':True, 'params' : [ 2, 1, values.get('prenom', ""), 2, 13, 20, 20]},
|
||||||
|
'Téléphone' : {'ldap':'tel', 'sub':True, 'params' : [ 3, 1, values.get('tel', ""), 3, 13, 10, 00]},
|
||||||
|
'Chambre' : {'ldap':'chbre','sub':True, 'params' : [ 4, 1, values.get('chbre',""), 4, 13, 05, 00]},
|
||||||
|
'aid' : {'ldap' : 'aid', 'sub':False, 'params' : [ 5, 1, values.get('aid',""), 5, 13, 05, 05]},
|
||||||
|
'mail' : {'ldap' : 'mail', 'sub':True, 'params' : [ 6, 1, values.get('mail',""), 6, 13, 20, 00]},
|
||||||
|
# seconde colone
|
||||||
|
'Machine' : {'ldap' : '*', 'sub':True, 'params' : [1, 35, "", 1, 43, 0, 0]},
|
||||||
|
'Host' : {'ldap' : 'host', 'sub':True, 'params' : [2, 37, values.get('host',""), 2, 43, 17, 17]},
|
||||||
|
'Mac' : {'ldap' : 'macAddress', 'sub':False, 'params' : [3, 37, values.get('macAddress',""), 3, 43, 17, 17]},
|
||||||
|
'IP' : {'ldap' : 'ipHostNumber', 'sub':False,'params' : [4, 37, values.get('ipHostNumber',""), 4, 43, 15, 15]},
|
||||||
|
'mid' : {'ldap' : 'mid', 'sub':False, 'params' : [5, 37, values.get('mid',""), 5, 43, 5, 5]},
|
||||||
|
}
|
||||||
|
# On a besoin de l'ordre pour récupérer les valeurs ensuite
|
||||||
|
select_adherent = ['Nom', 'Prenom', 'Téléphone', 'Chambre', 'aid', 'mail']
|
||||||
|
select_machine = ['Host', 'Mac', 'IP', 'mid']
|
||||||
|
def box():
|
||||||
|
# On met les argument à dialog à la main ici, sinon, c'est difficile de choisir comment mettre une seconde colone
|
||||||
|
cmd = ["--form", "Entrez vos paramètres de recherche", '0', '0', '0']
|
||||||
|
for key in select_adherent:
|
||||||
|
cmd.extend(['%s :' % key] + [str(e) for e in select_dict[key]['params']])
|
||||||
|
cmd.extend(['Machine :'] + [str(e) for e in select_dict['Machine']['params']])
|
||||||
|
for key in select_machine:
|
||||||
|
cmd.extend(['%s :' % key] + [str(e) for e in select_dict[key]['params']])
|
||||||
|
cmd.extend(["Les champs vides sont ignorés.", '7', '1', "", '0', '0', '0', '0'])
|
||||||
|
# On utilise quand même la fonction de la bibliothèques pour passer les arguments
|
||||||
|
(code, output) = dialog._perform(*(cmd,), title=title, backtitle="Entrez vos paramètres de recherche")
|
||||||
|
if output:
|
||||||
|
return (code, output.split('\n')[:-1])
|
||||||
|
else: # empty selection
|
||||||
|
return (code, [])
|
||||||
|
|
||||||
|
(code, dialog_values) = box()
|
||||||
|
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC):
|
||||||
|
return code, values, []
|
||||||
|
else:
|
||||||
|
# Transformation de la liste des valeures entrée en dictionnnaire
|
||||||
|
dialog_values = dict(zip(select_adherent + select_machine, dialog_values))
|
||||||
|
ldap_values = dict([(select_dict[key]['ldap'], value) for key, value in dialog_values.items()])
|
||||||
|
|
||||||
|
# Construction des filtres ldap pour les adhérents et les machines
|
||||||
|
filter_adherent = []
|
||||||
|
filter_machine = []
|
||||||
|
for (key, value) in dialog_values.items():
|
||||||
|
if value:
|
||||||
|
if key in select_adherent:
|
||||||
|
filter_adherent.append((u"(%s=*%s*)" if select_dict[key]['sub'] else u"(%s=%s)") % (select_dict[key]['ldap'], unicode(value, 'utf-8')))
|
||||||
|
elif key in select_machine:
|
||||||
|
filter_machine.append((u"(%s=*%s*)" if select_dict[key]['sub'] else u"(%s=%s)") % (select_dict[key]['ldap'], unicode(value, 'utf-8')))
|
||||||
|
if filter_adherent:
|
||||||
|
filter_adherent=u"(&%s)" % "".join(filter_adherent)
|
||||||
|
if filter_machine:
|
||||||
|
filter_machine=u"(&%s)" % "".join(filter_machine)
|
||||||
|
|
||||||
|
# Récupération des adhérents et des machines
|
||||||
|
adherents=conn.search(filter_adherent) if filter_adherent else []
|
||||||
|
machines=conn.search(filter_machine) if filter_machine else []
|
||||||
|
|
||||||
|
# Filtrage des machines en fonction des adhérents
|
||||||
|
if filter_adherent:
|
||||||
|
if filter_machine:
|
||||||
|
# Si on filtre sur des adhérent et des machines, on calcule l'intersection
|
||||||
|
adherents_dn = set([a.dn for a in adherents])
|
||||||
|
machines_f = [m for m in machines if m.parent_dn in adherents_dn]
|
||||||
|
else:
|
||||||
|
# Sinon on filtre seulement sur les adhérents, récupère les machines des adhérents trouvés
|
||||||
|
machines_f = [m for a in adherents for m in a.machines()]
|
||||||
|
else:
|
||||||
|
# Sinon si on filtre seulement sur des machines
|
||||||
|
machines_f = machines
|
||||||
|
|
||||||
|
# Filtrage des adhérents en fonction des machines
|
||||||
|
if filter_machine:
|
||||||
|
if filter_adherent:
|
||||||
|
# Si on filtre sur des adhérents et des machines, on calcule l'intersection
|
||||||
|
machines_dn = set([m.parent_dn for m in machines])
|
||||||
|
adherents_f = [a for a in adherents if a.dn in machines_dn]
|
||||||
|
else:
|
||||||
|
# Sinon on récupères les proprios des machines trouvées
|
||||||
|
adherents_f = [m.proprio() for m in machines]
|
||||||
|
else:
|
||||||
|
# Sinon si on filtre seulement sur des adhérents
|
||||||
|
adherents_f = adherents
|
||||||
|
|
||||||
|
# On filtre sur les objectClassS
|
||||||
|
return code, ldap_values, [ o for objectClass in objectClassS for o in machines_f+adherents_f if objectClass in o['objectClass'] ]
|
||||||
|
|
||||||
|
def select_one(dialog, items, default_item=None):
|
||||||
|
"""Fait selectionner un item parmis une liste d'items à l'utisateur"""
|
||||||
|
### TODO afficher correctement les objets dans items
|
||||||
|
choices=[]
|
||||||
|
count = 0
|
||||||
|
default_tag = items.index(default_item) if default_item in items else default_item
|
||||||
|
for i in items:
|
||||||
|
choices.append((str(count), str(i), 1 if default_tag == count else 0))
|
||||||
|
count+=1
|
||||||
|
tag=''
|
||||||
|
while not tag:
|
||||||
|
(line, col) = get_screen_size()
|
||||||
|
(code, tag) = dialog.radiolist(
|
||||||
|
"Choisir",
|
||||||
|
choices=choices,
|
||||||
|
default_item=str(default_tag),
|
||||||
|
width=col-4,
|
||||||
|
height=line-3,
|
||||||
|
list_height=line-3,
|
||||||
|
scrollbar=True)
|
||||||
|
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC):
|
||||||
|
return code, None
|
||||||
|
if not tag:
|
||||||
|
dialog.msgbox("Merci de choisir l'un des item de la liste ou d'annuler", title="Sélection", width=0, height=0)
|
||||||
|
return code, items[int(tag)]
|
||||||
|
|
||||||
|
def select_confirm(dialog, item, title):
|
||||||
|
"""Affiche un item et demande si c'est bien celui là que l'on veux (supprimer, éditer, créer,...)"""
|
||||||
|
return dialog.yesno(printing.sprint(item), no_collapse=True, colors=True, title=title, width=0, height=0, backtitle="Appuyez sur MAJ pour selectionner du texte") == dialog.DIALOG_OK
|
||||||
|
|
||||||
|
def select(dialog, objectClassS, title, values={}):
|
||||||
|
"""Permet de choisir un objet adhérent ou machine dans la base ldap"""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
# On fait effectuer une recherche à l'utilisateur
|
||||||
|
code, values, items = search(dialog, objectClassS, title, values)
|
||||||
|
# Si il a appuyé sur annuler ou sur escape, on annule
|
||||||
|
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC):
|
||||||
|
return code, None
|
||||||
|
# S'il n'y a pas de résultas, on recommence
|
||||||
|
elif not items:
|
||||||
|
dialog.msgbox("Aucun Résultat", title="Recherche", width=0, height=0)
|
||||||
|
# S'il y a plusieurs résultats
|
||||||
|
elif len(items)>1:
|
||||||
|
item = None
|
||||||
|
while True:
|
||||||
|
# On en fait choisir un
|
||||||
|
code, item = select_one(dialog, items, item)
|
||||||
|
# Si il à appuyer sur annuler ou sur escape, on recommence la recherche
|
||||||
|
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC):
|
||||||
|
break
|
||||||
|
# Sinon, on fait confirmer son choix à l'utilisateur
|
||||||
|
elif select_confirm(dialog, item, title):
|
||||||
|
return code, item
|
||||||
|
# S'il y a exactement 1 résultat à la recherche, on fait confirmer son choix à l'utilisateur
|
||||||
|
elif len(items) == 1 and select_confirm(dialog, items[0], title):
|
||||||
|
return code, items[0]
|
||||||
|
except Exception as e:
|
||||||
|
dialog.msgbox("%r" % e, title="Erreur rencontrée", width=0, height=0)
|
||||||
|
|
||||||
|
def modif_adherent(dialog):
|
||||||
|
code, adherent = select(dialog, ["adherent"], "Recherche d'un adhérent")
|
||||||
|
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC):
|
||||||
|
return code
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
def create_adherent(dialog):
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
def delete_adherent(dialog):
|
||||||
|
code, adherent = select(dialog, ["adherent"], "Recherche d'un adhérent")
|
||||||
|
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC):
|
||||||
|
return code
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
def modif_machine(dialog):
|
||||||
|
code, machine = select(dialog, ["machineFixe", "machineWifi", "machineCrans", "borneWifi"], "Recherche d'une machine")
|
||||||
|
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC):
|
||||||
|
return code
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
def create_machine_adherent(dialog):
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
def delete_machine(dialog):
|
||||||
|
code, machine = select(dialog, ["machineFixe", "machineWifi", "machineCrans", "borneWifi"], "Recherche d'une machine")
|
||||||
|
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC):
|
||||||
|
return code
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
|
||||||
|
def create_club(dialog):
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_club(dialog):
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
def modif_club(dialog):
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
def create_machine_club(dialog):
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
def create_machine_crans(dialog):
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
def create_borne(dialog):
|
||||||
|
dialog.msgbox("todo", width=0, height=0)
|
||||||
|
|
||||||
|
def menu_principal(dialog):
|
||||||
|
menu = {
|
||||||
|
'aA' : {'text':"Inscrire un nouvel adhérent", 'callback': create_adherent},
|
||||||
|
'mA' : {'text':"Modifier l'inscription d'un adhérent", 'callback': modif_adherent, 'help':"Changer la chambre, la remarque, la section, la carte d'étudiant ou précâbler."},
|
||||||
|
'aMA': {'text':"Ajouter une machine à un adhérent", 'callback': create_machine_adherent},
|
||||||
|
'dA' : {'text':"Détruire un adhérent", 'callback': delete_adherent, 'help':"Suppression de l'adhérent ainsi que de ses machines"},
|
||||||
|
'mM' : {'text':"Modifier une machine existante", 'callback': modif_machine, 'help':"Changer le nom ou la MAC d'une machine."},
|
||||||
|
'dM' : {'text':"Détruire une machine", 'callback': delete_machine},
|
||||||
|
'aC' : {'text':"Inscrire un nouveau club", 'callback': create_club},
|
||||||
|
'mC' : {'text':"Modifier un club", 'callback': modif_club},
|
||||||
|
'aMC': {'text':"Ajouter une machine à un club", 'callback': create_machine_club},
|
||||||
|
'dC' : {'text':"Détruire un club", 'callback': delete_club},
|
||||||
|
'aKM': {'text':"Ajouter une machine à l'association", 'callback': create_machine_crans},
|
||||||
|
'aKB': {'text':"Ajouter une borne wifi", 'callback': create_borne},
|
||||||
|
'' : {'text':"---------------------------------------",'callback': lambda x: x},
|
||||||
|
}
|
||||||
|
### Les clef qui n'existe pas sont toute renvoyé sur la clef ''
|
||||||
|
medu_order = ["aA", "mA", "aMA", "dA", "", "mM", "dM", " ", "aC", "mC", "aMC", "dC", " ", "aKM", "aKB"]
|
||||||
|
def box(default_item=None):
|
||||||
|
return dialog.menu(
|
||||||
|
"Que souhaitez vous faire ?",
|
||||||
|
width=55,
|
||||||
|
height=0,
|
||||||
|
menu_height=15,
|
||||||
|
item_help=1,
|
||||||
|
default_item=str(default_item),
|
||||||
|
title="Menu principal",
|
||||||
|
scrollbar=True,
|
||||||
|
cancel_label="Quitter",
|
||||||
|
backtitle=u"Vous êtes connecté en tant que %s" % conn.current_login,
|
||||||
|
choices=[(key, menu.get(key, menu[''])['text'], menu.get(key, menu['']).get('help', "")) for key in medu_order])
|
||||||
|
|
||||||
|
tag=None
|
||||||
|
while True:
|
||||||
|
(code, tag) = box(tag)
|
||||||
|
if handle_exit_code(dialog, code):
|
||||||
|
menu.get(tag, menu[''])['callback'](dialog)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||||
|
# On initialise le moteur de rendu en spécifiant qu'on va faire du dialog
|
||||||
|
printing.template(dialog=True)
|
||||||
|
|
||||||
|
# On ouvre une connexion lc_ldap
|
||||||
|
conn = lc_ldap.shortcuts.lc_ldap_admin()
|
||||||
|
# On vérifie que l'utilisateur système existe dans ldap (pour la gestion des droits)
|
||||||
|
luser=conn.search(u"uid=%s" % conn.current_login)
|
||||||
|
if not luser:
|
||||||
|
sys.stderr.write("L'utilisateur %s n'existe pas dans la base de donnée" % conn.current_login)
|
||||||
|
sys.exit(1)
|
||||||
|
conn.droits = [str(d) for d in luser[0]['droits']]
|
||||||
|
conn.dn = luser[0].dn
|
||||||
|
|
||||||
|
dialog = Dialog()
|
||||||
|
menu_principal(dialog)
|
||||||
|
os.system('clear')
|
Loading…
Add table
Add a link
Reference in a new issue