# "This will save me effort in the long run!", I tell myself. I have advanced experience in # the economics of effort. # MIT License # # Copyright (c) 2026 Jeffrey Serio # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. host := `secret-tool lookup qbt-url admin` password := `secret-tool lookup qbt-password admin` # Add AlmaLinux torrents [group('torrent')] qbt-alma: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import re import requests import subprocess from bs4 import BeautifulSoup from packaging.version import Version resp = requests.get("https://almalinux-mirror.dal1.hivelocity.net/", timeout=30) soup = BeautifulSoup(resp.text, "html.parser") versions = [] for link in soup.find_all("a"): link_text = link.get("href") res = bool(re.search(r'^\d.*\/$', link_text)) if res: versions.append(link.get("href").strip("/")) versions.sort(key=Version) major_versions = [] for v in versions: if v.isdigit(): major_versions.append(v) latest_versions = [] for mv in major_versions: full_version = [] for v in versions: if v.startswith(mv): full_version.append(v) full_version.sort(key=Version) latest_versions.append(full_version[-1]) urls = [] archs = ["aarch64", "ppc64le", "s390x", "x86_64"] for arch in archs: for ver in latest_versions: urls.append(f"https://almalinux-mirror.dal1.hivelocity.net/{ver}/isos/{arch}/AlmaLinux-{ver}-{arch}.torrent") conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "Alma" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for url in urls: try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add antiX torrents [group('torrent')] qbt-antix: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import requests from bs4 import BeautifulSoup base_url = "https://l2.mxrepo.com/torrents" resp = requests.get(base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") urls = [] for link in soup.find_all("a"): if link.get("href").startswith("antiX"): urls.append(f"{base_url}/{link.get('href')}") conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "antiX" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for url in urls: try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add Debian torrents [group('torrent')] qbt-debian: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import requests from bs4 import BeautifulSoup base_url = "https://cdimage.debian.org/debian-cd/current" archs = ["amd64", "arm64", "armel", "armhf", "mips64el", "mipsel", "ppc64el", "s390x"] urls = set() arch_urls = [] for arch in archs: arch_urls.append(f"https://cdimage.debian.org/debian-cd/current/{arch}/bt-dvd") for aurl in arch_urls: resp = requests.get(aurl, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") for link in soup.find_all("a"): if link.get("href").endswith(".torrent"): urls.add(f"{aurl}/{link.get('href')}") conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "debian" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for url in urls: try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add Devuan torrents [group('torrent')] qbt-devuan: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import requests from bs4 import BeautifulSoup base_url = "https://files.devuan.org" resp = requests.get(base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") torrent_files = [] for link in soup.find_all("a"): if link.get("href").endswith(".torrent"): if link.get("href") != "devuan_jessie.torrent": torrent_files.append(link.get("href")) url = f"{base_url}/{torrent_files[-1]}" conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "devuan" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(F"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add Fedora torrents [group('torrent')] qbt-fedora: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import requests from bs4 import BeautifulSoup base_url = "https://torrent.fedoraproject.org/torrents" urls = [] resp = requests.get(base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") torrents = [] for link in soup.find_all("a"): if link.get("href").endswith(".torrent"): torrents.append(link.get("href")) relver = torrents[-1][-10:-8] for link in soup.find_all("a"): if link.get("href").endswith(f"{relver}.torrent"): urls.append(f"{base_url}/{link.get('href')}") conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "Fedora" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for url in urls: try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add FreeBSD torrents [group('torrent')] qbt-freebsd: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import requests from bs4 import BeautifulSoup base_url = "https://people.freebsd.org/~jmg" rel_url = "https://www.freebsd.org/releases" rel_resp = requests.get(rel_url, timeout=30) soup = BeautifulSoup(rel_resp.text, "html.parser") sect2 = soup.find_all("div", class_="sect2") # Lmao. I ought to get a bronze medal in the string gymnastics olympics # for this monkey business. A banana would be nice, too. versions = [] for item in sect2: if "Production Release" in item.get_text(): versions.append(item.get_text().split(" ")[2]) versions.append(item.get_text().split(" ")[17]) magnet_urls = [] for v in versions: url = f"https://people.freebsd.org/~jmg/FreeBSD-{v}-R-magnet.txt" reqs = requests.get(url, timeout=30) data = reqs.text.split("\n") for line in data: if line.startswith("magnet:"): magnet_urls.append(line) conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "FreeBSD" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for murl in magnet_urls: try: qbt_client.torrents_add(murl, category="distro") print(f"Added torrent {murl}") except Exception as ex: print(f"Failed to add torrent {murl}") print(ex) # Add Kali Linux torrents [group('torrent')] qbt-kali: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import requests from bs4 import BeautifulSoup base_url = "https://kali.download/base-images/current" resp = requests.get(base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") urls = [] for link in soup.find_all("a"): if link.get("href").endswith(".torrent"): urls.append(f"{base_url}/{link.get('href')}") conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "kali" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for url in urls: try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add KDE Neon torrents [group('torrent')] qbt-kdeneon: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import requests from bs4 import BeautifulSoup user_base_url = "https://files.kde.org/neon/images/user" resp = requests.get(user_base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") user_version = str() for link in soup.find_all("a"): if link.get("href")[0:8].isdigit(): user_version = link.text.strip("/") dev_base_url = "https://files.kde.org/neon/images/dev" resp = requests.get(dev_base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") dev_version = str() for link in soup.find_all("a"): if link.get("href")[0:8].isdigit(): dev_version = link.text.strip("/") testing_base_url = "https://files.kde.org/neon/images/testing" resp = requests.get(testing_base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") testing_version = str() for link in soup.find_all("a"): if link.get("href")[0:8].isdigit(): testing_version = link.text.strip("/") unstable_base_url = "https://files.kde.org/neon/images/unstable" resp = requests.get(unstable_base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") unstable_version = str() for link in soup.find_all("a"): if link.get("href")[0:8].isdigit(): unstable_version = link.text.strip("/") urls = [ f"https://files.kde.org/neon/images/user/{user_version}/neon-user-{user_version}.iso.torrent", f"https://files.kde.org/neon/images/dev/{dev_version}/neon-dev-{dev_version}.iso.torrent", f"https://files.kde.org/neon/images/testing/{testing_version}/neon-testing-{testing_version}.iso.torrent", f"https://files.kde.org/neon/images/unstable/{unstable_version}/neon-unstable-{unstable_version}.iso.torrent", ] conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "neon" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for url in urls: try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add MX Linux torrents [group('torrent')] qbt-mx: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import requests from bs4 import BeautifulSoup base_url = "https://l2.mxrepo.com/torrents" resp = requests.get(base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") urls = [] for link in soup.find_all("a"): if link.get("href").startswith("MX-"): urls.append(f"{base_url}/{link.get('href')}") conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "MX-" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for url in urls: try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add NetBSD torrents [group('torrent')] qbt-netbsd: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import re import requests from bs4 import BeautifulSoup from packaging.version import Version base_url = "https://cdn.netbsd.org/pub/NetBSD" resp = requests.get(base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") versions = [] for link in soup.find_all("a"): link_text = link.get("href") res = bool(re.search(r'^NetBSD-(\d+\.\d+)\/$', link_text)) if res: versions.append(link.get("href").strip("/")) just_versions = [] for v in versions: just_versions.append(v[7:]) just_versions.sort(key=Version) latest_version_url = f"{base_url}/NetBSD-{just_versions[-1]}/images" urls = [] resp = requests.get(latest_version_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") for link in soup.find_all("a"): if link.get("href").endswith(".torrent"): urls.append(f"{latest_version_url}/{link.get('href')}") conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "NetBSD" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for url in urls: try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add NixOS torrents [group('torrent')] qbt-nixos: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import json import os import qbittorrentapi import requests base_url = "https://api.github.com/repos/AnimMouse/NixOS-ISO-Torrents/releases/latest" resp = requests.get(base_url, timeout=30) json_data = json.loads(resp.text) urls = [] for item in json_data["assets"]: urls.append(item["browser_download_url"]) conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "nixos" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for url in urls: try: qbt_client.torrents_add(url, category="distros") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add Qubes OS torrents [group('torrent')] qbt-qubes: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import requests from bs4 import BeautifulSoup base_url = "https://mirrors.edge.kernel.org/qubes/iso" resp = requests.get(base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") torrents = [] for link in soup.find_all("a"): if link.get("href").endswith(".torrent"): torrents.append(link.get("href")) url = f"{base_url}/{torrents[-1]}" conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "Qubes" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add Rocky Linux torrents [group('torrent')] qbt-rocky: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import re import requests from bs4 import BeautifulSoup from packaging.version import Version base_url = "https://download.rockylinux.org/pub/rocky" resp = requests.get(base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") versions = [] for link in soup.find_all("a"): link_text = link.get("href") res = bool(re.search(r'^\d.*\/$', link_text)) if res: versions.append(link.get("href").strip("/")) versions.sort(key=Version) major_versions = [] for v in versions: if v.isdigit(): major_versions.append(v) latest_versions = [] for mv in major_versions: full_version = [] for v in versions: if v.startswith(mv): full_version.append(v) full_version.sort(key=Version) latest_versions.append(full_version[-1]) archs = ["aarch64", "ppc64le", "s390x", "x86_64"] urls = [] for arch in archs: for lv in latest_versions: urls.append(f"{base_url}/{lv}/isos/{arch}/Rocky-{lv}-{arch}-dvd.torrent") conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "Rocky" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for url in urls: try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Add Tails OS torrents [group('torrent')] qbt-tails: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi import requests from bs4 import BeautifulSoup base_url = "https://tails.net/torrents/files" resp = requests.get(base_url, timeout=30) soup = BeautifulSoup(resp.text, "html.parser") urls = [] for link in soup.find_all("a"): if link.get("href").endswith(".torrent"): urls.append(f"{base_url}/{link.get('href')}") conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: try: qbt_client.auth_log_in() except qbittorrentapi.LoginFailed: exit("Login failed. Please verify credentials are correct.") for torrent in qbt_client.torrents_info(category="distro"): if "tails" in torrent.name: try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex) for url in urls: try: qbt_client.torrents_add(url, category="distro") print(f"Added torrent {os.path.basename(url)}") except Exception as ex: print(f"Failed to add torrent {os.path.basename(url)}") print(ex) # Destroy all the distro torrents! [group('torrent')] qbt-nuke: #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "beautifulsoup4", # "qbittorrent-api", # "requests", # ] # /// import os import qbittorrentapi conn_info = dict( host="{{ host }}", username="admin", password="{{ password }}", ) with qbittorrentapi.Client(**conn_info) as qbt_client: for torrent in qbt_client.torrents_info(category="distro"): try: qbt_client.torrents_delete(torrent_hashes=torrent.hash, delete_files=True) print(f"Deleted torrent {torrent.name}") except Exception as ex: print(f"Failed to delete torrent {torrent.name}") print(ex)