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 -*-
from __future__ import division
# Python 2.7
 
import sys, os
import ftplib
 
#############################################################################
def msgerr():
    """pour afficher l'erreur en clair: type d'erreur, message d'erreur"""
    return u"Erreur (%s): %s" % (sys.exc_info()[0].__name__, sys.exc_info()[1])
 
#############################################################################
class Callback(object):
 
    def __init__(self, ficdsk, offset=0, tailleftp=0):
        if offset==0:
            self.f = open(ficdsk, 'wb') # on crée le fichier ou on le remet à 0
        else:
            self.f = open(ficdsk, 'ab') # on ajoute au fichier existant
        self.nblocs = 0 # numéro de bloc téléchargé
        self.noctets = offset # nb d'octets chargés depuis le début du chargement
        self.tailleftp = tailleftp # taille du fichier à télécharger
 
    def __call__(self, bloc):
        """appelé à chaque bloc téléchargé """
        self.f.write(bloc)
        self.nblocs += 1 # incrémenter le nb de blocs téléchargés
        self.noctets += len(bloc) # incrémenter le nb d'octets téléchargés
 
        # affichage de la progression
        prog = u""
        if self.tailleftp > 0:
            prog = u"%.2f" % (self.noctets/self.tailleftp*100,)
        print self.nblocs, self.noctets, prog
 
        # à décommenter pour fabriquer un fichier disque incomplet
        #if self.nblocs == 10:
        #    self.fin()
 
    def fermer(self):
        self.f.close()
 
#############################################################################
def downloadfichierftp(ftp, ficftp, repdsk):
    """charge le fichier ftp ficftp (sans chemin) dans le rép. disque repdsk
       le fichier ficftp est censé être dans le répertoire courant ftp
    """
 
    # calcul du chemin du fichier à créer sur disque
    ficdsk = os.path.join(repdsk, ficftp)
 
    # calcul de la taille du fichier sur ftp
    ftp.sendcmd('TYPE I') # passer en mode binaire (sinon, erreur avec size)
    tailleftp = ftp.size(ficftp)
    if tailleftp == None:
        tailleftp = 0 # au cas où size ne serait pas supporté   
 
    # calcul de la taille du fichier sur disque s'il existe déjà
    tailledsk = 0
    if os.path.exists(ficdsk):
        tailledsk = os.path.getsize(ficdsk)
 
    # comparaison des tailles des fichiers et calcul de l'offset
    offset = 0        
    if tailleftp >= tailledsk:
        offset = tailledsk
 
    # téléchargement
    callback = Callback(ficdsk, offset, tailleftp)
    try:
        # télécharger avec reprise si offset>0
        ftp.retrbinary('RETR ' + ficftp, callback, rest=offset)
    except ftplib.error_reply:
        # l'option 'rest' n'est pas supportée
        callback.fermer() # fermer le fichier sur disque
        callback = Callback(ficdsk, 0, tailleftp) # réouvrir avec offset=0
        ftp.retrbinary('RETR ' + ficftp, callback) # télécharger sans le 'rest'   
    callback.fermer() # fermer le fichier sur disque
 
#############################################################################
def connectftp(serveur, nom, mdp):
 
    ftp = ftplib.FTP()    
 
    # tentative de connexion au serveur
    try:
        welcome = ftp.connect(serveur)
    except:
        raise ValueError ("serveur ftp inconnu ou non joignable")
 
    # tentative d'ouverture de session par l'utilisateur
    try:
        ftp.login(nom, mdp)
    except:
        ftp.quit()
        raise ValueError ("nom ou mot-de-passe inconnu du serveur ftp")                
 
    return ftp, welcome
 
#############################################################################
if __name__ == "__main__":
 
    serveur = "xxxxxxx" # <== l'adresse du serveur ftp
    nom = "xxxxxx" # <== nom de l'utilisateur
    mdp = "xxxxxxx" # <== mot de passe
 
    # répertoire dans lequel se trouve le fichier à télécharger
    repftp = "/xxxxx/xxxxx/xxxxx"
    # fichier à télécharger
    ficftp = "xxxxxxxxx.xxx"
 
    # répertoire du disque dans lequel on veut placer le fichier téléchargé
    repdsk = r"C:\xxxxxx\xxxxx\xxxx"
 
    try:
        ftp, welcome = connectftp(serveur, nom, mdp)
        print u"connexion serveur: " + welcome
        print
 
        # mettre le répertoire ftp comme répertoire courant
        ftp.cwd(repftp)
        # télécharger le fichier
        downloadfichierftp(ftp, ficftp, repdsk)
 
        ftp.quit()
        print
        print u"Fin du téléchargement"    
    except Exception:
        print msgerr() |