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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user