Skip to content

Commit

Permalink
Merge pull request #95 from shadowcz007/v0.7-apps
Browse files Browse the repository at this point in the history
V0.7 apps
  • Loading branch information
shadowcz007 committed Dec 30, 2023
2 parents 16ef10a + 5c9dd80 commit 2e228e8
Show file tree
Hide file tree
Showing 14 changed files with 1,891 additions and 803 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ __pycache__/
https/
nodes/config.json
workflow/my_workflow.json
workflow/my_workflow_app.json
workflow/my_workflow_app.json
app/*
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
##
v0.6.0 🚀🚗🚚🏃‍ Workflow-to-APP
v0.7.0 🚀🚗🚚🏃‍ Workflow-to-APP
- 支持多个web app 切换
- 新增AppInfo节点,可以通过简单的配置,把workflow转变为一个Web APP。
- Support multiple web app switching.
- Add the AppInfo node, which allows you to transform the workflow into a web app by simple configuration.

![](./assets/0-m-app.png)

![](./assets/appinfo-readme.png)

Example:
- workflow
![APP info](./workflow/appinfo-workflow.svg)
[text-to-image](./workflow/Text-to-Image-app.json)

APP-JSON:
- [text-to-image](./app/text-to-image_1_Wed%20Dec%2027%202023.json)
- [image-to-image](./app/image-to-image_1_Wed%20Dec%2027%202023.json)
- [text-to-image](./example/text-to-image_1_Wed%20Dec%2027%202023.json)
- [image-to-image](./example/image-to-image_1_Wed%20Dec%2027%202023.json)
- text-to-text

> 暂时支持6种节点作为界面上的输入节点:Load Image、CLIPTextEncode、TextInput_、FloatSlider、CheckpointLoaderSimple、LoraLoader
> 暂时支持6种节点作为界面上的输入节点:Load Image、CLIPTextEncode、TextInput_、FloatSlider、IntNumber、CheckpointLoaderSimple、LoraLoader
> 输出节点:PreviewImage 、SaveImage、ShowTextForGPT、VHS_VideoCombine
Expand Down
117 changes: 98 additions & 19 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import importlib.util
import sys,json
import urllib

import hashlib
import datetime


Expand Down Expand Up @@ -79,6 +79,13 @@ def install_openai():
current_path = os.path.abspath(os.path.dirname(__file__))



def calculate_md5(string):
encoded_string = string.encode()
md5_hash = hashlib.md5(encoded_string).hexdigest()
return md5_hash


def create_key(key_p,crt_p):
import OpenSSL
# 生成自签名证书
Expand Down Expand Up @@ -162,29 +169,98 @@ def get_workflows():
workflows=read_workflow_json_files(workflow_path)
return workflows

def get_my_workflow_for_app():
# print("#####path::", current_path)
workflow_path=os.path.join(current_path, "workflow/my_workflow_app.json")
print('workflow_path: ',workflow_path)
json_data={}
try:
with open(workflow_path) as json_file:
json_data = json.load(json_file)
except:
print('-')
return json_data
def get_my_workflow_for_app(filename="my_workflow_app.json"):
app_path=os.path.join(current_path, "app")
if not os.path.exists(app_path):
os.mkdir(app_path)

apps=[]
if filename==None:
data=read_workflow_json_files(app_path)
i=0
for item in data:
try:
x=item["data"]
if i==0:
apps.append({
"filename":item["filename"],
"data":x,
"date":item["date"]
})
else:
apps.append({
"filename":item["filename"],
"data":{
"app":{
"description":x['app']['description'],
"filename":(x['app']['filename'] if 'filename' in x['app'] else "") ,
"icon":(x['app']['icon'] if 'icon' in x['app'] else None),
"name":x['app']['name'],
"version":x['app']['version'],
}
},
"date":item["date"]
})
i+=1
except Exception as e:
print("发生异常:", str(e))
else:
app_workflow_path=os.path.join(app_path, filename)
# print('app_workflow_path: ',app_workflow_path)
try:
with open(app_workflow_path) as json_file:
apps = [{
'filename':filename,
'data':json.load(json_file)
}]
except Exception as e:
print("发生异常:", str(e))

if len(apps)==1:
data=read_workflow_json_files(app_path)

for item in data:
x=item["data"]
print(apps[0]['filename'] ,item["filename"])
if apps[0]['filename']!=item["filename"]:
apps.append({
"filename":item["filename"],
"data":{
"app":{
"description":x['app']['description'],
"filename":(x['app']['filename'] if 'filename' in x['app'] else "") ,
"icon":(x['app']['icon'] if 'icon' in x['app'] else None),
"name":x['app']['name'],
"version":x['app']['version'],
}
},
"date":item["date"]
})

return apps

def save_workflow_json(data):
workflow_path=os.path.join(current_path, "workflow/my_workflow.json")
with open(workflow_path, 'w') as file:
json.dump(data, file)
return workflow_path

def save_workflow_for_app(data):
workflow_path=os.path.join(current_path, "workflow/my_workflow_app.json")
with open(workflow_path, 'w') as file:
def save_workflow_for_app(data,filename="my_workflow_app.json"):
app_path=os.path.join(current_path, "app")
if not os.path.exists(app_path):
os.mkdir(app_path)
app_workflow_path=os.path.join(app_path, filename)

try:
output_str = json.dumps(data['output'])
data['app']['id']=calculate_md5(output_str)
# id=data['app']['id']
except Exception as e:
print("发生异常:", str(e))

with open(app_workflow_path, 'w') as file:
json.dump(data, file)
return workflow_path
return filename

def get_nodes_map():
# print("#####path::", current_path)
Expand Down Expand Up @@ -295,14 +371,17 @@ async def mixlab_workflow_hander(request):
'file_path':file_path
}
elif data['task']=='save_app':
file_path=save_workflow_for_app(data['data'])
file_path=save_workflow_for_app(data['data'],data['filename'])
result={
'status':'success',
'file_path':file_path
}
elif data['task']=='my_app':
filename=None
if 'filename' in data:
filename=data['filename']
result={
'data':get_my_workflow_for_app(),
'data':get_my_workflow_for_app(filename),
'status':'success',
}
elif data['task']=='list':
Expand Down Expand Up @@ -359,7 +438,7 @@ def new_add_routes(self):

# 导入节点
from .nodes.PromptNode import RandomPrompt
from .nodes.ImageNode import NoiseImage,TransparentImage,LoadImagesFromPath,LoadImagesFromURL,ResizeImage,TextImage,SvgImage,Image3D,EmptyLayer,ShowLayer,NewLayer,MergeLayers,AreaToMask,SmoothMask,FeatheredMask,SplitLongMask,ImageCropByAlpha,EnhanceImage,FaceToMask
from .nodes.ImageNode import NoiseImage,TransparentImage,LoadImagesFromPath,LoadImagesFromURL,ResizeImage,TextImage,SvgImage,Image3D,ShowLayer,NewLayer,MergeLayers,AreaToMask,SmoothMask,FeatheredMask,SplitLongMask,ImageCropByAlpha,EnhanceImage,FaceToMask
from .nodes.Vae import VAELoader,VAEDecode
from .nodes.ScreenShareNode import ScreenShareNode,FloatingVideo
from .nodes.Clipseg import CLIPSeg,CombineMasks
Expand Down
Binary file added assets/0-m-app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions nodes/ChatGPT.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ def INPUT_TYPES(cls):
"required": {
"api_key":("KEY", {"default": "", "multiline": True}),
"api_url":("URL", {"default": "", "multiline": True}),
"prompt": ("STRING", {"multiline": True}),
"prompt": ("STRING", {"multiline": True,"dynamicPrompts": False}),
"system_content": ("STRING",
{
"default": "You are ChatGPT, a large language model trained by OpenAI. Answer as concisely as possible.",
"multiline": True
"multiline": True,"dynamicPrompts": False
}),
"model": (["gpt-3.5-turbo","gpt-35-turbo","gpt-3.5-turbo-16k", "gpt-3.5-turbo-16k-0613", "gpt-4-0613","gpt-4-1106-preview"],
{"default": "gpt-3.5-turbo"}),
Expand Down Expand Up @@ -167,7 +167,7 @@ class ShowTextForGPT:
def INPUT_TYPES(s):
return {
"required": {
"text": ("STRING", {"forceInput": True}),
"text": ("STRING", {"forceInput": True,"dynamicPrompts": False}),
}
}

Expand All @@ -189,8 +189,8 @@ class CharacterInText:
def INPUT_TYPES(s):
return {
"required": {
"text": ("STRING", {"multiline": True}),
"character": ("STRING", {"multiline": True}),
"text": ("STRING", {"multiline": True,"dynamicPrompts": False}),
"character": ("STRING", {"multiline": True,"dynamicPrompts": False}),
"start_index": ("INT", {
"default": 1,
"min": 0, #Minimum value
Expand Down
13 changes: 7 additions & 6 deletions nodes/Utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,21 +369,22 @@ class AppInfo:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"name": ("STRING",{"multiline": False,"default": "Mixlab-App"}),
"name": ("STRING",{"multiline": False,"default": "Mixlab-App","dynamicPrompts": False}),
"image": ("IMAGE",),
"input_ids":("STRING",{"multiline": True,"default": "\n".join(["1","2","3"])}),
"output_ids":("STRING",{"multiline": True,"default": "\n".join(["5","9"])}),
"input_ids":("STRING",{"multiline": True,"default": "\n".join(["1","2","3"]),"dynamicPrompts": False}),
"output_ids":("STRING",{"multiline": True,"default": "\n".join(["5","9"]),"dynamicPrompts": False}),
},

"optional":{
"description":("STRING",{"multiline": True,"default": ""}),
"description":("STRING",{"multiline": True,"default": "","dynamicPrompts": False}),
"version":("INT", {
"default": 1,
"min": 1,
"max": 10000,
"step": 1,
"display": "number"
}),
"share_prefix":("STRING",{"multiline": False,"default": "","dynamicPrompts": False}),
}

}
Expand All @@ -398,13 +399,13 @@ def INPUT_TYPES(s):
INPUT_IS_LIST = False
OUTPUT_IS_LIST = (False,)

def run(self,name,image,input_ids,output_ids,description,version):
def run(self,name,image,input_ids,output_ids,description,version,share_prefix):

im=create_temp_file(image)

# id=get_json_hash([name,im,input_ids,output_ids,description,version])

return {"ui": {"json": [name,im,input_ids,output_ids,description,version]}, "result": (image,)}
return {"ui": {"json": [name,im,input_ids,output_ids,description,version,share_prefix]}, "result": (image,)}



Expand Down
Loading

0 comments on commit 2e228e8

Please sign in to comment.