Commit a614b9b1 by Tom Solberg Committed by GitHub

add progress to `download_file` if in Indicator context (#5451)

Co-authored-by: Arun Babu Neelicattu <arun.neelicattu@gmail.com>
Co-authored-by: Bjorn Neergaard <bjorn@neersighted.com>
parent f05329a6
...@@ -13,6 +13,7 @@ from contextlib import contextmanager ...@@ -13,6 +13,7 @@ from contextlib import contextmanager
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Any from typing import Any
from typing import Callable
from typing import Iterable from typing import Iterable
from typing import Iterator from typing import Iterator
from typing import cast from typing import cast
...@@ -55,6 +56,24 @@ logger = logging.getLogger(__name__) ...@@ -55,6 +56,24 @@ logger = logging.getLogger(__name__)
class Indicator(ProgressIndicator): # type: ignore[misc] class Indicator(ProgressIndicator): # type: ignore[misc]
CONTEXT: str | None = None
@staticmethod
@contextmanager
def context() -> Iterator[Callable[[str | None], None]]:
def _set_context(context: str | None) -> None:
Indicator.CONTEXT = context
yield _set_context
_set_context(None)
def _formatter_context(self) -> str:
if Indicator.CONTEXT is None:
return " "
else:
return f" <c1>{Indicator.CONTEXT}</> "
def _formatter_elapsed(self) -> str: def _formatter_elapsed(self) -> str:
elapsed = time.time() - self._start_time elapsed = time.time() - self._start_time
...@@ -796,7 +815,9 @@ class Provider: ...@@ -796,7 +815,9 @@ class Provider:
self._io.write_line("Resolving dependencies...") self._io.write_line("Resolving dependencies...")
yield yield
else: else:
indicator = Indicator(self._io, "{message} <debug>({elapsed:2s})</debug>") indicator = Indicator(
self._io, "{message}{context}<debug>({elapsed:2s})</debug>"
)
with indicator.auto( with indicator.auto(
"<info>Resolving dependencies...</info>", "<info>Resolving dependencies...</info>",
......
...@@ -89,15 +89,41 @@ def download_file( ...@@ -89,15 +89,41 @@ def download_file(
) -> None: ) -> None:
import requests import requests
from poetry.puzzle.provider import Indicator
get = requests.get if not session else session.get get = requests.get if not session else session.get
response = get(url, stream=True) response = get(url, stream=True)
response.raise_for_status() response.raise_for_status()
with open(dest, "wb") as f: set_indicator = False
for chunk in response.iter_content(chunk_size=chunk_size): with Indicator.context() as update_context:
if chunk: update_context(f"Downloading {url}")
f.write(chunk)
if "Content-Length" in response.headers:
try:
total_size = int(response.headers["Content-Length"])
except ValueError:
total_size = 0
fetched_size = 0
last_percent = 0
# if less than 1MB, we simply show that we're downloading
# but skip the updating
set_indicator = total_size > 1024 * 1024
with open(dest, "wb") as f:
for chunk in response.iter_content(chunk_size=chunk_size):
if chunk:
f.write(chunk)
if set_indicator:
fetched_size += len(chunk)
percent = (fetched_size * 100) // total_size
if percent > last_percent:
last_percent = percent
update_context(f"Downloading {url} {percent:3}%")
def get_package_version_display_string( def get_package_version_display_string(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment