scripts/gestion/interactive.py
Jeremie Dimino 49f0fbb4a3 Module pour faire facilement des scripts interactifs.
darcs-hash:20071217063153-af139-ab0ac6f47ecbc8aba1537658774c9be84c6526b3.gz
2007-12-17 07:31:53 +01:00

96 lines
3.6 KiB
Python

# -*- coding: utf-8 -*-
#
# interactive.py
# --------------
#
# Copyright (C) 2007 Jeremie Dimino <jeremie@dimino.org>
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
'''Utilitaire pour poser des questions de manières interactives
à l'utilisateur, à la manière de darcs.'''
import os, sys, tty, termios
from affich_tools import cprint
__all__ = ["getch", "ask", "Exit"]
def getch():
fd = sys.stdin.fileno()
mode = termios.tcgetattr(fd)
try:
tty.setraw(fd)
return os.read(fd, 1)
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, mode)
# Constantes de choix
Exit = ("q", "quitter le programme", None, lambda: sys.exit(0))
def ask(message, choices):
'''Pose une question à l'utilisateur.
choices est une liste d'élément de la forme (choix) ou (choix, doc)
ou (choix, doc, valeur) ou encore (choix, doc, valeur, operation), où:
- choix sont les lettres pour le choix, si une est en majuscule alors
ce choix est celui par défaut.
- doc est une description du choix
- valeur est la valeur renvoyée si ce choix est fait, par défaut c'est choix[0].lower()
- operation est soit une fonction, auquel cas elle est éxécutée si le choix est fait
(et le questionnement continue si elle renoie vrai),
soit un tuple sur lequel ask est éxécutée,
soit une chaîne qui est affichée'''
while True:
cprint("%s [%s], ou ? pour l'aide: " % (message, "".join([c[0] for c in choices])), "bleu", newline=False)
sys.stdout.flush()
answer = getch()
sys.stdout.write(answer+"\n")
if answer in ['\x03', '\x04']:
raise KeyboardInterrupt()
if answer == " ":
for choice in choices:
if choice[0].lower != choix[0]:
answer = choice[0][0].lower()
break
cprint("Aucun choix par défaut!")
else:
answer = answer.lower()
for choice in choices:
if answer in choice[0].lower():
answer = choice[0][0].lower()
break
if choices and answer == choice[0][0].lower():
if len(choice) <= 2:
return answer
elif len(choice) == 3:
return choice[2]
elif type(choice[3]) == tuple:
(message, choices) = choice[3]
elif type(choice[3]) == str:
print
print choice[3]
elif not choice[3]():
return choice[2]
if answer in ["h", "?"]:
print
cprint("Réponses possible:")
for choice in choices:
cprint("%s: %s" % (" ou ".join(list(choice[0])),
((len(choice) >= 2) and choice[1]) or "non documentée"))
cprint("h ou ?: afficher cette aide")
print
cprint("<Espace>: accepter le choix par défault (celui qui est en majuscule)")
print
else:
cprint("Choix invalide, essaies encore!")