qBittorrent API Helper

Funciones para interactuar con qBittorrent Web UI

Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta // @require https://update.greasyfork.org/scripts/531519/1563838/qBittorrent%20API%20Helper.js

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(Tôi đã có Trình quản lý tập lệnh người dùng, hãy cài đặt nó!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         qBittorrent API Helper
// @version      1.0
// @description  Funciones para interactuar con qBittorrent Web UI
// @grant        GM_xmlhttpRequest
// @grant        GM_notification
// ==/UserScript==

class QBittorrentAPI {
    constructor(host, username, password) {
        this.host = host;
        this.username = username;
        this.password = password;
        this.cookie = null;
    }

    async login() {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "POST",
                url: `${this.host}/api/v2/auth/login`,
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Referer": this.host
                },
                data: `username=${encodeURIComponent(this.username)}&password=${encodeURIComponent(this.password)}`,
                onload: (response) => {
                    if (response.responseText.trim() === "Ok.") {
                        // Obtener la cookie de la respuesta
                        const setCookie = response.responseHeaders.match(/SID=([^;]+)/);
                        if (setCookie) {
                            this.cookie = setCookie[0];
                        }
                        resolve();
                    } else {
                        reject(new Error("Login fallido. Verifica usuario y contraseña."));
                    }
                },
                onerror: (error) => {
                    reject(new Error(`No se pudo conectar a qBittorrent: ${error.statusText}`));
                }
            });
        });
    }

    async addMagnet(magnetLink) {
        if (!this.cookie) {
            await this.login();
        }

        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "POST",
                url: `${this.host}/api/v2/torrents/add`,
                headers: {
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Cookie": this.cookie,
                    "Referer": this.host
                },
                data: `urls=${encodeURIComponent(magnetLink)}`,
                onload: (response) => {
                    if (response.status === 200) {
                        resolve();
                    } else if (response.status === 403) {
                        // Sesión expirada, intentar reloguear
                        this.cookie = null;
                        this.addMagnet(magnetLink).then(resolve).catch(reject);
                    } else {
                        reject(new Error(`Error al agregar torrent: ${response.statusText}`));
                    }
                },
                onerror: (error) => {
                    reject(new Error(`Error de conexión: ${error.statusText}`));
                }
            });
        });
    }

    static isValidMagnet(magnetLink) {
        const magnetRegex = /^magnet:\?xt=urn:[a-zA-Z0-9]+:[a-zA-Z0-9]{32,}/i;
        return magnetRegex.test(magnetLink);
    }

    static showNotification(title, message, isError = false) {
        GM_notification({
            title: isError ? `⚠️ ${title}` : title,
            text: message,
            timeout: isError ? 6000 : 4000,
            silent: true
        });
    }
}