Desu Image Downloader

Download images with original filenames on desuarchive.org, archive.palanq.win, and add download button to direct image pages

当前为 2024-08-11 提交的版本,查看 最新版本

// ==UserScript==
// @name         Desu Image Downloader
// @version      1.20
// @description  Download images with original filenames on desuarchive.org, archive.palanq.win, and add download button to direct image pages
// @author       Anonimas
// @match        https://desuarchive.org/*
// @match        https://desu-usergeneratedcontent.xyz/*
// @match        https://archive.palanq.win/*
// @match        https://archive-media.palanq.win/*
// @grant        GM_download
// @grant        GM_addStyle
// @namespace https://greasyfork.org/users/1342214
// ==/UserScript==

(function() {
    'use strict';

    GM_addStyle(`
        #download-button {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background-color: rgba(0, 0, 0, 0.5);
            color: white;
            border: none;
            border-radius: 5px;
            padding: 10px 20px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s;
            text-decoration: none;
            font-family: Arial, sans-serif;
        }
        #download-button:hover {
            background-color: rgba(0, 0, 0, 0.7);
        }
    `);

    function getFullFilename(element) {
        return element.getAttribute('title') || element.textContent.trim();
    }

    function appendFilenameToUrl(url, filename) {
        return `${url}?filename=${encodeURIComponent(filename)}`;
    }

    function downloadImage(imageUrl, originalFilename) {
        if (imageUrl && originalFilename) {
            GM_download({
                url: imageUrl,
                name: originalFilename,
                onload: () => {},
                onerror: (error) => console.error('Download error:', error)
            });
        }
    }

    function handleImageClick(event) {
        event.preventDefault();
        const imageLink = event.target.closest('a[href*="//desu-usergeneratedcontent.xyz/"], a[href*="//archive-media.palanq.win/"]');
        if (!imageLink) return;

        const imageUrl = imageLink.href;
        let filenameElement = imageLink.closest('div.post_file, article.thread, article.post')?.querySelector('a.post_file_filename');
        if (!filenameElement) return;

        const originalFilename = getFullFilename(filenameElement);

        const newUrl = appendFilenameToUrl(imageUrl, originalFilename);
        window.open(newUrl, '_blank');
    }

    function addDownloadButtonToImagePage() {
        if (window.location.hostname === 'desu-usergeneratedcontent.xyz' || window.location.hostname === 'archive-media.palanq.win') {
            const button = document.createElement('a');
            button.id = 'download-button';
            button.textContent = 'Download';

            const imageUrl = window.location.href;

            const urlParams = new URLSearchParams(window.location.search);
            const originalFilename = urlParams.get('filename') || extractFilenameFromUrl(imageUrl);

            button.href = imageUrl;
            button.download = originalFilename;

            document.body.appendChild(button);
        }
    }

    function extractFilenameFromUrl(url) {
        return url.substring(url.lastIndexOf('/') + 1);
    }

    if (window.location.hostname === 'desuarchive.org' || window.location.hostname === 'archive.palanq.win') {
        document.querySelectorAll('a.post_file_filename').forEach(link => {
            link.addEventListener('click', event => {
                event.preventDefault();
                const imageUrl = link.closest('a').href;
                const originalFilename = getFullFilename(link);
                downloadImage(imageUrl, originalFilename);
            });
        });

        document.querySelectorAll('a[href*="//desu-usergeneratedcontent.xyz/"] i.icon-download-alt, a[href*="//archive-media.palanq.win/"] i.icon-download-alt').forEach(button => {
            button.closest('a').addEventListener('click', event => {
                event.preventDefault();
                const imageUrl = button.closest('a').href;
                let filenameElement = button.closest('div.post_file, article.thread, article.post')?.querySelector('a.post_file_filename');
                if (!filenameElement) return;

                const originalFilename = getFullFilename(filenameElement);
                downloadImage(imageUrl, originalFilename);
            });
        });

        document.querySelectorAll('a[href*="//desu-usergeneratedcontent.xyz/"] img, a[href*="//archive-media.palanq.win/"] img').forEach(image => {
            image.closest('a').addEventListener('click', handleImageClick);
        });
    }

    addDownloadButtonToImagePage();
})();