From 76a9da71632d5134f66a9ddf2df5fb2fbc78918e Mon Sep 17 00:00:00 2001 From: shadowcz007 Date: Fri, 2 Aug 2024 18:32:27 +0800 Subject: [PATCH] fixbug --- __init__.py | 77 ++++++++--------- nodes/Utils.py | 22 +++++ web/index.html | 18 +++- web/javascript/app_mixlab.js | 3 +- web/javascript/command.js | 11 ++- web/javascript/utils_mixlab.js | 148 +++++++++++++++++++++++++++------ 6 files changed, 211 insertions(+), 68 deletions(-) diff --git a/__init__.py b/__init__.py index 80357d37..1ba36689 100644 --- a/__init__.py +++ b/__init__.py @@ -22,9 +22,8 @@ print('#fix sys.stdout.isatty') sys.stdout.isatty = lambda: False -llama_port=None -llama_model="" -llama_chat_format="" +_URL_=None + # try: # from .nodes.ChatGPT import get_llama_models,get_llama_model_path,llama_cpp_client @@ -320,22 +319,22 @@ def get_my_workflow_for_app(filename="my_workflow_app.json",category="",is_all=F # 这个代码不需要 # if len(apps)==1 and category!='' and category!=None: - data=read_workflow_json_files(category_path) + data=read_workflow_json_files(category_path) - for item in data: - x=item["data"] - # print(apps[0]['filename'] ,item["filename"]) - if apps[0]['filename']!=item["filename"]: - category='' - input=None - output=None - if 'category' in x['app']: - category=x['app']['category'] - if 'input' in x['app']: - input=x['app']['input'] - if 'output' in x['app']: - output=x['app']['output'] - apps.append({ + for item in data: + x=item["data"] + # print(apps[0]['filename'] ,item["filename"]) + if apps[0]['filename']!=item["filename"]: + category='' + input=None + output=None + if 'category' in x['app']: + category=x['app']['category'] + if 'input' in x['app']: + input=x['app']['input'] + if 'output' in x['app']: + output=x['app']['output'] + apps.append({ "filename":item["filename"], # "category":category, "data":{ @@ -455,6 +454,7 @@ async def check_port_available(address, port): # https async def new_start(self, address, port, verbose=True, call_on_start=None): + global _URL_ try: runner = web.AppRunner(self.app, access_log=None) await runner.setup() @@ -534,7 +534,8 @@ async def new_start(self, address, port, verbose=True, call_on_start=None): # print("\033[93mStarting server\n") logging.info("\033[93mTo see the GUI go to: http://{}:{} or http://{}:{}".format(ip_address, http_port,address,http_port)) logging.info("\033[93mTo see the GUI go to: https://{}:{} or https://{}:{}\033[0m".format(ip_address, https_port,address,https_port)) - + + _URL_="http://{}:{}".format(address,http_port) # print("\033[93mTo see the GUI go to: http://{}:{}".format(address, http_port)) # print("\033[93mTo see the GUI go to: https://{}:{}\033[0m".format(address, https_port)) @@ -754,15 +755,16 @@ def random_seed(seed, data): for id, value in data.items(): # print(seed,id) - if 'seed' in value['inputs'] and not isinstance(value['inputs']['seed'], list) and seed[id] in ['increment', 'decrement', 'randomize']: - value['inputs']['seed'] = round(random.random() * max_seed) - - if 'noise_seed' in value['inputs'] and not isinstance(value['inputs']['noise_seed'], list) and seed[id] in ['increment', 'decrement', 'randomize']: - value['inputs']['noise_seed'] = round(random.random() * max_seed) - - if value.get('class_type') == "Seed_" and seed[id] in ['increment', 'decrement', 'randomize']: - value['inputs']['seed'] = round(random.random() * max_seed) - + if id in seed: + if 'seed' in value['inputs'] and not isinstance(value['inputs']['seed'], list) and seed[id] in ['increment', 'decrement', 'randomize']: + value['inputs']['seed'] = round(random.random() * max_seed) + + if 'noise_seed' in value['inputs'] and not isinstance(value['inputs']['noise_seed'], list) and seed[id] in ['increment', 'decrement', 'randomize']: + value['inputs']['noise_seed'] = round(random.random() * max_seed) + + if value.get('class_type') == "Seed_" and seed[id] in ['increment', 'decrement', 'randomize']: + value['inputs']['seed'] = round(random.random() * max_seed) + print('new Seed', value) return data @@ -992,7 +994,10 @@ def re_start(request): pass return os.execv(sys.executable, [sys.executable] + sys.argv) - +# 状态 +@routes.get('/mixlab/status') +def mix_status(request): + return web.Response(text="running#"+_URL_) # 导入节点 from .nodes.PromptNode import GLIGENTextBoxApply_Advanced,EmbeddingPrompt,RandomPrompt,PromptSlide,PromptSimplification,PromptImage,JoinWithDelimiter @@ -1001,7 +1006,7 @@ def re_start(request): from .nodes.ScreenShareNode import ScreenShareNode,FloatingVideo from .nodes.Audio import AudioPlayNode,SpeechRecognition,SpeechSynthesis -from .nodes.Utils import IncrementingListNode,ListSplit,CreateLoraNames,CreateSampler_names,CreateCkptNames,CreateSeedNode,TESTNODE_,TESTNODE_TOKEN,AppInfo,IntNumber,FloatSlider,TextInput,ColorInput,FontInput,TextToNumber,DynamicDelayProcessor,LimitNumber,SwitchByIndex,MultiplicationNode +from .nodes.Utils import KeyInput,IncrementingListNode,ListSplit,CreateLoraNames,CreateSampler_names,CreateCkptNames,CreateSeedNode,TESTNODE_,TESTNODE_TOKEN,AppInfo,IntNumber,FloatSlider,TextInput,ColorInput,FontInput,TextToNumber,DynamicDelayProcessor,LimitNumber,SwitchByIndex,MultiplicationNode from .nodes.Mask import PreviewMask_,MaskListReplace,MaskListMerge,OutlineMask,FeatheredMask from .nodes.Style import ApplyVisualStylePrompting,StyleAlignedReferenceSampler,StyleAlignedBatchAlign,StyleAlignedSampleReferenceLatents @@ -1061,6 +1066,7 @@ def re_start(request): "SpeechRecognition":SpeechRecognition, "SpeechSynthesis":SpeechSynthesis, + "KeyInput":KeyInput, "Color":ColorInput, "FloatSlider":FloatSlider, "IntNumber":IntNumber, @@ -1153,7 +1159,6 @@ def re_start(request): # web ui的节点功能 WEB_DIRECTORY = "./web" - logging.info('--------------') logging.info('\033[91m ### Mixlab Nodes: \033[93mLoaded') # print('\033[91m ### Mixlab Nodes: \033[93mLoaded') @@ -1162,7 +1167,7 @@ def re_start(request): from .nodes.ChatGPT import ChatGPTNode,ShowTextForGPT,CharacterInText,TextSplitByDelimiter,SiliconflowFreeNode logging.info('ChatGPT.available True') - NODE_CLASS_MAPPINGS_V = { + NODE_CLASS_MAPPINGS_V = { "ChatGPTOpenAI":ChatGPTNode, "SiliconflowLLM":SiliconflowFreeNode, "ShowTextForGPT":ShowTextForGPT, @@ -1171,7 +1176,7 @@ def re_start(request): } # 一个包含节点友好/可读的标题的字典 - NODE_DISPLAY_NAME_MAPPINGS_V = { + NODE_DISPLAY_NAME_MAPPINGS_V = { "ChatGPTOpenAI":"ChatGPT & Local LLM ♾️Mixlab", "SiliconflowLLM":"LLM Siliconflow ♾️Mixlab", "ShowTextForGPT":"Show Text ♾️MixlabApp", @@ -1268,7 +1273,7 @@ def re_start(request): try: from .nodes.TripoSR import LoadTripoSRModel,TripoSRSampler,SaveTripoSRMesh logging.info('TripoSR.available') - + # logging.info( folder_paths.get_temp_directory()) NODE_CLASS_MAPPINGS['LoadTripoSRModel_']=LoadTripoSRModel NODE_DISPLAY_NAME_MAPPINGS["LoadTripoSRModel_"]= "Load TripoSR Model" @@ -1283,8 +1288,4 @@ def re_start(request): logging.info('TripoSR.available False' ) - - - - logging.info('\033[93m -------------- \033[0m') diff --git a/nodes/Utils.py b/nodes/Utils.py index c01297ec..285ec562 100644 --- a/nodes/Utils.py +++ b/nodes/Utils.py @@ -181,6 +181,28 @@ def run(self,color): return (h,r,g,b,a,) +class KeyInput: + @classmethod + def INPUT_TYPES(s): + return {"required": { + "key":("KEY",), + }, + } + + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("key",) + + FUNCTION = "run" + + CATEGORY = "♾️Mixlab/Input" + + INPUT_IS_LIST = False + OUTPUT_IS_LIST = (False,) + + def run(self,key): + return (key,) + + class FontInput: @classmethod diff --git a/web/index.html b/web/index.html index eede765b..d8cb9c64 100644 --- a/web/index.html +++ b/web/index.html @@ -1740,7 +1740,7 @@ if (data.class_type === 'CheckpointLoaderSimple') { if (window._appData.data) window._appData.data[data.id].inputs.ckpt_name = selectDom.value; //更新输入参数 - updateInputData(nodeId, (inputs) => { + updateInputData(data.id, (inputs) => { inputs.ckpt_name = selectDom.value; return inputs }) @@ -1748,7 +1748,7 @@ if (data.class_type === 'LoraLoader') { if (window._appData.data) window._appData.data[data.id].inputs.lora_name = selectDom.value; //更新输入参数 - updateInputData(nodeId, (inputs) => { + updateInputData(data.id, (inputs) => { inputs.lora_name = selectDom.value; return inputs }) @@ -2870,7 +2870,12 @@ window._appData.category, window._appData.seed, inp, - api.clientId + api.clientId, + window._appData.data ? [{ + data: { + output: window._appData.data + } + }] : null ).then(res => { if (!res) { @@ -2900,7 +2905,12 @@ window._appData.category, window._appData.seed, window._appData.input.filter(inp => inp), - api.clientId + api.clientId, + window._appData.data ? [{ + data: { + output: window._appData.data + } + }] : null ).then(res => { if (!res) { diff --git a/web/javascript/app_mixlab.js b/web/javascript/app_mixlab.js index 6b723305..7b668c9d 100644 --- a/web/javascript/app_mixlab.js +++ b/web/javascript/app_mixlab.js @@ -3,7 +3,8 @@ import { $el } from '../../../scripts/ui.js' import { api } from '../../../scripts/api.js' import { td_bg } from './td_background.js' -console.log('td_bg', td_bg) +// console.log('td_bg', td_bg) + //本机安装的插件节点全集 window._nodesAll = null diff --git a/web/javascript/command.js b/web/javascript/command.js index e772ccc3..74ac3c74 100644 --- a/web/javascript/command.js +++ b/web/javascript/command.js @@ -1,4 +1,9 @@ function get_url () { + // 如果有缓存记录 + let hostUrl = localStorage.getItem('_hostUrl') || '' + if (hostUrl) { + return hostUrl + } let api_host = `${window.location.hostname}:${window.location.port}` let api_base = '' let url = `${window.location.protocol}//${api_host}${api_base}` @@ -143,8 +148,12 @@ function queuePromptNew (filename, category, seed, input, client_id) { // 随机seed // promptWorkflow = randomSeed(seed, promptWorkflow); + let d = { filename, category, seed, input, client_id } + if (apps) { + d.apps = apps + } - const data = JSON.stringify({ filename, category, seed, input, client_id }) + const data = JSON.stringify(d) return new Promise((res, rej) => { fetch(`${url}/mixlab/prompt`, { method: 'POST', diff --git a/web/javascript/utils_mixlab.js b/web/javascript/utils_mixlab.js index be5cf81c..8e527fed 100644 --- a/web/javascript/utils_mixlab.js +++ b/web/javascript/utils_mixlab.js @@ -1,5 +1,5 @@ import { app } from '../../../scripts/app.js' -import { $el } from '../../../scripts/ui.js' +import { $el } from '../../../scripts/ui.js' const getLocalData = key => { let data = {} @@ -122,7 +122,7 @@ app.registerExtension({ nodeType.prototype.onNodeCreated = function () { orig_nodeCreated?.apply(this, arguments) - // console.log('Color nodeData', this.widgets) + console.log('Color nodeData', this.div) const widget = { type: 'div', @@ -273,19 +273,19 @@ app.registerExtension({ }) const min_max = node => { - if(node.widgets){ + if (node.widgets) { const min_value = node.widgets.filter(w => w.name === 'min_value')[0] const max_value = node.widgets.filter(w => w.name === 'max_value')[0] - + const number = node.widgets.filter(w => w.name === 'number')[0] if (number) { number.options.min = min_value.value number.options.max = max_value.value - + number.value = Math.min(number.options.max, number.value) number.value = Math.max(number.options.min, number.value) } - + if (min_value) min_value.callback = e => { number.options.min = e @@ -297,22 +297,18 @@ const min_max = node => { number.value = e } } - } app.registerExtension({ name: 'Mixlab.utils.FloatSlider', async beforeRegisterNodeDef (nodeType, nodeData, app) { - if (nodeType.comfyClass == 'FloatSlider') { - const orig_nodeCreated = nodeType.prototype.onNodeCreated; + const orig_nodeCreated = nodeType.prototype.onNodeCreated nodeType.prototype.onNodeCreated = function () { orig_nodeCreated?.apply(this, arguments) min_max(this) } } - - }, async loadedGraphNode (node, app) { if (node.type === 'FloatSlider') { @@ -323,7 +319,6 @@ app.registerExtension({ app.registerExtension({ name: 'Mixlab.utils.IntNumber', async beforeRegisterNodeDef (nodeType, nodeData, app) { - if (nodeType.comfyClass == 'IntNumber') { const orig_nodeCreated = nodeType.prototype.onNodeCreated nodeType.prototype.onNodeCreated = function () { @@ -331,7 +326,6 @@ app.registerExtension({ min_max(this) } } - }, async loadedGraphNode (node, app) { if (node.type === 'IntNumber') { @@ -340,22 +334,128 @@ app.registerExtension({ } }) - app.registerExtension({ name: 'Mixlab.utils.TESTNODE_', async beforeRegisterNodeDef (nodeType, nodeData, app) { - if (nodeType.comfyClass == 'TESTNODE_') { - - const onExecuted = nodeType.prototype.onExecuted; - nodeType.prototype.onExecuted = function (message) { - onExecuted?.apply(this, arguments); - console.log('##',message) - - }; + const onExecuted = nodeType.prototype.onExecuted + nodeType.prototype.onExecuted = function (message) { + onExecuted?.apply(this, arguments) + console.log('##', message) + } + } + } +}) + +app.registerExtension({ + name: 'Mixlab.utils.KeyInput', + init () {}, + async getCustomWidgets (app) { + return { + KEY (node, inputName, inputData, app) { + // console.log('##node', node) + const widget = { + type: inputData[0], // the type, CHEESE + name: inputName, // the name, slice + size: [128, 32], // a default size + draw (ctx, node, width, y) {}, + computeSize (...args) { + return [128, 32] // a method to compute the current size of the widget + }, + async serializeValue (nodeId, widgetIndex) { + let data = getLocalData('_mixlab_api_key') + return data[node.id] || 'by Mixlab' + } + } + // widget.something = something; // maybe adds stuff to it + node.addCustomWidget(widget) // adds it to the node + return widget // and returns it. + } + } + }, + + async beforeRegisterNodeDef (nodeType, nodeData, app) { + if (nodeType.comfyClass == 'KeyInput') { + const orig_nodeCreated = nodeType.prototype.onNodeCreated + nodeType.prototype.onNodeCreated = function () { + orig_nodeCreated?.apply(this, arguments) + + const widget = { + type: 'div', + name: 'key_inp', + draw (ctx, node, widget_width, y, widget_height) { + Object.assign( + this.div.style, + get_position_style(ctx, widget_width, 44, node.size[1]) + ) + } + } + + widget.div = $el('div', {}) + + const inputDiv = (key, placeholder) => { + let div = document.createElement('div') + const ip = document.createElement('input') + ip.type = placeholder === 'Key' ? 'password' : 'text' + ip.className = `${'comfy-multiline-input'} ${placeholder}` + div.style = `display: flex; + align-items: center; + margin: 6px 8px; + margin-top: 0;` + ip.placeholder = placeholder + ip.value = placeholder + + ip.style = `margin-left: 24px; + outline: none; + border: none; + padding: 4px;width: 100%;` + const label = document.createElement('label') + label.style = 'font-size: 10px;min-width:32px' + label.innerText = placeholder + div.appendChild(label) + div.appendChild(ip) + + ip.addEventListener('change', () => { + let data = getLocalData(key) + data[this.id] = ip.value.trim() + localStorage.setItem(key, JSON.stringify(data)) + console.log(this.id, key) + }) + return div + } + + let inputKey = inputDiv('_mixlab_api_key', 'Key') + widget.div.appendChild(inputKey) + this.addCustomWidget(widget) + + console.log('KeyInput nodeData',widget.div) + + + const onRemoved = this.onRemoved + this.onRemoved = () => { + inputKey.remove() + widget.div.remove() + return onRemoved?.() + } + + this.serialize_widgets = true //需要保存参数 + } } - - }, + }, + async loadedGraphNode (node, app) { + // Fires every time a node is constructed + // You can modify widgets/add handlers/etc here + + if (node.type === 'KeyInput') { + let widget = node.widgets.filter(w => w.div)[0] + + let apiKey = getLocalData('_mixlab_api_key'); + + let id = node.id + + widget.div.querySelector('.Key').value = apiKey[id] || 'by Mixlab' + } + } })