Tidal Special

Click on elements and copy links to clipboard with user confirmation and success message, and download links as a .txt file

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

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

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

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

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

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Tidal Special
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  Click on elements and copy links to clipboard with user confirmation and success message, and download links as a .txt file
// @author       You
// @match        https://tidal.com/browse/playlist/*
// @match        https://pixeldrain.com/*
// @icon         https://w7.pngwing.com/pngs/973/746/png-transparent-tidal-round-logo-tech-companies-thumbnail.png
// @grant        none
// @license      MIT
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // Function to read text from the clipboard
    async function readClipboard() {
        try {
            const text = await navigator.clipboard.readText();
            return text;
        } catch (err) {
            console.error('Failed to read clipboard:', err);
        }
    }

    function createLoader() {
        // Check if the loader already exists
        if (document.querySelector('.loader-overlay')) {
            return; // Exit if the loader is already present
        }

        // Create the overlay div
        const overlay = document.createElement('div');
        overlay.className = 'loader-overlay'; // Add a class for easy removal
        overlay.style.position = 'fixed';
        overlay.style.top = '0';
        overlay.style.left = '0';
        overlay.style.width = '100vw';
        overlay.style.height = '100vh';
        overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; // Black background with slight transparency
        overlay.style.color = '#fff'; // White text color
        overlay.style.display = 'flex';
        overlay.style.flexDirection = 'column'; // Stack items vertically
        overlay.style.alignItems = 'center';
        overlay.style.justifyContent = 'center';
        overlay.style.fontSize = '1.5em';
        overlay.style.zIndex = '9999'; // Ensure it's on top of other content

        // Add the loading text
        const loadingText = document.createElement('div');
        loadingText.className = 'loader-text';
        loadingText.innerHTML = '<h1>STAY ON PAGE </h1>';
        loadingText.style.textAlign = "center";
        overlay.appendChild(loadingText);

        // Create the button
        const button = document.createElement('button');
        button.textContent = 'Start Extraction';
        button.style.marginTop = '20px'; // Space between text and button
        button.style.padding = '10px 20px';
        button.style.cursor = 'pointer';

        // Attach the click event handler to the button
        button.addEventListener('click', () => {
            handleClick()
            button.hidden = true
        });

        // Add the button to the overlay
        overlay.appendChild(button);

        // Append the overlay to the body
        document.body.appendChild(overlay);
    }

    function updateLoaderMessage(message) {
        const loadingText = document.querySelector('.loader-text');
        if (loadingText) {
            loadingText.textContent = message;
        }
    }

    function removeLoader() {
        // Find the overlay by its class name and remove it
        const overlay = document.querySelector('.loader-overlay');
        if (overlay) {
            document.body.removeChild(overlay);
        }
    }

    function downloadLinks(links) {
        const blob = new Blob([links.join('\n')], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = 'links.txt';
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    }

    // Collect all links
    let collectedLinks = [];

    async function handleClick() {
        updateLoaderMessage('Starting extraction...');

        // Click on all elements with class "track-options"
        let trackOptions = document.querySelectorAll('.track-options');
        let index = 0;

        function processNext() {
            if (index >= trackOptions.length) {
                updateLoaderMessage('All links collected!');
                setTimeout(() => {
                    updateLoaderMessage('Downloading links...');
                    downloadLinks(collectedLinks);
                    updateLoaderMessage('Success! All links have been collected and downloaded.');
                    setTimeout(removeLoader, 3000); // Show success message for a few seconds before removing the loader
                }, 1000); // Adjust the delay for the success message as needed
                return;
            }

            let element = trackOptions[index++];
            element.click();

            // Wait for the modal to appear and then click the button
            setTimeout(async () => {
                let copyButton = document.querySelector('#__layout > div > div.font-weight-bold.modal-wrapper-mobile-only > div > ul > li:nth-child(4) > button');
                if (copyButton) {
                    copyButton.click();

                    // Assuming there's a delay before the link is copied
                    setTimeout(async () => {
                        // Use a way to obtain the copied link if possible or retrieve it from modal
                        let link = await readClipboard();
                        if (link) {
                            collectedLinks.push(link);
                            updateLoaderMessage(`Collected ${collectedLinks.length} links...`);
                        } else {
                            console.warn('No link was copied.');
                        }
                        processNext();
                    }, 10); // Adjust the delay as needed
                } else {
                    console.error('Copy button not found');
                    processNext();
                }
            }, 10); // Adjust the delay as needed
        }

        processNext();
    }

    if (window.location.host == "tidal.com") {
        createLoader();
    }

    if (window.location.host == "pixeldrain.com") {
        // ==UserScript==
        // @name         Pixel Drain Auto Audio Downloader
        // @namespace    http://tampermonkey.net/
        // @version      0.2
        // @description  Automatically download audio files from Pixel Drain
        // @author       Your Name
        // @match        https://pixeldrain.com/*
        // @grant        none
        // @run-at       document-end
        // ==/UserScript==

        (function() {
            'use strict';

            function autoDownloadAudio() {
                // Select all audio elements
                const audioElements = document.querySelectorAll('audio.player');

                audioElements.forEach(audio => {
                    // Find the source element
                    const source = audio.querySelector('source');
                    if (!source) return;

                    // Check if the file is already downloaded or not
                    if (source.dataset.downloaded) return;

                    // Mark the file as downloaded to avoid multiple downloads
                    source.dataset.downloaded = 'true';

                    // Construct the absolute URL
                    const audioUrl = source.src;
                    const absoluteUrl = new URL(audioUrl, window.location.origin).href;

                    // Create a temporary anchor element to trigger download
                    const a = document.createElement('a');
                    a.href = absoluteUrl;
                    a.download = ''; // Use the filename if needed, e.g., `source.src.split('/').pop()`
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                });
            }

            // Run the function when the page is loaded
            window.addEventListener('load', autoDownloadAudio);

            // Also check for dynamically loaded content
            const observer = new MutationObserver((mutations) => {
                mutations.forEach(() => {
                    autoDownloadAudio();
                });
            });

            observer.observe(document.body, { childList: true, subtree: true });
        })();

    }
})();