#!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import pymysql import bencodepy from tqdm import tqdm # ===================================== # CONFIG # ===================================== ULTRACC_ROOT = r"\\tower\torrents\ultracc" DRY_MODE = False DB_CONFIG = dict( host="192.168.1.50", user="root", password="Vlado9674+", database="torrents", charset="utf8mb4" ) # ===================================== # TORRENT PARSER # ===================================== def parse_torrent(blob): data = bencodepy.decode(blob) info = data[b'info'] files = [] # multi file if b'files' in info: for f in info[b'files']: rel_path = "/".join(p.decode(errors="ignore") for p in f[b'path']) size = f[b'length'] files.append((rel_path, size)) multi = True else: name = info[b'name'].decode(errors="ignore") size = info[b'length'] files.append((name, size)) multi = False return files, multi # ===================================== # BUILD FILESYSTEM INDEX # ===================================== import pickle import os INDEX_FILE = r"U:\PycharmProjects\Torrents\fs_index_ultracc.pkl" FORCE_REBUILD = False def build_fs_index(): # ============================ # LOAD EXISTING INDEX # ============================ if os.path.exists(INDEX_FILE) and not FORCE_REBUILD: print("Načítám uložený filesystem index...") with open(INDEX_FILE, "rb") as f: index = pickle.load(f) print(f"Načten index ({len(index)} klíčů)") return index # ============================ # BUILD NEW INDEX # ============================ print("Indexuji filesystem...") index = {} pocet = 0 for root, _, files in os.walk(ULTRACC_ROOT): for f in files: full = os.path.join(root, f) try: size = os.path.getsize(full) except OSError: continue key = (f.lower(), size) pocet += 1 if pocet % 100 == 0: print(pocet) index.setdefault(key, []).append(full) print(f"Index obsahuje {len(index)} unikátních souborů") # ============================ # SAVE INDEX # ============================ print("Ukládám index na disk...") with open(INDEX_FILE, "wb") as f: pickle.dump(index, f, protocol=pickle.HIGHEST_PROTOCOL) print("Index uložen") return index # ===================================== # VALIDACE ROOTU # ===================================== def validate_root(root, torrent_files): for rel_path, size in torrent_files: check = os.path.join(root, rel_path.replace("/", os.sep)) if not os.path.exists(check): return False return True # ===================================== # MAIN # ===================================== def main(): fs_index = build_fs_index() conn = pymysql.connect(**DB_CONFIG) cur = conn.cursor() cur.execute(""" SELECT id, torrent_content FROM torrents WHERE torrent_content IS NOT NULL and physical_exists=FALSE """) rows = cur.fetchall() print(f"Torrentů ke kontrole: {len(rows)}") success = 0 for tid, blob in tqdm(rows): try: torrent_files, multi = parse_torrent(blob) # vezmeme největší soubor pro lookup rel_path, size = max(torrent_files, key=lambda x: x[1]) fname = os.path.basename(rel_path).lower() key = (fname, size) if key not in fs_index: continue found = False for full_path in fs_index[key]: if multi: # ROOT = odečtení relativní cesty root = full_path[:-len(rel_path)] root = root.rstrip("\\/") else: # single file root = os.path.dirname(full_path) if validate_root(root, torrent_files): found = True success += 1 print(f"[FOUND] Torrent {tid} → {root}") if not DRY_MODE: cur.execute(""" UPDATE torrents SET physical_exists = 1 WHERE id = %s """, (tid,)) break if not found: pass except Exception as e: print(f"ERROR torrent {tid}: {e}") if not DRY_MODE: conn.commit() print(f"Celkem nalezeno: {success}") cur.close() conn.close() if __name__ == "__main__": main()