cgiupload: possibilité de filtrer sur le nom du fichier ou son type de contenu
This commit is contained in:
parent
fae2111e71
commit
eac94a7f32
|
@ -3,30 +3,49 @@
|
|||
|
||||
u"""Ce script est prévu pour être utilisé dans un script CGI.
|
||||
Il enregistre les fichiers uploadés dans le répertoire spécifié, et éventuellement lance une commande avec comme argument les fichiers enregistrés.
|
||||
|
||||
Retourner 0 si tous les fichiers ont été traités, 1 si au moins un fichier a été rejeté, 2 si aucun fichier ne correspondait (ou si aucun fichier n'a été fourni)
|
||||
"""
|
||||
|
||||
import sys, os, types, cgi, tempfile
|
||||
import sys, os, re, types, cgi, tempfile
|
||||
from os import path
|
||||
|
||||
cgitb = None # marqueur pour savoir si le module cgitb a été importé
|
||||
#import cgitb; cgitb.enable()
|
||||
|
||||
class FileManager(object):
|
||||
def __init__(self, destdir=None, parse_env=True):
|
||||
fileinfos = None
|
||||
tries = None
|
||||
count = None
|
||||
destdir = None
|
||||
spec = None
|
||||
type = None
|
||||
exitcode = None
|
||||
|
||||
def __init__(self, destdir=None, spec=None, type=None, parse_env=True):
|
||||
if destdir is None: destdir = '/tmp'
|
||||
self.fileinfos = []
|
||||
self.tries = 0
|
||||
self.count = 0
|
||||
self.destdir = destdir
|
||||
if spec is not None: spec = re.compile(spec)
|
||||
self.spec = spec
|
||||
self.type = type
|
||||
if parse_env: self.parse_env()
|
||||
|
||||
def parse_env(self):
|
||||
class FieldStorage(cgi.FieldStorage):
|
||||
def make_file(self, binary=None):
|
||||
return self.fm._new_file(self)
|
||||
outf = self.fm._new_file(self)
|
||||
if outf is not None: return outf
|
||||
return cgi.FieldStorage.make_file(self, binary)
|
||||
FieldStorage.fm = self
|
||||
self.form = FieldStorage()
|
||||
|
||||
def _new_file(self, form):
|
||||
self.tries += 1
|
||||
if self.spec is not None and self.spec.match(form.filename) is None: return None
|
||||
if self.type is not None and self.type != form.type: return None
|
||||
fp = path.join(self.destdir, 'upload%i' % self.count)
|
||||
outf = open(fp, 'w+b')
|
||||
self.count += 1
|
||||
|
@ -45,11 +64,20 @@ class FileManager(object):
|
|||
finally:
|
||||
if close: outf.close()
|
||||
|
||||
def exitcode(self):
|
||||
if self.count == 0: return 2
|
||||
elif self.count != self.tries: return 1
|
||||
else: return 0
|
||||
|
||||
# Analyser les options
|
||||
from optparse import OptionParser
|
||||
parser = OptionParser(usage=u"\n\t%prog [options]\n\t%prog [options] -c command [args]", description=__doc__)
|
||||
parser.add_option('-d', '--destdir', dest='destdir',
|
||||
help=u"Spécifier le répertoire de destination des fichiers uploadés. Ce répertoire est créé si nécessaire.")
|
||||
parser.add_option('-e', '--spec', dest='spec',
|
||||
help=u"N'accepter que des fichiers dont le nom correspond à l'expression régulière spécifiée")
|
||||
parser.add_option('-t', '--type', dest='type',
|
||||
help=u"N'accepter que des fichiers dont le type mime correspond à la valeur spécifiée")
|
||||
parser.add_option('-p', '--printcsv', action='store_true', dest='printcsv',
|
||||
help=u"Afficher la liste des fichiers uploadés au format CSV. Chaque ligne est de la forme 'name,value,file,type' où name est le nom du champ dans le formulaire http, value le nom du fichier tel qu'il a été fourni par le client, file le chemin complet vers le fichier uploadé, et type le type mime du contenu.")
|
||||
parser.add_option('-c', '--cmd', action='store_true', dest='cmd',
|
||||
|
@ -84,7 +112,7 @@ if o.printcsv is None and o.cmd is None:
|
|||
if o.cmd and o.clear is None:
|
||||
o.clear = True
|
||||
|
||||
fm = FileManager(o.destdir)
|
||||
fm = FileManager(o.destdir, o.spec, o.type)
|
||||
|
||||
if o.printcsv:
|
||||
fm.write_csv(sys.stdout)
|
||||
|
@ -112,3 +140,5 @@ if o.clear:
|
|||
for fi in fm.fileinfos:
|
||||
try: os.remove(fi[0])
|
||||
except: pass
|
||||
|
||||
sys.exit(fm.exitcode())
|
||||
|
|
Loading…
Reference in New Issue