# qbitport.py import argparse import json import time import urllib.error import urllib.parse import urllib.request from pathlib import Path parser = argparse.ArgumentParser( prog="qBittorrent Port Manager", description="Update your qBittorrent port", usage=f"{Path(__file__).name} port [options]", ) parser.add_argument("port", type=str, help="Forwarding Port") parser.add_argument( "--host", type=str, default="localhost", help="IP/hostname of qBittorrent instance (default: %(default)s)", ) parser.add_argument( "--host-port", type=int, default=8080, help="qBittorrent port (default: %(default)s)", ) args = parser.parse_args() def ping_until_connected(url, max_retries=12): req = urllib.request.Request(url, method="HEAD") retries = 0 while retries < max_retries: try: with urllib.request.urlopen(req, timeout=5) as response: if response.status == 200: return True except (urllib.error.URLError, TimeoutError): print( f"{url} is unreachable, trying again in 5 sec... ({retries + 1}/{max_retries})", flush=True, ) time.sleep(5) retries += 1 print("Error: Could not connect to qBittorrent after maximum retries.", flush=True) exit(1) def main(): base_url = f"http://{args.host}:{args.host_port}" print("Establishing connection with qBittorrent...", flush=True) ping_until_connected(base_url) print("Connection established", flush=True) print(f"Setting qBittorrent port settings ({args.port})...", flush=True) prefs_data = urllib.parse.urlencode( {"json": json.dumps({"listen_port": int(args.port)})} ).encode("utf-8") prefs_req = urllib.request.Request( f"{base_url}/api/v2/app/setPreferences", data=prefs_data ) try: with urllib.request.urlopen(prefs_req, timeout=10) as response: if response.status == 200: print("Port has been set!", flush=True) except urllib.error.HTTPError as e: print( f"HTTP Error {e.code}: Failed to set port. (Is auth bypass enabled in qBittorrent?)", flush=True, ) if __name__ == "__main__": main()