fix: show active qBittorrent transfers
This commit is contained in:
@@ -410,6 +410,26 @@ def _qbittorrent_client(cache_key: tuple[str, str, str, str, int]) -> Qbittorren
|
||||
return QbittorrentClient(base_url, username, password, timeout=timeout)
|
||||
|
||||
|
||||
_QBITTORRENT_DOWNLOAD_STATES = frozenset(
|
||||
{"downloading", "forceddl", "stalleddl", "metadl", "allocating"}
|
||||
)
|
||||
_QBITTORRENT_UPLOAD_STATES = frozenset({"uploading", "forcedup", "stalledup"})
|
||||
|
||||
|
||||
def _qbit_torrent_direction(torrent: dict[str, Any]) -> str | None:
|
||||
"""Return the transfer direction for active qBittorrent states or speeds."""
|
||||
state = str(torrent.get("state") or "").lower()
|
||||
if state in _QBITTORRENT_DOWNLOAD_STATES:
|
||||
return "downloading"
|
||||
if state in _QBITTORRENT_UPLOAD_STATES:
|
||||
return "uploading"
|
||||
if _safe_int(torrent.get("dlspeed")) > 0:
|
||||
return "downloading"
|
||||
if _safe_int(torrent.get("upspeed")) > 0:
|
||||
return "uploading"
|
||||
return None
|
||||
|
||||
|
||||
class QbittorrentWidgetSource:
|
||||
"""Fetch qBittorrent data for totals, active, and speed widgets."""
|
||||
|
||||
@@ -456,24 +476,36 @@ class QbittorrentWidgetSource:
|
||||
|
||||
if widget_kind == "totals":
|
||||
by_state: dict[str, int] = {}
|
||||
for t in torrents.values():
|
||||
state = str(t.get("state", "unknown"))
|
||||
by_direction = {"downloading": 0, "uploading": 0}
|
||||
for torrent in torrents.values():
|
||||
state = str(torrent.get("state") or "unknown")
|
||||
by_state[state] = by_state.get(state, 0) + 1
|
||||
return {"total": len(torrents), "by_state": by_state}
|
||||
direction = _qbit_torrent_direction(torrent)
|
||||
if direction:
|
||||
by_direction[direction] += 1
|
||||
return {
|
||||
"total": len(torrents),
|
||||
"by_state": by_state,
|
||||
"by_direction": by_direction,
|
||||
}
|
||||
|
||||
if widget_kind == "active":
|
||||
active = [
|
||||
{
|
||||
"name": t.get("name"),
|
||||
"state": t.get("state"),
|
||||
"size": t.get("size"),
|
||||
"progress": t.get("progress"),
|
||||
"dl_speed": t.get("dlspeed"),
|
||||
"up_speed": t.get("upspeed"),
|
||||
}
|
||||
for t in torrents.values()
|
||||
if str(t.get("state", "")) in {"downloading", "uploading"}
|
||||
]
|
||||
active = []
|
||||
for torrent in torrents.values():
|
||||
direction = _qbit_torrent_direction(torrent)
|
||||
if not direction:
|
||||
continue
|
||||
active.append(
|
||||
{
|
||||
"name": torrent.get("name"),
|
||||
"state": torrent.get("state"),
|
||||
"direction": direction,
|
||||
"size": torrent.get("size"),
|
||||
"progress": torrent.get("progress"),
|
||||
"dl_speed": torrent.get("dlspeed"),
|
||||
"up_speed": torrent.get("upspeed"),
|
||||
}
|
||||
)
|
||||
return {"torrents": active}
|
||||
|
||||
return {"error": f"Unknown qBittorrent widget kind: {widget_kind}"}
|
||||
|
||||
@@ -1086,6 +1086,22 @@ def _fake_qbit_maindata():
|
||||
"dlspeed": 0,
|
||||
"upspeed": 0,
|
||||
},
|
||||
"h5": {
|
||||
"name": "Forced download",
|
||||
"state": "forcedDL",
|
||||
"size": 5000,
|
||||
"progress": 0.4,
|
||||
"dlspeed": 0,
|
||||
"upspeed": 0,
|
||||
},
|
||||
"h6": {
|
||||
"name": "Stalled upload",
|
||||
"state": "stalledUP",
|
||||
"size": 6000,
|
||||
"progress": 1.0,
|
||||
"dlspeed": 0,
|
||||
"upspeed": 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1107,11 +1123,12 @@ async def test_qbittorrent_totals_counts_all_torrents():
|
||||
mock_client.return_value.maindata.return_value = _fake_qbit_maindata()
|
||||
result = await adapter.fetch(service, "totals", {})
|
||||
|
||||
assert result["total"] == 4
|
||||
assert result["total"] == 6
|
||||
assert result["by_state"]["downloading"] == 1
|
||||
assert result["by_state"]["uploading"] == 1
|
||||
assert result["by_state"]["queuedDL"] == 1
|
||||
assert result["by_state"]["pausedDL"] == 1
|
||||
assert result["by_direction"] == {"downloading": 2, "uploading": 2}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -1132,10 +1149,12 @@ async def test_qbittorrent_active_filters_dl_ul_only():
|
||||
result = await adapter.fetch(service, "active", {})
|
||||
|
||||
active = result["torrents"]
|
||||
assert len(active) == 2
|
||||
assert len(active) == 4
|
||||
names = [t["name"] for t in active]
|
||||
assert "Movie.mkv" in names
|
||||
assert "Show.mkv" in names
|
||||
assert "Forced download" in names
|
||||
assert "Stalled upload" in names
|
||||
# Queued and paused are excluded
|
||||
assert "Queued" not in names
|
||||
assert "Paused" not in names
|
||||
|
||||
Reference in New Issue
Block a user