| HTTPFileUploader |
UserPreferences |
| Wiki Python Fr | FrontPage | RecentChanges | TitleIndex | WordIndex | SiteNavigation | HelpContents | moin.sf.net |
Comme j'ai un peu galéré pour trouver une classe python pour uploader des fichiers sur un serveur php, j'en ai créé une à partir de fonctions glanées sur le net.
Contenu du fichier upload/uploader.php (placer ce fichier sur le serveur)
<?php
// Scan de files list
foreach ($_FILES as $key => $value)
{
// Get the target filename
$target_path = $HTTP_POST_VARS["target_path"].'/'.$value['name'];
// Write target filename
if(copy($value['tmp_name'],$target_path))
{
echo "OK";
}
else
{
echo "KO";
}
}
?>
Contenu du fichier upload/index.html (placer ce fichier sur le serveur)
<html>
<body>
<form enctype="multipart/form-data" action="uploader.php" method="POST">
<input name="target_path" type="hidden" value="." />
<label>Choisir fichier : </label>
<input name="uploader" type="file" /><br />
<input type="submit" value="Valider" />
</form>
</body>
</html>
Pour avoir un accés par mot de passe, ajoutez le fichier suivant upload/.htaccess (lire la notice d'apache pour configurer correctement les mots de passes) (placer ce fichier sur le serveur)
AuthUserFile /var/www/.htpasswd AuthGroupFile /dev/null AuthName "ByPassword" AuthType Basic require user UserName
Fichier
HTTPFileUploader.py Classe python pour uploader les fichiers sur le serveur (placer ce fichier sur le poste client)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | class HTTPFileUploader:
""" HTTP file uploader """
def __init__(self, host, port=80):
""" Constructor """
from httplib import HTTP
self.host = host
self.port = port
self.user = None
self.password = None
self.page = "upload/uploader.php"
self.fields = {}
self.setTargetPath('.')
self.http = HTTP(self.host, self.port)
def setLogin(self, user, password):
""" Set user and password """
self.user = user
self.password = password
def setPage(self, selector = 'upload/uploader.php'):
""" Select the upload page """
self.page = selector
def setField(self, name, value):
""" Add fields in http """
self.fields[name] = value
def setTargetPath(self, path):
""" Change the target path """
self.fields["target_path"] = path
def uploadFile(self, sourceFilename):
""" Upload file on http server """
from string import replace
from base64 import encodestring
files = (("uploader",sourceFilename,open(sourceFilename,"rb").read()),)
content_type, body = self.encode_multipart_formdata(self.fields, files)
self.http.putrequest('POST', self.page)
if self.user != None and self.password != None:
self.http.putheader("AUTHORIZATION", "Basic %s" % replace(
encodestring("%s:%s" % (self.user, self.password)),
"\012", ""))
self.http.putheader('Content-Type', content_type)
self.http.putheader('Content-Length', str(len(body)))
self.http.endheaders()
self.http.send(body)
errcode, errmsg, headers = self.http.getreply()
result = self.http.file.read()
if result.strip() == "OK":
return True
else:
return False
def encode_multipart_formdata(self, fields, files):
"""
fields is a sequence of (name, value) elements for regular form fields.
files is a sequence of (name, filename, value) elements for data to be uploaded as files
Return (content_type, body) ready for httplib.HTTP instance
"""
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for key, value in fields.items():
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for file in files:
key = file[0]
filename = file[1]
if len(file) > 2:
value = file[2]
else:
value = None
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
L.append('Content-Type: %s' % self.get_content_type(filename))
L.append('Content-Transfer-Encoding: binary')
if value:
L.append('')
L.append(value)
else:
L.append('')
fp = open(filename, 'rb')
L.append(fp.read())
fp.close()
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
def get_content_type(self, filename):
import mimetypes
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
class HTTPSFileUploader(HTTPFileUploader):
""" HTTPS file uploader """
def __init__(self, host, port=443):
""" Constructor """
from httplib import HTTPS
HTTPFileUploader.__init__(self, host, port)
self.http = HTTPS(self.host, self.port) |
***IMPORTANT***
si votre serveur web utilise des "virtual host" et que vous specifiez "www.example.com" comme Hostname, vous devez absolument mettre le URL complet comme ceci uploader.setPage('http://www.example.com/upload/uploader.php') sinon votre serveur web cherchera dans le document root de votre "default virtual host" et ne trouvera pas votre script d'upload.
Exemple pour un serveur http sans accés par mot de passe
1 2 3 4 5 | from HTTPFileUploader import *
if __name__ == '__main__':
uploader = HTTPFileUploader("192.168.1.156") # Hostname du serveur
uploader.setPage('/upload/uploader.php') # Choix de la page d'upload
print uploader.uploadFile('d://toto.txt') |
Exemple pour un serveur https avec accés par mot de passe
1 2 3 4 5 6 7 | from HTTPFileUploader import *
if __name__ == '__main__':
uploader = HTTPSFileUploader("192.168.1.156")
uploader.setPage('/upload/uploader.php')
uploader.setLogin('user','password') # Insert your login password
#uploader.setTargetPath('titi') <- Pour configurer un chemin de destination des fichiers sur le serveur
print uploader.uploadFile('d://toto.txt') |
Exemple pour uploader plusieurs fichiers d'un seul coup
1 2 3 4 5 6 7 | from HTTPFileUploader import *
if __name__ == '__main__':
uploader = HTTPSFileUploader("192.168.1.156")
uploader.setPage('/upload/uploader.php')
from glob import glob
for file in glob("*.*"):
print file,uploader.uploadFile(file) |