From f1a596743094c9e84b5c45ead9665be8fb21183c Mon Sep 17 00:00:00 2001 From: Vladimir Buzalka Date: Mon, 9 Feb 2026 18:08:19 +0100 Subject: [PATCH] git --- Seedbox/10 Nahraniexistujicich.py | 219 +++++++++++++++++++----------- 1 file changed, 137 insertions(+), 82 deletions(-) diff --git a/Seedbox/10 Nahraniexistujicich.py b/Seedbox/10 Nahraniexistujicich.py index 5a3a088..ecbe631 100644 --- a/Seedbox/10 Nahraniexistujicich.py +++ b/Seedbox/10 Nahraniexistujicich.py @@ -4,9 +4,11 @@ import time import qbittorrentapi # ============================================================ -# KONFIGURACE +# CONFIG # ============================================================ MAX_SIZE_GB = 950 +DRY_RUN = False + QBT_URL = "https://vladob.zen.usbx.me/qbittorrent" QBT_USER = "vladob" QBT_PASS = "jCni3U6d#y4bfcm" @@ -21,130 +23,183 @@ DB_CONFIG = { "autocommit": True, } - # ============================================================ -# POMOCNÉ FUNKCE +# SIZE PARSER # ============================================================ 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 + 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 + 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 + 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 +# MAIN # ============================================================ 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 + print("=" * 60) + print("TORRENT DOWNLOAD SCHEDULER") + print(f"DRY_RUN = {DRY_RUN}") + print("=" * 60) + + # -------------------------------------------------------- + # DB LOAD + # -------------------------------------------------------- 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 + print("📥 Loading DB candidates...") + + cursor.execute(""" + SELECT + torrent_hash, + title_visible, + size_pretty, + seeders, + torrent_content + FROM torrents + WHERE + qb_completed_datetime IS NULL + 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ší...") + print(f"Candidates from DB: {len(rows)}") - # 2. Výběr do kapacity 950 GB - selected_torrents = [] - total_size_gb = 0.0 + # -------------------------------------------------------- + # CONNECT QBITTORRENT + # -------------------------------------------------------- + print("🔌 Connecting qBittorrent...") + + qbt = qbittorrentapi.Client( + host=QBT_URL, + username=QBT_USER, + password=QBT_PASS, + VERIFY_WEBUI_CERTIFICATE=False + ) + qbt.auth_log_in() + + qb_hashes = {t.hash.lower() for t in qbt.torrents_info()} + + print(f"qB active torrents: {len(qb_hashes)}") + + # -------------------------------------------------------- + # SELECTION + # -------------------------------------------------------- + selected = [] + total_size = 0.0 for row in rows: + t_hash, title, size_str, seeders, content = row + t_hash = t_hash.lower() + + # Guard 3 – already in qB + if t_hash in qb_hashes: + print(f"⏭ Already in qB → {title}") + continue + 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.") + if total_size + size_gb > MAX_SIZE_GB: + print(f"🛑 Capacity reached → {title}") break - selected_torrents.append({ - "filename": f"{t_hash}.torrent", # Virtuální název souboru - "content": content, # Binární data + selected.append({ + "hash": t_hash, "title": title, "size": size_gb, - "seeders": seeders + "seeders": seeders, + "content": content }) - 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) + total_size += size_gb - if not selected_torrents: - print("Nic k nahrání.") - exit() + print(f"✅ Selected → {title} | {size_gb:.2f} GB | seeders={seeders}") - confirm = input("❓ Nahrát tento výběr na Seedbox? (ano/ne): ") - if confirm.lower() not in ['ano', 'y', 'yes']: - print("❌ Zrušeno.") - exit() + # -------------------------------------------------------- + # REPORT + # -------------------------------------------------------- + print("-" * 50) + print(f"Selected torrents: {len(selected)}") + print(f"Total size: {total_size:.2f} GB / {MAX_SIZE_GB} GB") + print("-" * 50) - # 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() + if not selected: + print("Nothing to schedule.") + return - # 5. Odeslání dat - print("🚀 Odesílám...") - success_count = 0 + if not DRY_RUN: + confirm = input("Upload to qBittorrent? (ano/ne): ") + if confirm.lower() not in ["ano", "yes", "y"]: + print("Cancelled.") + return + + # -------------------------------------------------------- + # UPLOAD LOOP + # -------------------------------------------------------- + print("🚀 Uploading torrents...") + + success = 0 + + for i, item in enumerate(selected): - 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) + if DRY_RUN: + print(f"[DRY] Would upload: {item['title']}") + continue - 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 + file_dict = { + f"{item['hash']}.torrent": item["content"] + } + + qbt.torrents_add( + torrent_files=file_dict, + is_paused=False + ) + + # Mark scheduled in DB + cursor.execute(""" + UPDATE torrents + SET + qb_state = 'scheduled', + qb_last_update = NOW() + WHERE torrent_hash = %s + """, (item["hash"],)) + + print(f"[{i+1}/{len(selected)}] Uploaded → {item['title']}") + success += 1 + + time.sleep(0.2) except Exception as e: - print(f"❌ Chyba u {item['title']}: {e}") + print(f"❌ Error uploading {item['title']}: {e}") - print("\n✅ HOTOVO.") - print("Torrenty jsou na Seedboxu. Až se stáhnou, stáhni je domů a spusť skript 99_Scan...") + print("\n✔ DONE") + print(f"Uploaded torrents: {success}") + + db.close() if __name__ == "__main__": - main() \ No newline at end of file + main()