Gelbooru Bulk Unfavorite

Automatically remove all favorites from gelbooru using AJAX.

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

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

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Gelbooru Bulk Unfavorite
// @version      1.6
// @description  Automatically remove all favorites from gelbooru using AJAX.
// @author       https://github.com/binge-coder
// @match        *://gelbooru.com/index.php?page=favorites*
// @run-at       document-end
// @namespace https://greasyfork.org/users/1575858
// ==/UserScript==

(function() {
    'use strict';

    const removalDelay = 1000;
    const refreshDelay = 2000;
    const autoRun = true;

    function processFavoritesBatch() {
        // Find all <b>Remove</b> tags and get their parent <a> links
        let removeButtons = Array.from(document.querySelectorAll('b'))
            .filter(b => b.textContent.trim().toLowerCase() === "remove")
            .map(b => b.closest('a'))
            .filter(a => a !== null && a.getAttribute("href"));

        console.log("Found", removeButtons.length, "remove buttons.");

        if(removeButtons.length === 0) {
            console.log("No favorites found. Process complete.");
            return;
        }

        let index = 0;
        function removeNext() {
            if(index >= removeButtons.length) {
                console.log("Batch complete. Refreshing...");
                setTimeout(() => location.reload(), refreshDelay);
                return;
            }

            let button = removeButtons[index];
            let url = button.getAttribute("href"); // Direct access to href

            if(url) {
                console.log("Removing favorite via URL:", url);
                fetch(url, { credentials: 'include' })
                    .then(() => {
                        console.log("Removed index", index);
                        index++;
                        setTimeout(removeNext, removalDelay);
                    })
                    .catch(err => {
                        console.error("Error at index", index, err);
                        index++;
                        setTimeout(removeNext, removalDelay);
                    });
            } else {
                index++;
                removeNext();
            }
        }
        removeNext();
    }

    function addManualButton() {
        let btn = document.createElement("button");
        btn.innerText = "Remove All Favorites";
        btn.style = "position:fixed;top:10px;right:10px;z-index:1000;padding:10px;background:red;color:white;border:none;cursor:pointer;";
        btn.onclick = processFavoritesBatch;
        document.body.appendChild(btn);
    }

    addManualButton();

    if(autoRun) {
        // Short delay to ensure page is ready
        setTimeout(() => {
            const hasFavs = Array.from(document.querySelectorAll('b')).some(b => b.textContent.trim().toLowerCase() === "remove");
            if(hasFavs) processFavoritesBatch();
        }, 500);
    }
})();