nutools/lib/nulib/python/deploydb/utils.py

151 lines
4.6 KiB
Python

# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
"""Fonctions utilitaires diverses
"""
__all__ = (
'isnum',
'istrue', 'isfalse',
'isseq', 'seqof', 'listof', 'ulistof',
'flattenstr', 'flattenseq',
'qshell',
'withpath', 'cwithpath', 'find_in_path', 'relpath',
)
from os import path
def isnum(v):
return isinstance(v, int) or isinstance(v, long)
def istrue(b):
s = str(b).lower()
if s in ('true', 'vrai', 'yes', 'oui', '1'):
return True
elif s in ('false', 'faux', 'no', 'non', '0'):
return False
else:
return bool(b) # laisser python décider de la valeur
def isfalse(b):
s = str(b).lower()
if s in ('true', 'vrai', 'yes', 'oui', '1'):
return False
elif s in ('false', 'faux', 'no', 'non', '0'):
return True
else:
return not bool(b) # laisser python décider de la valeur
def isseq(t):
"""Tester si t est une séquence
"""
return isinstance(t, list) or isinstance(t, tuple) or isinstance(t, set)
_SEQOF_UNDEF = object()
def seqof(o, noneValue=_SEQOF_UNDEF):
"""Retourner un tuple à parti de o
* si o est une séquence, retourner tuple(o)
* si noneValue est défini, et que o is noneValue, retourner noneValue
* sinon, retourner le tuple (o,)
"""
if isseq(o): return tuple(o)
elif o is noneValue and noneValue is not _SEQOF_UNDEF: return noneValue
else: return (o,)
_LISTOF_UNDEF = object()
def listof(o, noneValue=_LISTOF_UNDEF):
"""Retourner une nouvelle liste à parti de o
* si o est une séquence, retourner list(o)
* si noneValue est défini, et que o is noneValue, retourner noneValue
* sinon, retourner la liste [o]
"""
if isseq(o): return list(o)
elif o is noneValue and noneValue is not _LISTOF_UNDEF: return noneValue
else: return [o]
def ulistof(o, noneValue=_LISTOF_UNDEF):
"""Retourner une nouvelle liste à parti de o
* si o est une séquence, retourner list(o)
* si noneValue est défini, et que o is noneValue, retourner noneValue
* sinon, retourner la liste [o]
La différence avec listof(), c'est que les doublons sont supprimés de la
liste, tout en préservant l'ordre original, ce qui n'est pas le cas avec
set()
"""
if isseq(o): tmplist = list(o)
elif o is noneValue and noneValue is not _LISTOF_UNDEF: return noneValue
else: return [o]
ulist = []
for item in tmplist:
if item not in ulist: ulist.append(item)
return ulist
def flattenstr(src, unique=True, clean=True, sep=','):
"""découper chaque élément du tableau src selon sep et les aplatir dans une
seule liste.
Si unique==True, supprimer les doublons.
Si clean==True, supprimer les valeurs vides et les espaces périphériques
e.g flattenstr(['a , b', 'c,']) --> ['a', 'b', 'c']
"""
if src is None: return None
dest = []
for items in seqof(src):
items = items.split(sep)
if clean: items = filter(None, map(lambda item: item.strip(), items))
if unique:
for item in items:
if item not in dest: dest.append(item)
else:
dest.extend(items)
return dest
def flattenseq(seq):
"""aplatir les éléments de seq en une seule liste
e.g flattenlist([(1, 2), (3, 4), 5]) --> [1, 2, 3, 4, 5]
"""
if seq is None: return None
if not isseq(seq): return [seq]
items = []
for item in seq:
if isseq(item): items.extend(item)
else: items.append(item)
return items
def qshell(values):
if isseq(values): return map(qshell, values)
elif not values: return ''
else: return "'%s'" % values.replace("'", "'\\''")
def withpath(p): return p is not None and '/' in p
def cwithpath(p): return p is not None and ('/' in p or p in ('.', '..'))
def find_in_path(filename, dirs, allow_path=False):
"""chercher le fichier nommé filename dans les répertoires dirs
si filename est un chemin (contient le caractère '/' ou path.sep) alors la
valeur est retournée telle quelle, sauf si allow_path=True
retourner le chemin complet dir/filename si le fichier est trouvé, ou None
si le fichier ne figure dans aucun des répertoires
"""
is_path = '/' in filename or path.sep in filename
if is_path and not allow_path: return filename
for dir in dirs:
pf = path.join(dir, filename)
if path.isfile(pf): return pf
return None
def relpath(filep, refp, abspath=True):
"""exprimer filep par rapport au répertoire de refp
si abspath==True, rendre le chemin absolu
"""
pf = path.join(dirname(refp), filep)
if abspath: pf = path.abspath(pf)
return pf