Bonjour ,
dans le cadre de mon travail je dois effectuer des transfert de fichier assez gros (entre 25 et 80 mo) vers un serveur FTP via une ligne RNIS.

Le problème est que cette ligne est assez mauvaise et à la fin du 1ere transfert je n'ai pas de réponse du serveur.

Pour cela, j'ai concu un programme python que je n'ai pas encore testé mais j'aimerai avoir l'avis de personne plus expirementé que moi en python ou pourriez vous m'orienter pour que le programme detecte les pertes de liaisons avec le serveur ?
Il faut savoir que la class GDDFTP herite d'une autre classe concu par un de mes collègues.
Merci d'avance pour votre aide
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
 
#!/usr/bin/python2
# -*- coding: iso_8859-1 -*-
 
import sys
import os
import telnetlib
import timedFtp as ftplib
import getopt
import traceback
import signal
import re
import getpass
from Singleton import Singleton
 
class TransfertError(Exception): pass
class SizeError(TransfertError) : pass
class TimeoutError(TransfertError) : pass
 
def handleTimeOut(signum, frame):
    raise TimeoutError
 
class GDDFTP(ftplib.FTP):
  def __init__(self, adresse, user, password):
    ftplib.FTP.__init__(self, adresse, user, password)
    self.user = user
    self.password = password
 
  def Reconnect(self):
    self.connect(self.host)
    self.login(self.user, self.password)
 
  def sendcmd(self, cmd):
    try: return ftplib.FTP.sendcmd(self, cmd)
    except:
        self.Reconnect()
        return ftplib.FTP.sendcmd(self, cmd)
 
 
class paramEnvoi(Singleton):
 
  server = "toto"
  user = "titi"
  psswd = "grosminet"
  verbose = False
  rdir = None
  log = None
  command = sys.argv[0]
  files = None
  timeout = None
 
  stdout = sys.stdout
  stderr = sys.stderr
 
  options = {
        "server=" : ("host", "Le serveur sur lequel se connecter"),
        "user=" : ("user", "Utilisateur distant"),
        "passwd=" : ("passwd", "Mot de passe pour l'utilisateur"),
        "rdir=" : ("rep","Le repertoire distant"),
        "log=" : ("file", "Le fichier de log. Pour l'instant inactif"),
        "verbose" : ("", "Affiche les messages de transfert."),
        "help" : ("", "Affiche ce message d'aide"),
        "timeout=" : ("delai", "delai max. d'attente de transmission de données")
        }
 
  usage1 = "%s [options] file..." % command
  usage2 = "Utilisez %s --help pour obtenir de plus amples imformations" % command
 
  longhelp = """Programme de transfert securisé du mieux possible
Utilisation : %s [options] fichier1 (fichier2....]
 
Les options sont :"""
 
  diagnostics = ""
 
  def __init__(self) :
     self.parseOpts(sys.argv[1:])
 
  def printUsage(self):
        print >> sys.stderr, self.usage1
        print >> sys.stderr, self.usage2
        sys.exit(1)
 
  def parseOpts(self, args) :
 
        excpt = None
        try:
            (opts, ar) = getopt.getopt(args, "", self.options.keys())
        except getopt.GetoptError, e :
            # Ce n'est pas fatal si on a --help....
            excpt = e
            if "--help" in args :
                opts = ['--help']
            else :
                print >> sys.stderr, excpt
                self.printUsage()
 
        # On tente de recuperer les differentes options
        for i in opts :
            if i[0] == "--help" :
                # Affiche l'aide, termine normalement
                self.help()
                sys.exit(0)
            elif i[0] == "--server" :
                self.server = i[1]
            elif i[0] == "--user" :
                self.user = i[1]
            elif i[0] == "--passwd" :
                self.psswd = i[1]
            elif i[0] == "--log" :
                self.log = i[1]
            elif i[0] == "--rdir" :
                self.rdir = i[1]
            elif i[0] == "--verbose" :
                self.verbose = True
            elif i[0] == "--timeout" :
                print "Here"
                self.timeout = int(i[1])
            else:
                raise ValueError(i)
                # Never get there
                pass
        if len(ar) < 1 :
            print >> sys.stderr, "Vous devez specifier au moins un argument"
            self.printUsage()
        else :
            self.files = ar
 
  def help(self) :
        print self.usage1
        print self.longhelp
        for i in self.options.items() :
            if i[1][0] :
                opt = i[0] + "<" + i[1][0] + ">"
            else :
                opt = i[0]
            print "  --" + opt + " : " + i[1][1]
 
        print self.diagnostics
 
 
def sendFile(fname) :
    param  = paramEnvoi()
 
    ## FIXME enlever la restriction
    if fname.find("/") >= 0:
        raise ValueError("Le nom du fichier ne doit pas contenir de '/'")
    size = os.stat(fname).st_size
    f = file(fname)
 
    # Determination du nom du fichier temporaire : on doit prendre en compte l'"extension" .tgz
    if fname.endswith(".tgz") :
        tmpfile = re.sub("\.tgz", ".tmp", fname)
    else :
        (base, ext) = os.path.splitext(fname)
        tmpfile = base + ".tmp"
    try:
        #Connexion
 
 
        ftp = GDDFTP(param.server, param.user, param.psswd)
 
        if param.timeout :
            ftp.set_timeout(param.timeout)
        if param.verbose :
            ftp.set_debuglevel(3)
        if param.rdir :
            ftp.cwd(param.rdir)
        # Envoi
        # On convertit un alarm clock en exception
        signal.signal(signal.SIGALRM, handleTimeOut)
#        print "************************************* ici *************************************"
        rep = ftp.storbinary("STOR " + tmpfile, f)
        if rep != "226 Transfer complete." :
            raise TransfertError("Probleme lors du transfert : " + rep)
        # Controle de la taille
        for i in range(3) :
            try:
                st = ftp.size(tmpfile)
                break
            except ftplib.error_perm, e:
                raise SizeError(str(e))
            except TimeoutError :
                print "Time out sur le controle de la taille"
        else :
            raise TimeoutError("On n'a pas reussi a determiner la taille")
        if st != size  :
            raise TransfertError("Tailles differentes")
        # Nommage definitif du fichier
        for i in range(3):
            try:
                ftp.rename(tmpfile, fname)
                break
            except TimeoutError :
                print "Timeout lors du move"
        else :
            raise TimeoutError("On n'a pas reussi a faire le move")
    finally:
        f.close()
        # On ne veut pas des exceptions qui seraient renvoyees ici
        # Utile en cas de pepin de connection
        try:
 
 
            ftp.quit()
            ftp.close()
        except :
            pass
 
 
def main() :
 
    param= paramEnvoi()
    if param.log :
        l = file(param.log, 'w')
        sys.stdout = l
        sys.stderr = l
 
    for i in param.files :
        try:
            sendFile(i)
        except SizeError :
            print >> param.stderr, "Attention: impossible de determiner la taille de", i
            print >> param.stderr, "Abandon. Le fichier %s a du etre transfere correctement." % i
            traceback.print_exc()
            sys.exit(3)
 
        except :
            print >> param.stderr, "Erreur lors du transfert de", i
            print >> param.stderr, "Abandon"
            traceback.print_exc()
            sys.exit(2)
 
 
if __name__ == "__main__" :
    main()