Add Seedbox/50 MrtveTorrenty.py — dead torrent cleanup for UltraCC seedbox
This commit is contained in:
152
Seedbox/50 MrtveTorrenty.py
Normal file
152
Seedbox/50 MrtveTorrenty.py
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
import pymysql
|
||||||
|
import qbittorrentapi
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# CONFIG
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
DRY_RUN = True # ← změň na False až si ověříš výstup
|
||||||
|
|
||||||
|
DEAD_AFTER_HOURS = 72 # torrent musí být v qB alespoň tolik hodin
|
||||||
|
DEAD_PROGRESS_THRESHOLD = 95.0 # pokud je progress < tato % po uplynutí doby → dead
|
||||||
|
|
||||||
|
QBT_URL = "https://vladob.zen.usbx.me/qbittorrent"
|
||||||
|
QBT_USER = "vladob"
|
||||||
|
QBT_PASS = "jCni3U6d#y4bfcm"
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "192.168.1.50",
|
||||||
|
"port": 3306,
|
||||||
|
"user": "root",
|
||||||
|
"password": "Vlado9674+",
|
||||||
|
"database": "torrents",
|
||||||
|
"charset": "utf8mb4",
|
||||||
|
"autocommit": True,
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# CONNECT
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
def connect_qbt():
|
||||||
|
qbt = qbittorrentapi.Client(
|
||||||
|
host=QBT_URL,
|
||||||
|
username=QBT_USER,
|
||||||
|
password=QBT_PASS,
|
||||||
|
VERIFY_WEBUI_CERTIFICATE=False
|
||||||
|
)
|
||||||
|
qbt.auth_log_in()
|
||||||
|
return qbt
|
||||||
|
|
||||||
|
|
||||||
|
def connect_db():
|
||||||
|
return pymysql.connect(**DB_CONFIG)
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# MAIN
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print("MRTVÉ TORRENTY — UltraCC Seedbox cleanup")
|
||||||
|
print(f"DRY_RUN = {DRY_RUN}")
|
||||||
|
print(f"Kritéria : v qB déle než {DEAD_AFTER_HOURS}h A progress < {DEAD_PROGRESS_THRESHOLD}%")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
qbt = connect_qbt()
|
||||||
|
db = connect_db()
|
||||||
|
cursor = db.cursor()
|
||||||
|
|
||||||
|
torrents = qbt.torrents_info()
|
||||||
|
|
||||||
|
now = datetime.now()
|
||||||
|
deadline = now - timedelta(hours=DEAD_AFTER_HOURS)
|
||||||
|
|
||||||
|
dead_count = 0
|
||||||
|
skip_count = 0
|
||||||
|
error_count = 0
|
||||||
|
|
||||||
|
for t in torrents:
|
||||||
|
|
||||||
|
# Přeskočit dokončené (ty řeší skript 40)
|
||||||
|
if t.completion_on:
|
||||||
|
skip_count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
added_on = t.added_on # unix timestamp
|
||||||
|
if not added_on:
|
||||||
|
skip_count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
added_dt = datetime.fromtimestamp(added_on)
|
||||||
|
progress_pct = float(t.progress) * 100.0
|
||||||
|
|
||||||
|
# Torrent ještě není dost starý
|
||||||
|
if added_dt > deadline:
|
||||||
|
skip_count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Progress je OK (téměř hotov) → přeskočit
|
||||||
|
if progress_pct >= DEAD_PROGRESS_THRESHOLD:
|
||||||
|
skip_count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# ── Torrent splňuje kritéria "mrtvý" ──────────────────
|
||||||
|
thash = t.hash.lower()
|
||||||
|
age_hours = (now - added_dt).total_seconds() / 3600
|
||||||
|
|
||||||
|
print(f"\n💀 MRTVÝ: {t.name}")
|
||||||
|
print(f" Přidán : {added_dt} ({age_hours:.1f}h zpět)")
|
||||||
|
print(f" Progress : {progress_pct:.1f}%")
|
||||||
|
print(f" Stav : {t.state}")
|
||||||
|
print(f" Seeds : {t.num_seeds} Peers: {t.num_leechs}")
|
||||||
|
|
||||||
|
if DRY_RUN:
|
||||||
|
print(f" [DRY] Smazal bych z qBittorrentu a označil v DB jako incomplete")
|
||||||
|
dead_count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Smazat z qBittorrentu (i soubory — nekompletní data jsou k ničemu)
|
||||||
|
try:
|
||||||
|
qbt.torrents_delete(torrent_hashes=thash, delete_files=True)
|
||||||
|
print(f" ✔ Smazán z qBittorrentu")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ❌ Smazání selhalo: {e}")
|
||||||
|
error_count += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Označit v DB jako incomplete
|
||||||
|
cursor.execute("""
|
||||||
|
UPDATE torrents
|
||||||
|
SET
|
||||||
|
qb_state = 'incomplete',
|
||||||
|
qb_progress = %s,
|
||||||
|
qb_last_update = NOW()
|
||||||
|
WHERE torrent_hash = %s
|
||||||
|
""", (progress_pct, thash))
|
||||||
|
|
||||||
|
if cursor.rowcount > 0:
|
||||||
|
print(f" ✔ DB → incomplete (progress={progress_pct:.1f}%)")
|
||||||
|
else:
|
||||||
|
print(f" ⚠ DB: žádný řádek pro hash {thash}")
|
||||||
|
|
||||||
|
dead_count += 1
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# SUMMARY
|
||||||
|
# ============================================================
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print(f"Mrtvé torrenty zpracováno : {dead_count}")
|
||||||
|
print(f"Přeskočeno : {skip_count}")
|
||||||
|
print(f"Chyby : {error_count}")
|
||||||
|
print(f"DRY_RUN : {DRY_RUN}")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user