Skip to content

Instantly share code, notes, and snippets.

@kLiHz
Last active May 19, 2024 10:22
Show Gist options
  • Save kLiHz/5673b5c1d50794edb68c7d863dfc1242 to your computer and use it in GitHub Desktop.
Save kLiHz/5673b5c1d50794edb68c7d863dfc1242 to your computer and use it in GitHub Desktop.
Automatically ban qBittorrent peers, based on client name, with JavaScript (Deno)
const endpoint = 'http://127.0.0.1:9876';
const mainDataUrl = new URL('/api/v2/sync/maindata', endpoint);
const torrentPeersUrl = new URL('/api/v2/sync/torrentPeers', endpoint);
const banPeers = new URL('/api/v2/transfer/banPeers', endpoint);
const f = async () => {
const r = await fetch(mainDataUrl);
const d = await r.json() as { torrents: {[hash: string]: { upspeed: number }} };
for (const [hash, _o] of Object.entries(d.torrents).filter(([_hash, { upspeed }]) => upspeed != 0)) {
torrentPeersUrl.search = `?hash=${hash}`;
const r = await fetch(torrentPeersUrl);
const d = await r.json() as { peers: {[socket: string]: {up_speed: number, client: string}} };
const { peers } = d;
for (const [socket, _o] of Object.entries(peers).filter(
([socket, { up_speed, client }]) => up_speed != 0 && (
client.startsWith('hp/torrent') /* ||
client.startsWith('hp/torrent') */
)
)) {
const q = await fetch(banPeers, {
body: new URLSearchParams({ hash, peers: socket }).toString(),
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
});
console.log(`Banning ${socket}. Status: ${q.status} ${await q.text()}`);
}
}
};
let running = true;
Deno.addSignalListener("SIGINT", () => { running = false; });
const wait = (ms: number) => new Promise(
(resolve, _reject) => {
setTimeout(() => { resolve(ms); }, ms);
}
);
while (running) {
const interval = await wait(1000);
try {
await f();
} catch (e) {
if (e instanceof Error) {
console.log(e.message);
}
}
await interval;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment