您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a "Show All Results" button and a Polish filter button to Debrid Media Manager.
// ==UserScript== // @name DMM - All Results & Polish Filter // @namespace http://tampermonkey.net/ // @version 4.2 // @description Adds a "Show All Results" button and a Polish filter button to Debrid Media Manager. // @author Your Assistant & tomfle // @match *://*.debridmediamanager.com/movie/* // @match *://*.debridmediamanager.com/show/*/* // @grant none // @run-at document-idle // @license MIT // ==/UserScript== (function() { 'use strict'; // --- SETTINGS AND GLOBAL VARIABLES --- const SHOW_ALL_BUTTON_ID = 'show-all-results-btn'; const POLISH_FILTER_BUTTON_ID = 'polish-filter-btn'; const CHECK_INTERVAL = 500; // Time in ms, how often the script checks for a new button // This regex is for finding Polish language releases. The keywords are names of Polish release groups or common terms. const POLISH_REGEX = String.raw`(\b(adl|agusiq|al3x|ale13|alusia|as76|azjatycki|azq|b89|bida|chrisvps|d11|denda|dsite|elladajarek|emis|enter1973|esperanza|eteam|feld|fiona9|gamer158|ghn|gr4pe|h3q|hmdb|intgrity|j60|joanna668|k83|kit|kolekcja|komplet|kpfr|ksq|lektor|ltn|m80|marcin0313|maxim|mg|mixio|mowy|napiproject|napisy|napisypl|nn|nonano|noq|ozw|p2p|paczka|pl|pl_1080p_web|pldub|plsub|pol|polish|psig|r22|r68|ralf|robsil|rx|s56|sezonów|sezonow|sezony|sfpi|sharpe|sk13|spajk85|spedboy|starlord|starlordx|superseed|syntezator|syrix|tfsh|tłumacz|toalien|topfilmyfilmweb|torrentmaniak|vantablack|wasik|wilu75|wersja|xupload|zbyszek|electro-torrent|devil-torrents|polskie-torrenty|cool-torents|ex-torrenty)\b)|(ą|ć|ę|ł|ń|ś|ź|ż)`; const POLISH_FILTER_BUTTON_TEXT = '🇵🇱'; // --- FUNCTIONS FOR "SHOW ALL RESULTS" BUTTON --- function findShowMoreButton() { const buttons = Array.from(document.querySelectorAll('button')); return buttons.find(button => button.textContent?.trim() === 'Show More Results' && button.offsetParent !== null ) || null; } function waitForNextButton() { return new Promise((resolve) => { const maxAttempts = 20; // Max 10 seconds let attempts = 0; const interval = setInterval(() => { const button = findShowMoreButton(); if (button) { clearInterval(interval); resolve(button); } else if (++attempts >= maxAttempts) { clearInterval(interval); resolve(null); } }, CHECK_INTERVAL); }); } async function fetchAllResults(showAllButton) { let pageCount = 1; showAllButton.textContent = `Loading page ${pageCount}...`; showAllButton.disabled = true; let showMoreButton = findShowMoreButton(); while (showMoreButton) { showMoreButton.click(); showMoreButton.style.display = 'none'; showMoreButton = await waitForNextButton(); if (showMoreButton) { pageCount++; showAllButton.textContent = `Loading page ${pageCount}...`; } } showAllButton.textContent = 'All results loaded'; showAllButton.style.borderColor = '#22c55e'; showAllButton.style.backgroundColor = 'rgba(34, 197, 94, 0.3)'; showAllButton.style.color = '#dcfce7'; showAllButton.style.fontWeight = 'bold'; // Set font to bold showAllButton.disabled = true; } function createShowAllButton() { if (!findShowMoreButton() || document.getElementById(SHOW_ALL_BUTTON_ID)) { return; } const buttons = Array.from(document.querySelectorAll('button')); const showRelatedButton = buttons.find(b => b.textContent?.includes('Show Related')); if (!showRelatedButton || !showRelatedButton.parentNode) { return; } const targetContainer = showRelatedButton.parentNode; const showAllButton = document.createElement('button'); showAllButton.textContent = 'Show All Results'; showAllButton.id = SHOW_ALL_BUTTON_ID; showAllButton.className = showRelatedButton.className; showAllButton.style.marginLeft = '0.5rem'; showAllButton.style.fontWeight = 'bold'; // Set font to bold showAllButton.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); fetchAllResults(showAllButton); }); targetContainer.appendChild(showAllButton); } // --- FUNCTIONS FOR POLISH FILTER BUTTON --- function createPolishFilterButton() { const filterInput = document.querySelector('input#query'); const buttonContainer = document.querySelector('.flex.items-center.gap-2.overflow-x-auto'); if (filterInput && buttonContainer && !buttonContainer.querySelector(`#${POLISH_FILTER_BUTTON_ID}`)) { const newButton = document.createElement('button'); newButton.id = POLISH_FILTER_BUTTON_ID; newButton.textContent = POLISH_FILTER_BUTTON_TEXT; newButton.className = 'cursor-pointer whitespace-nowrap rounded border border-cyan-500 bg-transparent px-2 py-1 text-xs text-blue-100 transition-colors hover:bg-cyan-900/50'; newButton.style.order = '-1'; // Sets the button as the first one newButton.addEventListener('click', function() { // This method is needed to correctly update the value in React applications const nativeInputValueSetter = Object.getOwnPropertyDescriptor( window.HTMLInputElement.prototype, 'value' ).set; nativeInputValueSetter.call(filterInput, POLISH_REGEX); // Simulate an input event so React notices the change const inputEvent = new Event('input', { bubbles: true, cancelable: true }); filterInput.dispatchEvent(inputEvent); }); buttonContainer.prepend(newButton); } } // --- MAIN LOGIC AND OBSERVER --- function initializeButtons() { createShowAllButton(); createPolishFilterButton(); } const observer = new MutationObserver((mutationsList, obs) => { // The initializeButtons function has built-in safeguards, // so it can be safely called multiple times. initializeButtons(); }); observer.observe(document.body, { childList: true, subtree: true }); // Run the function once at the beginning, just in case setTimeout(initializeButtons, 1500); })();