Assorted shell and Python scripts
1#!/usr/bin/env -S uv run --script
2# /// script
3# dependencies = [
4# "qbittorrent-api",
5# "requests",
6# "bs4",
7# "docopt"
8# ]
9# ///
10
11"""seed_armbian_torrents.py
12
13Description:
14Armbian torrents seed script
15
16This script will scrape https://mirrors.jevincanders.net/armbian/dl/ for
17torrent files and add them to a qBittorrent instance. If there are already
18Armbian torrents in the qBittorrent instance, they will be removed, and new
19ones will be added in their place. This script is intended to be run under
20/etc/cron.weekly or used in a systemd timer.
21
22Usage:
23 seed_armbian_torrents.py (HOSTNAME) (USERNAME) (PASSWORD)
24 seed_armbian_torrents.py -h
25
26Examples:
27 seed_armbian_torrents.py "http://localhost:8080" "admin" "adminadmin"
28 seed_armbian_torrents.py "https://cat.seedhost.eu/lol/qbittorrent" "lol" "pw"
29
30Options:
31 -h, --help show this help message and exit.
32"""
33
34import os
35
36import qbittorrentapi
37import requests
38from bs4 import BeautifulSoup
39from docopt import docopt
40
41
42def add_torrents(args: dict):
43 archive_dir_urls = [
44 "https://mirrors.jevincanders.net/armbian/dl/orangepi5-plus/archive/",
45 "https://mirrors.jevincanders.net/armbian/dl/rockpro64/archive/",
46 "https://mirrors.jevincanders.net/armbian/dl/rpi4b/archive/",
47 ]
48
49 torrent_urls = []
50 for url in archive_dir_urls:
51 response = requests.get(url, timeout=60)
52 soup = BeautifulSoup(response.content, "html.parser")
53 links = soup.find_all("a")
54 for link in links:
55 if link.text.endswith(".torrent"):
56 torrent_urls.append(url + link.text)
57
58 try:
59 qbt_client = qbittorrentapi.Client(
60 host=args["HOSTNAME"], username=args["USERNAME"], password=args["PASSWORD"]
61 )
62 qbt_client.auth_log_in()
63
64 for url in torrent_urls:
65 qbt_client.torrents_add(url, category="distro")
66 print(f"Added {os.path.basename(url)}")
67 qbt_client.auth_log_out()
68 except qbittorrentapi.LoginFailed as e:
69 print(e)
70
71
72def remove_torrents(args: dict):
73 try:
74 qbt_client = qbittorrentapi.Client(
75 host=args["HOSTNAME"], username=args["USERNAME"], password=args["PASSWORD"]
76 )
77 qbt_client.auth_log_in()
78
79 for torrent in qbt_client.torrents_info():
80 if torrent.name.startswith("Armbian"):
81 torrent.delete(delete_files=True)
82 print(f"Removed {torrent.name}")
83 qbt_client.auth_log_out()
84 except qbittorrentapi.LoginFailed as e:
85 print(e)
86
87
88if __name__ == "__main__":
89 args = docopt(__doc__) # type: ignore
90 remove_torrents(args)
91 add_torrents(args)