fix ququq
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
|
||||
from .client import *
|
||||
from .files import set_file_priorities
|
||||
from .system import disk_usage_for_default_path
|
||||
@@ -214,6 +216,7 @@ TORRENT_FIELDS = [
|
||||
]
|
||||
|
||||
TORRENT_OPTIONAL_FIELDS = [
|
||||
"d.timestamp.last_active=",
|
||||
"d.timestamp.finished=",
|
||||
]
|
||||
|
||||
@@ -252,7 +255,12 @@ def normalize_row(row: list) -> dict:
|
||||
directory = str(row[14] or "")
|
||||
base_path = str(row[15] or "")
|
||||
is_multi_file = int(row[22] or 0) if len(row) > 22 else 0
|
||||
completed_at = int(row[23] or 0) if len(row) > 23 else 0
|
||||
# Note: Last activity is optional because older rTorrent builds may not expose this timestamp.
|
||||
last_activity = int(row[23] or 0) if len(row) > 23 else 0
|
||||
if not last_activity and (down_rate > 0 or up_rate > 0):
|
||||
# Note: rTorrent builds without d.timestamp.last_active still expose live rates, so active rows get a safe current timestamp.
|
||||
last_activity = int(time.time())
|
||||
completed_at = int(row[24] or 0) if len(row) > 24 else 0
|
||||
|
||||
# Show the selected download location only. Hide the torrent root
|
||||
# directory for multi-file torrents and the filename for single-file
|
||||
@@ -310,6 +318,7 @@ def normalize_row(row: list) -> dict:
|
||||
"priority": int(row[13] or 0),
|
||||
"path": display_path,
|
||||
"created": int(row[16] or 0),
|
||||
"last_activity": last_activity,
|
||||
"completed_at": completed_at,
|
||||
"label": str(row[17] or ""),
|
||||
"ratio_group": str(row[18] or ""),
|
||||
|
||||
@@ -66,6 +66,8 @@ def _diagnostics_torrent(t: dict[str, Any] | None) -> dict[str, Any]:
|
||||
'hashing': int(t.get('hashing') or 0),
|
||||
'priority': int(t.get('priority') or 0),
|
||||
'down_rate': int(t.get('down_rate') or 0),
|
||||
'up_rate': int(t.get('up_rate') or 0),
|
||||
'last_activity': int(t.get('last_activity') or 0),
|
||||
'peers': int(t.get('peers') or 0),
|
||||
'seeds': int(t.get('seeds') or 0),
|
||||
'label': str(t.get('label') or ''),
|
||||
@@ -800,9 +802,22 @@ def _is_running_download_slot(t: dict[str, Any]) -> bool:
|
||||
return _is_started_download_slot(t)
|
||||
|
||||
|
||||
def _is_stalled_download(t: dict[str, Any], min_speed: int, min_seeds: int, min_peers: int, ignore_seed_peer: bool, ignore_speed: bool) -> bool:
|
||||
def _has_recent_transfer_activity(t: dict[str, Any], stalled_seconds: int) -> bool:
|
||||
"""Return True when a torrent is currently transferring or was active within the stalled window."""
|
||||
# Note: Live transfer rates always protect a torrent from being marked as stalled.
|
||||
if int(t.get('down_rate') or 0) > 0 or int(t.get('up_rate') or 0) > 0:
|
||||
return True
|
||||
last_activity = int(t.get('last_activity') or 0)
|
||||
if last_activity <= 0:
|
||||
return False
|
||||
return time.time() - last_activity < max(1, int(stalled_seconds or 0))
|
||||
|
||||
|
||||
def _is_stalled_download(t: dict[str, Any], min_speed: int, min_seeds: int, min_peers: int, stalled_seconds: int, ignore_seed_peer: bool, ignore_speed: bool) -> bool:
|
||||
"""Return True when a started torrent should begin or continue the stalled timer."""
|
||||
# Note: Each ignore switch removes only its own criterion; the stalled timer still applies after criteria match.
|
||||
# Note: Recent transfer activity wins over ignored source/speed criteria, preventing active torrents from being stopped as stalled.
|
||||
if _has_recent_transfer_activity(t, stalled_seconds):
|
||||
return False
|
||||
speed_ok = True if ignore_speed else int(t.get('down_rate') or 0) <= max(0, int(min_speed or 0))
|
||||
source_ok = True if ignore_seed_peer else int(t.get('seeds') or 0) <= max(0, int(min_seeds or 0)) and (min_peers <= 0 or int(t.get('peers') or 0) <= min_peers)
|
||||
return speed_ok and source_ok
|
||||
@@ -810,13 +825,15 @@ def _is_stalled_download(t: dict[str, Any], min_speed: int, min_seeds: int, min_
|
||||
|
||||
def _stalled_timer_key(min_speed: int, min_seeds: int, min_peers: int, stalled_seconds: int, ignore_seed_peer: bool, ignore_speed: bool) -> str:
|
||||
"""Return a stable key for the stalled rules that started the current timer."""
|
||||
# Note: Changing ignore switches or thresholds restarts existing stalled timers instead of reusing old rows.
|
||||
return f"v4|speed={int(min_speed or 0)}|seeds={int(min_seeds or 0)}|peers={int(min_peers or 0)}|seconds={int(stalled_seconds or 0)}|ignore_sources={int(bool(ignore_seed_peer))}|ignore_speed={int(bool(ignore_speed))}"
|
||||
# Note: Version bump clears old timers created by the previous ignore-speed/source behavior.
|
||||
return f"v5|speed={int(min_speed or 0)}|seeds={int(min_seeds or 0)}|peers={int(min_peers or 0)}|seconds={int(stalled_seconds or 0)}|ignore_sources={int(bool(ignore_seed_peer))}|ignore_speed={int(bool(ignore_speed))}"
|
||||
|
||||
|
||||
def _is_low_activity_download(t: dict[str, Any], min_speed: int, min_seeds: int, min_peers: int, ignore_seed_peer: bool = False, ignore_speed: bool = False) -> bool:
|
||||
def _is_low_activity_download(t: dict[str, Any], min_speed: int, min_seeds: int, min_peers: int, stalled_seconds: int, ignore_seed_peer: bool = False, ignore_speed: bool = False) -> bool:
|
||||
"""Return True when a started torrent is weak and should be stopped first."""
|
||||
# Note: Stop priority uses only criteria that are not ignored, so disabled criteria cannot stop torrents earlier.
|
||||
# Note: Active transfers are never preferred for cleanup while non-transferring rows are available.
|
||||
if _has_recent_transfer_activity(t, stalled_seconds):
|
||||
return False
|
||||
low_speed = False if ignore_speed else int(t.get('down_rate') or 0) <= max(0, int(min_speed or 0))
|
||||
low_seeds = False if ignore_seed_peer else int(t.get('seeds') or 0) <= max(0, int(min_seeds or 0))
|
||||
low_peers = False if ignore_seed_peer or min_peers <= 0 else int(t.get('peers') or 0) <= max(0, int(min_peers or 0))
|
||||
@@ -1232,9 +1249,9 @@ def check(profile: dict | None = None, user_id: int | None = None, force: bool =
|
||||
ignored_seed_peer_count += 1
|
||||
if ignore_speed and int(t.get('down_rate') or 0) <= max(0, int(min_speed or 0)):
|
||||
ignored_speed_count += 1
|
||||
is_stalled = _is_stalled_download(t, min_speed, min_seeds, min_peers, ignore_seed_peer, ignore_speed)
|
||||
is_stalled = _is_stalled_download(t, min_speed, min_seeds, min_peers, stalled_seconds, ignore_seed_peer, ignore_speed)
|
||||
# Note: Hard-limit enforcement uses only non-ignored weak criteria before choosing weak items.
|
||||
if _is_low_activity_download(t, min_speed, min_seeds, min_peers, ignore_seed_peer, ignore_speed):
|
||||
if _is_low_activity_download(t, min_speed, min_seeds, min_peers, stalled_seconds, ignore_seed_peer, ignore_speed):
|
||||
stop_eligible.append(t)
|
||||
h = str(t.get('hash') or '')
|
||||
if not h:
|
||||
|
||||
Reference in New Issue
Block a user