Ceci est une ancienne révision du document !
Définir des fonctions simples pour coder des téléchargements ftp dans les 2 sens (download / upload) en utilisant le module Python 'ftplib'
import ftplib def connexionftp(adresseftp, nom='anonymous', mdpasse='anonymous@', passif=True): """connexion au serveur ftp et ouverture de la session - adresseftp: adresse du serveur ftp - nom: nom de l'utilisateur enregistré ('anonymous' par défaut) - mdpasse: mot de passe de l'utilisateur ('anonymous@' par défaut) - passif: active ou désactive le mode passif (True par défaut) retourne la variable 'ftplib.FTP' après connexion et ouverture de session """ ftp = ftplib.FTP() ftp.connect(adresseftp) ftp.login(nom, mdpasse) ftp.set_pasv(passif) return ftp
Pour fermer la connexion, il y a 2 méthodes:
En fait, on pourrait proposer:
def fermerftp(ftp): """ferme la connexion ftp - ftp: variable 'ftplib.FTP' sur une connexion ouverte """ try: ftp.quit() except: ftp.close()
def downloadftp(ftp, ficftp, repdsk='.', ficdsk=None): """télécharge le fichier ficftp du serv. ftp dans le rép. repdsk du disque - ftp: variable 'ftplib.FTP' sur une session ouverte - ficftp: nom du fichier ftp dans le répertoire courant - repdsk: répertoire du disque dans lequel il faut placer le fichier - ficdsk: si mentionné => c'est le nom qui sera utilisé sur disque """ if ficdsk==None: ficdsk=ficftp with open(os.path.join(repdsk, ficdsk), 'wb') as f: ftp.retrbinary('RETR ' + ficftp, f.write)
def uploadftp(ftp, ficdsk, ficftp=None): """télécharge le fichier ficdsk du disque dans le rép. courant du Serv. ftp - ftp: variable 'ftplib.FTP' sur une session ouverte - ficdsk: nom du fichier disque avec son chemin - ficftp: si mentionné => c'est le nom qui sera utilisé sur ftp """ repdsk, ficdsk2 = os.path.split(ficdsk) if ficftp==None: ficftp = ficdsk2 with open(ficdsk, "rb") as f: ftp.storbinary("STOR " + ficftp, f)
Connaître le répertoire courant sur le serveur ftp
repftp = ftp.pwd()
Changer de répertoire sur le serveur ftp
ftp.cwd(repftp)
Obtenir la liste du contenu d'un répertoire sur le serveur ftp
print ftp.nlst() => liste pour le répertoire courant print ftp.nlst(repftp) => liste pour le répertoire repftp
Le problème de cette liste, c'est que les noms de sous-répertoires et les noms de fichiers sont retournés sans distinction, et qu'il n'y a pas de moyen simple de les distinguer.
Solution: passer par la méthode 'ftp.dir()'. Voilà comment on utilise cette méthode:
lignes = [] ftp.dir(repftp, lignes.append) # si repftp n'est pas cité: c'est le répertoire par défaut qui est pris for ligne in lignes: print ligne
Ce qui affiche (par exemple):
drwxrwsr-x 3 utilisateur site1396 4096 Apr 13 07:05 . drwxrwsr-x 3 utilisateur site1396 24 Jan 12 12:08 .. -rw-rw-r-- 1 utilisateur site1396 2853888 Jan 17 14:43 basesql.db3 -rw-rw-r-- 1 utilisateur site1396 2852784 Jan 17 15:07 basesql_sav1.db3 drwxrwsr-x 2 utilisateur site1396 6 Apr 12 10:46 repertoire -rw-rw-r-- 1 utilisateur site1396 2851325 Apr 13 07:06 basesql_sav2.db3
Remarque: les répertoires '.' et '..' ne sont renvoyés que pour les serveurs ftp sous Linux (pas sous Windows)
On a donc un moyen simple de savoir si un nom est un répertoire: si le 1er caractère de la ligne est 'd': c'est un répertoire. Sinon, c'est un fichier.
Voilà une fonction qui renvoie la liste des sous-répertoires, suivie de la liste des fichiers d'un répertoire donné du serveur ftp:
def listerepftp(ftp, repftp=None): """renvoie les noms de répertoires et de fichiers du répertoire sur ftp - ftp: variable 'ftplib.FTP' sur une session ouverte - repftp: répertoire sur ftp. Si absent => répertoire courant retourne la liste des sous-répertoires, suivie de la liste des fichiers """ lignes, nomsfic, nomsrep = [], [], [] if repftp==None: ftp.dir(lignes.append) else: ftp.dir(repftp, lignes.append) for ligne in lignes: liste = ligne.split() if liste[0][0]=='d': nom = liste[-1] if nom!='.' and nom!='..': nomsrep.append(nom) else: nomsfic.append(liste[-1]) return nomsrep, nomsfic
Utilisation: liste des répertoires et des fichiers du répertoire courant (reprise de l'exemple précédent):
repftps, ficftps = listerepftp(ftp) print repftps ['repertoire'] print ficftps ['basesql.db3', 'basesql_sav1.db3', 'basesql_sav2.db3'] print 'basesql.db3' in ficftps True
Connaitre la taille d'un fichier du serveur ftp.
Attention:
# ficftp = fichier dont on veut connaître la taille ftp.sendcmd('TYPE I') # passer en mode binaire (sinon, erreur avec size) tailleftp = ftp.size(ficftp) # donne la taille en octets if tailleftp != None: print tailleftp else: print "méthode 'ftp.size()' non supportée par le serveur ftp"
Il y a d'autres méthodes courantes: créer / effacer un répertoire, renommer, etc… ⇒ Voir la doc.
On voit qu'avec ces différentes fonctions et méthodes, on pourrait facilement télécharger dans les 2 sens (download / upload) des arborescences de répertoires!
Amusez-vous bien!