Fix the script,  it keeps repeating the proxy checking after all have been checked. One proxies are checked it should update the file then continue to Generating links and checking them.                                                              import random                                                                         import string                                                                         import requests                                                                       import time
import re                                                                             import threading                                                                      from concurrent.futures import ThreadPoolExecutor, as_completed                       from datetime import datetime, timedelta                                                                                                                                    # Import colorama for colored console output                                          from colorama import init, Fore, Style                                                                                                                                      # Initialize colorama                                                                 init(autoreset=True)                                                                  
# Constants                                                                           GOFILE_URL_TEMPLATE = "https://gofile.io/d/{}"                                        DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/..."  # Replace with your webhook URL
PROXY_FILE = "gofileproxies.txt"                                                      PROXY_SOURCE_URL = "https://raw.githubusercontent.com/officialputuid/KangProxy/refs/heads/KangProxy/https/https.txt"                                                        PROXY_VALIDATION_URL = "https://www.google.com/humans.txt"                            MAX_PROXY_VALIDATION_WORKERS = 50  # Adjust based on your system's capabilities                                                                                             # Thread-local storage for per-thread Session objects
thread_local = threading.local()                                                                                                                                            # Shared variables and locks for thread safety                                        valid_urls = []                                                                       valid_urls_lock = threading.Lock()                                                    rate_limited_lock = threading.Lock()                                                  proxies_list_lock = threading.Lock()                                                  print_lock = threading.Lock()  # Lock for printing to console                                                                                                               rate_limited = False                                                                  rate_limit_reset_time = None  # Time when rate limit is expected to reset
                                                                                      # Shared proxy list and index                                                         proxies_list = []                                                                     proxy_index = 0  # Index to track which proxy to use next
                                                                                      def download_and_update_proxies():                                                        """Download proxies from the source URL, validate them, and update the proxy list."""                                                                                       global proxies_list, proxy_index                                                      try:                                                                                      response = requests.get(PROXY_SOURCE_URL, timeout=10)                                 if response.status_code == 200:                                                           proxy_content = response.text.strip()                                                 # Save proxies to file                                                                with open(PROXY_FILE, 'w') as f:                                                          f.write(proxy_content)                                                            with print_lock:                                                                          print(f"{Fore.CYAN}[INFO] Proxies updated from source URL. Total proxies fetched: {len(proxy_content.splitlines())}")                                                   # Validate proxies                                                                    raw_proxies = [line.strip() for line in proxy_content.splitlines() if line.strip()]
            validated_proxies = validate_proxies(raw_proxies)                                     with proxies_list_lock:                                                                   proxies_list = validated_proxies                                                      proxy_index = 0  # Reset the index when proxies are updated
            with print_lock:                                                                          print(f"{Fore.CYAN}[INFO] Total proxies after validation: {len(proxies_list)}")                                                                                     else:                                                                                     with print_lock:                                                                          print(f"{Fore.YELLOW}[WARNING] Failed to download proxies. Status code: {response.status_code}")
    except requests.RequestException as e:                                                    with print_lock:                                                                          print(f"{Fore.RED}[ERROR] Exception occurred while downloading proxies: {e}")
                                                                                      def start_proxy_updater():                                                                """Start a background thread to update proxies every 30 minutes."""                   def proxy_updater():                                                                      while True:                                                                               download_and_update_proxies()                                                         time.sleep(1800)  # Sleep for 30 minutes
    updater_thread = threading.Thread(target=proxy_updater, daemon=True)                  updater_thread.start()                                                                                                                                                  def validate_proxy(proxy, session, progress_data):                                        """Validate a single proxy by attempting to connect to PROXY_VALIDATION_URL."""       test_url = PROXY_VALIDATION_URL                                                       proxy_dict = {'http': proxy, 'https': proxy}                                          try:                                                                                      response = session.get(test_url, proxies=proxy_dict, timeout=10)                      if response.status_code == 200:                                                           with progress_data['lock']:                                                               progress_data['valid_count'] += 1                                                 with print_lock:                                                                          print(f"{Fore.GREEN}[VALID PROXY] {proxy}")                                       return True
    except requests.RequestException:                                                         with progress_data['lock']:                                                               progress_data['invalid_count'] += 1                                               with print_lock:                                                                          print(f"{Fore.RED}[INVALID PROXY] {proxy}")                                   return False                                                                      
def validate_proxies(proxy_list):                                                         """Validate proxies using threading and return a list of valid proxies."""            validated_proxies = []                                                                total_proxies = len(proxy_list)                                                       progress_data = {                                                                         'valid_count': 0,                                                                     'invalid_count': 0,                                                                   'lock': threading.Lock()                                                          }                                                                                                                                                                           with ThreadPoolExecutor(max_workers=MAX_PROXY_VALIDATION_WORKERS) as executor:
        session = requests.Session()                                                          futures = []                                                                          for proxy in proxy_list:                                                                  futures.append(executor.submit(validate_proxy, proxy, session, progress_data))                                                                                                                                                                                # Wait for all futures to complete                                                    for _ in as_completed(futures):                                                           with progress_data['lock']:                                                               total_valid = progress_data['valid_count']                                            total_invalid = progress_data['invalid_count']
                total_checked = total_valid + total_invalid                                           # Display progress                                                                    with print_lock:                                                                          print(f"{Fore.CYAN}[PROXY VALIDATION PROGRESS] {total_checked}/{total_proxies} checked, {Fore.GREEN}{total_valid} valid{Fore.CYAN}, {Fore.RED}{total_invalid} invalid")                                                                                                                                                                 return [proxy for proxy, future in zip(proxy_list, futures) if future.result()]                                                                                         def generate_random_string(length=6):                                                     """Generate a random string of letters and digits."""
    return ''.join(random.choices(string.ascii_letters + string.digits, k=length))                                                                                          def get_session():                                                                        """Get a Session object for the current thread to enable connection pooling."""       if not hasattr(thread_local, "session"):                                                  session = requests.Session()                                                          # Set up retry strategy                                                               retries = requests.adapters.Retry(                                                        total=5,  # Increase total retries                                                    backoff_factor=0.5,  # Increase backoff between retries                               status_forcelist=[500, 502, 503, 504],
            allowed_methods=["HEAD", "GET", "OPTIONS"]                                        )                                                                                     adapter = requests.adapters.HTTPAdapter(max_retries=retries)                          session.mount('http://', adapter)
        session.mount('https://', adapter)                                                    thread_local.session = session                                                    return thread_local.session                                                                                                                                             def get_proxy():                                                                          """Get the next proxy from the list in a thread-safe manner."""                       global proxy_index
    with proxies_list_lock:                                                                   if proxies_list:                                                                          # Rotate through the proxy list                                                       proxy = proxies_list[proxy_index % len(proxies_list)]                                 proxy_index += 1                                                                      # Format the proxy for requests                                                       proxy_dict = {"http": proxy, "https": proxy}                                          return proxy_dict                                                                 else:                                                                                     return None                                                               
def check_rate_limit(response):                                                           """Check if the response indicates rate limiting."""                                  # Check for HTTP 429 Too Many Requests                                                if response.status_code == 429:                                                           retry_after = response.headers.get("Retry-After")                                     return True, retry_after                                                          # Check for custom rate limit headers or messages                                     # Example: GoFile might return a 403 with specific message                            if response.status_code == 403:                                                           if "Rate limit exceeded" in response.text:                                                return True, None
    # Add any additional checks specific to GoFile's rate limiting responses              return False, None                                                                                                                                                      def check_gofile_url_html(random_string):                                                 """                                                                                   Check if the randomly generated GoFile URL is valid by looking for a specific meta tag.                                                                                     Returns a tuple of (valid, url).                                                      """                                                                                   global rate_limited, rate_limit_reset_time                                            session = get_session()
    url = GOFILE_URL_TEMPLATE.format(random_string)                                       download_meta_pattern = r"<meta name='description' content='\d+ downloads' />"                                                                                              # Decide whether to use a proxy                                                       with rate_limited_lock:                                                                   current_rate_limited = rate_limited                                                                                                                                     if current_rate_limited:                                                                  proxy = get_proxy()                                                               else:                                                                                     proxy = None
                                                                                          try:                                                                                      response = session.get(url, timeout=15, proxies=proxy)                                                                                                                      # Check for rate limiting                                                             is_rate_limited, retry_after = check_rate_limit(response)                             if is_rate_limited:                                                                       with rate_limited_lock:                                                                   if not rate_limited:                                                                      with print_lock:                                                                          print(f"{Fore.YELLOW}[INFO] Rate limiting detected. Switching to proxies.")                                                                                             rate_limited = True                                                               # Set rate limit reset time based on Retry-After header if available                  if retry_after:                                                                           try:                                                                                      retry_after_seconds = int(retry_after)                                                rate_limit_reset_time = datetime.now() + timedelta(seconds=retry_after_seconds)                                                                                         except ValueError:                                                                        rate_limit_reset_time = datetime.now() + timedelta(minutes=1)                 else:                                                                                     # Default to 1 minute if Retry-After is not provided or invalid                       rate_limit_reset_time = datetime.now() + timedelta(minutes=1)                 return None, url                                                                                                                                                        # Process the response                                                                if response.status_code == 200:                                                           html_content = response.text                                                          if re.search(download_meta_pattern, html_content, re.IGNORECASE):                         return True, url                                                                  return False, url                                                                 else:                                                                                     return False, url                                                             except requests.exceptions.ConnectTimeout as e:                                           with print_lock:                                                                          print(f"{Fore.RED}[ERROR] Connection timed out for {url}: {e}")               except requests.exceptions.ProxyError as e:                                               with print_lock:                                                                          print(f"{Fore.RED}[ERROR] Proxy error with proxy {proxy}: {e}")               except requests.RequestException as e:                                                    with print_lock:                                                                          print(f"{Fore.RED}[ERROR] Request failed for {url}: {e}")                     return None, url                                                                                                                                                        def send_to_discord(urls):                                                                """Send the valid URLs to the specified Discord webhook in batches."""                # Format the message                                                                  content = "**Valid URLs found:**\n"                                                   for i, url in enumerate(urls, 1):                                                         content += f"{i}. {url}\n"                                                        data = {"content": content}                                                                                                                                                 try:                                                                                      response = requests.post(DISCORD_WEBHOOK_URL, json=data, timeout=10)                  if response.status_code not in (200, 204):                                                with print_lock:                                                                          print(f"{Fore.RED}[ERROR] Discord webhook failed with status code {response.status_code}: {response.text}")                                                     except requests.RequestException as e:                                                    with print_lock:                                                                          print(f"{Fore.RED}[ERROR] Failed to send data to Discord: {e}")                                                                                                 def worker():                                                                             """Worker function to generate a URL, check it, and collect valid URLs in batches."""                                                                                       random_string = generate_random_string()                                              url = GOFILE_URL_TEMPLATE.format(random_string)                                                                                                                             # Print that we're checking the URL                                                   with print_lock:                                                                          print(f"{Fore.CYAN}[CHECKING] Checking URL: {url}")                                                                                                                     valid, url = check_gofile_url_html(random_string)                                                                                                                           # Handle rate limit reset                                                             global rate_limited, rate_limit_reset_time                                            with rate_limited_lock:                                                                   if rate_limited and rate_limit_reset_time:                                                if datetime.now() >= rate_limit_reset_time:                                               with print_lock:                                                                          print(f"{Fore.YELLOW}[INFO] Rate limit period elapsed. Switching back to no proxy.")                                                                                    rate_limited = False                                                                  rate_limit_reset_time = None
                                                                                          if valid is True:                                                                         with print_lock:                                                                          print(f"{Fore.GREEN}[FOUND] URL exists: {url}")                                                                                                                         urls_to_send = None  # Placeholder for batch sending                                  with valid_urls_lock:                                                                     valid_urls.append(url)                                                                if len(valid_urls) >= 5:                                                                  # Copy the list to send and clear the shared list                                     urls_to_send = valid_urls.copy()                                                      valid_urls.clear()                                                                                                                                                  # Send the batch outside the lock to avoid blocking other threads                     if urls_to_send:                                                                          send_to_discord(urls_to_send)                                                 elif valid is False:                                                                      with print_lock:                                                                          print(f"{Fore.RED}[NOT FOUND] URL does not exist: {url}")                     else:                                                                                     # None indicates an error or rate limit; errors are already handled                   with print_lock:                                                                          print(f"{Fore.YELLOW}[ERROR] Could not determine existence of URL: {url}")                                                                                      def main():                                                                               # Download proxies at the start and start the proxy updater thread                    download_and_update_proxies()                                                         start_proxy_updater()                                                                                                                                                       max_workers = 50          # Adjust based on your system's capabilities                max_pending_tasks = 500   # Limit the number of pending tasks to control memory usage                                                                                                                                                                             with ThreadPoolExecutor(max_workers=max_workers) as executor:                             futures = set()                                                                       try:                                                                                      while True:                                                                               # Remove completed futures from the set                                               futures = {future for future in futures if not future.done()}                                                                                                               # If the number of pending tasks is below the threshold, submit new tasks                                                                                                   if len(futures) < max_pending_tasks:                                                      future = executor.submit(worker)                                                      futures.add(future)                                                               else:                                                                                     # Avoid tight loop when max pending tasks is reached                                  time.sleep(0.01)                                                          except KeyboardInterrupt:                                                                 with print_lock:                                                                          print(f"{Fore.CYAN}Stopping...")                                              finally:                                                                                  # Optionally, wait for all futures to complete
            for future in futures:                                                                    future.cancel()                                                                   # Send any remaining valid URLs                                                       with valid_urls_lock:
                if valid_urls:                                                                            send_to_discord(valid_urls.copy())                                                    valid_urls.clear()                                                
if __name__ == "__main__":                                                                main()