from __future__ import annotations import argparse import os import signal import subprocess import time from common import touch_ready, wait_for_tcp def console(config: str, command: str, check: bool = True) -> subprocess.CompletedProcess: return subprocess.run( ["deluge-console", "-c", config, command], text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=check, timeout=15, ) def main() -> int: ap = argparse.ArgumentParser(description="Seed a fixture with Deluge.") ap.add_argument("--torrent", required=True) ap.add_argument("--data", required=True) ap.add_argument("--port", type=int, required=True) ap.add_argument("--daemon-port", type=int, default=58846) args = ap.parse_args() config = "/tmp/deluge-config" os.makedirs(config, exist_ok=True) proc = subprocess.Popen([ "deluged", "-d", "-c", config, "-i", "0.0.0.0", "-p", str(args.daemon_port), "-L", "warning", ]) stop = False def _stop(signum, frame): nonlocal stop stop = True proc.terminate() signal.signal(signal.SIGTERM, _stop) signal.signal(signal.SIGINT, _stop) try: wait_for_tcp("127.0.0.1", args.daemon_port, timeout=45) settings = [ ("listen_ports", f"({args.port}, {args.port})"), ("random_port", "False"), ("dht", "False"), ("lsd", "False"), ("upnp", "False"), ("natpmp", "False"), ("add_paused", "False"), ("download_location", args.data), ] for key, value in settings: console(config, f"config -s {key} {value}") console(config, f"add -p {args.data} {args.torrent}") wait_for_tcp("127.0.0.1", args.port, timeout=45) touch_ready() print(f"Deluge seeding on {args.port}", flush=True) while not stop and proc.poll() is None: time.sleep(1) return proc.returncode or 0 finally: if proc.poll() is None: proc.terminate() try: proc.wait(timeout=10) except subprocess.TimeoutExpired: proc.kill() if __name__ == "__main__": raise SystemExit(main())