Intégration de la branche release-7.0.0
This commit is contained in:
commit
9b13be8142
14
CHANGES.md
14
CHANGES.md
|
@ -1,3 +1,17 @@
|
|||
## Version 7.0.0 du 25/08/2017-15:53
|
||||
|
||||
* `e4f154e` uawk: possibilité de lancer les versions locale-aware
|
||||
* `ef00e07` bug
|
||||
* `377ca5e` implémenter awkcsv2fsv. corriger un bug avec les outils qui utilisaient cawkrun à l'intérieur d'une fonction l*
|
||||
* `2f448d5` ussh: problèmes de compatibilité
|
||||
* `2cc2411` bug potentiel
|
||||
* `65bd363` webpyapp: réorganiser les fichiers pour supporter des librairies locales
|
||||
* `0b39b23` webpyapp: les variables de server.conf sont configurables
|
||||
* `d1a1d4d` webpyapp: cosmetic
|
||||
* `46fbec7` webpyapp: bootstrap facilité des sessions
|
||||
* `c541958` webpyapp: support du mode développement
|
||||
* `e2ea2ea` ufile: ajout de --force-cp
|
||||
|
||||
## Version 6.7.0 du 19/07/2017-15:45
|
||||
|
||||
* `1b92275` apacheconfig: support d'un script post-update.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
6.7.0
|
||||
7.0.0
|
||||
|
|
|
@ -8,12 +8,12 @@ from os import path
|
|||
|
||||
from ulib.base.base import isstr, isbool, isnum, isflt, seqof, make_prop
|
||||
from ulib.base.uio import _u, Utf8IO
|
||||
from ulib.base.output import set_verbosity, enote, edebug
|
||||
from ulib.base.output import set_verbosity, einfo, enote, edebug
|
||||
from ulib.base.args import get_args
|
||||
from ulib.base.dates import rfc2822
|
||||
from ulib.base.functions import apply_args
|
||||
from ulib.base.words import plural
|
||||
from ulib.formats import unicodeF, booleanF, integerF, floatF
|
||||
from ulib.formats import unicodeF, strF, booleanF, integerF, floatF
|
||||
from ulib.ext import web
|
||||
|
||||
def checked(b):
|
||||
|
@ -307,8 +307,13 @@ class Page(object):
|
|||
def index(self): return self.render()
|
||||
|
||||
class ShConfig(dict):
|
||||
def __init__(self, config, **defaults):
|
||||
super(ShConfig, self).__init__(**defaults)
|
||||
_formats = None
|
||||
def __init__(self, config, formats):
|
||||
super(ShConfig, self).__init__()
|
||||
self._formats = formats
|
||||
for name in formats.keys():
|
||||
self[name] = None
|
||||
|
||||
inf = open(config, 'rb')
|
||||
try: s = inf.read()
|
||||
finally: inf.close()
|
||||
|
@ -321,10 +326,18 @@ class ShConfig(dict):
|
|||
mo = self.RE_NAMEVALUE.match(part)
|
||||
if mo is None: continue #XXX ignorer pour le moment
|
||||
name, value = mo.groups()
|
||||
self[name] = value
|
||||
format = self._formats.get(name, unicodeF)
|
||||
self[name] = format.parse(value)
|
||||
|
||||
class Application(object):
|
||||
CONFIG = 'server.conf'
|
||||
# si ce fichier existe dans basedir, alors forcer le mode développement: la
|
||||
# variable HOST est ignorée et DEBUG vaut par défaut True
|
||||
DEVEL_SF = '.devel'
|
||||
# nom du fichier de configuration à charger automatiquement à partir de
|
||||
# basedir. pour désactiver cette fonctionnalité, utiliser la valeur None
|
||||
CONFIG_FILE = 'server.conf'
|
||||
CONFIG_VARS = dict(HOST=strF, PORT=integerF, DEBUG=booleanF)
|
||||
# configuration par défaut
|
||||
HOST = '0.0.0.0'
|
||||
PORT = 12345
|
||||
DEBUG = False
|
||||
|
@ -362,12 +375,17 @@ class Application(object):
|
|||
templatedir = path.join(self.basedir, 'templates')
|
||||
self.templatedir = templatedir
|
||||
|
||||
config = path.join(self.basedir, self.CONFIG)
|
||||
if path.exists(config):
|
||||
c = ShConfig(config, HOST=None, PORT=None, DEBUG=None)
|
||||
if host is None: host = c['HOST']
|
||||
if port is None: port = integerF.parse((c['PORT']))
|
||||
if debug is None: debug = booleanF.parse(c['DEBUG'])
|
||||
devel = path.exists(path.join(self.basedir, self.DEVEL_SF))
|
||||
if devel: einfo("Mode developpement activé")
|
||||
|
||||
if self.CONFIG_FILE is not None:
|
||||
config = path.join(self.basedir, self.CONFIG_FILE)
|
||||
if path.exists(config):
|
||||
c = ShConfig(config, self.CONFIG_VARS)
|
||||
for name, value in c.items():
|
||||
if devel and name == 'HOST': continue
|
||||
if devel and name == 'DEBUG' and value is None: value = True
|
||||
if value is not None: setattr(self, name, value)
|
||||
|
||||
if host is not None: self.HOST = host
|
||||
if port is not None: self.PORT = port
|
||||
|
|
|
@ -1 +1 @@
|
|||
014003000
|
||||
015000000
|
||||
|
|
73
lib/ulib/awk
73
lib/ulib/awk
|
@ -841,7 +841,7 @@ function lawkcsv() {
|
|||
reset_fields=
|
||||
fi
|
||||
|
||||
awkrun -f \
|
||||
lawkrun -f \
|
||||
skip_lines:int="$skip" parse_headers:int="$parse_headers" \
|
||||
autosep:int="$autosep" colsep="$colsep" qchar="$qchar" echar="$echar" \
|
||||
show_headers:int="$show_headers" reset_fields:int="$reset_fields" \
|
||||
|
@ -978,7 +978,7 @@ function lgrepcsv() {
|
|||
headers=("$@")
|
||||
if [ -z "${headers[*]}" ]; then
|
||||
parse_headers=1
|
||||
array_from_lines headers "$(awkrun -f lskip:int="$skip" 'NR <= lskip { next }
|
||||
array_from_lines headers "$(lawkrun -f lskip:int="$skip" 'NR <= lskip { next }
|
||||
{
|
||||
count = array_parsecsv(__fields, $0)
|
||||
for (i = 1; i <= count; i++) {
|
||||
|
@ -1077,7 +1077,7 @@ function lawkfsv2csv() {
|
|||
done
|
||||
shift
|
||||
|
||||
awkrun -f \
|
||||
lawkrun -f \
|
||||
skip_lines:int="$skip" trim_values:int="$rtrim" show_headers:int="$show_headers" \
|
||||
headers[@] starts[@] sizes[@] \
|
||||
"$__AWKCSV_FUNCTIONS"'
|
||||
|
@ -1109,6 +1109,55 @@ function awkfsv2csv() { LANG=C lawkfsv2csv "$@"; }
|
|||
|
||||
################################################################################
|
||||
|
||||
__AWKCSV2FSV_HELP="\
|
||||
Transformer un flux csv en fsv (colonnes à largeurs fixes)
|
||||
|
||||
Chaque argument doit être de la forme field:size"
|
||||
|
||||
function lawkcsv2fsv() {
|
||||
local -a args fieldsizes
|
||||
if parse_opts @ args -- "$@"; then
|
||||
set -- "${args[@]}"
|
||||
else
|
||||
eerror "$args"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local -a fields sizes
|
||||
local fieldsize field size
|
||||
while [ $# -gt 0 -a "$1" != "--" ]; do
|
||||
fieldsize="$1"
|
||||
shift
|
||||
|
||||
splitpair "$fieldsize" field size
|
||||
[ -n "$field" ] || {
|
||||
eerror "field est requis"
|
||||
return 1
|
||||
}
|
||||
[ -n "$size" ] || size=1
|
||||
array_add fields "$field"
|
||||
array_add sizes "$size"
|
||||
done
|
||||
shift
|
||||
|
||||
lawkcsv -v fields[@] -v sizes[@] -a '{
|
||||
line = ""
|
||||
for (i = 1; i <= fields_count; i++) {
|
||||
size = sizes[i] + 0
|
||||
value = get(fields[i]) ""
|
||||
while (length(value) < size) value = value " "
|
||||
if (length(value) > size) value = substr(value, 1, size)
|
||||
line = line value
|
||||
}
|
||||
print line
|
||||
}' -- "$@"
|
||||
}
|
||||
|
||||
function cawkcsv2fsv() { LANG=C lawkcsv2fsv "$@"; }
|
||||
function awkcsv2fsv() { LANG=C lawkcsv2fsv "$@"; }
|
||||
|
||||
################################################################################
|
||||
|
||||
__MERGECSV_HELP="\
|
||||
Fusionner deux fichiers csv en faisant la correspondance sur la valeur d'un
|
||||
champ, qui est la clé
|
||||
|
@ -1264,14 +1313,14 @@ function lmergecsv() {
|
|||
|
||||
[ "$parse_headers" == "auto" ] && parse_headers=1
|
||||
if [ -n "$parse_headers" ]; then
|
||||
[ -n "$lheaders" ] || lheaders="$(<"$lfile" awkrun lskip:int="$lskip" 'NR <= lskip { next } { print; exit }')"
|
||||
[ -n "$rheaders" ] || rheaders="$(<"$rfile" awkrun lskip:int="$lskip" 'NR <= lskip { next } { print; exit }')"
|
||||
[ -n "$lheaders" ] || lheaders="$(<"$lfile" lawkrun lskip:int="$lskip" 'NR <= lskip { next } { print; exit }')"
|
||||
[ -n "$rheaders" ] || rheaders="$(<"$rfile" lawkrun lskip:int="$lskip" 'NR <= lskip { next } { print; exit }')"
|
||||
fi
|
||||
|
||||
# faire le fichier de travail pour lfile
|
||||
local tmpleft
|
||||
ac_set_tmpfile tmpleft "" __mergecsv_left "" __MERGECSV_DEBUG
|
||||
<"$lfile" awkrun -f \
|
||||
<"$lfile" lawkrun -f \
|
||||
padding="$padding" padlen:int="$padlen" \
|
||||
parse_headers:int="$parse_headers" ignore_case:int="$ignore_case" \
|
||||
lskip:int="$lskip" lkey="$lkey" \
|
||||
|
@ -1295,7 +1344,7 @@ parse_headers && do_once("parse-headers") {
|
|||
# faire le fichier de travail pour rfile
|
||||
local tmpright
|
||||
ac_set_tmpfile tmpright "" __mergecsv_right "" __MERGECSV_DEBUG
|
||||
<"$rfile" awkrun -f \
|
||||
<"$rfile" lawkrun -f \
|
||||
padding="$padding" padlen:int="$padlen" \
|
||||
parse_headers:int="$parse_headers" ignore_case:int="$ignore_case" \
|
||||
rskip:int="$rskip" rkey="$rkey" \
|
||||
|
@ -1409,7 +1458,7 @@ parse_headers && do_once("parse-headers") {
|
|||
ac_set_tmpfile tmpmerged "" __mergecsv_merged "" __MERGECSV_DEBUG
|
||||
csort -s -k 1,$(($padlen + 1)) "$tmpleft" "$tmpright" >"$tmpmerged"
|
||||
|
||||
<"$tmpmerged" awkrun -f \
|
||||
<"$tmpmerged" lawkrun -f \
|
||||
padlen:int="$padlen" \
|
||||
parse_headers:int="$parse_headers" ignore_case:int="$ignore_case" \
|
||||
lheaderscsv="$lheaders" lkey="$lkey" lprefix="$lprefix" \
|
||||
|
@ -1700,14 +1749,14 @@ function lsortcsv() {
|
|||
cat >"$tmpinput"
|
||||
input="$tmpinput"
|
||||
fi
|
||||
headers="$(<"$input" awkrun skip:int="$skip" 'NR <= skip { next } { print; exit }')"
|
||||
headers="$(<"$input" lawkrun skip:int="$skip" 'NR <= skip { next } { print; exit }')"
|
||||
fi
|
||||
|
||||
# faire le fichier de travail
|
||||
local tmpinput
|
||||
ac_set_tmpfile tmpinput "" __sortcsv_input "" __SORTCSV_DEBUG
|
||||
array_add tmpfiles "$tmpinput"
|
||||
<"$input" >"$tmpinput" awkrun -f \
|
||||
<"$input" >"$tmpinput" lawkrun -f \
|
||||
padding="$padding" padlen:int="$padlen" \
|
||||
skip:int="$skip" parse_headers:int="$parse_headers" \
|
||||
key="$key" \
|
||||
|
@ -1740,7 +1789,7 @@ parse_headers && do_once("parse-headers") {
|
|||
|
||||
# résultat
|
||||
[ -n "$output" ] || output=/dev/stdout
|
||||
stdredir "$tmpsorted" "$output" "" awkrun -f \
|
||||
stdredir "$tmpsorted" "$output" "" lawkrun -f \
|
||||
padlen:int="$padlen" \
|
||||
headerscsv="$headers" show_headers:int="$show_headers" \
|
||||
'
|
||||
|
@ -2060,7 +2109,7 @@ function lprintcsv() {
|
|||
[ -n "$output" ] || output=/dev/stdout
|
||||
values=("$@")
|
||||
|
||||
stdredir "" ">>$output" "" awkrun -f fields[@] show_headers:int="$show_headers" values[@] '
|
||||
stdredir "" ">>$output" "" lawkrun -f fields[@] show_headers:int="$show_headers" values[@] '
|
||||
BEGIN {
|
||||
if (show_headers) array_printcsv(fields)
|
||||
if (fields_count > 0) count = fields_count
|
||||
|
|
|
@ -14,7 +14,8 @@ function pkg_check() {
|
|||
# Vérifier que les packages sont installés sur le système
|
||||
local pkg status
|
||||
for pkg in "$@"; do
|
||||
status="$(LANG=C dpkg -s "$pkg" 2>/dev/null | grep '^Status:')" || return 1
|
||||
LANG=C setx status=dpkg -s "$pkg" 2>/dev/null || return 1
|
||||
setx status=grep '^Status:' <<<"$status"
|
||||
[[ "$status" == *not-installed* ]] && return 1
|
||||
[[ "$status" == *deinstall* ]] && return 1
|
||||
done
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
*.py[co]
|
|
@ -57,7 +57,9 @@ fi
|
|||
etitle "Copie des fichiers"
|
||||
destdir="$destdir/$name"
|
||||
mkdir -p "$destdir" || die
|
||||
rsync -a --exclude /server.conf --exclude /install-or-update.sh "$scriptdir/" "$destdir"
|
||||
rsync -a \
|
||||
--exclude /server.conf --exclude /install-or-update.sh --exclude /.devel \
|
||||
"$scriptdir/" "$destdir"
|
||||
eend
|
||||
|
||||
etitle "Vérification de la configuration"
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
|
||||
__all__ = ()
|
||||
|
|
@ -3,19 +3,24 @@
|
|||
|
||||
__all__ = ('Server',)
|
||||
|
||||
import sys, os
|
||||
from os import path
|
||||
|
||||
SCRIPTDIR = path.abspath(path.split(__file__)[0])
|
||||
sys.path.insert(0, path.join(SCRIPTDIR, 'lib/python'))
|
||||
|
||||
from ulib.web import web, Application, Page, defaults
|
||||
|
||||
class Server(Application):
|
||||
def __init__(self, basedir=None, templatedir=None, host=None, port=None, debug=None):
|
||||
Application.__init__(self, basedir, templatedir, host, port, debug)
|
||||
super(Server, self).__init__(basedir, templatedir, host, port, debug)
|
||||
|
||||
def _new_session(self):
|
||||
pass # décommenter la ligne suivante pour activer les sessions
|
||||
#return web.session.DiskStore('sessions'), {}
|
||||
|
||||
class index(Page):
|
||||
PREFIX = r'/'
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
from os import path
|
||||
|
||||
basedir = path.abspath(path.split(__file__)[0])
|
||||
sys.path.append(path.join(basedir, 'lib'))
|
||||
Server(basedir).run(sys.argv[1:])
|
||||
Server(SCRIPTDIR).run(sys.argv[1:])
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
/*
|
||||
/*/
|
||||
!/.gitignore
|
38
uawk
38
uawk
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
|
||||
TOOLS=(awkrun awkcsv grepcsv awkfsv2csv mergecsv sortcsv dumpcsv printcsv)
|
||||
TOOLS=(awkrun awkcsv grepcsv awkfsv2csv awkcsv2fsv mergecsv sortcsv dumpcsv printcsv)
|
||||
if [ "$#" -eq 1 -a "$1" == --nutools-makelinks ]; then
|
||||
# créer les liens
|
||||
scriptname="$(basename "$0")"
|
||||
|
@ -45,13 +45,22 @@ fi
|
|||
|
||||
# Aliases pour les noms d'outils
|
||||
case "$tool" in
|
||||
run) tool=awkrun;;
|
||||
csv) tool=awkcsv;;
|
||||
grep) tool=grepcsv;;
|
||||
fsv2csv|fsv) tool=awkfsv2csv;;
|
||||
merge) tool=mergecsv;;
|
||||
sort) tool=sortcsv;;
|
||||
dump) tool=dumpcsv;;
|
||||
run) tool=awkrun; toolprefix=; prefix=c; Clang=1;;
|
||||
lrun) tool=awkrun; toolprefix=l; prefix=l; Clang=;;
|
||||
csv) tool=awkcsv; toolprefix=; prefix=c; Clang=1;;
|
||||
lcsv) tool=awkcsv; toolprefix=l; prefix=l; Clang=;;
|
||||
grep) tool=grepcsv; toolprefix=; prefix=c; Clang=1;;
|
||||
lgrep) tool=grepcsv; toolprefix=l; prefix=l; Clang=;;
|
||||
fsv2csv|fsv) tool=awkfsv2csv; toolprefix=; prefix=c; Clang=1;;
|
||||
lfsv2csv|lfsv) tool=awkfsv2csv; toolprefix=l; prefix=l; Clang=;;
|
||||
csv2fsv) tool=awkcsv2fsv; toolprefix=; prefix=c; Clang=1;;
|
||||
lcsv2fsv) tool=awkcsv2fsv; toolprefix=l; prefix=l; Clang=;;
|
||||
merge) tool=mergecsv; toolprefix=; prefix=c; Clang=1;;
|
||||
lmerge) tool=mergecsv; toolprefix=l; prefix=l; Clang=;;
|
||||
sort) tool=sortcsv; toolprefix=; prefix=c; Clang=1;;
|
||||
lsort) tool=sortcsv; toolprefix=l; prefix=l; Clang=;;
|
||||
dump) tool=dumpcsv; toolprefix=; prefix=c; Clang=1;;
|
||||
ldump) tool=dumpcsv; toolprefix=l; prefix=l; Clang=;;
|
||||
esac
|
||||
scriptname="$toolprefix$tool"
|
||||
|
||||
|
@ -95,12 +104,23 @@ elif [ "$tool" == "awkfsv2csv" ]; then
|
|||
${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C
|
||||
}
|
||||
USAGE
|
||||
$scriptname [options] -- [header:sizes...] [-- inputfiles...]
|
||||
$scriptname [options] -- [header:size,...] [-- inputfiles...]
|
||||
|
||||
$__AWKFSV2CSV_HELP"
|
||||
|
||||
"${prefix}awkfsv2csv" "$@"
|
||||
|
||||
elif [ "$tool" == "awkcsv2fsv" ]; then
|
||||
[ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: wrapper autour de awk pour transformer un fichier à colonnes fixes en fichier csv
|
||||
${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C
|
||||
}
|
||||
USAGE
|
||||
$scriptname [options] -- [field:size,...] [-- inputfiles...]
|
||||
|
||||
$__AWKCSV2FSV_HELP"
|
||||
|
||||
"${prefix}awkcsv2fsv" "$@"
|
||||
|
||||
elif [ "$tool" == "mergecsv" ]; then
|
||||
[ $# -eq 1 -a "$1" == --help ] && exit_with uecho "$scriptname: fusionner deux fichiers csv sur un champ commun
|
||||
${Clang:+note: ce script ne tient pas compte de la locale: il travaille avec LANG=C
|
||||
|
|
8
ufile
8
ufile
|
@ -44,6 +44,11 @@ OPTIONS
|
|||
défaut ~/etc/default/ufile
|
||||
--file
|
||||
Classer les fichiers spécifiés. C'est l'action par défaut
|
||||
--force-cp
|
||||
Spécifier le mode de classement des fichiers. Par défaut, le fichier est
|
||||
déplacé dans la destination s'il s'agit d'un classement local, ou copié
|
||||
s'il s'agit d'un classement distant. Avec --force-cp, le fichier est
|
||||
systématiquement copié dans la destination.
|
||||
-S, --ssh SSH
|
||||
S'il faut classer sur un hôte distant avec scp, utiliser le programme
|
||||
spécifié pour la connexion par ssh
|
||||
|
@ -108,6 +113,7 @@ args=(%
|
|||
--help '$exit_with display_help'
|
||||
-c:,--config: config=
|
||||
--file action=file
|
||||
--force-cp force_cp=1
|
||||
-S:,--ssh: SSH=
|
||||
--force-scp force_scp=1
|
||||
-n,--fake fake=1
|
||||
|
@ -251,7 +257,7 @@ for file in "$@"; do
|
|||
}
|
||||
setx destdir=dirname -- "$dest"
|
||||
docmd mkdir -p "$destdir" || die "$destdir: impossible de créer le répertoire"
|
||||
if [ $i -eq $mvi ]; then
|
||||
if [ $i -eq $mvi -a -z "$force_cp" ]; then
|
||||
mvdesc="du déplacement"
|
||||
mvcmd=mv
|
||||
else
|
||||
|
|
16
ussh
16
ussh
|
@ -343,15 +343,18 @@ function __update_sshopts_cm() {
|
|||
version="$(ssh -V 2>&1)"
|
||||
version="${version#OpenSSH_}"; major="${version%%.*}"
|
||||
minor="${version#$major.}"; minor="${minor:0:1}"
|
||||
if [ $major -ge 6 ]; then
|
||||
if [ -z "$major" ]; then
|
||||
# ne devrait pas se produire... mais au cas où
|
||||
persist=
|
||||
elif [ "$major" -ge 6 ]; then
|
||||
persist="$DEFAULT_PERSIST"
|
||||
elif [ $major -eq 5 ]; then
|
||||
elif [ "$major" -eq 5 ]; then
|
||||
if [ "$minor" -ge 6 ]; then
|
||||
persist="$DEFAULT_PERSIST"
|
||||
else
|
||||
persist=
|
||||
fi
|
||||
elif [ $major -le 4 ]; then
|
||||
elif [ "$major" -le 4 ]; then
|
||||
persist=
|
||||
fi
|
||||
fi
|
||||
|
@ -383,7 +386,10 @@ function show_vars() {
|
|||
function do_ssh() {
|
||||
local -a sshopts
|
||||
local onehost r
|
||||
if [ "${#hosts[*]}" -gt 1 ]; then
|
||||
if [ ${#hosts[*]} -eq 0 -a $# -eq 0 ]; then
|
||||
${exec:+exec} "$SSH" "${SSHOPTS[@]}"
|
||||
return
|
||||
elif [ "${#hosts[*]}" -gt 1 ]; then
|
||||
onehost=
|
||||
exec=
|
||||
else
|
||||
|
@ -447,7 +453,7 @@ if [ -n "$remove" ]; then
|
|||
hosts=("$1"); shift
|
||||
fix_hosts
|
||||
remove_keys
|
||||
else
|
||||
elif [ -n "$1" ]; then
|
||||
hosts=("$1"); shift
|
||||
fix_hosts
|
||||
fi
|
||||
|
|
Loading…
Reference in New Issue