feat: TUI 速度曲线栏增加实时速度文字 (当前/峰值/平均)
This commit is contained in:
1 parent
7b11c33d0c
commit
5b8160358e
2 files changed
+34
-2
No files matched your search
@@ -254,3 +254,19 @@ def test_apply_policy_global_overwrite_keeps_explicit_no():
|
||||
answers = {"a.txt": "n", "*": "a"}
|
||||
skipped = transfer.apply_policy(conflicts, "ask", answers)
|
||||
assert skipped == ["a.txt"]
|
||||
|
||||
# ---------- 速度统计 ----------
|
||||
|
||||
def test_speed_stats_basic():
|
||||
h = [10 * 1024 * 1024, 20 * 1024 * 1024, 15 * 1024 * 1024]
|
||||
cur, peak, avg = transfer.speed_stats(h)
|
||||
assert cur == 15 * 1024 * 1024
|
||||
assert peak == 20 * 1024 * 1024
|
||||
assert avg == 15 * 1024 * 1024
|
||||
|
||||
def test_speed_stats_empty():
|
||||
assert transfer.speed_stats([]) == (0.0, 0.0, 0.0)
|
||||
|
||||
def test_speed_stats_single():
|
||||
cur, peak, avg = transfer.speed_stats([8 * 1024 * 1024])
|
||||
assert (cur, peak, avg) == (8 * 1024 * 1024, 8 * 1024 * 1024, 8 * 1024 * 1024)
|
||||
+18
-2
@@ -55,6 +55,16 @@ def human_speed(bps: float) -> str:
|
||||
return f"{human_size(bps)}/s"
|
||||
|
||||
|
||||
def speed_stats(history) -> tuple[float, float, float]:
|
||||
"""速度统计: (当前, 峰值, 平均) 字节/秒"""
|
||||
if not history:
|
||||
return 0.0, 0.0, 0.0
|
||||
cur = float(history[-1])
|
||||
peak = max(history)
|
||||
avg = sum(history) / len(history)
|
||||
return cur, peak, avg
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 数据结构
|
||||
|
||||
@dataclass
|
||||
@@ -689,7 +699,8 @@ TUI_CSS = """
|
||||
Screen { layout: vertical; }
|
||||
#top { height: 7; border: round $primary; padding: 0 1; }
|
||||
#stats-line { height: 1; content-align: left middle; }
|
||||
#chart-box { height: 5; border: round $secondary; padding: 0 1; }
|
||||
#chart-box { height: 6; border: round $secondary; padding: 0 1; }
|
||||
#speed-stats { height: 1; color: $text-muted; }
|
||||
#logs { height: 1fr; }
|
||||
#file-log { width: 1fr; border: round $success; }
|
||||
#error-log { width: 1fr; border: round $error; }
|
||||
@@ -734,8 +745,9 @@ class TransferApp(App):
|
||||
yield ProgressBar(total=100, show_eta=True, id="total-bar")
|
||||
yield ProgressBar(total=100, id="file-bar")
|
||||
with Vertical(id="chart-box"):
|
||||
yield Static("速度曲线 (最近 80 秒)")
|
||||
yield Static("速度曲线 (最近 80 秒)", id="speed-title")
|
||||
yield Sparkline([0], summary_function=max, id="speed-spark")
|
||||
yield Static("", id="speed-stats")
|
||||
with Horizontal(id="logs"):
|
||||
yield RichLog(id="file-log", highlight=True, markup=True)
|
||||
yield RichLog(id="error-log", highlight=True, markup=True)
|
||||
@@ -920,6 +932,10 @@ class TransferApp(App):
|
||||
if st.speed_bps:
|
||||
self.speed_history.append(st.speed_bps)
|
||||
self.query_one("#speed-spark", Sparkline).data = list(self.speed_history)
|
||||
cur, peak, avg = speed_stats(self.speed_history)
|
||||
self.query_one("#speed-stats", Static).update(
|
||||
f"当前 {human_speed(cur)} | 峰值 {human_speed(peak)} | "
|
||||
f"平均 {human_speed(avg)} ({len(self.speed_history)} 样本)")
|
||||
parts = [f"总进度 {st.pct:5.1f}%"]
|
||||
if st.bytes_total:
|
||||
parts.append(f"{human_size(st.bytes_done)}/{human_size(st.bytes_total)}")
|
||||
|
||||
Reference in new issue
Block a user