import os import time import subprocess import threading import random import shutil import logging import requests import gc import json from flask import Flask, request, jsonify from huggingface_hub import HfApi app = Flask(__name__) logging.basicConfig(level=logging.INFO) DATASET_REPO = os.environ.get("DATASET_REPO") HF_TOKEN = os.environ.get("HF_TOKEN") RENDER_URL = os.environ.get("RENDER_URL") ACCOUNTS_FILE = "accounts.txt" WARP_PORT = 40000 api = HfApi(token=HF_TOKEN) # --- YARDIMCI KOMUTLAR --- def run_command(cmd): try: return subprocess.run(cmd, shell=True, capture_output=True, text=True) except Exception as e: print(f"⚠️ Komut Hatası: {e}", flush=True) return None def get_accounts(): if not os.path.exists(ACCOUNTS_FILE): return [] with open(ACCOUNTS_FILE, 'r') as f: return [line.strip() for line in f if ':' in line] def report_to_render(status, message, task_id, download_url=None): print(f"📡 Rapor: {status} - {message}", flush=True) if not RENDER_URL: return try: requests.post(f"{RENDER_URL}/webhook", json={ 'status': status, 'message': message, 'task_id': task_id, 'download_url': download_url }, timeout=10) except: pass # --- GÜVENLİ WARP YÖNETİMİ --- def rotate_warp_ip(): """WARP IP'sini güvenli bir şekilde değiştirir (Çökmeden)""" print("\n♻️ IP ROTASYONU BAŞLATILIYOR...", flush=True) try: os.system("pkill wireproxy") os.system("pkill wgcf") time.sleep(2) for f in ["wgcf-account.toml", "wgcf-profile.conf", "wireproxy.conf"]: if os.path.exists(f): try: os.remove(f) except: pass print("⚡ Cloudflare ile görüşülüyor...", flush=True) subprocess.run(["wgcf", "register", "--accept-tos"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=30) subprocess.run(["wgcf", "generate"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=30) if not os.path.exists("wgcf-profile.conf"): print("❌ WARP Config alınamadı!", flush=True) return False with open("wgcf-profile.conf", "r") as f: content = f.read() private_key = content.split("PrivateKey = ")[1].split("\n")[0].strip() address = content.split("Address = ")[1].split("\n")[0].strip() wp_conf = f"""[Interface] PrivateKey = {private_key} Address = {address} DNS = 1.1.1.1 [Peer] PublicKey = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo= AllowedIPs = 0.0.0.0/0 Endpoint = engage.cloudflareclient.com:2408 [Socks5] BindAddress = 127.0.0.1:{WARP_PORT}""" with open("wireproxy.conf", "w") as f: f.write(wp_conf) print(f"🚀 Tünel Açılıyor...", flush=True) subprocess.Popen(["wireproxy", "-c", "wireproxy.conf"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) time.sleep(5) return True except Exception as e: print(f"❌ IP Rotasyonunda Hata: {e}", flush=True) return False def safe_mega_reset(): """MegaCMD'yi güvenli sıfırlar""" try: os.system("pkill mega-cmd") time.sleep(2) subprocess.Popen(["nohup", "mega-cmd-server"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) time.sleep(5) except: pass def login_with_proxy(account_str): try: email, password = account_str.split(":", 1) proxy_url = f"socks5://127.0.0.1:{WARP_PORT}" subprocess.run(["mega-proxy", proxy_url], capture_output=True) print(f"🔑 Giriş Deneniyor: {email[:3]}***", flush=True) res = subprocess.run(["mega-login", email, password], capture_output=True, text=True, timeout=45) if res.returncode == 0: print("✅ Giriş Başarılı.", flush=True) return True else: print(f"❌ Giriş Başarısız: {res.stderr}", flush=True) return False except Exception as e: return False def get_mega_details(): try: res = subprocess.run(["mega-transfers"], capture_output=True, text=True) return res.stdout.strip() except: return "" def download_engine(link, task_id): try: print(f"\n⚙️ WORKER BAŞLADI: {task_id}", flush=True) base_dir = "downloads" abs_base = os.path.abspath(base_dir) download_folder = f"{abs_base}/{task_id}" zip_file = f"{abs_base}/{task_id}.zip" os.makedirs(download_folder, exist_ok=True) accounts = get_accounts() random.shuffle(accounts) if not accounts: return is_completed = False safe_mega_reset() rotate_warp_ip() for i, account in enumerate(accounts): if is_completed: break print(f"\n🔄 --- HESAP {i+1} / {len(accounts)} ---", flush=True) if not login_with_proxy(account): rotate_warp_ip() safe_mega_reset() if not login_with_proxy(account): continue print(f"📥 İNDİRME BAŞLATILIYOR...", flush=True) cmd = f'nohup mega-get "{link}" "{download_folder}" > /dev/null 2>&1 &' os.system(cmd) no_transfer_count = 0 loop_counter = 0 # 🔴 ZOMBİ VE HIZ KORUMASI V3 (Acımasız Mod) previous_active_transfers = [] stuck_counter = 0 while True: time.sleep(5) output = get_mega_details() lower_output = output.lower() lines = output.split('\n') # 1. Klasik Limit ve Ban Kontrolü if "bandwidth quota exceeded" in lower_output or "paused" in lower_output or "retrying" in lower_output: print("\n🚨 KOTA/IP BAN TESPİT EDİLDİ! Tünel Değiştiriliyor...", flush=True) os.system("pkill mega-get") if rotate_warp_ip(): safe_mega_reset() else: time.sleep(60) break # 2. V3 Zombi ve Hız Koruması (Tamamen Harf ve Rakam Kontrolü) # Sadece ACTIVE olan satırları bul ve listele current_active_transfers = [line for line in lines if "ACTIVE" in line] if current_active_transfers: # Eğer ACTIVE olan indirmeler bir önceki saniyeyle HARFİ HARFİNE aynıysa (Yani 1 KB bile inmediyse veya 100%'de takıldıysa) if current_active_transfers == previous_active_transfers: stuck_counter += 1 print(f"⚠️ HIZ SIFIR VEYA 100% BUG'I! (Tüneli patlatmaya son {6 - stuck_counter} adım)", flush=True) if stuck_counter >= 6: # 30 Saniye tık yoksa acıma print("\n💥 SİSTEM TIKANDI! Mega'nın kafasına sıkılıp Tünel değiştiriliyor...", flush=True) os.system("pkill mega-get") rotate_warp_ip() safe_mega_reset() stuck_counter = 0 break # Tüneli yeniler ve mega-get'i taze iple tetikler else: # Eğer 1 KB bile indiyse rakam değişeceği için sayacı sıfırla stuck_counter = 0 previous_active_transfers = current_active_transfers else: stuck_counter = 0 # 3. İndirme Bitiş Kontrolü if "no active transfers" in lower_output: loop_counter += 1 if loop_counter > 3: no_transfer_count += 1 if no_transfer_count >= 2: if len(os.listdir(download_folder)) > 0: print("\n✅ İNDİRME TAMAMLANDI!", flush=True) is_completed = True break else: break else: no_transfer_count = 0 # Terminale Temiz Log Basma for line in lines: if "TRANSFERRING" in line or "%" in line: print(f"📊 {line.strip()}", flush=True) loop_counter += 1 if is_completed: break time.sleep(2) if not is_completed: return print("📦 ZİPLENİYOR...", flush=True) shutil.make_archive(f"{abs_base}/{task_id}", 'zip', download_folder) print("📤 YÜKLENİYOR...", flush=True) try: api.upload_file( path_or_fileobj=zip_file, repo_id=DATASET_REPO, repo_type="dataset", path_in_repo=f"uploads/{task_id}.zip" ) print("✅ HUGGING FACE YÜKLEMESİ BAŞARILI!") except Exception as e: print(f"❌ Upload Hatası: {e}", flush=True) try: shutil.rmtree(download_folder, ignore_errors=True) os.remove(zip_file) except: pass gc.collect() except Exception as e: print(f"🔥 KRİTİK HATA: {e}", flush=True) @app.route('/process', methods=['POST']) def process(): data = request.json threading.Thread(target=download_engine, args=(data['link'], data.get('task_id', 'mega_task'))).start() return jsonify({'status': 'started'}) @app.route('/') def ui(): return """

Yael Mega-Worker Paneli 🚀



""" if __name__ == '__main__': app.run(host='0.0.0.0', port=7860)