Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Avant toute programmation, je tiens à préciser plusieurs petites choses.
Tout d'abord, sachez que je ne suis pas un pro de Python,
il y a donc certainement une meilleure façon de coder que celle donnée ici.
Dans ce tuto, vous apprenez tout d'abord à vous servir de la librairie, et non à coder.
D'ailleurs, je dois vous signaler que si vous n'avez pas lu le tuto
Apprenons Python (ou équivalent), vous devez aller le lire

.
Sans les bases expliquées là-bas, il vous sera impossible de comprendre le moindre code de ce tutoriel

.
Bon, maintenant, je vais essayer de vous donner envie de lire la suite, en vous donnant la liste des choses que vous saurez faire à la fin de votre lecture :
- se connecter à un serveur FTP
- envoyer un fichier sur le serveur
- créer un dossier
- renommer un fichier, ou un dossier
- supprimer un fichier, ou un dossier
- changer le répertoire courant
- lister tous les fichiers et dossiers d'un répertoire
- envoyer une commande au serveur (sans passer par des fonctions Python)
- recevoir les messages renvoyés par le serveur après chaque action.
Comme vous pouvez le constater, la liste est longue !
Mais attention : les fonctions expliquées sur cette page sont les plus générales, il en existe plusieurs autres mais de moindre importance. Afin de ne pas vous embrouiller, je ne vais pas vous en parler ici

.
Toutefois, si vous souhaitez voir la liste complète :
DOC sur la librairie (en anglais).
À la fin du tutoriel, vous aurez un script qui permettra d'exécuter toutes ces commandes, mais il ne vous sera donné que vers la fin.
Quand j'expliquerai comment faire telle ou telle action, je ne vous donnerai que le strict minimum en code.
Dans cette partie, je vous expliquerai en détail comment on utilise la fonction
N ou
Y.
J'ai décidé d'effectuer cela par "mini-chapitre", c'est-à-dire que chaque fonction aura son titre

.
Grâce à cette mise en page, ce tuto vous sera utile comme référence lorsque vous coderez

.
La connexion
Cette étape est la plus importante, car toutes les autres découlent de la connexion !
Rassurez-vous, son utilisation est on ne peut plus simple

.
Code : Python1
2
3
4 | host = "votre_host.com" # adresse du serveur FTP
user = "votre_pseudo" # votre identifiant
password = "votre password" # votre mot de passe
connect = ftp.ftplib(host,user,password) # on se connecte
|
Je ne vais pas détailler ce code, tout est dans les commentaires

.
Déconnexion
Étape tout aussi importante, la déconnexion. À vrai dire, théoriquement, si vous fermez la console, la connexion se ferme. Mais dans de gros scripts, il vaut mieux la fermer.
Un inconvénient tout de même : une fois la connexion fermée, on ne peut plus la rouvrir !
Code : Python1 | connect.quit() # où "connect" est le nom de la variable dans laquelle vous avez déclaré la connexion !
|
Envoyer un fichier
Cette commande est certainement l'une des plus utilisées !
Encore une fois, elle est très simple.
Pour l'adresse du fichier, s'il n'est pas dans le dossier courant (celui où est votre script), vous devrez indiquer son adresse complète (C:\Dossier\Dossier\Fichier.py, par exemple).
Voici les lignes à insérer pour envoyer un fichier :
Code : Python1
2
3
4 | fichier = "C:\Python_exercices\ftp.py"
file = open(fichier, 'rb') # ici, j'ouvre le fichier ftp.py
connect.storbinary('STOR '+fichier, file) # ici (où, encore, connect est la variable de la connexion), j'indique le fichier à envoyer
file.close() #on ferme le fichier
|
Comme vous le voyez, à la 3e ligne du code, on met
'STOR'+fichier.
Pourquoi on met ça ??

Bonne question. Sachez que
'STOR' est une commande FTP (et non Python). Ici, on indique au serveur quelle action on va effectuer, c'est très important. J'ai effectué juste derrière une concaténation ; à la fin, cela donnera ça :
STOR C:\Python_exercices\ftp.py 
.
État de la connexion
Lorsque l'on se connecte au serveur, il nous renvoie un message. Avec la fonction que je vais donner ci-dessous, nous allons récupérer ce message pour éventuellement l'afficher après

.
Code : Python1
2 | etat = connect.getwelcome() # grâce à la fonction getwelcome(), on récupère le message "de bienvenue"
print "Etat : ",state # ici, on l'affiche, cette ligne est facultative mais si vous ne l'affichez pas, c'est bête :p
|
Lister les fichiers & dossiers du répertoire
Après plusieurs actions effectuées sur le serveur, vous avez envie de voir si tout s'est bien déroulé ?
Pour cela, il vous suffira de lister le répertoire, avec la fonction
dir().
Code : Python1
2 | rep = connect.dir() # on récupère le listing
print rep # on l'affiche dans la console
|
Personnellement, je vous conseille d'afficher le listing du répertoire après chaque action de renommage, effaçage, ... Cela vous permettra de voir si tout s'est bien passé

.
Renommer un fichier, ou un dossier
Parmi les actions que j'ai citées dans la première partie, il y avait "Renommer un fichier, ou un dossier". Ici, je vous explique comment le faire

.
Code : Python1
2
3 | renommer = raw_input('Tapez le nom du fichier / dossier à renommer : ') # ici, vous devez entrer le nom du fichier à renommer, par exemple fichier.txt ou le nom du dossier sans les /
renommer_en = raw_input('Le renommer en : ') # le nom de sortie, vous pouvez aussi changer l'extension
rename = connect.rename(renommer, renommer_en) # maintenant, on effectue vraiment l'action
|
J'ai rajouté deux
raw_input() afin de faciliter votre travail dans la console, mais la fonction pour renommer tient sur une seule ligne

.
Effacer un fichier
Après "renommer un fichier", il y a évidemment "effacer un fichier"

.
Ici, c'est encore plus simple (si c'est possible

), il faut juste indiquer le nom !
Code : Python1
2 | effacer = raw_input('Tapez le nom du fichier à effacer : ') # vous indiquez dans la console le fichier, ex. : fichier.py
delete = connect.delete(effacer) # là, c'est la fonction en elle-même
|
Créer un répertoire
Cela ne sert à rien d'expliquer en trente lignes, je vous laisse lire le code

.
Code : Python1
2 | rep = raw_input('Tapez le nom du répertoire à créer : ') # entrez le nom du répertoire, sans les slash ( / )
repertoire = connect.mkd(rep) # la fonction pour le créer, "mkd()"
|
Supprimer un répertoire
Pour supprimer un dossier, ce n'est pas la même fonction que pour supprimer un fichier. Ça peut paraître logique, mais je tiens à le signaler.
Voici le code :
Code : Python1
2 | supprimer = raw_input('Tapez le nom du répertoire à supprimer : ') # entrez le nom du dossier
delete_dir = connect.rmd(supprimer) # la fonction rmd supprime le dossier
|
Envoyer une fonction FTP au serveur
Quand vous ouvrez votre client FTP (par exemple Filezilla), il a une partie qui concerne les commandes envoyées au serveur (ce n'est peut-être pas présent sur tous les clients FTP).
Quand vous changez de répertoire, vous pouvez voir des lignes défiler, avec des noms bizarres...
Et c'est quoi, ces noms ?
Je ne vous le dirai pas, nananèreuh
.
Ce sont des commandes FTP ! Juste que là, Python nous servait d'intermédiaire entre le serveur et nous. Mais qu'envoie Python au serveur ? Pas des fonctions Python, quand même

?
Eh bien non, tout simplement des commandes, c'est-à-dire des noms barbares du type "
CWD".
Ici, je vais vous décrire la marche à suivre pour en envoyer, mais point vous lister toutes les commandes existantes !
Code : Python1
2 | commande = raw_input('Tapez la commande à effectuer : ') # entrez la commande à effectuer
resultat = connect.sendcmd(commande) # on envoie la commande au serveur : si elle n'est pas bonne, Python plantera
|
Je vous donne juste un exemple de commande FTP, qui vous servira forcément :
CWD rep.
Elle sert à changer le répertoire. Par exemple, pour aller au répertoire "Admin" de votre site :
Code : Python1 | connect.sendcmd('CWD Admin')
|
Recevoir la réponse du serveur suite à une action
Rassurez-vous, rien de plus simple à faire

.
Imaginons que vous avez cette ligne en python :
Code : Python1 | rename = connect.rename('Admin', 'Administration') # action de renommage
|
Il vous suffira d'afficher la variable
rename :
Code : Python1
2 | rename = connect.rename('Admin', 'Administration') # action de renommage
print rename # on affiche la réponse du serveur
|
Arrêter le transfert d'un fichier
Il existe une fonction (incluse à la librairie
ftplib) qui permet de stopper (ou "d'avorter") le transfert d'un fichier.
Je vous donne la fonction, mais je vous indique que dans la partie suivante, dans le script que nous allons réaliser, elle n'y sera pas. En effet, lors du traitement d'une commande (donc ici, l'envoi d'un fichier), le script ne nous permet pas de renvoyer une autre commande ; du coup, mieux vaut fermer la fenêtre de la console, cela aura le même effet

.
Code : Python1 | connect.abort() # abort() avorte le transfert
|
C'est la fin de cette partie !
Dans la dernière partie (c'est-à-dire la suivante), je vais vous montrer comment faire pour mettre nos connaissances à profit en faisant un script Python contenant toutes les fonctions vues ensemble

.
Dans cette dernière partie, je vous propose de faire un petit programme et toutes les fonctions que l'on a vues y seront.
Dans ce script, nous allons utiliser une notion importante,
les décorateurs.
En gros, grâce à eux, vous pourrez appeler une fonction à l'initialisation d'une autre.
C'est un peu compliqué à expliquer ici : je préfère vous donner un lien vers un tutoriel traitant de ce sujet :
Décorateurs.
Bon : maintenant, passons au vif du sujet.
Nous allons créer une fonction pour chaque action possible, et auxiliairement une aide pour chaque fonction

.
À l'entrée des commandes dans la console, on effectuera deux tests principaux :
- si la fonction existe
- et si oui, si l'on a précisé des paramètres.
Pour cela, on utilisera évidemment (c'est tellement plus simple

)
try,
except et compagnie.
Remarque : je vous mets le script directement, sans montrer chaque étape avec son petit bout de code. Ce choix est justifié : toutes les fonctions sont ci-dessus et dans cette partie, je vous montre seulement un exemple d'utilisation

.
Voici la bête :
Code : Python 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 | #!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ftp.py
# FTP CLI interface
#
# Copyright (C) 2007 delroth <root@delroth.is-a-geek.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import ftplib as ftp # on importe la librairie et on la renomme juste pour le script en "ftp"
commands = {} # on crée le dictionnaire qui contiendra toutes les commandes & descriptions
def connection(value=None):
if value == None:
return getattr(connection, 'value', None)
else:
connection.value = value
return value
def ftpcommand(nom_court, description): # fonction pour ajouter la fonction au dictionnaire commands
def decorator(function):
global commands # on n'oublie pas de mettre le dico commands global, sinon ça va en redéfinir un
commands[nom_court] = (function, description) # on ajoute au dictionnaire
return function
return decorator
@ftpcommand("help", "Affiche l'aide des commandes") # ici on appelle le décorateur : il va s'occuper d'ajouter la fonction help avec sa description au dictionnaire commands
def help(): # définition de la commande, juste après @ftpcommand car ON EST OBLIGÉS
global commands
keys = commands.keys() # on récupère les clés == fonctions dans notre cas
keys.sort() # on trie par ordre alphabétique :)
for i in keys:
print i+" : "+commands[i][1] # on affiche le nom de la fonction et sa description
@ftpcommand("connect", "Se connecte au serveur. Syntaxe: connect <host> <user> <password>")
def connect(host, user, password):
connection(ftp.FTP(host, user, password))
@ftpcommand("ls", "Liste le contenu du répertoire actuel")
def ls():
print connection().dir() # on affiche le listing du répertoire
@ftpcommand("deco", "Se déconnecte du serveur. Syntaxe: deco")
def deco():
connection().quit() # la déconnexion avec quit()
@ftpcommand("envoi", "Envoie un fichier au serveur. Syntaxe: envoi <adresse_fichier>")
def envoi(adresse_fichier):
fichier = adresse_fichier
file = open(fichier, 'rb') # on ouvre le fichier en mode "read-binary"
connection().storbinary('STOR '+fichier, file) # envoi
file.close() # fermeture du fichier
@ftpcommand("rename", "Renomme un fichier. Syntaxe: rename <avant> <apres>")
def rename(avant, apres):
renommer, renommer_en = avant, apres
rename = connection().rename(renommer, renommer_en) # on renomme
@ftpcommand("efface", "Efface un fichier. Syntaxe : efface <fichier>")
def efface(fichier):
effacer = fichier
delete = connection().delete(effacer) # on efface
@ftpcommand("creer_rep", "Crée un répertoire (dossier). Syntaxe : creer_rep <nom>")
def creer_rep(nom):
rep = nom
repertoire = connection().mkd(rep) # on crée le répertoire
@ftpcommand("sup_rep", "Supprimer un répertoire (dossier). Syntaxe : sup_rep <nom>")
def sup_rep(nom):
supprimer = nom
delete_dir = connection().rmd(supprimer) # on supprime le répertoire
@ftpcommand("cmd", "Envoie une commande au serveur. Syntaxe: cmd <commande>")
def cmd(commande):
resultat = connection().sendcmd(commande) # on envoi la commande
# un petit message à propos de la license du script :)
welcome = '''ftp.py version 1.0, Copyright (C) 2007
ftp.py comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
welcome to redistribute it under certain conditions; see the GNU General Public
License for more details: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html'''
def main():
global commands
print welcome # affichage du message ci-dessus
def command_to_argv(cmd):
argv = cmd.split(' ') # on met dans une liste les différents arguments
argv_size = len(argv) # on compte le nombre de paramètres
i = 0 # on initialise le compteur
while i < argv_size:
if argv[i].endswith('\\') and i + 1 != argv_size: # si c'est un nom de fichier du type : test\ 1.py
argv[i] = argv[i][:-1] + " " + argv[i + 1] # on ajoute le "1.py" à "test", ce qui fait "test 1.py"
del argv[i + 1]
argv_size -= 1
i += 1 # on incrémente le compteur
return argv # on retourne les arguments
while True: # boucle infinie, il va encore falloir utiliser break pour en sortir
try: cmd = command_to_argv(raw_input('> ')) # si la commande entrée provoque une erreur...
except EOFError: return 0 # on quitte la boucle
except KeyboardInterrupt: return 0 # on quitte la boucle
cmdname, args = cmd[0], cmd[1:] # cmdname = fonction appelée, args = arguments
if not cmdname in commands.keys(): # si la fonction appelée n'existe pas dans le script
print "Erreur: '%s' commande incorrecte." % cmdname # on affiche un message d'erreur
continue
try:
commands[cmdname][0](*args)
except TypeError:
print "Erreur: mauvais nombre d'arguments pour '%s' command." % cmdname
except AttributeError:
print "Erreur : vous n'êtes pas connecté !"
return 0
import sys
if __name__ == "__main__": sys.exit(main()) # si le script est utilisé comme une librairie, on n'exécute pas le script
|