import pymysql import re import time import qbittorrentapi # ============================================================ # KONFIGURACE # ============================================================ MAX_SIZE_GB = 950 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, } # ============================================================ # POMOCNÉ FUNKCE # ============================================================ def parse_size_to_gb(size_str): """Převede text '1.5 GB' nebo '500 MB' na float v GB""" if not size_str: return 0.0 s = str(size_str).upper().replace(",", ".").strip() match = re.search(r"([\d\.]+)", s) if not match: return 0.0 val = float(match.group(1)) if "TB" in s: return val * 1024 if "GB" in s: return val if "MB" in s: return val / 1024 if "KB" in s: return val / 1024 / 1024 return 0.0 # ============================================================ # HLAVNÍ LOGIKA # ============================================================ def main(): print(f"🚀 Plánuji přímý upload z DB (Limit: {MAX_SIZE_GB} GB, řazeno dle seederů)...") # 1. Načtení dat z DB # Stahujeme i BLOB (torrent_content), takže to může chvilku trvat db = pymysql.connect(**DB_CONFIG) cursor = db.cursor() print("⏳ Načítám data z MySQL...") sql = """ SELECT torrent_hash, title_visible, size_pretty, seeders, torrent_content FROM torrents WHERE physical_exists = 0 AND torrent_content IS NOT NULL ORDER BY seeders DESC """ cursor.execute(sql) rows = cursor.fetchall() db.close() print(f"🔍 Nalezeno {len(rows)} kandidátů. Vybírám ty nejlepší...") # 2. Výběr do kapacity 950 GB selected_torrents = [] total_size_gb = 0.0 for row in rows: t_hash, title, size_str, seeders, content = row size_gb = parse_size_to_gb(size_str) # Pojistka proti nesmyslně velkým souborům nebo chybám v parsování if size_gb == 0 and "MB" not in str(size_str).upper() and "KB" not in str(size_str).upper(): pass # Kontrola limitu if total_size_gb + size_gb > MAX_SIZE_GB: # Jakmile narazíme na něco, co se nevejde, končíme výběr (protože jsou seřazeny dle priority) print(f"🛑 Limit naplněn! '{title}' ({size_gb:.2f} GB) by přesáhl {MAX_SIZE_GB} GB.") break selected_torrents.append({ "filename": f"{t_hash}.torrent", # Virtuální název souboru "content": content, # Binární data "title": title, "size": size_gb, "seeders": seeders }) total_size_gb += size_gb # 3. Report print("-" * 40) print(f"📦 Vybráno: {len(selected_torrents)} torrentů") print(f"💾 Celková velikost: {total_size_gb:.2f} GB / {MAX_SIZE_GB} GB") if selected_torrents: avg_seeders = sum(t['seeders'] for t in selected_torrents) / len(selected_torrents) print(f"⚡ Průměrně seederů: {avg_seeders:.1f}") print("-" * 40) if not selected_torrents: print("Nic k nahrání.") exit() confirm = input("❓ Nahrát tento výběr na Seedbox? (ano/ne): ") if confirm.lower() not in ['ano', 'y', 'yes']: print("❌ Zrušeno.") exit() # 4. Připojení k qBittorrent try: qbt = qbittorrentapi.Client( host=QBT_URL, username=QBT_USER, password=QBT_PASS, VERIFY_WEBUI_CERTIFICATE=False ) qbt.auth_log_in() print("✅ Připojeno k Seedboxu.") except Exception as e: print(f"❌ Chyba připojení: {e}") exit() # 5. Odeslání dat print("🚀 Odesílám...") success_count = 0 for i, item in enumerate(selected_torrents): try: # Posíláme binární data přímo (tváříme se, že posíláme soubor) # formát: {'nazev_souboru.torrent': b'binarni_data...'} file_dict = {item['filename']: item['content']} qbt.torrents_add(torrent_files=file_dict, is_paused=False) print(f"[{i + 1}/{len(selected_torrents)}] 📤 {item['title']} ({item['size']:.1f} GB)") success_count += 1 time.sleep(0.2) # Malá pauza pro stabilitu API except Exception as e: print(f"❌ Chyba u {item['title']}: {e}") print("\n✅ HOTOVO.") print("Torrenty jsou na Seedboxu. Až se stáhnou, stáhni je domů a spusť skript 99_Scan...") if __name__ == "__main__": main()