Magnet Link Handler for qBittorrent WebUI

Intercept magnet links and open qBittorrent download dialog in a popup.

当前为 2025-01-24 提交的版本,查看 最新版本

// ==UserScript==
// @name         Magnet Link Handler for qBittorrent WebUI
// @namespace    http://tampermonkey.net/
// @version      1.1
// @author       down_to_earth
// @description  Intercept magnet links and open qBittorrent download dialog in a popup.
// @match        *://*/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @license      MIT
// ==/UserScript==

(async function() {
    'use strict';

    const sleep = (ms) => {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    // Define the default qBittorrent WebUI URL
    const defaultQbWebUIHost = 'http://localhost:8080';

    // Retrieve the saved qBittorrent WebUI URL or use the default
    let qbWebUIHost = GM_getValue('qbWebUIHost', defaultQbWebUIHost);

    // Add a menu command to set the qBittorrent WebUI URL
    GM_registerMenuCommand('Set qBittorrent WebUI URL', () => {
        const newUrl = prompt('Enter the qBittorrent WebUI URL:', qbWebUIHost);
        if (newUrl) {
            GM_setValue('qbWebUIHost', newUrl); // Save the new URL
            qbWebUIHost = newUrl; // Update the script's URL
            alert(`qBittorrent WebUI URL set to: ${newUrl}`);
        }
    });

    // Check if the current page is the qBittorrent WebUI's download.html
    const isDownloadPage = window.location.href.startsWith(qbWebUIHost) && window.location.pathname === '/download.html';

    if (isDownloadPage) {
        // Check if the URL contains the `?url=` parameter
        const urlParams = new URLSearchParams(window.location.search);
        const encodedMagnetLink = urlParams.get('url');
        if (!encodedMagnetLink) {
            return; // Exit if no `?url=` parameter is found
        }

        const autoDownload = urlParams.get('autoDownload') === 'true';

        // Decode the magnet link
        const magnetLink = decodeURIComponent(encodedMagnetLink);

        // Function to fill the textarea with the magnet link
        const magnetTextarea = document.querySelector('#urls');
        if (magnetTextarea) {
            magnetTextarea.value = magnetLink; // Fill the textarea
        }

        // Wait for the preference load
        const savePath = document.querySelector('#savepath');
        while (!savePath.value) {
            await sleep(10);
        }

        const startDownload = () => {
            const downloadButton = document.querySelector('#submitButton');
            if (downloadButton) {
                downloadButton.click(); // Click the Download button
            }
        }

        // Register close handler.
        document.querySelector('#download_frame').addEventListener("load", function() {
            if (sourceHostname) {
                localStorage.setItem(`category_${sourceHostname}`, document.querySelector('#categorySelect').value);
            }
            window.close();
        });

        const sourceHostname = decodeURIComponent(urlParams.get('source'));
        const lastCategory = localStorage.getItem(`category_${sourceHostname}`);
        const categorySelect = document.querySelector('#categorySelect');
        if (lastCategory && categorySelect) {
            // Function to set the category once options are available
            const setCategory = () => {
                const optionExists = Array.from(categorySelect.options).some(option => option.value === lastCategory);
                if (optionExists) {
                    categorySelect.value = lastCategory; // Set the category
                    // Trigger the onchange event
                    const event = new Event('change', { bubbles: true });
                    categorySelect.dispatchEvent(event);

                    // Trigger auto-download
                    if (autoDownload) {
                        startDownload();
                    }
                } else {
                    // If the category is not yet available, wait and try again
                    setTimeout(setCategory, 10);
                }
            };

            // Start trying to set the category
            setCategory();
        } else if (autoDownload) {
            startDownload();
        }
    } else {
        // Function to handle magnet link clicks
        function handleMagnetLinkClick(event) {
            let target = event.target;

            while (target && target.tagName !== 'A') {
                target = target.parentElement;
            }

            // Check if the clicked element is a magnet link
            if (target?.href.startsWith('magnet:')) {
                event.preventDefault(); // Prevent the default behavior

                // Encode the magnet link for use in a URL
                const encodedMagnetLink = encodeURIComponent(target.href);

                // Get the source website hostname
                const sourceHostname = window.location.hostname;

                // Check if Ctrl key is pressed
                const autoDownload = event.ctrlKey;

                // Open the qBittorrent WebUI's download.html in a popup
                const popupUrl = `${qbWebUIHost}/download.html?url=${encodedMagnetLink}&source=${sourceHostname}&autoDownload=${autoDownload}`;

                // Define the popup dimensions
                const popupWidth = 500;
                const popupHeight = 600;

                // Calculate the position to center the popup
                const left = (window.screen.width - popupWidth) / 2;
                const top = (window.screen.height - popupHeight) / 2;

                // Open the popup with centered position
                let popupName = 'qBittorrentAddMagnet';
                if (autoDownload) {
                    popupName += crypto.randomUUID()
                }
                window.open(
                    popupUrl,
                    popupName,
                    `width=${popupWidth},height=${popupHeight},left=${left},top=${top}`
                );
            }
        }

        // Attach the event listener to the document
        document.addEventListener('click', handleMagnetLinkClick, true);
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址