liblib助手[废弃]

liblib助手,下载作者例图、返图、生成信息

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği yüklemek için Tampermonkey gibi bir uzantı yüklemeniz gerekir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği indirebilmeniz için ayrıca Tampermonkey gibi bir eklenti kurmanız gerekmektedir.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

Bu stili yüklemek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için Stylus gibi bir uzantı kurmanız gerekir.

Bu stili yükleyebilmek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı kurmanız gerekir.

Bu stili yükleyebilmek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name         liblib助手[废弃]
// @namespace    http://tampermonkey.net/
// @version      1.6.2
// @description  liblib助手,下载作者例图、返图、生成信息
// @author       kaiery
// @match        https://www.liblib.ai/modelinfo/*
// @match        https://www.liblib.art/modelinfo/*
// @grant        none
// @license      MIT License
// ==/UserScript==

(function() {
    'use strict';



    // 定义全局变量
    var modelDir;
    var textDesc, uuid, buildId, webid, modelId, modelName, modelVersionId, downloadUrl;
    var page = 1;
    var pageSize = 16;
    var sortType = 0;
    const default_download_pic_num = 100;

    // ---------------------------------------------------------------
    // demo
    // ---------------------------------------------------------------
    async function createDirectory() {
        // open directory picker
        const dirHandle = await window.showDirectoryPicker({mode:"readwrite"});
        // create a new directory named 'newDir'
        const newDirHandle = await dirHandle.getDirectoryHandle('newDir', {create: true});
        console.log(newDirHandle);
    }


    // ---------------------------------------------------------------
    // html转文本
    // ---------------------------------------------------------------
    function htmlToText(html) {
        var tempDiv = document.createElement('div');
        tempDiv.innerHTML = html;
        var text = '';
        for (var i = 0; i < tempDiv.childNodes.length; i++) {
            if (tempDiv.childNodes[i].nodeName === 'P') {
                text += tempDiv.childNodes[i].textContent + '\n';
            }
        }
        return text;
    }
    // ---------------------------------------------------------------
    // 保存作者图片信息
    // ---------------------------------------------------------------
    async function saveAuthImagesInfo() {
        var modelType = 1; // 1:CheckPoint 2:embedding;3:HYPERNETWORK ;4:AESTHETIC GRADIENT; 5:Lora;6:LyCORIS;  9:WILDCARDS
        var hasTriggerWord = false;

        // open directory picker
        const dirHandle = await window.showDirectoryPicker({mode:"readwrite"});

        // 根据选项卡获取模型版本id
        const div = document.querySelector('.ant-tabs-tab.ant-tabs-tab-active');
        const modelVersionId = parseInt(div.getAttribute('data-node-key'));
        const modelVer = div.innerText.replace(/ /g, "").replace(/[/\\?%*:|"<>]/g, '');

        var allElements = document.querySelectorAll('div');
        allElements.forEach(function(element) {
            var classNames = element.className.split(/\s+/);
            for (var i = 0; i < classNames.length; i++) {
                if (classNames[i].startsWith('ModelDescription_desc')) {
                    textDesc = htmlToText(element.innerHTML);
                    textDesc = textDesc.replace(/\\n/g, '\n');
                    break;
                }
            }
        });
        if(textDesc){
            // Get the content of the script element
            var scriptContent = document.getElementById('__NEXT_DATA__').textContent;
            var scriptJson = JSON.parse(scriptContent);

            // Extract uuid, buildId, and webid
            uuid = scriptJson.query.uuid;
            buildId = scriptJson.buildId;
            webid = scriptJson.props.webid;
            //------------
            // 预请求地址
            var url_acceptor = "https://liblib-api.vibrou.com/api/www/log/acceptor/f";
            // 模型信息地址
            var url_model = "https://liblib-api.vibrou.com/api/www/model/getByUuid/" + uuid;


           // 发送预请求-------------------------------------------------------
            const resp_acc = await fetch(url_acceptor, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({timestamp: Date.now()})
            })

            // 发送模型信息
            const resp = await fetch(url_model, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({timestamp: Date.now()})
            })

            const model_data = await resp.json();
            // console.log("----------模型信息-----------");
            // console.log(model_data);

            if(model_data.code!==0){ return;}

            modelId = model_data.data.id
            modelName = model_data.data.name.replace(/ /g, "").replace(/[/\\?%*:|"<>]/g, '');
            modelDir = modelName;
            modelName = modelDir+"_"+modelVer;
            if(modelName.slice(-1)==='.'){
                modelName = modelName.substring(0, modelName.length -1);
            }
            modelType = model_data.data.modelType // 1:CheckPoint 2:embedding;3:HYPERNETWORK ;4:AESTHETIC GRADIENT; 5:Lora;6:LyCORIS;  9:WILDCARDS

            var modelTypeName = '未分类'
            switch (modelType){
                case 1:
                    modelTypeName = 'CheckPoint'
                    hasTriggerWord = false
                    break;
                case 2:
                    modelTypeName = 'embedding'
                    hasTriggerWord = true
                    break;
                case 3:
                    modelTypeName = 'HYPERNETWORK'
                    hasTriggerWord = true
                    break;
                case 4:
                    modelTypeName = 'AESTHETIC GRADIENT'
                    hasTriggerWord = true
                    break;
                case 5:
                    modelTypeName = 'Lora'
                    hasTriggerWord = true
                    break;
                case 6:
                    modelTypeName = 'LyCORIS'
                    hasTriggerWord = true
                    break;
                case 9:
                    modelTypeName = 'WILDCARDS'
                    hasTriggerWord = true
                    break;
            }

            // console.log(modelDir+"/"+modelName);

            const versions = model_data.data.versions;
            for (const verItem of versions){
                // 匹配版本号
                if(verItem.id === modelVersionId){

                    // 模型信息json信息
                    var modelInfoJson = {
                        modelType:modelTypeName,
                        description: textDesc,
                        uuid: uuid,
                        buildId: buildId,
                        webid: webid
                    };

                    var triggerWord = '无';
                    if(hasTriggerWord){
                        if('triggerWord' in verItem && verItem.triggerWord){
                           triggerWord = verItem.triggerWord
                           modelInfoJson.triggerWord = triggerWord
                        }
                    }


                    // 创建模型目录
                    const modelDirHandle = await dirHandle.getDirectoryHandle(modelDir, {create: true});
                    // 创建模型版本目录
                    const modelVerDirHandle = await modelDirHandle.getDirectoryHandle(modelName, {create: true});
                    // 获取文件句柄
                    const savejsonHandle = await modelDirHandle.getFileHandle(modelName+".json", { create: true });
                    // 写入模型信息json文件
                    const writablejson = await savejsonHandle.createWritable();
                    await writablejson.write(JSON.stringify(modelInfoJson));
                    await writablejson.close();


                    const authImages = verItem.imageGroup.images;
                    let isCover = false;
                    const numberInput1 = document.getElementById('numberInput1');
                    numberInput1.setAttribute('value', authImages.length);
                    numberInput1.dispatchEvent(new Event('change'));

                    var count = 0;
                    for(const authImage of authImages){
                        const authImageUrl = authImage.imageUrl;
                        var authimageName = authImage.id;
                        var authimageExt = authImageUrl.split("/").pop().split(".").pop();
                        var tmp = authimageExt.indexOf("?");
                        if (tmp>0){
                            authimageExt = authimageExt.substring(0,tmp);
                        }

                        const authImageUuid = authImage.uuid;

                        if(!isCover){
                            // 下载封面图片
                            isCover = true;
                            // 下载图片
                            const resp_download = await fetch(authImageUrl);
                            const blob = await resp_download.blob();
                            // 获取文件句柄
                            const picHandle = await modelDirHandle.getFileHandle(modelName+"."+authimageExt, { create: true });
                            // 写入图片
                            const writable = await picHandle.createWritable();
                            await writable.write(blob);
                            await writable.close();
                        }



                        // 下载图片
                        const resp_download = await fetch(authImageUrl);
                        const blob = await resp_download.blob();
                        // 获取文件句柄
                        const picHandle = await modelVerDirHandle.getFileHandle(authimageName+"."+authimageExt, { create: true });
                        // 写入图片
                        const writable = await picHandle.createWritable();
                        await writable.write(blob);
                        await writable.close();

                        // 查看图片生成信息地址
                        var url_img_generate = "https://liblib-api.vibrou.com/api/www/img/generate/"+authImageUuid+"?timestamp="+Date.now();
                        // 请求图片生成信息
                        const response_img_gen = await fetch(url_img_generate, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json'
                            }
                        })
                        const data_img_gen = await response_img_gen.json();
                        if(data_img_gen.code===0){
                            var metainformation = data_img_gen.data.metainformation;
                            if(!metainformation){
                                metainformation = 'prompt:'+data_img_gen.data.prompt +"\n";
                                metainformation = metainformation + 'negativePrompt:'+data_img_gen.data.negativePrompt +"\n";
                                metainformation = metainformation + 'modelNames:'+data_img_gen.data.modelNames +"\n";
                                metainformation = metainformation + 'seed:'+data_img_gen.data.seed +"\n";
                                metainformation = metainformation + 'samplingMethod:'+data_img_gen.data.samplingMethod +"\n";
                                metainformation = metainformation + 'samplingStep:'+data_img_gen.data.samplingStep +"\n";
                                metainformation = metainformation + 'cfgScale:'+data_img_gen.data.cfgScale +"\n";
                            }
                            // console.log(metainformation);
                            // 获取文件句柄
                            const savefileHandle = await modelVerDirHandle.getFileHandle(authimageName+".json", { create: true });
                            // 写入文件
                            const writablefile = await savefileHandle.createWritable();
                            await writablefile.write(metainformation);
                            await writablefile.close();
                        }
                        count++;
                        const numberInput1 = document.getElementById('numberInput1');
                        numberInput1.setAttribute('value', authImages.length-count);
                        numberInput1.dispatchEvent(new Event('change'));
                    }
                }
            }
        }
        alert("作者图例信息下载完成");
    }

    // ---------------------------------------------------------------
    // 保存返图信息
    // ---------------------------------------------------------------
    async function saveReturnImagesInfo() {
        // open directory picker
        const dirHandle = await window.showDirectoryPicker({mode:"readwrite"});

        // 根据选项卡获取模型版本id
        const div = document.querySelector('.ant-tabs-tab.ant-tabs-tab-active');
        const modelVersionId = parseInt(div.getAttribute('data-node-key'));
        const modelVer = div.innerText.replace(/ /g, "").replace(/[/\\?%*:|"<>]/g, '');

        // Get the content of the script element
        var scriptContent = document.getElementById('__NEXT_DATA__').textContent;
        var scriptJson = JSON.parse(scriptContent);

        // Extract uuid, buildId, and webid
        uuid = scriptJson.query.uuid;
        //------------
        // 预请求地址
        var url_acceptor = "https://liblib-api.vibrou.com/api/www/log/acceptor/f";
        // 模型信息地址
        var url_model = "https://liblib-api.vibrou.com/api/www/model/getByUuid/" + uuid;
        // 评论列表地址
        var url_community = "https://liblib-api.vibrou.com/api/www/community/returnPicList?timestamp="+Date.now();

        // 发送预请求-------------------------------------------------------
        const resp_acc = await fetch(url_acceptor, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({timestamp: Date.now()})
        })

        // 发送模型信息
        const resp = await fetch(url_model, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({timestamp: Date.now()})
        })

        const model_data = await resp.json();
        // console.log("----------模型信息-----------");
        // console.log(model_data);

        if(model_data.code!==0){ return;}

        modelId = model_data.data.id
        modelName = model_data.data.name.replace(/ /g, "").replace(/[/\\?%*:|"<>]/g, '');
        // modelName = modelName+"_返图";
        modelDir = modelName;
        modelName = modelDir+"_"+modelVer;
        if(modelName.slice(-1)==='.'){
                modelName = modelName.substring(0, modelName.length -1);
        }

        // 创建模型目录
        const modelDirHandle = await dirHandle.getDirectoryHandle(modelDir, {create: true});
        // 创建一个返图目录
        const newDirHandle = await modelDirHandle.getDirectoryHandle(modelName, {create: true});

        let count = 0;
        var number = 0;
        const numberInput2 = document.getElementById('numberInput2');
        number = parseInt(numberInput2.value);
        if(number> returnNum){
            number = returnNum;
        }

        while (true) {
            // 请求回图列表
            const response = await fetch(url_community, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    page: page,
                    pageSize: pageSize,
                    sortType: sortType,
                    uuid: uuid
                })
            });

            // 解析JSON数据
            const data = await response.json();
            // console.log(data);
            if(data.code===0){
                var datalist = data.data.dataList;
                var returnNum = data.data.returnNum;
                for(var i=0;i<datalist.length;i++){
                    var commItem = datalist[i];
                    var pics = commItem.pics;
                    for(var j=0;j<pics.length;j++){
                        var picItem = pics[j];
                        var picUuid = picItem.uuid;
                        var imageUrl = picItem.imageUrl;
                        var imageName = picItem.id;
                        var imageExt = imageUrl.split("/").pop().split(".").pop();
                        var tmp = imageExt.indexOf("?");
                        if (tmp>0){
                            imageExt = imageExt.substring(0,tmp);
                        }
                        // 下载图片
                        const resp_download = await fetch(imageUrl);
                        const blob = await resp_download.blob();
                        // 获取文件句柄
                        // console.log(imageName+"."+imageExt);
                        const picHandle = await newDirHandle.getFileHandle(imageName+"."+imageExt, { create: true });
                        // 写入文件
                        const writable = await picHandle.createWritable();
                        await writable.write(blob);
                        await writable.close();

                        // 查看图片生成信息地址
                        var url_img_generate = "https://liblib-api.vibrou.com/api/www/img/generate/"+picUuid+"?timestamp="+Date.now();
                        // 请求图片生成信息
                        const response_img_gen = await fetch(url_img_generate, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json'
                            }
                        })
                        const data_img_gen = await response_img_gen.json();
                        if(data_img_gen.code===0){
                            var metainformation = data_img_gen.data.metainformation;
                            if(!metainformation){
                                metainformation = 'prompt:'+data_img_gen.data.prompt +"\n";
                                metainformation = metainformation + 'negativePrompt:'+data_img_gen.data.negativePrompt +"\n";
                                metainformation = metainformation + 'modelNames:'+data_img_gen.data.modelNames +"\n";
                                metainformation = metainformation + 'seed:'+data_img_gen.data.seed +"\n";
                                metainformation = metainformation + 'samplingMethod:'+data_img_gen.data.samplingMethod +"\n";
                                metainformation = metainformation + 'samplingStep:'+data_img_gen.data.samplingStep +"\n";
                                metainformation = metainformation + 'cfgScale:'+data_img_gen.data.cfgScale +"\n";
                            }
                            // console.log(metainformation);
                            // 获取文件句柄
                            const savefileHandle = await newDirHandle.getFileHandle(imageName+".json", { create: true });
                            // 写入文件
                            const writablefile = await savefileHandle.createWritable();
                            await writablefile.write(metainformation);
                            await writablefile.close();
                        }

                        count ++;

                        const numberInput2 = document.getElementById('numberInput2');
                        numberInput2.setAttribute('value', number-count);
                        numberInput2.dispatchEvent(new Event('change'));

                        // 如果已经获取了所有数据,就跳出循环
                        if (count >= number) {
                            alert("返图信息下载完成");
                            const numberInput2 = document.getElementById('numberInput2');
                            numberInput2.setAttribute('value', default_download_pic_num);
                            numberInput2.dispatchEvent(new Event('change'));
                            return;
                        }
                    }
                }
            }
            // 增加page以获取下一页的数据
            page++;
        }
    }

    // 定义元素------------------------------------
    var div1 = document.createElement('div');
    div1.style.display = 'flex';
    div1.style.justifyContent="space-between";
    div1.style.alignItems = "center";

    var button1 = document.createElement('button');
    button1.textContent = '下载作者图例+生成信息';
    button1.onclick = saveAuthImagesInfo;
    button1.style.padding = '10px';
    button1.style.width = "200px";
    button1.style.backgroundColor = 'red';
    button1.style.color = 'white';
    button1.style.display = 'none';
    button1.style.flex = "1";

    const span1 = document.createElement('span');
    span1.textContent = '数量:';
    span1.style.marginLeft = "8px";

    const numberInput1 = document.createElement('input');
    numberInput1.setAttribute('type', 'number');
    numberInput1.setAttribute('id', 'numberInput1');
    numberInput1.setAttribute('value', 0);
    numberInput1.style.display = 'none';
    numberInput1.style.border = "1px solid";
    numberInput1.style.textAlign = "center";
    numberInput1.style.width = "80px";
    numberInput1.style.height = "38px";
    numberInput1.disabled = true;

    div1.appendChild(button1);
    div1.appendChild(span1);
    div1.appendChild(numberInput1);

    //----------------------------------------------
    var div2 = document.createElement('div');
    div2.style.display = 'flex';
    div2.style.justifyContent="space-between";
    div2.style.alignItems = "center";
    div2.style.margin = "2px 0";

    var button2 = document.createElement('button');
    button2.textContent = '下载返图图片+生成信息';
    button2.onclick = saveReturnImagesInfo;
    button2.style.padding = '10px';
    button2.style.width = "200px";
    button2.style.backgroundColor = 'blue';
    button2.style.color = 'white';
    button2.style.display = 'none';
    button2.style.flex = "1";

    const span2 = document.createElement('span');
    span2.textContent = '数量:';
    span2.style.marginLeft = "8px";

    const numberInput2 = document.createElement('input');
    numberInput2.setAttribute('type', 'number');
    numberInput2.setAttribute('id', 'numberInput2');
    numberInput2.setAttribute('value', default_download_pic_num);
    numberInput2.style.display = 'none';
    numberInput2.style.border = "1px solid";
    numberInput2.style.textAlign = "center";
    numberInput2.style.width = "80px";
    numberInput2.style.height = "38px";

    div2.appendChild(button2);
    div2.appendChild(span2);
    div2.appendChild(numberInput2);

    // 监听
    var observer = new MutationObserver(function(mutations) {
        var found = false;
        mutations.forEach(function(mutation) {
            if (mutation.type === 'childList' && !found) {
                var allElements = document.querySelectorAll('div');
                allElements.forEach(function(element) {
                    var classNames = element.className.split(/\s+/);
                    for (var i = 0; i < classNames.length; i++) {
                        if (classNames[i].startsWith('ModelDescription_desc')) {
                            found = true;
                            observer.disconnect(); // 停止观察
                            var actionCard = document.querySelector('[class^="ModelActionCard_modelActionCard"]');
                            if (actionCard) {
                                actionCard.parentNode.insertBefore(div2, actionCard);
                                actionCard.parentNode.insertBefore(div1, div2);

                                button1.style.display = 'block';
                                numberInput1.style.display = 'block';
                                button2.style.display = 'block';
                                numberInput2.style.display = 'block';
                            }
                            break;
                        }
                    }
                });
            }
        });
    });

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