Gelbooru Bulk Unfavorite

Automatically remove all favorites from gelbooru using AJAX.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==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);
    }
})();