def _download(self, url, cache_path):
import requests
def copy_callback(read, total):
if self.callback:
self.callback('copy_file', read, total)
if self.callback:
self.callback('download', url, 0)
if url.startswith('s3:'):
from appurl.url import Url
s3url = Url(url)
try:
with self.cache.open(cache_path, 'wb') as f:
s3url.object.download_fileobj(f)
except Exception as e:
raise DownloadError("Failed to fetch S3 url '{}': {}".format(url, e))
elif url.startswith('ftp:'):
from contextlib import closing
with closing(urlopen(url)) as fin:
with self.cache.open(cache_path, 'wb') as fout:
read_len = 16 * 1024
total_len = 0
while 1:
buf = fin.read(read_len)
if not buf:
break
fout.write(buf)
total_len += len(buf)
if self.callback:
copy_callback(len(buf), total_len)
else:
try:
r = requests.get(url, stream=True)
r.raise_for_status()
except SSLError as e:
raise DownloadError("Failed to GET {}: {} ".format(url, e))
# Requests will auto decode gzip responses, but not when streaming. This following
# monkey patch is recommended by a core developer at
# https://github.com/kennethreitz/requests/issues/2155
if r.headers.get('content-encoding') == 'gzip':
r.raw.read = functools.partial(r.raw.read, decode_content=True)
with self.cache.open(cache_path, 'wb') as f:
copy_file_or_flo(r.raw, f, cb=copy_callback)
assert self.cache.exists(cache_path)
评论列表
文章目录