mirror of
https://github.com/python/cpython.git
synced 2025-08-02 08:02:56 +00:00
Changes by Eric Raymond:
1. Generate a correct Content-Length header visible through the info() method if a request to open an FTP URL gets a length in the response to RETR. 2. Take a third argument to urlretrieve() that makes it possible to progress- meter an urlretrieve call (this is what I needed the above change for). See the second patch band below for details. 3. To avoid spurious errors, I commented out the gopher test. The target document no longer exists.
This commit is contained in:
parent
d5af7bd489
commit
9ab96d40eb
1 changed files with 32 additions and 14 deletions
|
@ -59,14 +59,11 @@ def urlopen(url, data=None):
|
||||||
return _urlopener.open(url)
|
return _urlopener.open(url)
|
||||||
else:
|
else:
|
||||||
return _urlopener.open(url, data)
|
return _urlopener.open(url, data)
|
||||||
def urlretrieve(url, filename=None):
|
def urlretrieve(url, filename=None, reporthook=None):
|
||||||
global _urlopener
|
global _urlopener
|
||||||
if not _urlopener:
|
if not _urlopener:
|
||||||
_urlopener = FancyURLopener()
|
_urlopener = FancyURLopener()
|
||||||
if filename:
|
return _urlopener.retrieve(url, filename, reporthook)
|
||||||
return _urlopener.retrieve(url, filename)
|
|
||||||
else:
|
|
||||||
return _urlopener.retrieve(url)
|
|
||||||
def urlcleanup():
|
def urlcleanup():
|
||||||
if _urlopener:
|
if _urlopener:
|
||||||
_urlopener.cleanup()
|
_urlopener.cleanup()
|
||||||
|
@ -171,7 +168,7 @@ class URLopener:
|
||||||
# External interface
|
# External interface
|
||||||
# retrieve(url) returns (filename, None) for a local object
|
# retrieve(url) returns (filename, None) for a local object
|
||||||
# or (tempfilename, headers) for a remote object
|
# or (tempfilename, headers) for a remote object
|
||||||
def retrieve(self, url, filename=None):
|
def retrieve(self, url, filename=None, reporthook=None):
|
||||||
url = unwrap(url)
|
url = unwrap(url)
|
||||||
if self.tempcache and self.tempcache.has_key(url):
|
if self.tempcache and self.tempcache.has_key(url):
|
||||||
return self.tempcache[url]
|
return self.tempcache[url]
|
||||||
|
@ -200,10 +197,21 @@ class URLopener:
|
||||||
self.tempcache[url] = result
|
self.tempcache[url] = result
|
||||||
tfp = open(filename, 'wb')
|
tfp = open(filename, 'wb')
|
||||||
bs = 1024*8
|
bs = 1024*8
|
||||||
|
size = -1
|
||||||
|
blocknum = 1
|
||||||
|
if reporthook:
|
||||||
|
if headers.has_key("content-length"):
|
||||||
|
size = int(headers["Content-Length"])
|
||||||
|
reporthook(0, bs, size)
|
||||||
block = fp.read(bs)
|
block = fp.read(bs)
|
||||||
|
if reporthook:
|
||||||
|
reporthook(1, bs, size)
|
||||||
while block:
|
while block:
|
||||||
tfp.write(block)
|
tfp.write(block)
|
||||||
block = fp.read(bs)
|
block = fp.read(bs)
|
||||||
|
blocknum = blocknum + 1
|
||||||
|
if reporthook:
|
||||||
|
reporthook(blocknum, bs, size)
|
||||||
fp.close()
|
fp.close()
|
||||||
tfp.close()
|
tfp.close()
|
||||||
del fp
|
del fp
|
||||||
|
@ -366,9 +374,14 @@ class URLopener:
|
||||||
if string.lower(attr) == 'type' and \
|
if string.lower(attr) == 'type' and \
|
||||||
value in ('a', 'A', 'i', 'I', 'd', 'D'):
|
value in ('a', 'A', 'i', 'I', 'd', 'D'):
|
||||||
type = string.upper(value)
|
type = string.upper(value)
|
||||||
return addinfourl(
|
(fp, retrlen) = self.ftpcache[key].retrfile(file, type)
|
||||||
self.ftpcache[key].retrfile(file, type),
|
if retrlen >= 0:
|
||||||
noheaders(), "ftp:" + url)
|
import mimetools, StringIO
|
||||||
|
headers = mimetools.Message(StringIO.StringIO(
|
||||||
|
'Content-Length: %d\n' % retrlen))
|
||||||
|
else:
|
||||||
|
headers = noheaders()
|
||||||
|
return addinfourl(fp, headers, "ftp:" + url)
|
||||||
except ftperrors(), msg:
|
except ftperrors(), msg:
|
||||||
raise IOError, ('ftp error', msg), sys.exc_info()[2]
|
raise IOError, ('ftp error', msg), sys.exc_info()[2]
|
||||||
|
|
||||||
|
@ -574,7 +587,7 @@ class ftpwrapper:
|
||||||
# Try to retrieve as a file
|
# Try to retrieve as a file
|
||||||
try:
|
try:
|
||||||
cmd = 'RETR ' + file
|
cmd = 'RETR ' + file
|
||||||
conn = self.ftp.transfercmd(cmd)
|
conn = self.ftp.ntransfercmd(cmd)
|
||||||
except ftplib.error_perm, reason:
|
except ftplib.error_perm, reason:
|
||||||
if reason[:3] != '550':
|
if reason[:3] != '550':
|
||||||
raise IOError, ('ftp error', reason), \
|
raise IOError, ('ftp error', reason), \
|
||||||
|
@ -585,9 +598,10 @@ class ftpwrapper:
|
||||||
# Try a directory listing
|
# Try a directory listing
|
||||||
if file: cmd = 'LIST ' + file
|
if file: cmd = 'LIST ' + file
|
||||||
else: cmd = 'LIST'
|
else: cmd = 'LIST'
|
||||||
conn = self.ftp.transfercmd(cmd)
|
conn = self.ftp.ntransfercmd(cmd)
|
||||||
self.busy = 1
|
self.busy = 1
|
||||||
return addclosehook(conn.makefile('rb'), self.endtransfer)
|
# Pass back both a suitably decorated object and a retrieval length
|
||||||
|
return (addclosehook(conn[0].makefile('rb'), self.endtransfer), conn[1])
|
||||||
def endtransfer(self):
|
def endtransfer(self):
|
||||||
if not self.busy:
|
if not self.busy:
|
||||||
return
|
return
|
||||||
|
@ -977,6 +991,10 @@ def test1():
|
||||||
print round(t1 - t0, 3), 'sec'
|
print round(t1 - t0, 3), 'sec'
|
||||||
|
|
||||||
|
|
||||||
|
def reporthook(blocknum, blocksize, totalsize):
|
||||||
|
# Report during remote transfers
|
||||||
|
print "Block number: %d, Block size: %d, Total size: %d" % (blocknum, blocksize, totalsize)
|
||||||
|
|
||||||
# Test program
|
# Test program
|
||||||
def test(args=[]):
|
def test(args=[]):
|
||||||
if not args:
|
if not args:
|
||||||
|
@ -985,13 +1003,13 @@ def test(args=[]):
|
||||||
'file:/etc/passwd',
|
'file:/etc/passwd',
|
||||||
'file://localhost/etc/passwd',
|
'file://localhost/etc/passwd',
|
||||||
'ftp://ftp.python.org/etc/passwd',
|
'ftp://ftp.python.org/etc/passwd',
|
||||||
'gopher://gopher.micro.umn.edu/1/',
|
## 'gopher://gopher.micro.umn.edu/1/',
|
||||||
'http://www.python.org/index.html',
|
'http://www.python.org/index.html',
|
||||||
]
|
]
|
||||||
try:
|
try:
|
||||||
for url in args:
|
for url in args:
|
||||||
print '-'*10, url, '-'*10
|
print '-'*10, url, '-'*10
|
||||||
fn, h = urlretrieve(url)
|
fn, h = urlretrieve(url, None, reporthook)
|
||||||
print fn, h
|
print fn, h
|
||||||
if h:
|
if h:
|
||||||
print '======'
|
print '======'
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue