Compare commits

..

1 Commits

Author SHA1 Message Date
3ce8fa0080 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>
2026-03-18 13:54:35 +01:00

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)