import pymysql import qbittorrentapi from datetime import datetime # ============================================================ # CONFIG # ============================================================ DRY_RUN = False # ← change to True for testing 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("🚀 UltraCC completed torrent cleanup") print(f"DRY_RUN = {DRY_RUN}") print("------------------------------------------------") qbt = connect_qbt() db = connect_db() cursor = db.cursor() torrents = qbt.torrents_info() removed_count = 0 skipped_count = 0 updated_db_count = 0 for t in torrents: # ---------------------------------------------------- # Only completed torrents # ---------------------------------------------------- if not t.completion_on: continue thash = t.hash.lower() name = t.name state = t.state completion_dt = datetime.fromtimestamp(t.completion_on) # ---------------------------------------------------- # Check DB # ---------------------------------------------------- cursor.execute(""" SELECT qb_completed_datetime FROM torrents WHERE torrent_hash = %s """, (thash,)) row = cursor.fetchone() # ==================================================== # CASE 1 — Torrent completed in qBittorrent but NOT in DB # → Update DB + Remove torrent # ==================================================== if not row or not row[0]: print(f"✔ COMPLETED (DB update required): {name}") print(f" Completion time: {completion_dt}") if not DRY_RUN: cursor.execute(""" UPDATE torrents SET qb_state = %s, qb_progress = 1, qb_completed_datetime = %s, qb_last_update = NOW() WHERE torrent_hash = %s """, (f"completed_removed ({state})", completion_dt, thash)) updated_db_count += 1 # Remove torrent if DRY_RUN: print(" [DRY] Would remove torrent") else: qbt.torrents_delete(delete_files=False, torrent_hashes=thash) removed_count += 1 continue # ==================================================== # CASE 2 — Torrent completed in qBittorrent AND already completed in DB # → Just remove torrent # ==================================================== if row and row[0]: print(f"✔ COMPLETED (Already in DB → removing): {name}") if DRY_RUN: print(" [DRY] Would remove torrent") else: qbt.torrents_delete(delete_files=False, torrent_hashes=thash) removed_count += 1 continue skipped_count += 1 # ========================================================= # SUMMARY # ========================================================= print("------------------------------------------------") print(f"Removed torrents : {removed_count}") print(f"DB updated : {updated_db_count}") print(f"Skipped torrents : {skipped_count}") print(f"DRY_RUN : {DRY_RUN}") print("------------------------------------------------") if __name__ == "__main__": main()