@@ -59,14 +59,11 @@ def urlopen(url, data=None):
59
59
return _urlopener .open (url )
60
60
else :
61
61
return _urlopener .open (url , data )
62
- def urlretrieve (url , filename = None ):
62
+ def urlretrieve (url , filename = None , reporthook = None ):
63
63
global _urlopener
64
64
if not _urlopener :
65
65
_urlopener = FancyURLopener ()
66
- if filename :
67
- return _urlopener .retrieve (url , filename )
68
- else :
69
- return _urlopener .retrieve (url )
66
+ return _urlopener .retrieve (url , filename , reporthook )
70
67
def urlcleanup ():
71
68
if _urlopener :
72
69
_urlopener .cleanup ()
@@ -171,7 +168,7 @@ def open_unknown(self, fullurl, data=None):
171
168
# External interface
172
169
# retrieve(url) returns (filename, None) for a local object
173
170
# or (tempfilename, headers) for a remote object
174
- def retrieve (self , url , filename = None ):
171
+ def retrieve (self , url , filename = None , reporthook = None ):
175
172
url = unwrap (url )
176
173
if self .tempcache and self .tempcache .has_key (url ):
177
174
return self .tempcache [url ]
@@ -200,10 +197,21 @@ def retrieve(self, url, filename=None):
200
197
self .tempcache [url ] = result
201
198
tfp = open (filename , 'wb' )
202
199
bs = 1024 * 8
200
+ size = - 1
201
+ blocknum = 1
202
+ if reporthook :
203
+ if headers .has_key ("content-length" ):
204
+ size = int (headers ["Content-Length" ])
205
+ reporthook (0 , bs , size )
203
206
block = fp .read (bs )
207
+ if reporthook :
208
+ reporthook (1 , bs , size )
204
209
while block :
205
210
tfp .write (block )
206
211
block = fp .read (bs )
212
+ blocknum = blocknum + 1
213
+ if reporthook :
214
+ reporthook (blocknum , bs , size )
207
215
fp .close ()
208
216
tfp .close ()
209
217
del fp
@@ -366,9 +374,14 @@ def open_ftp(self, url):
366
374
if string .lower (attr ) == 'type' and \
367
375
value in ('a' , 'A' , 'i' , 'I' , 'd' , 'D' ):
368
376
type = string .upper (value )
369
- return addinfourl (
370
- self .ftpcache [key ].retrfile (file , type ),
371
- noheaders (), "ftp:" + url )
377
+ (fp , retrlen ) = self .ftpcache [key ].retrfile (file , type )
378
+ if retrlen >= 0 :
379
+ import mimetools , StringIO
380
+ headers = mimetools .Message (StringIO .StringIO (
381
+ 'Content-Length: %d\n ' % retrlen ))
382
+ else :
383
+ headers = noheaders ()
384
+ return addinfourl (fp , headers , "ftp:" + url )
372
385
except ftperrors (), msg :
373
386
raise IOError , ('ftp error' , msg ), sys .exc_info ()[2 ]
374
387
@@ -574,7 +587,7 @@ def retrfile(self, file, type):
574
587
# Try to retrieve as a file
575
588
try :
576
589
cmd = 'RETR ' + file
577
- conn = self .ftp .transfercmd (cmd )
590
+ conn = self .ftp .ntransfercmd (cmd )
578
591
except ftplib .error_perm , reason :
579
592
if reason [:3 ] != '550' :
580
593
raise IOError , ('ftp error' , reason ), \
@@ -585,9 +598,10 @@ def retrfile(self, file, type):
585
598
# Try a directory listing
586
599
if file : cmd = 'LIST ' + file
587
600
else : cmd = 'LIST'
588
- conn = self .ftp .transfercmd (cmd )
601
+ conn = self .ftp .ntransfercmd (cmd )
589
602
self .busy = 1
590
- return addclosehook (conn .makefile ('rb' ), self .endtransfer )
603
+ # Pass back both a suitably decorated object and a retrieval length
604
+ return (addclosehook (conn [0 ].makefile ('rb' ), self .endtransfer ), conn [1 ])
591
605
def endtransfer (self ):
592
606
if not self .busy :
593
607
return
@@ -977,6 +991,10 @@ def test1():
977
991
print round (t1 - t0 , 3 ), 'sec'
978
992
979
993
994
+ def reporthook (blocknum , blocksize , totalsize ):
995
+ # Report during remote transfers
996
+ print "Block number: %d, Block size: %d, Total size: %d" % (blocknum , blocksize , totalsize )
997
+
980
998
# Test program
981
999
def test (args = []):
982
1000
if not args :
@@ -985,13 +1003,13 @@ def test(args=[]):
985
1003
'file:/etc/passwd' ,
986
1004
'file://localhost/etc/passwd' ,
987
1005
'ftp://ftp.python.org/etc/passwd' ,
988
- 'gopher://gopher.micro.umn.edu/1/' ,
1006
+ ## 'gopher://gopher.micro.umn.edu/1/',
989
1007
'http://www.python.org/index.html' ,
990
1008
]
991
1009
try :
992
1010
for url in args :
993
1011
print '-' * 10 , url , '-' * 10
994
- fn , h = urlretrieve (url )
1012
+ fn , h = urlretrieve (url , None , reporthook )
995
1013
print fn , h
996
1014
if h :
997
1015
print '======'
0 commit comments