[gest_crans_lc] (par Valentin) Je préfère commiter ça pour qu'on ait une trace, quitte à revert.

This commit is contained in:
Pierre-Elliott Bécue 2014-03-10 10:09:10 +01:00
parent ffe5f8ddf3
commit 82804b7924

View file

@ -12,6 +12,7 @@ Licence : GPLv3
import os import os
import sys import sys
import signal import signal
import collections
from pythondialog import Dialog from pythondialog import Dialog
from gestion.affich_tools import get_screen_size, coul from gestion.affich_tools import get_screen_size, coul
@ -19,6 +20,49 @@ from gestion.affich_tools import get_screen_size, coul
import lc_ldap.shortcuts import lc_ldap.shortcuts
import lc_ldap.printing as printing import lc_ldap.printing as printing
# Implémentation "à la main" de la tail récursion en python
# voir http://kylem.net/programming/tailcall.html
# je trouve ça assez sioux
class TailCaller(object) :
def __init__(self, f) :
self.f = f
def __call__(self, *args, **kwargs) :
ret = self.f(*args, **kwargs)
while isinstance(ret, TailCall) :
ret = ret.handle()
return ret
def tailCaller(f):
f.tailCaller = True
return f
class TailCall(object) :
def __init__(self, call, *args, **kwargs) :
if isinstance(call, TailCall):
call.update(**kwargs)
kwargs = call.kwargs
args = call.args + args
call = call.call
self.call = call
self.args = args
self.kwargs = kwargs
def __call__(self, *args, **kwargs):
self.kwargs.update(kwargs)
self.args = self.args + args
return self
def update(self, **d):
self.kwargs.update(d)
return self
def handle(self) :
if isinstance(self.call, TailCaller) :
return self.call.f(*self.args, **self.kwargs)
else :
return self.call(*self.args, **self.kwargs)
def handle_exit_code(d, code): def handle_exit_code(d, code):
if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): if code in (d.DIALOG_CANCEL, d.DIALOG_ESC):
if code == d.DIALOG_CANCEL: if code == d.DIALOG_CANCEL:
@ -37,269 +81,422 @@ def handle_exit_code(d, code):
return True # code est d.DIALOG_OK return True # code est d.DIALOG_OK
class GestCrans(object):
def search(dialog, objectClassS, title, values={}): def __getattribute__(self, attr):
""" ret = super(GestCrans, self).__getattribute__(attr)
Rechercher des adhérents ou des machines dans la base ldap if getattr(ret, 'tailCaller', False) and not isinstance(ret, TailCaller):
retourne le tuple (code de retour dialog, valeurs entrée par l'utilisateur, liste d'objets trouvés) ret = TailCaller(ret)
La fonction est découpé en trois partie : setattr(self, attr, ret)
* affichage dialog et récupération du résultat return ret
* 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() def __init__(self):
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC): signal.signal(signal.SIGINT, signal.SIG_IGN)
return code, values, [] # On initialise le moteur de rendu en spécifiant qu'on va faire du dialog
else: printing.template(dialog=True)
# 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 # On ouvre une connexion lc_ldap
filter_adherent = [] self.conn = lc_ldap.shortcuts.lc_ldap_admin()
filter_machine = [] # On vérifie que l'utilisateur système existe dans ldap (pour la gestion des droits)
for (key, value) in dialog_values.items(): luser=self.conn.search(u'(&(uid=%s)(objectClass=cransAccount))' % self.conn.current_login)
if value: if not luser:
if key in select_adherent: sys.stderr.write("L'utilisateur %s n'existe pas dans la base de donnée" % self.conn.current_login)
filter_adherent.append((u"(%s=*%s*)" if select_dict[key]['sub'] else u"(%s=%s)") % (select_dict[key]['ldap'], unicode(value, 'utf-8'))) sys.exit(1)
elif key in select_machine: self.conn.droits = [str(d) for d in luser[0]['droits']]
filter_machine.append((u"(%s=*%s*)" if select_dict[key]['sub'] else u"(%s=%s)") % (select_dict[key]['ldap'], unicode(value, 'utf-8'))) self.conn.dn = luser[0].dn
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 self.dialog = Dialog()
adherents=conn.search(filter_adherent) if filter_adherent else [] self.menu_principal()
machines=conn.search(filter_machine) if filter_machine else []
# Filtrage des machines en fonction des adhérents @tailCaller
if filter_adherent: def search(self, objectClassS, title, values={}, cont=None):
if filter_machine: """
# Si on filtre sur des adhérent et des machines, on calcule l'intersection Rechercher des adhérents ou des machines dans la base ldap
adherents_dn = set([a.dn for a in adherents]) retourne le tuple (code de retour dialog, valeurs entrée par l'utilisateur, liste d'objets trouvés)
machines_f = [m for m in machines if m.parent_dn in adherents_dn] La fonction est découpé en trois partie :
else: * affichage dialog et récupération du résultat
# Sinon on filtre seulement sur les adhérents, récupère les machines des adhérents trouvés * construction de filtres de recherche ldap et recherches ldap
machines_f = [m for a in adherents for m in a.machines()] * 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) = self.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()
# Si il a appuyé sur annuler ou sur escape, on saute sur la continuation
if code in (self.dialog.DIALOG_CANCEL, self.dialog.DIALOG_ESC):
return cont
else: else:
# Sinon si on filtre seulement sur des machines # Transformation de la liste des valeures entrée en dictionnnaire
machines_f = machines 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()])
# Filtrage des adhérents en fonction des machines # Construction des filtres ldap pour les adhérents et les machines
if filter_machine: 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: if filter_adherent:
# Si on filtre sur des adhérents et des machines, on calcule l'intersection filter_adherent=u"(&%s)" % "".join(filter_adherent)
machines_dn = set([m.parent_dn for m in machines]) if filter_machine:
adherents_f = [a for a in adherents if a.dn in machines_dn] filter_machine=u"(&%s)" % "".join(filter_machine)
# Récupération des adhérents et des machines
adherents=self.conn.search(filter_adherent) if filter_adherent else []
machines=self.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: else:
# Sinon on récupères les proprios des machines trouvées # Sinon si on filtre seulement sur des machines
adherents_f = [m.proprio() for m in machines] machines_f = machines
else:
# Sinon si on filtre seulement sur des adhérents
adherents_f = adherents
# On filtre sur les objectClassS # Filtrage des adhérents en fonction des machines
return code, ldap_values, [ o for objectClass in objectClassS for o in machines_f+adherents_f if objectClass in o['objectClass'] ] 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
def select_one(dialog, items, default_item=None): # On filtre sur les objectClassS
"""Fait selectionner un item parmis une liste d'items à l'utisateur""" return ldap_values, [ o for objectClass in objectClassS for o in machines_f+adherents_f if objectClass in o['objectClass'] ]
### TODO afficher correctement les objets dans items
choices=[] # select_one n'est pas un tailcaller, les continuations sont traitée par les fonctions appelantes
count = 0 def select_one(self, items, title, default_item=None, cont=None):
default_tag = items.index(default_item) if default_item in items else default_item """Fait selectionner un item parmis une liste d'items à l'utisateur"""
for i in items: choices=[]
choices.append((str(count), str(i), 1 if default_tag == count else 0)) olist={}
count+=1 count = 0
tag=''
while not tag: # On sépare les item d'items en fonction de leur type
for o in items:
olist[o.__class__] = olist.get(o.__class__, []) + [o]
default_tag = items.index(default_item) if default_item in items else default_item
# On se débrouille pour faire corresponde l'ordre d'affichache des objets
# et leur ordre dans la liste items. On donne la largeur de l'affichage à la main
# pour prendre en compte la largeur du widget dialog
items=[]
items_id = {}
(line, col) = get_screen_size() (line, col) = get_screen_size()
(code, tag) = dialog.radiolist( for c in olist.keys():
"Choisir", items.extend(olist[c])
choices=choices, items_s = printing.sprint_list(olist[c], col-20).encode('utf-8').split('\n')
default_item=str(default_tag), choices.append(("", str(items_s[0])))
width=col-4, choices.append(("", str(items_s[1])))
height=line-3, for i in items_s[2:]:
list_height=line-3, choices.append((str(count), str(i)))
scrollbar=True) count+=1
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC): # On laisse une ligne vide pour séparer les listes d'objets de type différent
return code, None choices.append(("", ""))
if not tag: # On supprime la dernière ligne qui est vide
dialog.msgbox("Merci de choisir l'un des item de la liste ou d'annuler", title="Sélection", width=0, height=0) del(choices[-1])
return code, items[int(tag)]
def select_confirm(dialog, item, title): (code, tag) = self.dialog.menu(
"""Affiche un item et demande si c'est bien celui là que l'on veux (supprimer, éditer, créer,...)""" "Que souhaitez vous faire ?",
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 width=0,
height=0,
menu_height=0,
item_help=0,
default_item=str(default_tag),
title=title,
scrollbar=True,
choices=choices,
colors=True)
def select(dialog, objectClassS, title, values={}): # Si l'utilisateur à annulé, on coninue avec la continuation
"""Permet de choisir un objet adhérent ou machine dans la base ldap""" if code in (self.dialog.DIALOG_CANCEL, self.dialog.DIALOG_ESC):
while True: return cont
# Si l'utilisateur n'a pas choisis une ligne correspondant à quelque chose
elif not tag:
self.dialog.msgbox("Merci de choisir l'un des item de la liste ou d'annuler", title="Sélection", width=0, height=0)
return TailCall(self.select_one, items, title, default_item, cont)
# Sinon on retourne l'item choisis
elif self.select_confirm(items[int(tag)], title):
return items[int(tag)]
else:
return cont
def select_confirm(self, item, title):
"""Affiche un item et demande si c'est bien celui là que l'on veux (supprimer, éditer, créer,...)"""
return self.dialog.yesno(
printing.sprint(item),
no_collapse=True,
colors=True,
title=title,
width=0, height=0,
backtitle="Appuyez sur MAJ pour selectionner du texte"
) == self.dialog.DIALOG_OK
@tailCaller
def select(self, objectClassS, title, values={}, cont=None):
"""Permet de choisir un objet adhérent ou machine dans la base ldap"""
try: try:
# On fait effectuer une recherche à l'utilisateur # On fait effectuer une recherche à l'utilisateur
code, values, items = search(dialog, objectClassS, title, values) values, items = self.search(objectClassS, title, values, cont=cont)
# 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 # S'il n'y a pas de résultas, on recommence
elif not items: if not items:
dialog.msgbox("Aucun Résultat", title="Recherche", width=0, height=0) self.dialog.msgbox("Aucun Résultat", title="Recherche", width=0, height=0)
return TailCall(self.select, objectClassS, title, values, cont=cont)
# S'il y a plusieurs résultats # S'il y a plusieurs résultats
elif len(items)>1: elif len(items)>1:
item = None # On en fait choisir un, si c'est une continuation qui est renvoyé, elle est gérée par select
while True: return self.select_one(items, title, cont=TailCall(self.select, objectClassS, title, values, cont))
# 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 # 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): elif len(items) == 1:
return code, items[0] item=items[0]
# On fait confirmer son choix à l'utilisateur
if self.select_confirm(item, title):
return item
else:
return TailCall(self.select, objectClassS, title, values, cont=cont)
except Exception as e: except Exception as e:
dialog.msgbox("%r" % e, title="Erreur rencontrée", width=0, height=0) self.dialog.msgbox("%r" % e, title="Erreur rencontrée", width=0, height=0)
return TailCall(self.select, objectClassS, title, values, cont=cont)
def modif_adherent(dialog): @tailCaller
code, adherent = select(dialog, ["adherent"], "Recherche d'un adhérent") def modif_adherent(self, cont, adherent=None):
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC): if adherent is None:
return code adherent = self.select(["adherent"], "Recherche d'un adhérent pour modification", cont=cont)
dialog.msgbox("todo", width=0, height=0) self.dialog.msgbox("todo", width=0, height=0)
return cont(proprio=adherent)
def create_adherent(dialog): @tailCaller
dialog.msgbox("todo", width=0, height=0) def create_adherent(self, cont):
self.dialog.msgbox("todo", width=0, height=0)
return cont
def delete_adherent(dialog): @tailCaller
code, adherent = select(dialog, ["adherent"], "Recherche d'un adhérent") def delete_adherent(self, cont):
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC): adherent = self.select(["adherent"], "Recherche d'un adhérent pour supression", cont=cont)
return code self.dialog.msgbox("todo", width=0, height=0)
dialog.msgbox("todo", width=0, height=0) return cont
def modif_machine(dialog): def modif_machine_information(self, machine, cont):
code, machine = select(dialog, ["machineFixe", "machineWifi", "machineCrans", "borneWifi"], "Recherche d'une machine") self.dialog.msgbox("todo", width=0, height=0)
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC): (code, tag) = self.dialog.form(
return code text="",
dialog.msgbox("todo", width=0, height=0) height=0, width=0, form_height=0,
fields=[("Nom de machine :", "", 10, 30),
("Rugby Team", "", 20),
("Car", "", 20),
("Celebrity", "", 20)],
title="A demo of the form dialog.",
backtitle="And now, for something "
"completely different...")
return cont
def create_machine_adherent(dialog): def modif_machine_blacklist(self, machine, cont):
dialog.msgbox("todo", width=0, height=0) self.dialog.msgbox("todo", width=0, height=0)
return cont
def delete_machine(dialog): def modif_machine_alias(self, machine, cont):
code, machine = select(dialog, ["machineFixe", "machineWifi", "machineCrans", "borneWifi"], "Recherche d'une machine") self.dialog.msgbox("todo", width=0, height=0)
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC): return cont
return code
dialog.msgbox("todo", width=0, height=0)
def modif_machine_exemption(self, machine, cont):
self.dialog.msgbox("todo", width=0, height=0)
return cont
def create_club(dialog): def modif_machine_remarque(self, machine, cont):
dialog.msgbox("todo", width=0, height=0) self.dialog.msgbox("todo", width=0, height=0)
return cont
@tailCaller
def delete_club(dialog): def modif_machine(self, cont, machine=None, tag=None):
dialog.msgbox("todo", width=0, height=0) if machine is None:
machine = self.select(["machineFixe", "machineWifi", "machineCrans", "borneWifi"], "Recherche d'une machine pour modification", cont=cont)
def modif_club(dialog): menu = {
dialog.msgbox("todo", width=0, height=0) 'Information' : {'text' : "Modifier le nom de machine, l'IP, adresse MAC", "callback":self.modif_machine_information},
'Blackliste' : {'text': 'Modifier les blacklist de la machine', 'callback':self.modif_machine_blacklist},
def create_machine_club(dialog): 'Alias' : {'text': 'Créer ou supprimer un alias de la machine', 'callback':self.modif_machine_alias},
dialog.msgbox("todo", width=0, height=0) 'Exemption' : {'text':"Modifier la liste d'exemption d'upload de la machine", 'callback':self.modif_machine_exemption},
'Remarques' : {'text':'Ajouter ou supprimer une remarque de la machine', 'callback':self.modif_machine_remarque},
def create_machine_crans(dialog): }
dialog.msgbox("todo", width=0, height=0) menu_order = ['Information', 'Blackliste', 'Alias', 'Exemption', 'Remarques']
def box(default_item=None):
def create_borne(dialog): return self.dialog.menu(
dialog.msgbox("todo", width=0, height=0) "Que souhaitez vous modifier ?",
width=0,
def menu_principal(dialog): height=0,
menu = { menu_height=0,
'aA' : {'text':"Inscrire un nouvel adhérent", 'callback': create_adherent}, item_help=0,
'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."}, default_item=str(default_item),
'aMA': {'text':"Ajouter une machine à un adhérent", 'callback': create_machine_adherent}, title="Modification de %s" % machine['host'][0],
'dA' : {'text':"Détruire un adhérent", 'callback': delete_adherent, 'help':"Suppression de l'adhérent ainsi que de ses machines"}, scrollbar=True,
'mM' : {'text':"Modifier une machine existante", 'callback': modif_machine, 'help':"Changer le nom ou la MAC d'une machine."}, cancel_label="Retour",
'dM' : {'text':"Détruire une machine", 'callback': delete_machine}, backtitle=u"Vous êtes connecté en tant que %s" % self.conn.current_login,
'aC' : {'text':"Inscrire un nouveau club", 'callback': create_club}, choices=[(key, menu[key]['text']) for key in menu_order])
'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) (code, tag) = box(tag)
if handle_exit_code(dialog, code): if code in (self.dialog.DIALOG_CANCEL, self.dialog.DIALOG_ESC):
menu.get(tag, menu[''])['callback'](dialog) return cont(machine=machine)
elif not tag in menu_order:
return TailCall(self.modif_machine, cont=cont, machine=machine, tag=tag)
else:
return TailCall(menu[tag]['callback'], machine=machine, cont=TailCall(self.modif_machine, cont=cont, machine=machine, tag=tag))
@tailCaller
def create_machine_adherent(self, cont, adherent=None):
if adherent is None:
adherent = self.select(["adherent"], "Recherche d'un adhérent pour lui ajouter une machine", cont=cont)
self.dialog.msgbox("todo", width=0, height=0)
return cont(proprio=adherent)
@tailCaller
def delete_machine(self, cont):
machine = self.select(["machineFixe", "machineWifi", "machineCrans", "borneWifi"], "Recherche d'une machine pour supression", cont=cont)
self.dialog.msgbox("todo", width=0, height=0)
return cont
@tailCaller
def create_club(self, cont):
self.dialog.msgbox("todo", width=0, height=0)
return cont
@tailCaller
def delete_club(self, cont):
self.dialog.msgbox("todo", width=0, height=0)
return cont
@tailCaller
def modif_club(self, cont):
self.dialog.msgbox("todo", width=0, height=0)
return cont
@tailCaller
def create_machine_club(self, cont):
self.dialog.msgbox("todo", width=0, height=0)
return cont
@tailCaller
def create_machine_crans(self, cont):
self.dialog.msgbox("todo", width=0, height=0)
return cont
@tailCaller
def create_borne(self, cont):
self.dialog.msgbox("todo", width=0, height=0)
return cont
@tailCaller
def menu_principal(self, tag=None, machine=None, proprio=None):
menu = {
'aA' : {'text':"Inscrire un nouvel adhérent", 'callback': self.create_adherent},
'mA' : {'text':"Modifier l'inscription d'un adhérent", 'callback': self.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': self.create_machine_adherent},
'dA' : {'text':"Détruire un adhérent", 'callback': self.delete_adherent, 'help':"Suppression de l'adhérent ainsi que de ses machines"},
'mM' : {'text':"Modifier une machine existante", 'callback': self.modif_machine, 'help':"Changer le nom ou la MAC d'une machine."},
'dM' : {'text':"Détruire une machine", 'callback': self.delete_machine},
'aC' : {'text':"Inscrire un nouveau club", 'callback': self.create_club},
'mC' : {'text':"Modifier un club", 'callback': self.modif_club},
'aMC': {'text':"Ajouter une machine à un club", 'callback': self.create_machine_club},
'dC' : {'text':"Détruire un club", 'callback': self.delete_club},
'aKM': {'text':"Ajouter une machine à l'association", 'callback': self.create_machine_crans},
'aKB': {'text':"Ajouter une borne wifi", 'callback': self.create_borne},
'' : {'text':"---------------------------------------",'callback': None},
}
### Les clef qui n'existe pas sont toute renvoyé sur la clef ''
menu_order = ["aA", "mA", "aMA", "dA", "", "mM", "dM", " ", "aC", "mC", "aMC", "dC", " ", "aKM", "aKB"]
if machine and not proprio:
proprio = machine.proprio()
if machine or proprio:
menu_order = [' '] + menu_order
if machine:
menu_machine = {
'mMc' : {
'text':"Modifier la machine %s" % machine['host'][0],
'callback': TailCall(self.modif_machine, machine=machine),
'help':"Changer le nom ou la MAC d'une machine."
},
}
menu_machine_order = ['mMc']
menu.update(menu_machine)
menu_order = menu_machine_order + menu_order
if proprio:
menu_proprio = {
'mAc' : {
'text':"Modifier l'inscription de %s" % proprio.get("cn", proprio["nom"])[0],
'callback': TailCall(self.modif_adherent, adherent=proprio)
},
'aMc' : {
'text':"Ajouter une machine à %s" % proprio.get("cn", proprio["nom"])[0],
'callback': TailCall(self.create_machine_adherent, adherent=proprio)
},
}
menu_proprio_order = ['mAc', 'aMc']
menu.update(menu_proprio)
menu_order = menu_proprio_order + menu_order
def box(default_item=None):
return self.dialog.menu(
"Que souhaitez vous faire ?",
width=0,
height=0,
menu_height=0,
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" % self.conn.current_login,
choices=[(key, menu.get(key, menu[''])['text'], menu.get(key, menu['']).get('help', "")) for key in menu_order])
(code, tag) = box(tag)
callback = menu.get(tag, menu[''])['callback']
if handle_exit_code(self.dialog, code) and callback:
return TailCall(callback, cont=TailCall(self.menu_principal, tag, machine=machine, proprio=proprio))
else:
return TailCall(self.menu_principal, tag, proprio=proprio, machine=machine)
if __name__ == '__main__': if __name__ == '__main__':
signal.signal(signal.SIGINT, signal.SIG_IGN) GestCrans()
# 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') os.system('clear')