[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 __getattribute__(self, attr):
ret = super(GestCrans, self).__getattribute__(attr)
if getattr(ret, 'tailCaller', False) and not isinstance(ret, TailCaller):
ret = TailCaller(ret)
setattr(self, attr, ret)
return ret
def __init__(self):
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)
def search(dialog, objectClassS, title, values={}): # On ouvre une connexion lc_ldap
""" self.conn = lc_ldap.shortcuts.lc_ldap_admin()
Rechercher des adhérents ou des machines dans la base ldap # On vérifie que l'utilisateur système existe dans ldap (pour la gestion des droits)
retourne le tuple (code de retour dialog, valeurs entrée par l'utilisateur, liste d'objets trouvés) luser=self.conn.search(u'(&(uid=%s)(objectClass=cransAccount))' % self.conn.current_login)
La fonction est découpé en trois partie : if not luser:
* affichage dialog et récupération du résultat sys.stderr.write("L'utilisateur %s n'existe pas dans la base de donnée" % self.conn.current_login)
* construction de filtres de recherche ldap et recherches ldap sys.exit(1)
* filtre sur les résultats des recherches ldap self.conn.droits = [str(d) for d in luser[0]['droits']]
""" self.conn.dn = luser[0].dn
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() self.dialog = Dialog()
if code in (dialog.DIALOG_CANCEL, dialog.DIALOG_ESC): self.menu_principal()
return code, values, []
else: @tailCaller
# Transformation de la liste des valeures entrée en dictionnnaire def search(self, objectClassS, title, values={}, cont=None):
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()]) 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) = 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, [])
# Construction des filtres ldap pour les adhérents et les machines (code, dialog_values) = box()
filter_adherent = [] # Si il a appuyé sur annuler ou sur escape, on saute sur la continuation
filter_machine = [] if code in (self.dialog.DIALOG_CANCEL, self.dialog.DIALOG_ESC):
for (key, value) in dialog_values.items(): return cont
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: 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')