mirror of
https://github.com/httpie/cli.git
synced 2025-06-26 04:21:24 +02:00
Fixed downloads with no Content-Length.
This commit is contained in:
parent
c63a92f9b7
commit
5a1177d57e
@ -49,6 +49,7 @@ Main Features
|
|||||||
* Arbitrary request data
|
* Arbitrary request data
|
||||||
* Custom headers
|
* Custom headers
|
||||||
* Persistent sessions
|
* Persistent sessions
|
||||||
|
* Wget-like downloads
|
||||||
* Python 2.6, 2.7 and 3.x support
|
* Python 2.6, 2.7 and 3.x support
|
||||||
* Linux, Mac OS X and Windows support
|
* Linux, Mac OS X and Windows support
|
||||||
* Documentation
|
* Documentation
|
||||||
|
@ -22,8 +22,8 @@ PARTIAL_CONTENT = 206
|
|||||||
|
|
||||||
CLEAR_LINE = '\r\033[K'
|
CLEAR_LINE = '\r\033[K'
|
||||||
PROGRESS = (
|
PROGRESS = (
|
||||||
'{downloaded: >9}'
|
'{downloaded: >10}'
|
||||||
' {percentage: 5.2f}%'
|
' {percentage: 6.2f}%'
|
||||||
' {speed: >10}/s'
|
' {speed: >10}/s'
|
||||||
' {eta: >8} ETA'
|
' {eta: >8} ETA'
|
||||||
)
|
)
|
||||||
@ -103,7 +103,7 @@ def filename_from_content_disposition(content_disposition):
|
|||||||
# attachment; filename=jkbr-httpie-0.4.1-20-g40bd8f6.tar.gz
|
# attachment; filename=jkbr-httpie-0.4.1-20-g40bd8f6.tar.gz
|
||||||
match = re.search('filename=(\S+)', content_disposition)
|
match = re.search('filename=(\S+)', content_disposition)
|
||||||
if match and match.group(1):
|
if match and match.group(1):
|
||||||
fn = match.group(1).lstrip('.')
|
fn = match.group(1).strip('."')
|
||||||
if re.match('^[a-zA-Z0-9._-]+$', fn):
|
if re.match('^[a-zA-Z0-9._-]+$', fn):
|
||||||
return fn
|
return fn
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ class Download(object):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
total_size = int(response.headers['Content-Length'])
|
total_size = int(response.headers['Content-Length'])
|
||||||
except (KeyError, ValueError):
|
except (KeyError, ValueError, TypeError):
|
||||||
total_size = None
|
total_size = None
|
||||||
|
|
||||||
if self._output_file:
|
if self._output_file:
|
||||||
@ -343,23 +343,24 @@ class ProgressReporter(object):
|
|||||||
|
|
||||||
downloaded = self.progress.downloaded
|
downloaded = self.progress.downloaded
|
||||||
|
|
||||||
if self.progress.total_size:
|
|
||||||
template = PROGRESS
|
|
||||||
percentage = (
|
|
||||||
downloaded / self.progress.total_size * 100)
|
|
||||||
else:
|
|
||||||
template = PROGRESS_NO_CONTENT_LENGTH
|
|
||||||
percentage = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# TODO: Use a longer interval for the speed/eta calculation?
|
# TODO: Use a longer interval for the speed/eta calculation?
|
||||||
speed = ((downloaded - self._prev_bytes)
|
speed = ((downloaded - self._prev_bytes)
|
||||||
/ (now - self._prev_time))
|
/ (now - self._prev_time))
|
||||||
s = int((self.progress.total_size - downloaded) / speed)
|
|
||||||
except ZeroDivisionError:
|
except ZeroDivisionError:
|
||||||
speed = 0
|
speed = 0
|
||||||
|
|
||||||
|
if not self.progress.total_size:
|
||||||
|
template = PROGRESS_NO_CONTENT_LENGTH
|
||||||
|
percentage = None
|
||||||
|
eta = None
|
||||||
|
else:
|
||||||
|
template = PROGRESS
|
||||||
|
percentage = downloaded / self.progress.total_size * 100
|
||||||
|
if not speed:
|
||||||
eta = '-:--:--'
|
eta = '-:--:--'
|
||||||
else:
|
else:
|
||||||
|
s = int((self.progress.total_size - downloaded) / speed)
|
||||||
h, s = divmod(s, 60 * 60)
|
h, s = divmod(s, 60 * 60)
|
||||||
m, s = divmod(s, 60)
|
m, s = divmod(s, 60)
|
||||||
eta = '{}:{:0>2}:{:0>2}'.format(h, m, s)
|
eta = '{}:{:0>2}:{:0>2}'.format(h, m, s)
|
||||||
@ -397,7 +398,8 @@ class ProgressReporter(object):
|
|||||||
self.output.write(CLEAR_LINE)
|
self.output.write(CLEAR_LINE)
|
||||||
self.output.write(SUMMARY.format(
|
self.output.write(SUMMARY.format(
|
||||||
downloaded=humanize_bytes(actually_downloaded),
|
downloaded=humanize_bytes(actually_downloaded),
|
||||||
total=humanize_bytes(self.progress.total_size),
|
total=(self.progress.total_size
|
||||||
|
and humanize_bytes(self.progress.total_size)),
|
||||||
speed=humanize_bytes(actually_downloaded / time_taken),
|
speed=humanize_bytes(actually_downloaded / time_taken),
|
||||||
time=time_taken,
|
time=time_taken,
|
||||||
))
|
))
|
||||||
|
@ -38,6 +38,7 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
skip = lambda msg: lambda self: None
|
skip = lambda msg: lambda self: None
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
def skipIf(cond, reason):
|
def skipIf(cond, reason):
|
||||||
def decorator(test_method):
|
def decorator(test_method):
|
||||||
if cond:
|
if cond:
|
||||||
@ -251,10 +252,12 @@ class BaseTestCase(unittest.TestCase):
|
|||||||
def assertIsNone(self, obj, msg=None):
|
def assertIsNone(self, obj, msg=None):
|
||||||
self.assertEqual(obj, None, msg=msg)
|
self.assertEqual(obj, None, msg=msg)
|
||||||
|
|
||||||
|
|
||||||
#################################################################
|
#################################################################
|
||||||
# High-level tests using httpbin.
|
# High-level tests using httpbin.
|
||||||
#################################################################
|
#################################################################
|
||||||
|
|
||||||
|
|
||||||
class HTTPieTest(BaseTestCase):
|
class HTTPieTest(BaseTestCase):
|
||||||
|
|
||||||
def test_GET(self):
|
def test_GET(self):
|
||||||
@ -1465,7 +1468,7 @@ class DownloadUtilsTest(BaseTestCase):
|
|||||||
'hello-WORLD_123.txt'
|
'hello-WORLD_123.txt'
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
parse('attachment; filename=.hello-WORLD_123.txt'),
|
parse('attachment; filename=".hello-WORLD_123.txt"'),
|
||||||
'hello-WORLD_123.txt'
|
'hello-WORLD_123.txt'
|
||||||
)
|
)
|
||||||
self.assertIsNone(parse('attachment; filename='))
|
self.assertIsNone(parse('attachment; filename='))
|
||||||
@ -1493,7 +1496,7 @@ class DownloadUtilsTest(BaseTestCase):
|
|||||||
def test_unique_filename(self):
|
def test_unique_filename(self):
|
||||||
|
|
||||||
def make_exists(unique_on_attempt=0):
|
def make_exists(unique_on_attempt=0):
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences,PyUnusedLocal
|
||||||
def exists(filename):
|
def exists(filename):
|
||||||
if exists.attempt == unique_on_attempt:
|
if exists.attempt == unique_on_attempt:
|
||||||
return False
|
return False
|
||||||
|
Loading…
x
Reference in New Issue
Block a user