Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions httpie/output/ui/rich_progress.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ def console(self) -> 'Console':
return self.env.rich_error_console

def _print_summary(
self, is_finished: bool, observed_steps: int, time_spent: float
self,
is_finished: bool,
observed_steps: float,
time_spent: float,
total_steps: Optional[float] = None,
):
from rich import filesize

Expand All @@ -37,7 +41,10 @@ def _print_summary(
else:
verb = 'Interrupted'

total_size = filesize.decimal(observed_steps)
if total_steps is None:
total_steps = observed_steps

total_size = filesize.decimal(total_steps)
avg_speed = filesize.decimal(observed_steps / time_spent)

minutes, seconds = divmod(time_spent, 60)
Expand All @@ -63,6 +70,7 @@ class StatusDisplay(BaseDisplay):
def start(
self, *, total: Optional[float], at: float, description: str
) -> None:
self.initial_observed = at
self.observed = at
self.description = (
f'[progress.description]{description}[/progress.description]'
Expand All @@ -89,8 +97,9 @@ def stop(self, time_spent: float) -> None:
if time_spent:
self._print_summary(
is_finished=True,
observed_steps=self.observed,
observed_steps=self.observed - self.initial_observed,
time_spent=time_spent,
total_steps=self.observed,
)


Expand All @@ -107,6 +116,7 @@ def start(
)

assert total is not None
self.initial_completed = at
self.console.print(f'[progress.description]{description}')
self.progress_bar = Progress(
'[',
Expand Down Expand Up @@ -136,6 +146,7 @@ def stop(self, time_spent: Optional[float]) -> None:
[task] = self.progress_bar.tasks
self._print_summary(
is_finished=task.finished,
observed_steps=task.completed,
observed_steps=task.completed - self.initial_completed,
time_spent=time_spent,
total_steps=task.completed,
)
27 changes: 26 additions & 1 deletion tests/test_downloads.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import os
import tempfile
import time
import requests
from io import StringIO
from unittest import mock
from urllib.request import urlopen

import pytest
import requests
from rich.console import Console
from requests.structures import CaseInsensitiveDict

from httpie.downloads import (
parse_content_range, filename_from_content_disposition, filename_from_url,
get_unique_filename, ContentRangeError, Downloader, PARTIAL_CONTENT
)
from httpie.output.ui.rich_progress import ProgressDisplay
from .utils import http, MockEnvironment


Expand Down Expand Up @@ -247,6 +250,28 @@ def test_download_resumed(self, mock_env, httpbin_both):
downloader.chunk_downloaded(b'45')
downloader.finish()

def test_resumed_download_summary_uses_current_transfer_for_speed(self):
stderr = StringIO()
env = MockEnvironment(
stderr=stderr,
stderr_isatty=False,
show_displays=True,
)
env.rich_error_console = Console(
file=stderr,
force_terminal=False,
no_color=True,
width=120,
)
display = ProgressDisplay(env)

display.start(total=5, at=3, description='Downloading to file.bin')
display.update(2)
display.stop(time_spent=2)

summary = stderr.getvalue()
assert 'Done. 5 bytes in 00:2.00000 (1 byte/s)' in summary

def test_download_with_redirect_original_url_used_for_filename(self, httpbin):
# Redirect from `/redirect/1` to `/get`.
expected_filename = '1.json'
Expand Down
Loading