Assorted shell and Python scripts
1#!/usr/bin/env -S uv run --script 2# /// script 3# dependencies = [ 4# "qbittorrent-api", 5# "docopt", 6# ] 7# /// 8 9"""list_torrents.py 10 11Description: 12Fetch a list of torrents from a qBittorrent instance running on localhost. 13The qBittorrent instance must be configured to allow login on localhost 14without authentication. The output is formatted into a plaintext table. 15 16Usage: 17 list_torrents.py 18 list_torrents.py -h 19 20Options: 21 -h, --help show this help message and exit 22""" 23 24import qbittorrentapi 25from docopt import docopt 26 27 28# convert byte units 29def human_bytes(input_bytes: int) -> str: 30 B = float(input_bytes) 31 KiB = float(1024) 32 MiB = float(KiB**2) 33 GiB = float(KiB**3) 34 TiB = float(KiB**4) 35 36 match B: 37 case B if B < KiB: 38 return "{0} {1}".format(B, "bytes" if 0 == B > 1 else "byte") 39 case B if KiB <= B <= MiB: 40 return "{0:.2f} KiB".format(B / KiB) 41 case B if MiB <= B <= GiB: 42 return "{0:.2f} MiB".format(B / MiB) 43 case B if GiB <= B <= TiB: 44 return "{0:.2f} GiB".format(B / GiB) 45 case B if TiB <= B: 46 return "{0:.2f} TiB".format(B / TiB) 47 case _: 48 return "" 49 50 51def print_ssv(): 52 with qbittorrentapi.Client( 53 host="localhost", port=8080, username="", password="" 54 ) as qbt_client: 55 try: 56 qbt_client.auth_log_in() 57 except qbittorrentapi.LoginFailed as e: 58 print(e) 59 60 sorted_torrents = sorted( 61 qbt_client.torrents_info(), key=lambda d: d.ratio, reverse=True 62 ) 63 print("Name Size # of Trackers Ratio Uploaded") 64 for torrent in sorted_torrents: 65 name = torrent.name 66 size = human_bytes(torrent.total_size) 67 trackers = torrent.trackers_count 68 ratio = torrent.ratio 69 uploaded = human_bytes(torrent.uploaded) 70 print(f"{name} {size} {trackers} {ratio} {uploaded}") 71 72 73if __name__ == "__main__": 74 args = docopt(__doc__) # type: ignore 75 print_ssv()