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()