Skip to content

Commit 199be59

Browse files
committed
Fix resumed download average speed
1 parent 5b604c3 commit 199be59

2 files changed

Lines changed: 41 additions & 5 deletions

File tree

httpie/output/ui/rich_progress.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ def console(self) -> 'Console':
2828
return self.env.rich_error_console
2929

3030
def _print_summary(
31-
self, is_finished: bool, observed_steps: int, time_spent: float
31+
self,
32+
is_finished: bool,
33+
observed_steps: float,
34+
time_spent: float,
35+
total_steps: Optional[float] = None,
3236
):
3337
from rich import filesize
3438

@@ -37,7 +41,10 @@ def _print_summary(
3741
else:
3842
verb = 'Interrupted'
3943

40-
total_size = filesize.decimal(observed_steps)
44+
if total_steps is None:
45+
total_steps = observed_steps
46+
47+
total_size = filesize.decimal(total_steps)
4148
avg_speed = filesize.decimal(observed_steps / time_spent)
4249

4350
minutes, seconds = divmod(time_spent, 60)
@@ -63,6 +70,7 @@ class StatusDisplay(BaseDisplay):
6370
def start(
6471
self, *, total: Optional[float], at: float, description: str
6572
) -> None:
73+
self.initial_observed = at
6674
self.observed = at
6775
self.description = (
6876
f'[progress.description]{description}[/progress.description]'
@@ -89,8 +97,9 @@ def stop(self, time_spent: float) -> None:
8997
if time_spent:
9098
self._print_summary(
9199
is_finished=True,
92-
observed_steps=self.observed,
100+
observed_steps=self.observed - self.initial_observed,
93101
time_spent=time_spent,
102+
total_steps=self.observed,
94103
)
95104

96105

@@ -107,6 +116,7 @@ def start(
107116
)
108117

109118
assert total is not None
119+
self.initial_completed = at
110120
self.console.print(f'[progress.description]{description}')
111121
self.progress_bar = Progress(
112122
'[',
@@ -136,6 +146,7 @@ def stop(self, time_spent: Optional[float]) -> None:
136146
[task] = self.progress_bar.tasks
137147
self._print_summary(
138148
is_finished=task.finished,
139-
observed_steps=task.completed,
149+
observed_steps=task.completed - self.initial_completed,
140150
time_spent=time_spent,
151+
total_steps=task.completed,
141152
)

tests/test_downloads.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import os
22
import tempfile
33
import time
4-
import requests
4+
from io import StringIO
55
from unittest import mock
66
from urllib.request import urlopen
77

88
import pytest
9+
import requests
10+
from rich.console import Console
911
from requests.structures import CaseInsensitiveDict
1012

1113
from httpie.downloads import (
1214
parse_content_range, filename_from_content_disposition, filename_from_url,
1315
get_unique_filename, ContentRangeError, Downloader, PARTIAL_CONTENT
1416
)
17+
from httpie.output.ui.rich_progress import ProgressDisplay
1518
from .utils import http, MockEnvironment
1619

1720

@@ -247,6 +250,28 @@ def test_download_resumed(self, mock_env, httpbin_both):
247250
downloader.chunk_downloaded(b'45')
248251
downloader.finish()
249252

253+
def test_resumed_download_summary_uses_current_transfer_for_speed(self):
254+
stderr = StringIO()
255+
env = MockEnvironment(
256+
stderr=stderr,
257+
stderr_isatty=False,
258+
show_displays=True,
259+
)
260+
env.rich_error_console = Console(
261+
file=stderr,
262+
force_terminal=False,
263+
no_color=True,
264+
width=120,
265+
)
266+
display = ProgressDisplay(env)
267+
268+
display.start(total=5, at=3, description='Downloading to file.bin')
269+
display.update(2)
270+
display.stop(time_spent=2)
271+
272+
summary = stderr.getvalue()
273+
assert 'Done. 5 bytes in 00:2.00000 (1 byte/s)' in summary
274+
250275
def test_download_with_redirect_original_url_used_for_filename(self, httpbin):
251276
# Redirect from `/redirect/1` to `/get`.
252277
expected_filename = '1.json'

0 commit comments

Comments
 (0)