您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Click Download button will download the file and save the JSON and images at the same time. Also add a button to download JSON and images under details.
当前为
// ==UserScript== // @name Civitai Text Downloader Mod // @name:ja Civitai Text Downloader Mod // @namespace http://tampermonkey.net/ // @version 5.3.5 // @description Click Download button will download the file and save the JSON and images at the same time. Also add a button to download JSON and images under details. // @description:ja Downloadボタンをクリックするとファイルのダウンロードと同時にJSONと画像が保存されます。また、Detailsの下にJSONと画像をダウンロードするボタンを追加します。 // @author Takenoko3333 // @match https://civitai.com/* // @icon https://civitai.com/favicon.ico // @grant GM.addStyle // @grant GM.xmlHttpRequest // @connect civitai.com // @license BSD // ==/UserScript== (function() { 'use strict'; GM.addStyle(`.ctd-button:not([data-disabled]) {color: #ffff00;}`); let file_id = null; let category = ""; if (typeof MutationObserver !== 'undefined') { let lastUrl = location.href; let observerTriggered = false; const observer = new MutationObserver((mutations) => { if (lastUrl !== location.href) { lastUrl = location.href; observerTriggered = true; const interval = setInterval(function() { downloadFiles(); if (file_id || category != "models" ) { clearInterval(interval); } }, 200); } }); const config = { subtree: true, childList: true }; observer.observe(document, config); // URL change not detected (initial access) setTimeout(() => { if (!observerTriggered) { if (isFirefox()) { runDownloadFilesForFirefox(); } else { downloadFiles(); } } }, 0); } else { // MutationObserver is not supported setInterval(function(){ downloadFiles(); }, 500); } function isFirefox() { const isFirefoxBrowser = typeof InstallTrigger !== 'undefined'; return isFirefoxBrowser; } function runDownloadFilesForFirefox() { let counter = 0; const interval = setInterval(function() { downloadFiles(); counter++; if (category != "models" || counter >= 3) { clearInterval(interval); } }, 500); } function createButton() { const newElement = document.createElement('a'); newElement.className = 'mantine-UnstyledButton-root mantine-Button-root mantine-4fe1an json-image-download-button'; newElement.type = 'button'; newElement.setAttribute('data-button', 'true'); newElement.style.marginTop = '8px'; const innerDiv = document.createElement('div'); innerDiv.className = 'mantine-3xbgk5 mantine-Button-inner'; const innerSpan = document.createElement('span'); innerSpan.className = 'mantine-qo1k2 mantine-Button-label'; innerSpan.textContent = 'JSON and Image Download'; innerDiv.appendChild(innerSpan); newElement.appendChild(innerDiv); const tableElement = document.querySelector('table'); let currentElement = tableElement; while (currentElement && !currentElement.classList.contains('mantine-Accordion-item')) { currentElement = currentElement.parentElement; } if (currentElement) { currentElement.insertAdjacentElement('afterend', newElement); } } function downloadFiles() { file_id = null category = location.pathname.split("/")[1]; if (category != "models") return; const codeElements = document.querySelectorAll('table code'); codeElements.forEach((element, index) => { if (element.textContent === '@') { if (codeElements[index + 1]) { file_id = codeElements[index + 1].textContent; } } }); const jsonImageDownloadButton = document.querySelector('.json-image-download-button'); if (file_id && !jsonImageDownloadButton) createButton(); document.querySelectorAll('main a[type^="button"]').forEach(button => { if(!button.classList.contains("ctd-done")){ button.addEventListener("click", function(){ const modelName = document.querySelector('main h1').textContent; const spanElements = document.querySelectorAll('table span'); let strength = null; let _id = location.pathname.split("/")[2]; spanElements.forEach((element, index) => { if (/^Strength:/.test(element.textContent)) { strength = element.textContent.split(":")[1].trim(); } }); GM.xmlHttpRequest({ method: "GET", url: "https://civitai.com/api/v1/models/" + _id, onload: function(response) { let j = JSON.parse(response.responseText); let file = j.modelVersions.find(x => x.id == file_id); let link = document.createElement('a'); let text = { "description": "", "model name": modelName, "model url": document.URL, "base model": file.baseModel, "sd version": "Unknown", "activation text": "", "preferred weight": 0, "notes": document.URL + "\nModel name: " + modelName + "\nBase model: " + file.baseModel }; if (/^SD 1/.test(file.baseModel)) { text["sd version"] = "SD1"; } else if (/^SD 2/.test(file.baseModel)) { text["sd version"] = "SD2"; } else if (/^SDXL/.test(file.baseModel) || /^Pony/.test(file.baseModel)) { text["sd version"] = "SDXL"; } else if (/^SD 3/.test(file.baseModel)) { text["sd version"] = "SD3"; } if (j.description && j.description.textContent) { text.description = j.description.textContent; } if (file.trainedWords) { text["activation text"] = file.trainedWords.join(" "); } if (strength) { text["preferred weight"] = strength; } text = [JSON.stringify(text)]; link.href = window.URL.createObjectURL(new Blob(text)); let filename = file.files.find(x => x).name || file_id + ".json"; filename = filename.replace(/\.[a-z]*$/, ".json") link.download = filename; link.click(); let image = file.images.find(x =>x.type === 'image'); if (image) { GM.xmlHttpRequest({ method: "GET", url: image.url, responseType: "blob", onload: function (response) { let dlLink = document.createElement("a"); const dataUrl = URL.createObjectURL(response.response); dlLink.href = dataUrl; let suffix = "." + image.url.slice(image.url.lastIndexOf('.') + 1).toLowerCase(); if (suffix === ".jpeg") { suffix = ".jpg"; } filename = filename.replace(".json", suffix) dlLink.download = filename; document.body.insertAdjacentElement("beforeEnd", dlLink); dlLink.click(); dlLink.remove(); setTimeout(function () { window.URL.revokeObjectURL(dataUrl); }, 1000); } }); } } }); }); if (file_id && !jsonImageDownloadButton) button.classList.add("ctd-button"); button.classList.add("ctd-done"); } }); } })();