mirror of
https://codeberg.org/hyperreal/admin-scripts
synced 2024-11-25 09:03:41 +01:00
Use qbittorrentapi, refactor qbth
This commit is contained in:
parent
7e09519e62
commit
ae478e4675
4
.envrc
4
.envrc
@ -1 +1,3 @@
|
||||
use nix
|
||||
source_url "https://raw.githubusercontent.com/cachix/devenv/82c0147677e510b247d8b9165c54f73d32dfd899/direnvrc" "sha256-7u4iDd1nZpxL4tCzmPG0dQgC5V+/44Ba+tHkPob1v2k="
|
||||
|
||||
use devenv
|
||||
|
9
.gitignore
vendored
9
.gitignore
vendored
@ -1 +1,10 @@
|
||||
.direnv
|
||||
# Devenv
|
||||
.devenv*
|
||||
devenv.local.nix
|
||||
|
||||
# direnv
|
||||
.direnv
|
||||
|
||||
# pre-commit
|
||||
.pre-commit-config.yaml
|
||||
|
116
devenv.lock
Normal file
116
devenv.lock
Normal file
@ -0,0 +1,116 @@
|
||||
{
|
||||
"nodes": {
|
||||
"devenv": {
|
||||
"locked": {
|
||||
"dir": "src/modules",
|
||||
"lastModified": 1730745597,
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"rev": "7cfc04e544e67adf803c3634b53a911c670e046e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"dir": "src/modules",
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"pre-commit-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1716977621,
|
||||
"owner": "cachix",
|
||||
"repo": "devenv-nixpkgs",
|
||||
"rev": "4267e705586473d3e5c8d50299e71503f16a6fb6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"ref": "rolling",
|
||||
"repo": "devenv-nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1730741070,
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d063c1dd113c91ab27959ba540c0d9753409edf3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1730814269,
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "d70155fdc00df4628446352fc58adc640cd705c2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"devenv": "devenv",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"pre-commit-hooks": "pre-commit-hooks"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
34
devenv.nix
Normal file
34
devenv.nix
Normal file
@ -0,0 +1,34 @@
|
||||
{ pkgs, lib, config, inputs, ... }:
|
||||
|
||||
{
|
||||
# https://devenv.sh/basics/
|
||||
env.GREET = "devenv";
|
||||
|
||||
# https://devenv.sh/packages/
|
||||
packages = [
|
||||
pkgs.git
|
||||
pkgs.python312Packages.beautifulsoup4
|
||||
pkgs.python312Packages.black
|
||||
pkgs.python312Packages.bpython
|
||||
pkgs.python312Packages.docopt
|
||||
pkgs.python312Packages.isort
|
||||
pkgs.python312Packages.pandas
|
||||
pkgs.python312Packages.pytest
|
||||
pkgs.python312Packages.qbittorrent-api
|
||||
pkgs.python312Packages.requests
|
||||
pkgs.python312Packages.resend
|
||||
pkgs.python312Packages.rich
|
||||
pkgs.python312Packages.tabulate
|
||||
pkgs.pyright
|
||||
pkgs.shellcheck
|
||||
];
|
||||
|
||||
# https://devenv.sh/languages/
|
||||
# languages.rust.enable = true;
|
||||
languages.python.enable = true;
|
||||
|
||||
enterShell = ''
|
||||
hello
|
||||
git --version
|
||||
'';
|
||||
}
|
15
devenv.yaml
Normal file
15
devenv.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json
|
||||
inputs:
|
||||
nixpkgs:
|
||||
url: github:cachix/devenv-nixpkgs/rolling
|
||||
|
||||
# If you're using non-OSS software, you can set allowUnfree to true.
|
||||
# allowUnfree: true
|
||||
|
||||
# If you're willing to use a package that's vulnerable
|
||||
# permittedInsecurePackages:
|
||||
# - "openssl-1.1.1w"
|
||||
|
||||
# If you have more than one devenv you can merge them
|
||||
#imports:
|
||||
# - ./backend
|
124
qbth.py
124
qbth.py
@ -17,15 +17,25 @@ Options:
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
from shutil import which
|
||||
|
||||
import qbittorrentapi
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
from docopt import docopt
|
||||
from qbittorrent import Client
|
||||
|
||||
args = docopt(__doc__)
|
||||
qb = Client(args["HOSTNAME"])
|
||||
qb.login(username=args["USERNAME"], password=args["PASSWORD"])
|
||||
conn_info = dict(
|
||||
host=args["HOSTNAME"],
|
||||
username=args["USERNAME"],
|
||||
password=args["PASSWORD"],
|
||||
)
|
||||
qbt_client = qbittorrentapi.Client(**conn_info)
|
||||
|
||||
try:
|
||||
qbt_client.auth_log_in()
|
||||
except qbittorrentapi.LoginFailed as e:
|
||||
print(e)
|
||||
|
||||
|
||||
def add_torrents(urls: list[str]):
|
||||
@ -35,9 +45,16 @@ def add_torrents(urls: list[str]):
|
||||
Params:
|
||||
urls: list of strings that are URLs.
|
||||
"""
|
||||
for url in urls:
|
||||
qb.download_from_link(url, category="distro")
|
||||
print(f"Added {os.path.basename(url)}")
|
||||
with qbittorrentapi.Client(**conn_info) as qbt_client:
|
||||
for url in urls:
|
||||
response = requests.get(url)
|
||||
if response.status_code == 200:
|
||||
if qbt_client.torrents_add(url, category="distro") != "Ok.":
|
||||
raise Exception("Failed to add torrent: " + os.path.basename(url))
|
||||
else:
|
||||
print(f"Added {os.path.basename(url)}")
|
||||
else:
|
||||
print(f"{response.status_code}: {url}")
|
||||
|
||||
|
||||
def add_torrents_from_html(webpage_url: str, torrent_substring: str):
|
||||
@ -52,11 +69,21 @@ def add_torrents_from_html(webpage_url: str, torrent_substring: str):
|
||||
"""
|
||||
reqs = requests.get(webpage_url, timeout=60)
|
||||
soup = BeautifulSoup(reqs.text, "html.parser")
|
||||
for link in soup.find_all("a"):
|
||||
if torrent_substring in link.get("href"):
|
||||
url = f"{webpage_url}/{link.get('href')}"
|
||||
qb.download_from_link(url, category="distro")
|
||||
print(f"Added {link.get('href')}")
|
||||
with qbittorrentapi.Client(**conn_info) as qbt_client:
|
||||
for link in soup.find_all("a"):
|
||||
if torrent_substring in link.get("href"):
|
||||
url = f"{webpage_url}/{link.get('href')}"
|
||||
response = requests.get(url)
|
||||
if response.status_code == 200:
|
||||
if qbt_client.torrents_add(url, category="distro") != "Ok.":
|
||||
raise Exception(
|
||||
"Failed to add torrent: " + os.path.basename(url)
|
||||
)
|
||||
else:
|
||||
print(f"Added {os.path.basename(url)}")
|
||||
|
||||
else:
|
||||
print(f"{response.status_code}: {url}")
|
||||
|
||||
|
||||
def remove_torrents(distro_substring: str):
|
||||
@ -69,10 +96,13 @@ def remove_torrents(distro_substring: str):
|
||||
distro_substring: a string that is a substring of the distro
|
||||
torrent's file name.
|
||||
"""
|
||||
for torrent in qb.torrents():
|
||||
if distro_substring in torrent.get("name"): # type: ignore
|
||||
qb.delete_permanently(torrent.get("hash")) # type: ignore
|
||||
print(f"Removed {torrent.get('name')}") # type: ignore
|
||||
with qbittorrentapi.Client(**conn_info) as qbt_client:
|
||||
for torrent in qbt_client.torrents_info():
|
||||
if distro_substring in torrent.name:
|
||||
qbt_client.torrents_delete(
|
||||
torrent_hashes=torrent.hash, delete_files=True
|
||||
)
|
||||
print(f"Removed {torrent.name}")
|
||||
|
||||
|
||||
def add_almalinux(rel_ver: str):
|
||||
@ -142,8 +172,7 @@ def add_devuan(rel_ver: str):
|
||||
relver: the Devuan release version.
|
||||
"""
|
||||
url = f"https://files.devuan.org/devuan_{rel_ver}.torrent"
|
||||
qb.download_from_link(url, category="distro")
|
||||
print(f"Added {os.path.basename(url)}")
|
||||
add_torrents([url])
|
||||
|
||||
|
||||
def remove_devuan(rel_ver: str):
|
||||
@ -175,11 +204,13 @@ def remove_fedora(rel_ver: str):
|
||||
Params:
|
||||
relver: the Fedora release version.
|
||||
"""
|
||||
torrents = qb.torrents()
|
||||
for torrent in torrents:
|
||||
if torrent.get("name").startswith("Fedora") and torrent.get("name").endswith(rel_ver): # type: ignore
|
||||
qb.delete_permanently(torrent.get("hash")) # type: ignore
|
||||
print(f"Removed {torrent.get('name')}") # type: ignore
|
||||
with qbittorrentapi.Client(**conn_info) as qbt_client:
|
||||
for torrent in qbt_client.torrents_info():
|
||||
if torrent.name.startswith("Fedora") and torrent.name.endswith(rel_ver):
|
||||
qbt_client.torrents_delete(
|
||||
torrent_hashes=torrent.hash, delete_files=True
|
||||
)
|
||||
print(f"Removed {torrent.name}")
|
||||
|
||||
|
||||
def add_freebsd(rel_ver: str):
|
||||
@ -194,10 +225,13 @@ def add_freebsd(rel_ver: str):
|
||||
reqs = requests.get(url, timeout=60)
|
||||
data = reqs.text.split("\n")
|
||||
|
||||
for line in data:
|
||||
if line.startswith("magnet:"):
|
||||
qb.download_from_link(line, category="distro")
|
||||
print(f"Added {line.split('=')[2]}")
|
||||
with qbittorrentapi.Client(**conn_info) as qbt_client:
|
||||
for line in data:
|
||||
if line.startswith("magnet:"):
|
||||
if qbt_client.torrents_add(line) != "Ok.":
|
||||
raise Exception("Failed to add torrent: " + line.split("=")[2])
|
||||
|
||||
print(f"Added {line.split('=')[2]}")
|
||||
|
||||
|
||||
def remove_freebsd(rel_ver: str):
|
||||
@ -266,9 +300,25 @@ def add_nixos():
|
||||
url = "https://api.github.com/repos/AnimMouse/NixOS-ISO-Torrents/releases/latest"
|
||||
reqs = requests.get(url, timeout=60)
|
||||
json_data = json.loads(reqs.text)
|
||||
for item in json_data["assets"]:
|
||||
qb.download_from_link(item["browser_download_url"], category="distro")
|
||||
print(f"Added {os.path.basename(item['browser_download_url'])}")
|
||||
|
||||
with qbittorrentapi.Client(**conn_info) as qbt_client:
|
||||
for item in json_data["assets"]:
|
||||
response = requests.get(item["browser_download_url"])
|
||||
if response.status_code == 200:
|
||||
if (
|
||||
qbt_client.torrents_add(
|
||||
item["browser_download_url"], category="distro"
|
||||
)
|
||||
!= "Ok."
|
||||
):
|
||||
raise Exception(
|
||||
"Failed to add torrent: "
|
||||
+ os.path.basename(item["browser_download_url"])
|
||||
)
|
||||
else:
|
||||
print(f"Added {os.path.basename(item['browser_download_url'])}")
|
||||
else:
|
||||
print(f"{response.status_code}: {item['browser_download_url']}")
|
||||
|
||||
|
||||
def remove_nixos():
|
||||
@ -289,8 +339,16 @@ def add_qubes(rel_ver: str):
|
||||
relver: the QubesOS release version.
|
||||
"""
|
||||
url = f"https://mirrors.edge.kernel.org/qubes/iso/Qubes-R{rel_ver}-x86_64.torrent"
|
||||
qb.download_from_link(url, category="distro")
|
||||
print(f"Added {os.path.basename(url)}")
|
||||
|
||||
response = requests.get(url)
|
||||
if response.status_code == 200:
|
||||
with qbittorrentapi.Client(**conn_info) as qbt_client:
|
||||
if qbt_client.torrents_add(url, category="distro") != "Ok.":
|
||||
raise Exception("Failed to add torrent: " + os.path.basename(url))
|
||||
else:
|
||||
print(f"Added {os.path.basename(url)}")
|
||||
else:
|
||||
print(f"{response.status_code}: {url}")
|
||||
|
||||
|
||||
def remove_qubes(rel_ver: str):
|
||||
@ -356,6 +414,10 @@ def remove_tails(rel_ver: str):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Check if gum is installed.
|
||||
if which("gum") is None:
|
||||
exit("Please install gum first. https://github.com/charmbracelet/gum")
|
||||
|
||||
# Run the gum program in a subprocess to allow easy selecting of distro
|
||||
# torrents.
|
||||
distro_selection = subprocess.run(
|
||||
|
44
shell.nix
44
shell.nix
@ -1,44 +0,0 @@
|
||||
with import <nixpkgs> { };
|
||||
|
||||
let
|
||||
python-qbittorrent = pkgs.python312Packages.buildPythonPackage rec {
|
||||
name = "python-qbittorrent-${version}";
|
||||
version = "0.4.3";
|
||||
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://files.pythonhosted.org/packages/86/25/a5ad35ad229c8016a8c98327495e649cb795be2fda63f8cace6c9a739af7/python-qbittorrent-${version}.tar.gz";
|
||||
sha256 = "4e22cf89890628b054a60aa4bd1161a68c2b0fad48ef0886fa4d325e69d3828a";
|
||||
};
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/v1k45/python-qBittorrent";
|
||||
description = "Python wrapper for qBittorrent Web API (for versions above v3.1.x)";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with maintainers; [ v1k45 ];
|
||||
};
|
||||
|
||||
nativeBuildInputs = with pkgs.python312Packages; [
|
||||
pip
|
||||
requests
|
||||
];
|
||||
};
|
||||
|
||||
in
|
||||
mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
python312Packages.beautifulsoup4
|
||||
python312Packages.black
|
||||
python312Packages.bpython
|
||||
python312Packages.docopt
|
||||
python312Packages.isort
|
||||
python312Packages.pandas
|
||||
python312Packages.pytest
|
||||
python312Packages.requests
|
||||
python312Packages.resend
|
||||
python312Packages.rich
|
||||
python312Packages.tabulate
|
||||
pyright
|
||||
python-qbittorrent
|
||||
shellcheck
|
||||
];
|
||||
}
|
Loading…
Reference in New Issue
Block a user