Skip to content

Commit 2ecd470

Browse files
authored
merge: 🔀 pull request #50 from melMass/dev/august-refactor
2 parents 414beb9 + ea5d73d commit 2ecd470

30 files changed

Lines changed: 1270 additions & 3301 deletions

‎__init__.py‎

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,15 @@ def extract_nodes_from_source(filename):
4545
if isinstance(target, ast.Name) and target.id == "__nodes__":
4646
value = ast.get_source_segment(source_code, node.value)
4747
node_value = ast.parse(value).body[0].value
48-
if isinstance(node_value, ast.List) or isinstance(
49-
node_value, ast.Tuple
50-
):
51-
for element in node_value.elts:
52-
if isinstance(element, ast.Name):
53-
print(element.id)
54-
nodes.append(element.id)
55-
48+
if isinstance(node_value, (ast.List, ast.Tuple)):
49+
nodes.extend(
50+
element.id
51+
for element in node_value.elts
52+
if isinstance(element, ast.Name)
53+
)
5654
break
5755
except SyntaxError:
5856
log.error("Failed to parse")
59-
pass # File couldn't be parsed
60-
6157
return nodes
6258

6359

@@ -187,6 +183,14 @@ def load_nodes():
187183
from .endpoint import endlog
188184

189185
if hasattr(PromptServer, "instance"):
186+
restore_deps = ["basicsr"]
187+
swap_deps = ["insightface", "onnxruntime"]
188+
189+
node_dependency_mapping = {
190+
"FaceSwap": swap_deps,
191+
"LoadFaceSwapModel": swap_deps,
192+
"LoadFaceAnalysisModel": restore_deps,
193+
}
190194

191195
@PromptServer.instance.routes.get("/mtb/status")
192196
async def get_full_library(request):
@@ -202,7 +206,13 @@ async def get_full_library(request):
202206
NODE_CLASS_MAPPINGS_DEBUG, title="Registered"
203207
)
204208
html_response += endpoint.render_table(
205-
{k: "-" for k in failed}, title="Failed to load"
209+
{
210+
k: {"dependencies": node_dependency_mapping.get(k)}
211+
if node_dependency_mapping.get(k)
212+
else "-"
213+
for k in failed
214+
},
215+
title="Failed to load",
206216
)
207217

208218
return web.Response(
@@ -226,11 +236,10 @@ async def set_debug(request):
226236
log.setLevel(logging.DEBUG)
227237
log.debug("Debug mode set from API (/mtb/debug POST route)")
228238

229-
else:
230-
if "MTB_DEBUG" in os.environ:
231-
# del os.environ["MTB_DEBUG"]
232-
os.environ.pop("MTB_DEBUG")
233-
log.setLevel(logging.INFO)
239+
elif "MTB_DEBUG" in os.environ:
240+
# del os.environ["MTB_DEBUG"]
241+
os.environ.pop("MTB_DEBUG")
242+
log.setLevel(logging.INFO)
234243

235244
return web.json_response(
236245
{"message": f"Debug mode {'set' if enabled else 'unset'}"}
@@ -244,7 +253,7 @@ async def get_home(request):
244253
# Check if the request prefers HTML content
245254
if "text/html" in request.headers.get("Accept", ""):
246255
# # Return an HTML page
247-
html_response = f"""
256+
html_response = """
248257
<div class="flex-container menu">
249258
<a href="/mtb/debug">debug</a>
250259
<a href="/mtb/status">status</a>
@@ -263,9 +272,7 @@ async def get_debug(request):
263272
from . import endpoint
264273

265274
reload(endpoint)
266-
enabled = False
267-
if "MTB_DEBUG" in os.environ:
268-
enabled = True
275+
enabled = "MTB_DEBUG" in os.environ
269276
# Check if the request prefers HTML content
270277
if "text/html" in request.headers.get("Accept", ""):
271278
# # Return an HTML page
@@ -285,7 +292,7 @@ async def no_route(request):
285292
from . import endpoint
286293

287294
if "text/html" in request.headers.get("Accept", ""):
288-
html_response = f"""
295+
html_response = """
289296
<h1>Actions has no get for now...</h1>
290297
"""
291298
return web.Response(

‎endpoint.py‎

Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,35 @@
1-
from .utils import here
1+
from .utils import here, run_command, comfy_mode
22
from aiohttp import web
33
from .log import mklog
4-
import os
4+
import sys
55

66
endlog = mklog("mtb endpoint")
77

8-
#- ACTIONS
8+
# - ACTIONS
9+
import requirements
10+
11+
12+
13+
def ACTIONS_installDependency(dependency_names=None):
14+
if dependency_names is None:
15+
return {"error": "No dependency name provided"}
16+
endlog.debug(f"Received Install Dependency request for {dependency_names}")
17+
reqs = []
18+
if comfy_mode == "embeded":
19+
reqs = list(requirements.parse((here / "reqs_portable.txt").read_text()))
20+
else:
21+
reqs = list(requirements.parse((here / "reqs.txt").read_text()))
22+
print([x.specs for x in reqs])
23+
print(
24+
"\n".join([f"{x.line} {''.join(x.specs[0] if x.specs else '')}" for x in reqs])
25+
)
26+
for dependency_name in dependency_names:
27+
for req in reqs:
28+
if req.name == dependency_name:
29+
endlog.debug(f"Dependency {dependency_name} installed")
30+
break
31+
return {"success": True}
32+
933

1034
def ACTIONS_getStyles(style_name=None):
1135
from .nodes.conditions import StylesLoader
@@ -19,10 +43,7 @@ def ACTIONS_getStyles(style_name=None):
1943
if not key.startswith("__") and key not in match_list
2044
}
2145
if style_name:
22-
if style_name in filtered_styles:
23-
return filtered_styles[style_name]
24-
else:
25-
return {"error": "Style not found"}
46+
return filtered_styles.get(style_name, {"error": "Style not found"})
2647
return filtered_styles
2748
return {"error": "No styles found"}
2849

@@ -35,7 +56,7 @@ async def do_action(request) -> web.Response:
3556

3657
endlog.debug(f"Received action request: {name} {args}")
3758

38-
method_name = "ACTIONS_" + name
59+
method_name = f"ACTIONS_{name}"
3960
method = globals().get(method_name)
4061

4162
if callable(method):
@@ -53,16 +74,36 @@ async def do_action(request) -> web.Response:
5374

5475

5576
# - HTML UTILS
77+
78+
79+
def dependencies_button(name, dependencies):
80+
deps = ",".join([f"'{x}'" for x in dependencies])
81+
return f"""
82+
<button class="dependency-button" onclick="window.mtb_action('installDependency',[{deps}])">Install {name} deps</button>
83+
"""
84+
85+
5686
def render_table(table_dict, sort=True, title=None):
57-
table_rows = ""
5887
table_dict = sorted(
5988
table_dict.items(), key=lambda item: item[0]
6089
) # Sort the dictionary by keys
6190

62-
for name, description in table_dict:
63-
table_rows += f"<tr><td>{name}</td><td>{description}</td></tr>"
91+
table_rows = ""
92+
for name, item in table_dict:
93+
if isinstance(item, dict):
94+
if "dependencies" in item:
95+
table_rows += f"<tr><td>{name}</td><td>"
96+
table_rows += f"{dependencies_button(name,item['dependencies'])}"
97+
98+
table_rows += "</td></tr>"
99+
else:
100+
table_rows += f"<tr><td>{name}</td><td>{render_table(item)}</td></tr>"
101+
# elif isinstance(item, str):
102+
# table_rows += f"<tr><td>{name}</td><td>{item}</td></tr>"
103+
else:
104+
table_rows += f"<tr><td>{name}</td><td>{item}</td></tr>"
64105

65-
html_response = f"""
106+
return f"""
66107
<div class="table-container">
67108
{"" if title is None else f"<h1>{title}</h1>"}
68109
<table>
@@ -78,7 +119,6 @@ def render_table(table_dict, sort=True, title=None):
78119
</table>
79120
</div>
80121
"""
81-
return html_response
82122

83123

84124
def render_base_template(title, content):
@@ -98,6 +138,29 @@ def render_base_template(title, content):
98138
{css_content}
99139
</style>
100140
</head>
141+
<script type="module">
142+
import {{ api }} from '/scripts/api.js'
143+
const mtb_action = async (action, args) =>{{
144+
console.log(`Sending ${{action}} with args: ${{args}}`)
145+
}}
146+
window.mtb_action = async (action, args) =>{{
147+
console.log(`Sending ${{action}} with args: ${{args}} to the API`)
148+
const res = await api.fetchApi('/actions', {{
149+
method: 'POST',
150+
body: JSON.stringify({{
151+
name: action,
152+
args,
153+
}}),
154+
}})
155+
156+
const output = await res.json()
157+
console.debug(`Received ${{action}} response:`, output)
158+
if (output?.result?.error){{
159+
alert(`An error occured: {{output?.result?.error}}`)
160+
}}
161+
return output?.result
162+
}}
163+
</script>
101164
<body>
102165
<header>
103166
<a href="/">Back to Comfy</a>
@@ -117,5 +180,6 @@ def render_base_template(title, content):
117180
<!-- Shared footer content here -->
118181
</footer>
119182
</body>
183+
120184
</html>
121185
"""

0 commit comments

Comments
 (0)