diff --git a/gestion/gest_crans_lc.py b/gestion/gest_crans_lc.py index 2bc6f51a..7f91f37c 100755 --- a/gestion/gest_crans_lc.py +++ b/gestion/gest_crans_lc.py @@ -69,91 +69,212 @@ def handle_dialog_exit_code(dialog, code): else: return True + class GestCrans(adherent.Dialog, club.Dialog, machine.Dialog): @tailcaller def menu_principal(self, tag=None, machine=None, proprio=None): - """Menu principal de l'application affiché au lancement""" - a = attributs + """Menu principal de l'application. + + Paramètres: + - ``tag``: (str) clé du menu sélectionnée par défaut + - ``machine``: (lc_ldap.Machine) machine sélectionnée + - ``proprio``: (lc_ldap.Adherent ou lc_ldap.Club) proprio + sélectionné + + Le menu principal est affiché lorsqu'on démarre l'application, + et lorsqu'on revient au menu principal suite à une action sur un + objet (arguments machine ou proprio). + + Le menu est créé en deux étapes : + - Actions spécifiques à l'objet (`machine`, `proprio`) sélectionné + - Actions génériques + + """ + + # Droits nécessaires pour effectuer les différentes actions. + # Par défaut, on vérifie les droits ''. + # La clé correspond à la clé dans le dictionnaire menu. menu_droits = { - 'default' : [a.cableur, a.nounou], - 'aKM' : [a.nounou], + '': [attributs.cableur, attributs.nounou], + 'aKM': [attributs.nounou], } + + # On initialise le menu avec des actions "génériques" 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}, - '' : {'text':"---------------------------------------",'callback': None}, + '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, + }, + + '': { + '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"] - #menu_order = ["aA", "mA", "aMA", "", "mM", " ", "aC", "mC", "aMC", " ", "aKM"] - menu_order = ["aA", "mA", "aMA", "", "mM", "", "aC", "mC", "aMC", "", "aKM"] + + # On liste les actions pour définir leur ordre d'affichage + menu_order = [ + # Actions adhérent + "aA", "mA", "aMA", "", + # Actions machine + "mM", "", + # Actions club + "aC", "mC", "aMC", "", + # Actions Cr@ns + "aKM", + ] + + # Ajout des actions spécifiques en tête du menu + + # On récupère le propriétaire de la machine pour ajouter les + # actions associées if machine and not proprio: proprio = machine.proprio() + + # Sauf si le propriétaire est le Cr@ns if isinstance(proprio, objets.AssociationCrans): proprio = None + + # On a sélectionné un objet. On ajoute les actions spécifiques à + # l'objet avant les actions génériques. if machine or proprio: menu_order = [''] + menu_order + + # Actions spécifiques à une machine 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." + '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 + + # Actions spécifiques à un proprio (adhérent ou club) if proprio: - menu_adherent = { - '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_club = { - 'mCc' : { - 'text':"Modifier l'inscription de %s" % proprio.get("cn", proprio["nom"])[0], - 'callback': TailCall(self.modif_club, club=proprio) - }, - 'aMc' : { - 'text':"Ajouter une machine à %s" % proprio.get("cn", proprio["nom"])[0], - 'callback': TailCall(self.create_machine_club, club=proprio) - }, - } if 'adherent' in proprio['objectClass']: - menu_proprio = menu_adherent + 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'] elif 'club' in proprio['objectClass']: - menu_proprio = menu_club + menu_proprio = { + 'mCc': { + 'text': ("Modifier l'inscription de %s" % + proprio.get("cn", proprio["nom"])[0]), + 'callback': TailCall(self.modif_club, club=proprio) + }, + 'aMc': { + 'text': ("Ajouter une machine à %s" % + proprio.get("cn", proprio["nom"])[0]), + 'callback': TailCall(self.create_machine_club, + club=proprio) + }, + } menu_proprio_order = ['mCc', 'aMc'] else: - raise EnvironmentError("Je ne connais que des adherents et des club comme proprio") + raise EnvironmentError( + "Le proprio sélectionné doit être un adhérent ou un club." + ) menu.update(menu_proprio) menu_order = menu_proprio_order + menu_order - def box(default_item=None): + def dialog_menu_principal(default_item=None): + """Renvoie la boîte de dialogue telle que définie avec le menu + précédent.""" + + # On construit une liste de triplets (clé, titre, texte + # d'aide), passée à dialog, à partir de la liste des clés du + # menu et des fonctions associées choices = [] + + # On reprend les clés dans l'ordre défini par la liste menu_order for key in menu_order: - if self.has_right(menu_droits.get(key, menu_droits['default'])): - choices.append((key, menu[key]['text'], menu[key].get('help', ""))) - while choices[-1][0] == '': - choices=choices[:-1] + # Vérification des droits + if self.has_right(menu_droits.get(key, menu_droits[''])): + choices.append(( + key, + menu[key]['text'], + menu[key].get('help', ""), + )) + + # On enlève les lignes de séparation qui seraient au début + # ou à la fin de la boîte de dialogue while choices[0][0] == '': - choices=choices[1:] + choices = choices[1:] + while choices[-1][0] == '': + choices = choices[:-1] + return self.dialog.menu( "Que souhaitez vous faire ?", width=0, @@ -166,23 +287,79 @@ class GestCrans(adherent.Dialog, club.Dialog, machine.Dialog): timeout=self.timeout, cancel_label="Quitter", backtitle=self._connected_as(), - choices=choices) + choices=choices, + ) - (code, tag) = self.handle_dialog(TailCall(handle_dialog_exit_code, self.dialog, self.dialog.DIALOG_ESC), box, tag) - self_cont = TailCall(self.menu_principal, tag=tag, proprio=proprio, machine=machine) - callback = menu.get(tag, menu[''])['callback'] - if handle_dialog_exit_code(self.dialog, code) and callback: - return TailCall(callback, cont=TailCall(self.menu_principal, tag=tag, machine=machine, proprio=proprio)) + # Appel de dialog pour afficher le menu construit précédemment. + # Oui, il faut passer la fonction qui gère une annulation d'abord... + (code, tag) = self.handle_dialog( + TailCall( + handle_dialog_exit_code, + self.dialog, + self.dialog.DIALOG_ESC, + ), + dialog_menu_principal, + tag, + ) + + # Appel qui permet de revenir au menu principal + rappel_menu_principal = TailCall( + self.menu_principal, + tag=tag, + proprio=proprio, + machine=machine, + ) + + # On récupère le callback de la ligne sélectionnée par + # l'utilisateur + fonction_selectionnee = menu.get(tag, menu[''])['callback'] + + # On vérifie si l'utilisateur a appelé une ligne non-séparateur + if ( + handle_dialog_exit_code(self.dialog, code) and + fonction_selectionnee + ): + # On appelle la fonction sélectionnée puis on revient au + # menu principal + return TailCall(fonction_selectionnee, cont=rappel_menu_principal) else: - return self_cont - + # La ligne est un séparateur ou l'utilisateur a annulé, on + # revient au menu principal immédiatement + return rappel_menu_principal if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Interface utilisateur du système de gestion des machines et adhérents du crans') - parser.add_argument('--test', help='Utiliser la base de test', dest='ldap_test', default=False, action='store_true') - parser.add_argument('--debug', help='Afficher des info de débug comme les tracebacks', dest='debug_enable', default=False, action='store_true') - parser.add_argument('login', help="Se connecter en tant qu'un autre utilisateur", type=str, default=None, nargs='?') + parser = argparse.ArgumentParser( + description=( + 'Interface utilisateur du système de gestion ' + 'des machines et adhérents du Cr@ns' + ) + ) + parser.add_argument( + '--test', + help='Utiliser la base de test', + dest='ldap_test', + default=False, + action='store_true', + ) + parser.add_argument( + '--debug', + help='Afficher des info de débug comme les tracebacks', + dest='debug_enable', + default=False, + action='store_true', + ) + parser.add_argument( + 'login', + help="Se connecter en tant qu'un autre utilisateur", + type=str, + default=None, + nargs='?', + ) args = parser.parse_args() - main(GestCrans(ldap_test=args.ldap_test, debug_enable=args.debug_enable, custom_user=args.login)) + main(GestCrans( + ldap_test=args.ldap_test, + debug_enable=args.debug_enable, + custom_user=args.login, + )) os.system('clear')