[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