Intégration de la branche release-3.4.0

This commit is contained in:
Jephté Clain 2016-02-09 11:26:06 +04:00
commit e6c3a5dc10
4 changed files with 61 additions and 26 deletions

View File

@ -1,3 +1,7 @@
## Version 3.4.0 du 09/02/2016-11:25
788e1ff cgilsxml.py: ajout de l'option -E. bug avec le tri sur des valeurs inexistantes
## Version 3.3.0 du 08/02/2016-09:41 ## Version 3.3.0 du 08/02/2016-09:41
da3ef60 cgilsxml.py: ajouter de squery_string permettant d'ajouter un préfixe da3ef60 cgilsxml.py: ajouter de squery_string permettant d'ajouter un préfixe

View File

@ -1 +1 @@
3.3.0 3.4.0

View File

@ -1 +1 @@
011001000 011002000

View File

@ -34,14 +34,19 @@ RE_SORT_FIELD_TYPE = re.compile(r'([_a-zA-Z][-_a-zA-Z0-9]*)(?::([aAdDcCnN]+))?')
class Filter: class Filter:
re_spec = None re_spec = None
re_allows = None
ex_vars = None ex_vars = None
ex_group = None ex_group = None
def __init__(self, re_spec): def __init__(self, re_spec):
self.re_spec = re.compile(re_spec) self.re_spec = re.compile(re_spec)
self.re_allows = []
self.ex_vars = [] self.ex_vars = []
self.ex_group = None self.ex_group = None
def allow_spec(self, re_allow):
self.re_allows.append(re.compile(re_allow))
def add_var(self, ex_var): def add_var(self, ex_var):
mo = RE_VAR_NAME_EXPR.match(ex_var) mo = RE_VAR_NAME_EXPR.match(ex_var)
if mo is None: raise ValueError('Invalid VAR_EXPR: %s' % ex_var) if mo is None: raise ValueError('Invalid VAR_EXPR: %s' % ex_var)
@ -52,7 +57,8 @@ class Filter:
self.ex_group = ex_group self.ex_group = ex_group
def __repr__(self): def __repr__(self):
return 'Filter<%s,%s,%s>' % (self.re_spec, repr(self.ex_vars), self.ex_group) return 'Filter<%s,%s,%s,%s>' % (self.re_spec, repr(self.re_allows),
repr(self.ex_vars), self.ex_group)
def match_fill(self, file): def match_fill(self, file):
mo = self.re_spec.match(file.name) mo = self.re_spec.match(file.name)
@ -67,17 +73,25 @@ class Filter:
file.group = group file.group = group
return True return True
def match_allow(self, file):
for re_allow in self.re_allows:
if re_allow.match(file.name) is not None:
return True
return False
class File: class File:
pf = None pf = None
group = None group = None
vars = None vars = None
dontlist = None
def __init__(self, dir, name): def __init__(self, dir, name, dontlist=False):
dir = path.abspath(dir) dir = path.abspath(dir)
pf = path.join(dir, name) pf = path.join(dir, name)
self.__dict__['pf'] = pf self.__dict__['pf'] = pf
self.__dict__['group'] = None self.__dict__['group'] = None
self.__dict__['vars'] = {} self.__dict__['vars'] = {}
self.__dict__['dontlist'] = dontlist
stat = os.stat(pf) stat = os.stat(pf)
mtime = int(stat.st_mtime) mtime = int(stat.st_mtime)
@ -97,12 +111,12 @@ class File:
def __getitem__(self, name): return self.vars[name] def __getitem__(self, name): return self.vars[name]
def __setitem__(self, name, value): self.vars[name] = value def __setitem__(self, name, value): self.vars[name] = value
def has_key(self, name): return self.vars.has_key(name) def has_key(self, name): return self.vars.has_key(name)
def __getattr__(self, name): return self.vars[name] def __getattr__(self, name):
try: return self.vars[name]
except KeyError: raise AttributeError(name)
def __setattr__(self, name, value): def __setattr__(self, name, value):
if self.__dict__.has_key(name): if self.__dict__.has_key(name): self.__dict__[name] = value
self.__dict__[name] = value else: self.vars[name] = value
else:
self.vars[name] = value
def __repr__(self): return 'File<%s>' % (self.pf) def __repr__(self): return 'File<%s>' % (self.pf)
def find_files(basedir, filters): def find_files(basedir, filters):
@ -111,9 +125,13 @@ def find_files(basedir, filters):
file = File(basedir, name) file = File(basedir, name)
if not file.isfile(): continue if not file.isfile(): continue
matched = False matched = False
allowed = False
for filter in filters: for filter in filters:
matched = filter.match_fill(file) or matched matched = filter.match_fill(file) or matched
if not matched: continue allowed = filter.match_allow(file) or allowed
if matched: pass
elif allowed: file.dontlist = True
else: continue
files.append(file) files.append(file)
return files return files
@ -134,17 +152,23 @@ def build_sortfunc(sortby):
SORTS.append((field, method, order)) SORTS.append((field, method, order))
def sortfunc(a, b): def sortfunc(a, b):
for field, method, order in SORTS: for field, method, order in SORTS:
av = getattr(a, field) av = getattr(a, field, None)
bv = getattr(b, field) bv = getattr(b, field, None)
if method == 'C': if av is None:
av = str(av) if bv is None: outcome = 0
bv = str(bv) else: outcome = 1
elif method == 'N': elif bv is None:
av = int(av) outcome = -1
bv = int(bv) else:
if av < bv: outcome = -1 if method == 'C':
elif av > bv: outcome = 1 av = str(av)
else: outcome = 0 bv = str(bv)
elif method == 'N':
av = int(av)
bv = int(bv)
if av < bv: outcome = -1
elif av > bv: outcome = 1
else: outcome = 0
if order == 'A': pass if order == 'A': pass
elif order == 'D': outcome = -outcome elif order == 'D': outcome = -outcome
if outcome != 0: return outcome if outcome != 0: return outcome
@ -165,8 +189,9 @@ def build_fgroups(files):
return fgroups return fgroups
def filter_files(files, group): def filter_files(files, group):
if group: return filter(lambda file: file.group == group, files) if group: func = lambda file: file.dontlist or file.group == group
else: return filter(lambda file: not file.group, files) else: func = lambda file: file.dontlist or not file.group
return filter(func, files)
def select_file(files, name): def select_file(files, name):
matches = filter(lambda file: file.name == name, files) matches = filter(lambda file: file.name == name, files)
@ -241,6 +266,7 @@ def print_files(files, fgroups=None, select_group=None, script_name=None, xslt=N
xfgroup.set('selected', 'selected') xfgroup.set('selected', 'selected')
xfiles = ET.SubElement(xresult, "files") xfiles = ET.SubElement(xresult, "files")
for file in files: for file in files:
if file.dontlist: continue
xfile = ET.SubElement(xfiles, "file") xfile = ET.SubElement(xfiles, "file")
if file.group is not None: xfile.set('group', file.group) if file.group is not None: xfile.set('group', file.group)
for name, value in file.vars.items(): for name, value in file.vars.items():
@ -256,6 +282,9 @@ def run_cgilsxml():
def add_spec(option, opt, value, parser, *args, **kw): def add_spec(option, opt, value, parser, *args, **kw):
if env['filter'] is not None: env['filters'].append(env['filter']) if env['filter'] is not None: env['filters'].append(env['filter'])
env['filter'] = Filter(value) env['filter'] = Filter(value)
def allow_spec(option, opt, value, parser, *args, **kw):
if env['filter'] is None: env['filter'] = default_filter
env['filter'].allow_spec(value)
def add_var(option, opt_str, value, parser, *args, **kw): def add_var(option, opt_str, value, parser, *args, **kw):
if env['filter'] is None: env['filter'] = default_filter if env['filter'] is None: env['filter'] = default_filter
env['filter'].add_var(value) env['filter'].add_var(value)
@ -265,14 +294,16 @@ def run_cgilsxml():
from optparse import OptionParser from optparse import OptionParser
OP = OptionParser(usage=u"\n\t%prog [options] /path/to/dir", description=__doc__) OP = OptionParser(usage=u"\n\t%prog [options] /path/to/dir", description=__doc__)
OP.add_option('-e', '--spec', dest='spec', action='callback', callback=add_spec, type="string", OP.add_option('-e', '--spec', dest='spec', action='callback', callback=add_spec, type='string',
help=u"Spécifier l'expression régulière permettant de sélectionner les fichiers à lister. L'expression régulière peut définir des groupes qui sont utilisées pour l'extraction des variables." help=u"Spécifier l'expression régulière permettant de sélectionner les fichiers à lister. L'expression régulière peut définir des groupes qui sont utilisées pour l'extraction des variables."
+ u"\n Il est possible de spécifier cette option plusieurs fois." + u"\n Il est possible de spécifier cette option plusieurs fois."
+ u"\n Note: TOUTES les expressions régulières sont testées par rapport au nom du fichier, et pour celles qui correspondent, les variables correspondantes sont définies. Il faut donc ordonner les expressions régulières de la plus générale à la plus spécifique, contrairement à ce qui se fait d'habitude.") + u"\n Note: TOUTES les expressions régulières sont testées par rapport au nom du fichier, et pour celles qui correspondent, les variables correspondantes sont définies. Il faut donc ordonner les expressions régulières de la plus générale à la plus spécifique, contrairement à ce qui se fait d'habitude.")
OP.add_option('-v', '--var', dest='var', action='callback', callback=add_var, type="string", OP.add_option('-E', '--allow-spec', dest='spec', action='callback', callback=allow_spec, type='string',
help=u"Ajouter une spécification de fichier qui peut être demandé avec --cgi-path-info. Ces fichiers ne sont pas inclus dans la liste.")
OP.add_option('-v', '--var', dest='var', action='callback', callback=add_var, type='string',
help=u"Définir la variable NAME à la valeur de l'expression VAR_EXPR. Dans cette expression, il est possible d'utiliser des expressions de la forme %%(var)s pour inclure des variables déjà définies, ou \\N et \\g<NAME> pour inclure respective le groupe numéro N et le groupe nommé NAME de l'expression régulière --spec." help=u"Définir la variable NAME à la valeur de l'expression VAR_EXPR. Dans cette expression, il est possible d'utiliser des expressions de la forme %%(var)s pour inclure des variables déjà définies, ou \\N et \\g<NAME> pour inclure respective le groupe numéro N et le groupe nommé NAME de l'expression régulière --spec."
+ u"\n Cette option peut être spécifiée plusieurs fois. Elle s'applique à l'expression régulière définie par la dernière option --spec") + u"\n Cette option peut être spécifiée plusieurs fois. Elle s'applique à l'expression régulière définie par la dernière option --spec")
OP.add_option('-g', '--group', dest='group', action='callback', callback=set_group, type="string", OP.add_option('-g', '--group', dest='group', action='callback', callback=set_group, type='string',
help=u"Spécifier l'expression qui permet de construire des ensembles de fichiers sur la base des groupes définis dans l'expression régulière de l'option --spec. Dans cette expression, il est possible d'utiliser des expressions de la forme %%(var)s pour inclure des variables déjà définies, ou \\N ou \\g<NAME> pour inclure respective le groupe numéro N et le groupe nommé NAME de l'expression régulière --spec." help=u"Spécifier l'expression qui permet de construire des ensembles de fichiers sur la base des groupes définis dans l'expression régulière de l'option --spec. Dans cette expression, il est possible d'utiliser des expressions de la forme %%(var)s pour inclure des variables déjà définies, ou \\N ou \\g<NAME> pour inclure respective le groupe numéro N et le groupe nommé NAME de l'expression régulière --spec."
+ u"\n Cette option ne peut être spécifiée qu'une seule fois par option --spec") + u"\n Cette option ne peut être spécifiée qu'une seule fois par option --spec")
OP.add_option('-s', '--sort', dest='sortby', OP.add_option('-s', '--sort', dest='sortby',