Kapowarr Automation with Interactive List

Automate "Add Volume" with an interactive list of searches for Kapowarr instances.

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Kapowarr Automation with Interactive List
// @namespace    https://greasyfork.org/fr/scripts/520321-kapowarr-automation-with-interactive-list
// @version      3.2
// @license MIT
// @description  Automate "Add Volume" with an interactive list of searches for Kapowarr instances.
// @author       thertemis
// @match        *://*/add*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // Variables for configuration
    const kapowarr_url = "https://your-kapowarr-instance.com"; // Base URL of the Kapowarr instance
    const marvel_only = true; // Set to true to include "&p=Marvel", false to exclude it

    let recherches = JSON.parse(localStorage.getItem('kapowarr_recherches')) || [];
    let indexRecherche = parseInt(localStorage.getItem('kapowarr_indexRecherche')) || 0;

    // Save searches and current index to local storage
    function saveSearches() {
        localStorage.setItem('kapowarr_recherches', JSON.stringify(recherches));
        localStorage.setItem('kapowarr_indexRecherche', indexRecherche);
    }

    // Automate the form after clicking "Add Volume"
    async function automateForm() {
        try {
            console.log("Automation started...");

            // Check "Start search for missing volume"
            const checkbox = document.querySelector("#auto-search-input");
            if (checkbox && !checkbox.checked) {
                checkbox.click();
                console.log("Checkbox checked");
            }

            // Select "Normal Volume"
            const selectOption = document.querySelector("#specialoverride-input > option[value='']");
            if (selectOption) {
                selectOption.selected = true;
                const select = selectOption.parentNode;
                select.dispatchEvent(new Event("change", { bubbles: true }));
                console.log("Option 'Normal Volume' selected");
            }

            // Click "Add Volume" button
            const addVolumeButton = document.querySelector("#add-volume");
            if (addVolumeButton) {
                addVolumeButton.click();
                console.log("Add Volume button clicked");

                // Move to the next search after 1 second
                setTimeout(() => {
                    moveToNextSearch();
                    executeSearch();
                }, 1000);
            }
        } catch (error) {
            console.error("Error during automation:", error.message);
        }
    }

    // Move to the next active search
    function moveToNextSearch() {
        let attempts = 0;
        do {
            indexRecherche = (indexRecherche + 1) % recherches.length;
            attempts++;
        } while (!recherches[indexRecherche].active && attempts <= recherches.length);

        saveSearches();
    }

    // Execute the current search
    function executeSearch() {
        const activeSearch = recherches[indexRecherche];
        if (!activeSearch || !activeSearch.active) return;

        const baseURL = `${kapowarr_url}/add`;
        const cleanedSearch = activeSearch.value
            .replace(/[?%&+:]/g, " ")
            .trim()
            .replace(/\s+/g, "+");
        const querySuffix = marvel_only ? "&p=Marvel" : "";
        const searchURL = `${baseURL}?q=${cleanedSearch}&t=all${querySuffix}`;

        if (window.location.href !== searchURL) {
            window.location.href = searchURL;
        }
    }

    // Create the user interface
    function createInterface() {
        const container = document.createElement("div");
        container.style.position = "fixed";
        container.style.bottom = "20px";
        container.style.right = "20px";
        container.style.backgroundColor = "#f9f9f9";
        container.style.border = "1px solid #ccc";
        container.style.borderRadius = "8px";
        container.style.padding = "10px";
        container.style.width = "300px";
        container.style.zIndex = "9999";
        container.style.boxShadow = "0px 4px 8px rgba(0,0,0,0.2)";
        container.style.display = "flex";
        container.style.flexDirection = "column";
        container.style.gap = "10px";

        const textArea = document.createElement("textarea");
        textArea.style.width = "100%";
        textArea.style.height = "100px";
        textArea.placeholder = "Enter your searches, one per line";
        textArea.value = recherches.map((r) => r.value).join("\n");

        const searchList = document.createElement("ul");
        searchList.style.listStyle = "none";
        searchList.style.padding = "0";
        searchList.style.margin = "0";
        searchList.style.maxHeight = "200px";
        searchList.style.overflowY = "auto";
        searchList.style.border = "1px solid #ccc";
        searchList.style.borderRadius = "4px";

        function updateSearchList() {
            searchList.innerHTML = "";
            recherches.forEach((search, i) => {
                const item = document.createElement("li");
                item.style.display = "flex";
                item.style.alignItems = "center";
                item.style.padding = "5px";
                item.style.cursor = "pointer";

                const checkbox = document.createElement("input");
                checkbox.type = "checkbox";
                checkbox.checked = search.active;
                checkbox.addEventListener("change", () => {
                    search.active = checkbox.checked;
                    saveSearches();
                });

                const label = document.createElement("span");
                label.textContent = search.value;
                label.style.flexGrow = "1";
                label.style.marginLeft = "10px";

                item.appendChild(checkbox);
                item.appendChild(label);

                item.addEventListener("click", () => {
                    indexRecherche = i;
                    saveSearches();
                    highlightSearch(searchList, indexRecherche);
                });

                searchList.appendChild(item);
            });

            highlightSearch(searchList, indexRecherche);
        }

        function highlightSearch(list, index) {
            Array.from(list.children).forEach((item, i) => {
                if (i === index) {
                    item.style.backgroundColor = "blue";
                    item.style.color = "white";
                } else {
                    item.style.backgroundColor = "";
                    item.style.color = "";
                }
            });
        }

        const saveButton = document.createElement("button");
        saveButton.textContent = "Save";
        saveButton.style.width = "100%";
        saveButton.style.padding = "10px";
        saveButton.style.backgroundColor = "#007bff";
        saveButton.style.color = "white";
        saveButton.style.border = "none";
        saveButton.style.borderRadius = "4px";
        saveButton.style.cursor = "pointer";

        saveButton.addEventListener("click", () => {
            recherches = textArea.value
                .split("\n")
                .map((line) => ({ value: line.trim(), active: true }))
                .filter((search) => search.value);
            saveSearches();
            updateSearchList();
        });

        const nextButton = document.createElement("button");
        nextButton.textContent = "Next →";
        nextButton.style.width = "100%";
        nextButton.style.padding = "10px";
        nextButton.style.backgroundColor = "#28a745";
        nextButton.style.color = "white";
        nextButton.style.border = "none";
        nextButton.style.borderRadius = "4px";
        nextButton.style.cursor = "pointer";

        nextButton.addEventListener("click", () => {
            moveToNextSearch();
            executeSearch();
        });

        container.appendChild(textArea);
        container.appendChild(searchList);
        container.appendChild(saveButton);
        container.appendChild(nextButton);

        document.body.appendChild(container);
        updateSearchList();
    }

    // Initialize the user interface
    createInterface();

    // Listen for clicks on buttons with the "search-entry" class
    document.addEventListener("click", (event) => {
        if (event.target.closest(".search-entry")) {
            console.log("Button 'search-entry' clicked");
            setTimeout(automateForm, 1000);
        }
    });
})();