From 904f36e06f3315324d6503ae4a4da005c8e55ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Tue, 5 May 2026 14:43:58 +0200 Subject: [PATCH] smart queue fix --- pytorrent/services/smart_queue.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/pytorrent/services/smart_queue.py b/pytorrent/services/smart_queue.py index a538544..e121fc9 100644 --- a/pytorrent/services/smart_queue.py +++ b/pytorrent/services/smart_queue.py @@ -272,9 +272,10 @@ def _read_live_start_state(client: Any, torrent_hash: str) -> dict[str, Any]: result[key] = int(value or 0) if key in {'state', 'active'} else str(value or '') except Exception as exc: result[f'{key}_error'] = str(exc) - # Note: Dla Smart Queue slot aktywny musi zniknąć z UI jako Paused, więc wymagamy active=1. - # state=1 alone może oznaczać nadal zapauzowany torrent po d.pause. - result['started'] = bool(int(result.get('state') or 0)) and bool(int(result.get('active') or 0)) + # Note: rTorrent po masowym d.resume/d.start potrafi długo zwracać d.is_active=0 + # dla torrentów bez bieżącego transferu. Dla Smart Queue start oznacza state=1; + # inaczej weryfikacja zalicza tylko 1 pozycję i kolejne przebiegi dokładają po jednej sztuce. + result['started'] = bool(int(result.get('state') or 0)) return result def _set_smart_queue_label(client: Any, torrent_hash: str, attempts: int = 3) -> bool: @@ -351,12 +352,13 @@ def _cleanup_auto_labels(client: Any, profile_id: int, torrents: list[dict[str, def _is_running_download_slot(t: dict[str, Any]) -> bool: - """Return True only for torrents that occupy a visible active download slot.""" - # Note: normalize_row oznacza state=1/active=0 jako Paused; takich nie liczymy jako aktywne sloty. + """Return True for torrents already started by rTorrent.""" + # Note: Nie używamy d.is_active/paused do liczenia slotów Smart Queue. + # active=0 może oznaczać brak transferu/peerów, a nie wolny slot. Liczenie po active + # powodowało startowanie kolejki po 1 sztuce mimo targetu 100. return ( not int(t.get('complete') or 0) - and int(t.get('state') or 0) - and not bool(t.get('paused')) + and bool(int(t.get('state') or 0)) ) @@ -396,7 +398,7 @@ def check(profile: dict | None = None, user_id: int | None = None, force: bool = return str(t.get('label') or '') == SMART_QUEUE_LABEL # Note: Slot Smart Queue liczymy po d.state, nie po d.is_active. d.is_active bywa 0 - # dla torrentu juz wystartowanego, ale chwilowo bez transferu, wiec powodowal startowanie po jednej sztuce. + # dla torrentu już wystartowanego, ale chwilowo bez transferu, więc powodował startowanie po jednej sztuce. downloading = [ t for t in torrents if _is_running_download_slot(t)