Civitai Direct Link Helper

Adds a convenient copy button next to download buttons on Civitai to easily get direct download links for models

目前為 2024-12-15 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Civitai Direct Link Helper
// @name:zh-CN   Civitai 下载助手
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Adds a convenient copy button next to download buttons on Civitai to easily get direct download links for models
// @description:zh-CN  在 Civitai 的下载按钮旁添加复制按钮,轻松复制直链地址
// @author       hua
// @match        https://civitai.com/*
// @grant        unsafeWindow
// @grant        GM_xmlhttpRequest
// @run-at       document-start
// @license      MIT
// ==/UserScript==



(function() {
    'use strict';
    const href = location.href;
    if (href.startsWith('https://civitai.com/models')) {
        setModelCopyButton()
    }


    function setModelCopyButton() { 
    let Interval = null;
    function addCopyButtons() {
            const buttons = document.querySelectorAll('a[href^="/api/download/models/"][type="button"]');
            if (buttons.length === 0) {
                return;
            }
            clearInterval(Interval);
            buttons.forEach(button => {
                const wrapper = document.createElement('span');
                wrapper.style.cssText = 'display: inline-flex; align-items: center;';
                
                button.parentNode.insertBefore(wrapper, button);
                wrapper.appendChild(button);
                
                const buttonStyle = window.getComputedStyle(button);
                
                const copyButton = document.createElement('button');
                copyButton.textContent = 'copy';
                copyButton.style.cssText = `
                    margin-left: 4px;
                    padding: 2px 6px;
                    font-size: 12px;
                    border: 1px solid #ccc;
                    border-radius: 3px;
                    cursor: pointer;
                    height: ${buttonStyle.height};
                    background-color: ${buttonStyle.backgroundColor};
                    color: ${buttonStyle.color};
                    width: 70px;
                    text-align: center;
                `;
                
                copyButton.addEventListener('click', function() {
                    const uri = button.getAttribute('href');
                    copyButton.textContent = 'loading...';
                    
                    GM_xmlhttpRequest({
                        method: "GET",
                        url: `https://civitai.com${uri}`,
                        timeout: 10000,
                        anonymous: false,
                        redirect: 'manual',
                        onload: function(response) {
                        
                            
                            const downloadUrl = response.responseHeaders.match(/location:(.*?)(?:\r?\n)/i)?.[1];
                            if (downloadUrl) {
                                navigator.clipboard.writeText(downloadUrl).then(() => {
                                    copyButton.textContent = 'copied!';
                                    setTimeout(() => {
                                        copyButton.textContent = 'copy';
                                    }, 2000);
                                });
                            } else {
                                copyButton.textContent = 'failed';
                                setTimeout(() => {
                                    copyButton.textContent = 'copy';
                                }, 2000);
                            }
                        },
                        onerror: function(error) {
                            console.error('Error:', error);
                            copyButton.textContent = 'error';
                            setTimeout(() => {
                                copyButton.textContent = 'copy';
                            }, 2000);
                        },
                        ontimeout: function() {
                            copyButton.textContent = 'timeout';
                            setTimeout(() => {
                                copyButton.textContent = 'copy';
                            }, 2000);
                        }
                    });
                });
                
                wrapper.appendChild(copyButton);
            });
    }

    Interval = setInterval(addCopyButtons, 500);
    }
})();