diff --git a/pytorrent/services/smart_queue.py b/pytorrent/services/smart_queue.py index e121fc9..12969d2 100644 --- a/pytorrent/services/smart_queue.py +++ b/pytorrent/services/smart_queue.py @@ -304,10 +304,12 @@ def _is_smart_queue_hold(torrent: dict[str, Any] | None, manage_stopped: bool = return False if str(torrent.get('label') or '') == SMART_QUEUE_LABEL: return True - # Note: Gdy manage_stopped=False, techniczne labele Smart Queue dotyczą tylko paused, a nie całkiem zatrzymanych torrentów. - if bool(torrent.get('paused')) and not int(torrent.get('state') or 0): + # Note: Paused w rTorrent zwykle ma state=1 i active=0, więc nie wolno wymagać state=0. + # Dzięki temu Smart Queue widzi pauzowane torrenty jako oczekujące i może później dobić target kolejki. + if bool(torrent.get('paused')): return True - if not manage_stopped and not int(torrent.get('state') or 0): + # Note: Całkiem zatrzymane pozycje są zarządzane tylko po włączeniu opcji Use stopped torrents. + if not manage_stopped: return False return not int(torrent.get('state') or 0) @@ -352,14 +354,17 @@ 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 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 bool(int(t.get('state') or 0)) - ) + """Return True only for incomplete torrents that are currently allowed to run.""" + # Note: Samo state=1 nie wystarcza, bo d.pause w rTorrent zostawia state=1. + # Poprzednia logika traktowała pauzowane torrenty jako aktywne sloty, przez co Smart Queue + # nie dobijał do targetu i nie wybierał ich jako kandydatów do wznowienia. + if int(t.get('complete') or 0): + return False + if bool(t.get('paused')) or str(t.get('status') or '').lower() == 'paused': + return False + if str(t.get('status') or '').lower() == 'checking': + return False + return bool(int(t.get('state') or 0)) def _is_waiting_download_candidate(t: dict[str, Any], manage_stopped: bool) -> bool: @@ -368,8 +373,10 @@ def _is_waiting_download_candidate(t: dict[str, Any], manage_stopped: bool) -> b return False if str(t.get('label') or '') == SMART_QUEUE_LABEL: return True - if bool(t.get('paused')): + # Note: Paused jest podstawowym źródłem dobijania kolejki, niezależnie od opcji manage_stopped. + if bool(t.get('paused')) or str(t.get('status') or '').lower() == 'paused': return True + # Note: Stopped dokładamy tylko wtedy, gdy użytkownik zaznaczył Use stopped torrents. return bool(manage_stopped) and not int(t.get('state') or 0)