2015-12-07 12:26:37 +04:00
#!/usr/bin/env python
# -*- coding: utf-8 mode: python -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
2015-12-07 14:59:20 +04:00
u """ Ce script est prévu pour être utilisé dans un script CGI.
2015-12-07 12:26:37 +04:00
Il permet de lister le contenu d ' un répertoire au format XML, et de télécharger les fichiers trouvés.
"""
2016-02-07 23:03:38 +04:00
import os , sys , re , shutil , mimetypes , urlparse , urllib
2015-12-07 12:26:37 +04:00
from os import path
from time import time , localtime
from types import UnicodeType , StringTypes
import xml . etree . ElementTree as ET
# _u() et datef() sont des fonctions de pyulib, recopiées ici pour ne pas devoir
# dépendre d'une librairie extérieure
def _u ( u ) :
2016-06-10 01:34:38 +04:00
if u is None : return None
elif type ( u ) not in StringTypes : u = unicode ( str ( u ) , ' utf-8 ' , ' strict ' )
2015-12-07 12:26:37 +04:00
elif type ( u ) is not UnicodeType : u = unicode ( u , ' utf-8 ' , ' strict ' )
return u
DATEF_MAP = { ' % Y ' : ' %(y)04i ' , ' % m ' : ' %(m)02i ' , ' %d ' : ' %(d)02i ' , ' % H ' : ' %(H)02i ' , ' % M ' : ' %(M)02i ' , ' % S ' : ' %(S)02i ' }
DATE_DATEF = ' %d / % m/ % Y '
TIME_DATEF = ' % H: % M: % S '
def datef ( format = None , t = None ) :
if format is None : format = DATE_DATEF
if t is None : t = time ( )
y , m , d , H , M , S , W , J , dst = localtime ( t )
for fr , to in DATEF_MAP . items ( ) : format = format . replace ( fr , to )
return format % locals ( )
RE_COMMA = re . compile ( r ' \ s*, \ s* ' )
RE_VAR_NAME_EXPR = re . compile ( r ' ([_a-zA-Z][-_a-zA-Z0-9]*)=(.*) ' )
RE_SORT_FIELD_TYPE = re . compile ( r ' ([_a-zA-Z][-_a-zA-Z0-9]*)(?::([aAdDcCnN]+))? ' )
class Filter :
re_spec = None
2016-02-09 11:25:33 +04:00
re_allows = None
2015-12-07 12:26:37 +04:00
ex_vars = None
ex_group = None
2016-06-08 16:06:23 +04:00
ex_break_on = None
2015-12-07 12:26:37 +04:00
def __init__ ( self , re_spec ) :
self . re_spec = re . compile ( re_spec )
2016-02-09 11:25:33 +04:00
self . re_allows = [ ]
2015-12-07 12:26:37 +04:00
self . ex_vars = [ ]
self . ex_group = None
2016-06-08 16:06:23 +04:00
self . ex_break_on = None
2015-12-07 12:26:37 +04:00
2016-02-09 11:25:33 +04:00
def allow_spec ( self , re_allow ) :
self . re_allows . append ( re . compile ( re_allow ) )
2015-12-07 12:26:37 +04:00
def add_var ( self , ex_var ) :
mo = RE_VAR_NAME_EXPR . match ( ex_var )
if mo is None : raise ValueError ( ' Invalid VAR_EXPR: %s ' % ex_var )
name , expr = mo . groups ( )
self . ex_vars . append ( ( name , expr ) )
def set_group ( self , ex_group ) :
self . ex_group = ex_group
2016-06-08 16:06:23 +04:00
def set_break_on ( self , ex_break_on ) :
self . ex_break_on = ex_break_on
2015-12-07 12:26:37 +04:00
def __repr__ ( self ) :
2016-06-08 16:06:23 +04:00
return ' Filter< %s , %s , %s , %s , %s > ' % \
( self . re_spec , repr ( self . re_allows ) ,
repr ( self . ex_vars ) ,
self . ex_group , self . ex_break_on ,
)
2015-12-07 12:26:37 +04:00
def match_fill ( self , file ) :
mo = self . re_spec . match ( file . name )
if mo is None : return None
for name , expr in self . ex_vars :
value = mo . expand ( expr )
if ' % ' in value : value = value % file . vars
file [ name ] = value
if self . ex_group is not None :
group = mo . expand ( self . ex_group )
if ' % ' in group : group = group % file . vars
2016-06-08 16:06:23 +04:00
else :
group = None
file . group = group
if self . ex_break_on is not None :
break_on = mo . expand ( self . ex_break_on )
if ' % ' in break_on : break_on = break_on % file . vars
else :
break_on = None
file . break_on = break_on
2015-12-07 12:26:37 +04:00
return True
2016-02-09 11:25:33 +04:00
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
2015-12-07 12:26:37 +04:00
class File :
pf = None
group = None
vars = None
2016-02-09 11:25:33 +04:00
dontlist = None
2015-12-07 12:26:37 +04:00
2016-02-09 11:25:33 +04:00
def __init__ ( self , dir , name , dontlist = False ) :
2015-12-07 12:26:37 +04:00
dir = path . abspath ( dir )
pf = path . join ( dir , name )
self . __dict__ [ ' pf ' ] = pf
self . __dict__ [ ' group ' ] = None
self . __dict__ [ ' vars ' ] = { }
2016-02-09 11:25:33 +04:00
self . __dict__ [ ' dontlist ' ] = dontlist
2015-12-07 12:26:37 +04:00
stat = os . stat ( pf )
mtime = int ( stat . st_mtime )
self . dir = dir
self . name = name
2015-12-07 14:59:20 +04:00
self . dlname = name
self . size = stat . st_size
2015-12-07 12:26:37 +04:00
self . mtime = mtime
self . date = datef ( DATE_DATEF , mtime )
self . time = datef ( TIME_DATEF , mtime )
2015-12-07 14:59:20 +04:00
self . Y , self . m , self . d , self . H , self . M , self . S = datef ( ' % Y % m %d % H % M % S ' , mtime ) . split ( ' ' )
2015-12-07 12:26:37 +04:00
def isfile ( self ) :
return path . isfile ( self . pf )
def __getitem__ ( self , name ) : return self . vars [ name ]
def __setitem__ ( self , name , value ) : self . vars [ name ] = value
2015-12-07 14:59:20 +04:00
def has_key ( self , name ) : return self . vars . has_key ( name )
2016-02-09 11:25:33 +04:00
def __getattr__ ( self , name ) :
try : return self . vars [ name ]
except KeyError : raise AttributeError ( name )
2015-12-07 12:26:37 +04:00
def __setattr__ ( self , name , value ) :
2016-02-09 11:25:33 +04:00
if self . __dict__ . has_key ( name ) : self . __dict__ [ name ] = value
else : self . vars [ name ] = value
2015-12-07 12:26:37 +04:00
def __repr__ ( self ) : return ' File< %s > ' % ( self . pf )
def find_files ( basedir , filters ) :
files = [ ]
for name in os . listdir ( basedir ) :
file = File ( basedir , name )
if not file . isfile ( ) : continue
matched = False
2016-02-09 11:25:33 +04:00
allowed = False
2015-12-07 12:26:37 +04:00
for filter in filters :
matched = filter . match_fill ( file ) or matched
2016-02-09 11:25:33 +04:00
allowed = filter . match_allow ( file ) or allowed
if matched : pass
elif allowed : file . dontlist = True
else : continue
2015-12-07 12:26:37 +04:00
files . append ( file )
return files
def build_sortfunc ( sortby ) :
SORTS = [ ]
for term in RE_COMMA . split ( sortby . strip ( ) ) :
mo = RE_SORT_FIELD_TYPE . match ( term )
if mo is None : raise ValueError ( ' Invalid SORT_EXPR: %s ' % term )
field , type = mo . groups ( )
if type is None : type = ' '
type = type . upper ( )
if ' A ' in type : order = ' A '
elif ' D ' in type : order = ' D '
else : order = ' A '
if ' C ' in type : method = ' C '
elif ' N ' in type : method = ' N '
else : method = ' C '
SORTS . append ( ( field , method , order ) )
def sortfunc ( a , b ) :
for field , method , order in SORTS :
2016-02-09 11:25:33 +04:00
av = getattr ( a , field , None )
bv = getattr ( b , field , None )
if av is None :
if bv is None : outcome = 0
else : outcome = 1
elif bv is None :
outcome = - 1
else :
if method == ' C ' :
av = str ( av )
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
2015-12-07 12:26:37 +04:00
if order == ' A ' : pass
elif order == ' D ' : outcome = - outcome
if outcome != 0 : return outcome
return 0
return sortfunc
def sort_files ( files , sortfunc ) :
files . sort ( sortfunc )
return files
def build_fgroups ( files ) :
fgroups = set ( )
for file in files :
if file . group is not None :
fgroups . add ( file . group )
fgroups = list ( fgroups )
fgroups . sort ( )
return fgroups
def filter_files ( files , group ) :
2016-02-09 11:25:33 +04:00
if group : func = lambda file : file . dontlist or file . group == group
else : func = lambda file : file . dontlist or not file . group
return filter ( func , files )
2015-12-07 12:26:37 +04:00
def select_file ( files , name ) :
matches = filter ( lambda file : file . name == name , files )
if matches : return matches [ 0 ]
else : return None
2015-12-24 11:14:57 +04:00
def cgi_nocache ( ) :
print " Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0 "
print " Pragma: no-cache "
print " Expires: Thu, 01 Jan 1970 00:00:00 GMT "
2016-02-07 23:03:38 +04:00
RE_COMMA = re . compile ( ' , ' )
def lfix ( values ) :
if values is None : return None
fvalues = [ ]
for parts in values :
parts = RE_COMMA . split ( parts )
fvalues . extend ( parts )
return fvalues
def filter_query_string ( query_string , includes = None , excludes = None , prefix = None ) :
params = urlparse . parse_qsl ( query_string , keep_blank_values = True )
includes = lfix ( includes )
if includes is None : names = dict ( params ) . keys ( )
else : names = includes [ : ]
excludes = lfix ( excludes )
if excludes is not None :
for name in excludes :
if name in names : names . remove ( name )
params = [ ( name , value ) for ( name , value ) in params if name in names ]
query_string = urllib . urlencode ( params )
if prefix :
if query_string != " " : query_string = " %s & %s " % ( prefix , query_string )
elif prefix != " " : query_string = prefix
return query_string
def print_files ( files , fgroups = None , select_group = None , script_name = None , xslt = None ,
query_string = None , includes = None , excludes = None , prefix = None ) :
2015-12-07 12:26:37 +04:00
xresult = ET . Element ( " result " )
xenv = ET . SubElement ( xresult , " env " )
if script_name is not None :
ET . SubElement ( xenv , " script_name " ) . text = _u ( script_name )
2016-02-04 13:52:09 +04:00
ET . SubElement ( xenv , " script_base " ) . text = _u ( re . sub ( r ' [^/]+$ ' , ' ' , script_name ) )
2016-06-09 16:29:24 +04:00
orig_query_string = query_string
if orig_query_string is not None :
query_string = orig_query_string
2016-06-10 01:34:38 +04:00
params = [ ]
if query_string is not None :
params = urlparse . parse_qsl ( query_string , keep_blank_values = True )
query_string = _u ( query_string )
fquery_string = orig_query_string
fparams = [ ]
if fquery_string is not None :
fquery_string = filter_query_string ( fquery_string , includes , excludes , prefix )
fparams = urlparse . parse_qsl ( fquery_string , keep_blank_values = True )
fquery_string = _u ( fquery_string )
2016-06-09 16:29:24 +04:00
2016-02-07 23:03:38 +04:00
if includes or excludes or prefix :
xorig = ET . SubElement ( xenv , " orig " )
2016-02-08 09:34:02 +04:00
if query_string :
ET . SubElement ( xorig , " query_string " ) . text = u ' ? %s ' % query_string
ET . SubElement ( xorig , " squery_string " ) . text = u ' & %s ' % query_string
2016-02-07 23:03:38 +04:00
xvars = ET . SubElement ( xorig , " query_vars " )
for name , value in params :
ET . SubElement ( xvars , name ) . text = value
query_string = fquery_string
params = fparams
2016-06-09 16:29:24 +04:00
2016-02-08 09:34:02 +04:00
if query_string :
ET . SubElement ( xenv , " query_string " ) . text = u ' ? %s ' % query_string
ET . SubElement ( xenv , " squery_string " ) . text = u ' & %s ' % query_string
2016-06-09 16:29:24 +04:00
2015-12-24 12:16:57 +04:00
xvars = ET . SubElement ( xenv , " query_vars " )
2016-02-07 23:03:38 +04:00
for name , value in params :
ET . SubElement ( xvars , name ) . text = value
2016-06-09 16:29:24 +04:00
2015-12-07 12:26:37 +04:00
xfgroups = ET . SubElement ( xresult , " fgroups " )
if fgroups is not None :
for fgroup in fgroups :
xfgroup = ET . SubElement ( xfgroups , ' fgroup ' )
xfgroup . text = _u ( fgroup )
if fgroup == select_group :
xfgroup . set ( ' selected ' , ' selected ' )
2016-06-09 16:29:24 +04:00
2015-12-07 12:26:37 +04:00
xfiles = ET . SubElement ( xresult , " files " )
2016-06-08 16:06:23 +04:00
first = True
last_classifier = ( None , None )
2015-12-07 12:26:37 +04:00
for file in files :
2016-02-09 11:25:33 +04:00
if file . dontlist : continue
2016-06-08 16:06:23 +04:00
current_classifier = ( file . group , file . break_on )
2016-06-10 01:34:38 +04:00
if first or current_classifier != last_classifier :
file . break_here = None
2016-06-08 16:06:23 +04:00
last_classifier = current_classifier
first = False
2015-12-07 12:26:37 +04:00
xfile = ET . SubElement ( xfiles , " file " )
if file . group is not None : xfile . set ( ' group ' , file . group )
for name , value in file . vars . items ( ) :
ET . SubElement ( xfile , name ) . text = _u ( value )
2016-06-08 15:05:41 +04:00
sys . stdout . write ( ' <?xml version= " 1.0 " encoding= " utf-8 " ?> \n ' )
2015-12-07 12:26:37 +04:00
if xslt is not None :
sys . stdout . write ( ' <?xml-stylesheet version= " 1.0 " type= " text/xsl " href= " %s " ?> \n ' % xslt )
ET . ElementTree ( xresult ) . write ( sys . stdout , " utf-8 " )
def run_cgilsxml ( ) :
default_filter = Filter ( r ' (.*) ' )
def add_spec ( option , opt , value , parser , * args , * * kw ) :
if env [ ' filter ' ] is not None : env [ ' filters ' ] . append ( env [ ' filter ' ] )
env [ ' filter ' ] = Filter ( value )
2016-02-09 11:25:33 +04:00
def allow_spec ( option , opt , value , parser , * args , * * kw ) :
if env [ ' filter ' ] is None : env [ ' filter ' ] = default_filter
env [ ' filter ' ] . allow_spec ( value )
2015-12-07 12:26:37 +04:00
def add_var ( option , opt_str , value , parser , * args , * * kw ) :
if env [ ' filter ' ] is None : env [ ' filter ' ] = default_filter
env [ ' filter ' ] . add_var ( value )
def set_group ( option , opt_str , value , parser , * args , * * kw ) :
if env [ ' filter ' ] is None : env [ ' filter ' ] = default_filter
env [ ' filter ' ] . set_group ( value )
2016-06-08 16:06:23 +04:00
def set_break_on ( option , opt_str , value , parser , * args , * * kw ) :
if env [ ' filter ' ] is None : env [ ' filter ' ] = default_filter
env [ ' filter ' ] . set_break_on ( value )
2015-12-07 12:26:37 +04:00
from optparse import OptionParser
OP = OptionParser ( usage = u " \n \t % prog [options] /path/to/dir " , description = __doc__ )
2016-02-09 11:25:33 +04:00
OP . add_option ( ' -e ' , ' --spec ' , dest = ' spec ' , action = ' callback ' , callback = add_spec , type = ' string ' ,
2015-12-15 10:05:45 +04:00
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 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. " )
2016-02-09 11:25:33 +04:00
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 ' ,
2016-06-08 16:06:23 +04:00
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 respectivement le groupe numéro N et le groupe nommé NAME de l ' expression régulière --spec. "
2015-12-15 10:05:45 +04:00
+ 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 " )
2016-02-09 11:25:33 +04:00
OP . add_option ( ' -g ' , ' --group ' , dest = ' group ' , action = ' callback ' , callback = set_group , type = ' string ' ,
2016-06-08 16:06:23 +04:00
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 respectivement 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 " )
OP . add_option ( ' -b ' , ' --break-on ' , dest = ' break_on ' , action = ' callback ' , callback = set_break_on , type = ' string ' ,
help = u " Spécifier une expression qui permet de partitionner la list des fichiers au sein d ' un même groupe. 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 respectivement le groupe numéro N et le groupe nommé NAME de l ' expression régulière --spec. "
+ u " \n Bien que ce ne soit pas une obligation, il est logique de trier la liste sur cette expression pour que les groupes de fichiers soient ensembles dans la liste. "
2015-12-15 10:05:45 +04:00
+ u " \n Cette option ne peut être spécifiée qu ' une seule fois par option --spec " )
2015-12-07 12:26:37 +04:00
OP . add_option ( ' -s ' , ' --sort ' , dest = ' sortby ' ,
2015-12-15 10:05:45 +04:00
help = u " Spécifier le champ sur lequel trier ainsi que le type de tri à utiliser. SORT_EXPR est de la forme FIELD:TYPE où FIELD est le nom du champ et TYPE est le type de tri: A, D, C et/ou N pour (A)scendant, (D)escendant, (C)haine, (N)numérique. Si un champ est spécifié mais que le type de tri ne l ' est pas, la valeur par défaut est AC. Si cette option n ' est pas spécifiée, le tri par défaut est ' mtime:DN ' . "
+ u " \n Il est possible de spécifier plusieurs champs pour le tri en les séparant par des virgules. " )
2015-12-07 12:26:37 +04:00
OP . add_option ( ' --cgi ' , dest = ' cgi_mode ' , action = ' store_true ' ,
help = u " Activer le mode CGI. Ce mode est automatiquement activé si la variable d ' environnement REQUEST_METHOD existe. " )
2015-12-24 11:14:57 +04:00
OP . add_option ( ' --cgi-allow-cache ' , dest = ' cgi_allow_cache ' , action = ' store_true ' ,
help = u " En mode CGI, ne pas rajouter les en-tête désactivant la mise en cache du résultat. " )
2016-06-08 15:05:41 +04:00
OP . add_option ( ' --cgi-content-type ' , ' --cgict ' , dest = ' cgi_content_type ' ,
help = u " En mode CGI, forcer le type de contenu avec lequel servir le fichier. " )
OP . add_option ( ' --cgi-content-charset ' , ' --cgicc ' , dest = ' cgi_content_charset ' ,
help = u " En mode CGI, forcer l ' encoding de contenu avec lequel servir le fichier. " )
OP . add_option ( ' --cgi-content-disposition ' , ' --cgicd ' , dest = ' cgi_content_disposition ' ,
help = u " En mode CGI, forcer la disposition de contenu avec lequel servir le fichier. Les valeurs valides sont attachment (par défaut), inline, none " )
2015-12-15 10:05:45 +04:00
OP . add_option ( ' -P ' , ' --cgi-path-info ' , dest = ' path_info ' ,
2015-12-07 12:26:37 +04:00
help = u " Spécifier un chemin d ' un fichier à télécharger. En mode CGI, cette valeur est prise dans la variable d ' environnement PATH_INFO " )
2015-12-15 10:05:45 +04:00
OP . add_option ( ' -Q ' , ' --cgi-query-string ' , dest = ' query_string ' ,
help = u " Spécifier la valeur de QUERY_STRING pour provisionner l ' environnement du fichier résultat. En mode CGI, cette valeur est prise dans la variable d ' environnement QUERY_STRING. " )
OP . add_option ( ' -N ' , ' --cgi-script-name ' , dest = ' script_name ' ,
help = u " Spécifier la valeur de SCRIPT_NAME pour provisionner l ' environnement du fichier résultat. En mode CGI, cette option est automatiquement activée si QUERY_STRING contient le paramètre script_name=SCRIPT_NAME, la valeur par défaut étant la valeur de la variable d ' environnement SCRIPT_NAME. "
+ u " \n L ' ordre de priorité pour le calcul de cette valeur est: d ' abord le paramètre script_name dans QUERY_STRING, puis l ' option de la ligne de commande, enfin la valeur de la variable d ' environnement " )
OP . add_option ( ' -G ' , ' --cgi-param-group ' , dest = ' select_group ' ,
help = u " Sélectionner le groupe spécifié. Seuls les fichiers du groupe sont affichés. En mode CGI, cette option est automatiquement activée si QUERY_STRING contient le paramètre group=GROUP. "
2015-12-15 11:01:27 +04:00
+ u " \n S ' il n ' y a qu ' un seul groupe, il est automatiquement sélectionné. "
2015-12-15 10:05:45 +04:00
+ u " \n L ' ordre de priorité pour le calcul de cette valeur est: d ' abord le paramètre group dans QUERY_STRING, puis l ' option de la ligne de commande " )
OP . add_option ( ' -t ' , ' --cgi-param-xslt ' , dest = ' xslt ' ,
help = u " Ajouter le chemin vers la feuille de style XSLT dans le flux XML généré. En mode CGI, cette option est automatiquement activée si QUERY_STRING contient le paramètre xslt=XSLT. "
+ u " \n L ' ordre de priorité pour le calcul de cette valeur est: d ' abord le paramètre xslt dans QUERY_STRING, puis l ' option de la ligne de commande " )
2016-02-07 23:03:38 +04:00
OP . add_option ( ' -i ' , ' --include ' , dest = ' includes ' , action = ' append ' ,
help = u " Spécifier un paramètre à inclure pour construire la valeur du chemin xpath /result/env/query_string dans le résultat. Il est possible de spécifier plusieurs paramètres en les séparant par des virgules. Par défaut, prendre tous les paramètres de la requête. " )
OP . add_option ( ' -x ' , ' --exclude ' , dest = ' excludes ' , action = ' append ' ,
help = u " Spécifier un paramètre à exclure pour construire la valeur du chemin xpath /result/env/query_string dans le résultat. Il est possible de spécifier plusieurs paramètres en les séparant par des virgules. " )
OP . add_option ( ' -p ' , ' --prefix ' , dest = " prefix " ,
help = u " Ajouter les paramètres supplémentaires spécifiés à /result/env/query_string. " )
2015-12-07 12:26:37 +04:00
env = dict ( filters = [ ] , filter = None )
o , args = OP . parse_args ( )
filters = env [ ' filters ' ]
filter = env [ ' filter ' ]
2015-12-15 10:05:45 +04:00
sortby = o . sortby
2015-12-07 12:26:37 +04:00
environ = os . environ
2015-12-15 10:05:45 +04:00
cgi_mode = o . cgi_mode
2016-06-08 15:05:41 +04:00
cgi_cache = o . cgi_allow_cache and True or False
cgi_content_type = o . cgi_content_type
cgi_content_charset = o . cgi_content_charset or ' utf-8 '
cgi_content_disposition = o . cgi_content_disposition or ' attachment '
if cgi_content_disposition in ( ' attachment ' , ' inline ' ) : pass
elif cgi_content_disposition == ' none ' : cgi_content_disposition = None
else :
if cgi_mode :
if not cgi_cache : cgi_nocache ( )
print " Content-Type: text/plain; charset=utf-8 "
print
print " %s : Disposition de contenu invalide. Ce soit être attachment, inline ou none " % cgi_content_disposition
sys . exit ( 1 )
2016-02-07 23:03:38 +04:00
cgi_query_string = o . query_string
if cgi_query_string is not None : environ [ ' QUERY_STRING ' ] = cgi_query_string
2015-12-15 10:05:45 +04:00
if cgi_mode is None :
cgi_mode = ' REQUEST_METHOD ' in environ
2015-12-07 12:26:37 +04:00
if cgi_mode :
2015-12-15 10:05:45 +04:00
import cgi ; form = cgi . FieldStorage ( )
cgi_path_info = o . path_info
if cgi_path_info is None and ' PATH_INFO ' in environ : cgi_path_info = environ . get ( ' PATH_INFO ' )
2016-02-07 23:03:38 +04:00
if cgi_query_string is None and ' QUERY_STRING ' in environ : cgi_query_string = environ . get ( ' QUERY_STRING ' )
2015-12-15 10:05:45 +04:00
cgi_script_name = None
if ' script_name ' in form and cgi_script_name is None : cgi_script_name = form . getfirst ( " script_name " )
if cgi_script_name is None : cgi_script_name = o . script_name
if cgi_script_name is None and ' SCRIPT_NAME ' in environ : cgi_script_name = environ . get ( ' SCRIPT_NAME ' )
cgi_select_group = None
if ' group ' in form and cgi_select_group is None : cgi_select_group = form . getfirst ( " group " )
if cgi_select_group is None : cgi_select_group = o . select_group
cgi_xslt = None
if ' xslt ' in form and cgi_xslt is None : cgi_xslt = form . getfirst ( " xslt " )
if cgi_xslt is None : cgi_xslt = o . xslt
else :
cgi_path_info = o . path_info
cgi_query_string = o . query_string
cgi_script_name = o . script_name
cgi_select_group = o . select_group
cgi_xslt = o . xslt
2015-12-07 12:26:37 +04:00
if cgi_path_info is not None : cgi_path_info = path . split ( cgi_path_info ) [ 1 ]
if filter is not None : filters . append ( filter )
if filter is None and not filters : filters . append ( default_filter )
if len ( args ) == 0 : args = [ ' . ' ]
if sortby is None : sortby = ' mtime:DN '
files = [ ]
for basedir in args :
files . extend ( find_files ( basedir , filters ) )
sortfunc = build_sortfunc ( sortby )
files = sort_files ( files , sortfunc )
fgroups = build_fgroups ( files )
if cgi_mode and fgroups and cgi_select_group is None :
# En mode CGI, s'il y a plusieurs groupes, ne pas afficher la liste
2015-12-15 11:01:27 +04:00
# complète, mais requérir la sélection d'un groupe, sauf s'il n'y a
# qu'une seul groupe défini
if len ( fgroups ) == 1 : cgi_select_group = fgroups [ 0 ]
else : cgi_select_group = ' '
2015-12-07 12:26:37 +04:00
if cgi_select_group is not None :
files = filter_files ( files , cgi_select_group )
if cgi_path_info :
file = select_file ( files , cgi_path_info )
if file is None :
if cgi_mode :
2015-12-24 11:14:57 +04:00
if not cgi_cache : cgi_nocache ( )
2016-06-08 15:05:41 +04:00
print " Content-Type: text/plain; charset=utf-8 "
2015-12-07 12:26:37 +04:00
print
print " Impossible de trouver le fichier %s " % cgi_path_info
2016-06-08 15:05:41 +04:00
sys . exit ( 1 )
2015-12-07 12:26:37 +04:00
else :
if cgi_mode :
2015-12-24 11:14:57 +04:00
if not cgi_cache : cgi_nocache ( )
2015-12-07 14:59:20 +04:00
dlname = file . dlname or file . name
2016-06-08 15:05:41 +04:00
ctype = cgi_content_type
if ctype is None : ctype = file . has_key ( ' type ' ) and file . type or None
2015-12-07 14:59:20 +04:00
if ctype is None : ctype , encoding = mimetypes . guess_type ( dlname , False )
2015-12-07 12:26:37 +04:00
if ctype is None : ctype = " application/octet-stream "
2016-06-08 15:05:41 +04:00
print " Content-Type: %s ; charset= %s " % ( ctype , cgi_content_charset )
if cgi_content_disposition is not None :
print " Content-Disposition: %s ; filename= \" %s \" " % ( cgi_content_disposition , dlname )
2015-12-07 12:26:37 +04:00
print
inf = open ( file . pf , ' rb ' )
try : shutil . copyfileobj ( inf , sys . stdout )
finally : inf . close ( )
2016-06-08 15:05:41 +04:00
sys . exit ( 0 )
2015-12-07 12:26:37 +04:00
if cgi_mode :
2015-12-24 11:14:57 +04:00
if not cgi_cache : cgi_nocache ( )
2016-06-08 15:05:41 +04:00
print " Content-Type: text/xml; charset=utf-8 "
2015-12-07 12:26:37 +04:00
print
2016-02-07 23:03:38 +04:00
print_files ( files , fgroups , cgi_select_group , cgi_script_name , cgi_xslt ,
cgi_query_string , o . includes , o . excludes , o . prefix )
2015-12-07 12:26:37 +04:00
if __name__ == ' __main__ ' :
run_cgilsxml ( )