Integrate dead torrent cleanup into Manager loop

Move dead torrent detection logic from 50 MrtveTorrenty.py into 70 Manager.py as step 1b, so the manager handles completed, dead, and new torrents in a single run cycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-18 13:54:35 +01:00
parent c4f2d8b13d
commit 3ce8fa0080

View File

@@ -14,12 +14,16 @@ Oba klienti sdílí stejnou DB frontu. Torrent "nárokovaný" jedním klientem
import pymysql
import qbittorrentapi
import sys
from datetime import datetime
from datetime import datetime, timedelta
# ============================================================
# CONFIG
# ============================================================
DEAD_AFTER_HOURS = 72 # progress < 95% po 72h → dead
DEAD_PROGRESS_THRESHOLD = 95.0
STUCK_AFTER_HOURS = 168 # progress >= 95% ale < 100% po 7 dnech → dead
CLIENTS = [
{
"name": "UltraCC Seedbox",
@@ -142,6 +146,68 @@ def handle_completed(qbt, cursor):
return removed
# ============================================================
# STEP 1b: Handle dead torrents (z 50 MrtveTorrenty.py)
# ============================================================
def handle_dead_torrents(qbt, cursor):
"""
Mrtvé torrenty: nízký progress po 72h NEBO zaseknutý >= 95% po 7 dnech.
Smaže z qBittorrentu včetně souborů a označí v DB jako incomplete.
"""
now = datetime.now()
deadline_a = now - timedelta(hours=DEAD_AFTER_HOURS)
deadline_b = now - timedelta(hours=STUCK_AFTER_HOURS)
dead_count = 0
for t in qbt.torrents_info():
# Přeskočit dokončené
if t.completion_on and t.completion_on > 0:
continue
added_on = t.added_on
if not added_on:
continue
added_dt = datetime.fromtimestamp(added_on)
progress_pct = float(t.progress) * 100.0
# Kritérium A: nízký progress po 72h
is_dead_a = (added_dt <= deadline_a) and (progress_pct < DEAD_PROGRESS_THRESHOLD)
# Kritérium B: zaseknutý blízko 100% po 7 dnech
is_dead_b = (added_dt <= deadline_b) and (progress_pct >= DEAD_PROGRESS_THRESHOLD) and (progress_pct < 100.0)
if not is_dead_a and not is_dead_b:
continue
thash = t.hash.lower()
reason = "nízký progress po 72h" if is_dead_a else "zaseknutý blízko 100% po 7 dnech"
print(f" 💀 MRTVÝ ({reason}): {t.name[:50]}")
print(f" Progress: {progress_pct:.1f}% | Stav: {t.state} | Seeds: {t.num_seeds}")
try:
qbt.torrents_delete(torrent_hashes=thash, delete_files=True)
except Exception as e:
print(f" ❌ Smazání selhalo: {e}")
continue
cursor.execute("""
UPDATE torrents
SET
qb_state = 'incomplete',
qb_progress = %s,
qb_last_update = NOW()
WHERE torrent_hash = %s OR qb_hash = %s
""", (progress_pct, thash, thash))
dead_count += 1
return dead_count
# ============================================================
# STEP 2: Count active (non-completed) torrents in qBittorrent
# ============================================================
@@ -230,6 +296,14 @@ def process_client(client_cfg: dict, cursor):
if removed == 0:
print(f" │ Žádné dokončené.")
# Krok 1b: Mrtvé torrenty
print(f" │ [1b] Kontrola mrtvých torrentů...")
dead = handle_dead_torrents(qbt, cursor)
if dead == 0:
print(f" │ Žádné mrtvé.")
else:
print(f" │ Odstraněno mrtvých: {dead}")
# Krok 2: Stav slotů
active_hashes = get_active_hashes(qbt)
active = len(active_hashes)