189 lines
5.3 KiB
Python
Executable file
189 lines
5.3 KiB
Python
Executable file
#!/usr/bin/env python
|
|
# -*- coding: iso-8859-15 -*-
|
|
|
|
""" Collection de fonction/classe pour avoir un bel affichage
|
|
|
|
Copyright (C) Frédéric Pauget
|
|
Licence : GPLv2
|
|
"""
|
|
|
|
import sys, sre, os, tempfile
|
|
|
|
def dialog(backtitle,arg) :
|
|
""" Affiche la boite de dialogue défine avec les arguments fournis
|
|
(cf man dialog)
|
|
si tout se déroule bien retourne :
|
|
[ 0, [ reponse(s) ] ]
|
|
si annulatin retourne :
|
|
[ 1, [] ]
|
|
si appui sur ESC demande confirmation de l'abandon et exécute sys.exit(0)
|
|
si erreur dans les arguments raise RuntimeError
|
|
"""
|
|
f = tempfile.NamedTemporaryFile()
|
|
cmd = u'/usr/bin/dialog --backtitle "%s" --cancel-label "Retour" %s 2>%s' % (backtitle,arg,f.name)
|
|
res = os.system(cmd.encode('iso-8859-15','ignore'))
|
|
|
|
if res == 256 :
|
|
# Annuler
|
|
f.close()
|
|
return [ 1, [] ]
|
|
|
|
# Lecture du fichier de résultat et effacement
|
|
try:
|
|
result=f.readlines()
|
|
f.close()
|
|
except :
|
|
result = [ "n'importe quoi", '']
|
|
res = 65280
|
|
|
|
# Traitement
|
|
if res==65280 and result:
|
|
# Erreur dans les arguments
|
|
raise RuntimeError( arg, result[1].strip() )
|
|
elif res==65280 :
|
|
# Appui sur ESC
|
|
arg1 = u'--title "Annulation" --yesno "Quitter ?\nLes dernières modifications seront perdues." 6 48'
|
|
print backtitle
|
|
cmd = u'/usr/bin/dialog --backtitle "%s" %s' % (backtitle,arg1)
|
|
res = os.system(cmd.encode('iso-8859-15','ignore') )
|
|
if res==0 : sys.exit(0)
|
|
else : return dialog(backtitle,arg)
|
|
elif not result : result=['']
|
|
|
|
return [ 0, result ]
|
|
|
|
def coul(txt,col):
|
|
"""
|
|
Retourne la chaine donnée encadrée des séquences qui
|
|
vont bien pour obtenir la couleur souhaitée
|
|
Les couleur sont celles de codecol
|
|
Il est possible de changer la couleur de fond grace aux couleur f_<couleur>
|
|
"""
|
|
codecol={'rouge' : 31 , 'vert' : 32 , 'jaune' : 33 , 'bleu': 34 , 'violet' : 35 , 'cyan' : 36 , 'gras' : 50}
|
|
try :
|
|
if col[:2]=='f_' : add=10; col=col[2:]
|
|
else : add=0
|
|
txt = "\033[1;%sm%s\033[1;0m" % (codecol[col]+add,txt)
|
|
finally :
|
|
return txt
|
|
|
|
OK = coul('OK','vert')
|
|
WARNING = coul('WARNING','jaune')
|
|
ERREUR = coul('ERREUR','rouge')
|
|
|
|
def cprint(txt,col):
|
|
print coul(txt,col)
|
|
|
|
def tableau(largeurs,data) :
|
|
"""
|
|
retourne une chaine formatée repésentant un tableau
|
|
largeur est la liste des largeurs des colones
|
|
data est une liste de tuples :
|
|
[ ( données entète), (données ligne1), .... ]
|
|
"""
|
|
sep_col = u'|'
|
|
|
|
# Si l'une des largeurs est '*', alors on la met la plus grande possible
|
|
if '*' in largeurs:
|
|
rows, cols = get_screen_size()
|
|
nlargeurs = []
|
|
for n in largeurs:
|
|
if n != '*':
|
|
nlargeurs.append(n)
|
|
else:
|
|
nlargeurs.append(max(cols - sum(filter(lambda x:x!='*',largeurs)) - len(largeurs) - 1, 3))
|
|
largeurs = nlargeurs
|
|
|
|
# Ligne de séparation entète corps
|
|
s=u'\n'
|
|
for l in largeurs :
|
|
s+= sep_col + u'-'*l
|
|
s += sep_col + u'\n'
|
|
|
|
nb_cols = len(largeurs)
|
|
|
|
# Remplissage tableau
|
|
f=u''
|
|
for ligne in data :
|
|
for i in range(0, nb_cols) :
|
|
f+= sep_col
|
|
# Centrage
|
|
l = len(sre.sub('\x1b\[1;([0-9]|[0-9][0-9])m','',ligne[i])) # Longeur sans les chaines de formatage
|
|
if l >= largeurs[i] :
|
|
f += ligne[i]
|
|
else :
|
|
n = largeurs[i] - l
|
|
f += u' '*(n/2) + ligne[i] + u' '*(n/2 + n%2)
|
|
f+= sep_col + u'\n'
|
|
|
|
# Final
|
|
f = f.replace(u'\n',s,1) # Insertion du séparateur entète - corps
|
|
return f[:-1] # Supression du \n final
|
|
|
|
def get_screen_size():
|
|
"""Retourne la taille de l'écran.
|
|
|
|
Sous la forme d'un tuble (colonnes, lignes)"""
|
|
try:
|
|
from termios import TIOCGWINSZ
|
|
from struct import pack, unpack
|
|
from fcntl import ioctl
|
|
s = pack("HHHH", 0, 0, 0, 0)
|
|
rows, cols = unpack("HHHH", ioctl(sys.stdout.fileno(), TIOCGWINSZ, s))[:2]
|
|
return (rows, cols)
|
|
except:
|
|
return (80, 24)
|
|
|
|
def prompt(prompt, defaut=''):
|
|
""" Pose la question prompt, retourne la réponse """
|
|
sys.stdout.write(coul(prompt,'gras'))
|
|
if defaut :
|
|
sys.stdout.write(" ["+defaut+"]")
|
|
sys.stdout.write(" ")
|
|
v=sys.stdin.readline().strip()
|
|
if not v : v = defaut
|
|
return v
|
|
|
|
class anim :
|
|
""" Permet de créer une animation :
|
|
truc................./
|
|
truc.................-
|
|
truc.................\
|
|
truc.................|
|
|
ou une barre de progression si le nombre total d'itérations est founi.
|
|
"""
|
|
def __init__(self,truc,iter=0) :
|
|
""" Affichage de :
|
|
truc................."""
|
|
self.txt = truc + '.'*(40-len(truc))
|
|
self.c = 1
|
|
self.iter = iter
|
|
sys.stdout.write(self.txt)
|
|
sys.stdout.flush()
|
|
|
|
def reinit(self) :
|
|
""" Efface la ligne courrante et
|
|
affiche : truc................. """
|
|
sys.stdout.write('\r' + self.txt)
|
|
if self.iter :
|
|
sys.stdout.write(' '*28)
|
|
sys.stdout.write('\r' + self.txt)
|
|
sys.stdout.flush()
|
|
|
|
def cycle(self) :
|
|
""" Efface la ligne courrante et
|
|
affiche : truc..................?
|
|
? caratère variant à chaque appel """
|
|
sys.stdout.write('\r' + self.txt)
|
|
if self.iter!=0 :
|
|
sys.stdout.write('[')
|
|
av = float(self.c) / float(self.iter)
|
|
n = int(20 * av)
|
|
sys.stdout.write('='*n)
|
|
sys.stdout.write('>')
|
|
sys.stdout.write(' '*(20 - n))
|
|
sys.stdout.write('] %3i%%' % int(100 * av) )
|
|
else :
|
|
sys.stdout.write('/-\|'[self.c%4])
|
|
sys.stdout.flush()
|
|
self.c += 1
|