sync
This commit is contained in:
62
buzzer_tool/core/commands/pull.py
Normal file
62
buzzer_tool/core/commands/pull.py
Normal file
@@ -0,0 +1,62 @@
|
||||
import os
|
||||
import posixpath
|
||||
import time
|
||||
|
||||
|
||||
def _resolve_local_target(remote_path: str, target: str | None) -> str:
|
||||
if target:
|
||||
return target
|
||||
|
||||
basename = posixpath.basename(remote_path.rstrip("/"))
|
||||
if not basename:
|
||||
raise ValueError("Kann keinen lokalen Dateinamen aus dem Remote-Pfad ableiten. Bitte Zielpfad angeben.")
|
||||
return basename
|
||||
|
||||
|
||||
def execute(conn, source: str, target: str | None = None):
|
||||
local_path = _resolve_local_target(source, target)
|
||||
|
||||
os.makedirs(os.path.dirname(local_path) or ".", exist_ok=True)
|
||||
|
||||
last_print = 0.0
|
||||
start_time = time.monotonic()
|
||||
|
||||
def _progress(_chunk_len: int, received: int, expected: int | None):
|
||||
nonlocal last_print
|
||||
now = time.monotonic()
|
||||
if now - last_print < 0.2:
|
||||
return
|
||||
last_print = now
|
||||
|
||||
elapsed = max(now - start_time, 1e-6)
|
||||
speed_kb_s = (received / 1024.0) / elapsed
|
||||
|
||||
if expected is not None and expected > 0:
|
||||
percent = (received * 100.0) / expected
|
||||
remaining = max(expected - received, 0)
|
||||
eta_sec = (remaining / 1024.0) / speed_kb_s if speed_kb_s > 0 else 0.0
|
||||
eta_str = f"{int(eta_sec // 60):02d}:{int(eta_sec % 60):02d}"
|
||||
print(
|
||||
f"\r⬇️ {received}/{expected} B ({percent:5.1f}%) | {speed_kb_s:6.1f} KB/s | ETA {eta_str}",
|
||||
end="",
|
||||
flush=True,
|
||||
)
|
||||
else:
|
||||
print(f"\r⬇️ {received} B | {speed_kb_s:6.1f} KB/s", end="", flush=True)
|
||||
|
||||
data = conn.get_file_data(source, progress_callback=_progress)
|
||||
|
||||
if len(data) > 0:
|
||||
print()
|
||||
|
||||
with open(local_path, "wb") as f:
|
||||
f.write(data)
|
||||
|
||||
total_duration = max(time.monotonic() - start_time, 1e-6)
|
||||
avg_speed_kb_s = (len(data) / 1024.0) / total_duration
|
||||
print(f"✅ Heruntergeladen: '{source}' -> '{local_path}' ({len(data)} B, {avg_speed_kb_s:.1f} KB/s)")
|
||||
return {
|
||||
"source": source,
|
||||
"target": local_path,
|
||||
"size": len(data),
|
||||
}
|
||||
Reference in New Issue
Block a user