+
+- Scan models and try to download information & preview.
+- Support migration from `cdb-boop/ComfyUI-Model-Manager/main`
diff --git a/__init__.py b/__init__.py
index 31e6d87..c5a0770 100644
--- a/__init__.py
+++ b/__init__.py
@@ -3,9 +3,26 @@ import folder_paths
from .py import config
from .py import utils
+extension_uri = utils.normalize_path(os.path.dirname(__file__))
+
+requirements_path = utils.join_path(extension_uri, "requirements.txt")
+
+with open(requirements_path, "r", encoding="utf-8") as f:
+ requirements = f.readlines()
+
+requirements = [x.strip() for x in requirements]
+requirements = [x for x in requirements if not x.startswith("#")]
+
+uninstalled_package = [p for p in requirements if not utils.is_installed(p)]
+
+if len(uninstalled_package) > 0:
+ utils.print_info(f"Install dependencies...")
+ for p in uninstalled_package:
+ utils.pip_install(p)
+
# Init config settings
-config.extension_uri = utils.normalize_path(os.path.dirname(__file__))
+config.extension_uri = extension_uri
utils.resolve_model_base_paths()
version = utils.get_current_version()
@@ -97,9 +114,8 @@ async def create_model(request):
- downloadUrl: download url.
- hash: a JSON string containing the hash value of the downloaded model.
"""
- post = await request.post()
+ task_data = await request.json()
try:
- task_data = dict(post)
task_id = await services.create_model_download_task(task_data, request)
return web.json_response({"success": True, "data": {"taskId": task_id}})
except Exception as e:
@@ -158,13 +174,12 @@ async def update_model(request):
index = int(request.match_info.get("index", None))
filename = request.match_info.get("filename", None)
- post: dict = await request.post()
+ model_data: dict = await request.json()
try:
model_path = utils.get_valid_full_path(model_type, index, filename)
if model_path is None:
raise RuntimeError(f"File {filename} not found")
- model_data = dict(post)
services.update_model(model_path, model_data)
return web.json_response({"success": True})
except Exception as e:
@@ -194,6 +209,37 @@ async def delete_model(request):
return web.json_response({"success": False, "error": error_msg})
+@routes.get("/model-manager/model-info")
+async def fetch_model_info(request):
+ """
+ Fetch model information from network with model page.
+ """
+ try:
+ model_page = request.query.get("model-page", None)
+ result = services.fetch_model_info(model_page)
+ return web.json_response({"success": True, "data": result})
+ except Exception as e:
+ error_msg = f"Fetch model info failed: {str(e)}"
+ utils.print_error(error_msg)
+ return web.json_response({"success": False, "error": error_msg})
+
+
+@routes.post("/model-manager/model-info/scan")
+async def download_model_info(request):
+ """
+ Create a task to download model information.
+ """
+ post = await utils.get_request_body(request)
+ try:
+ scan_mode = post.get("scanMode", "diff")
+ await services.download_model_info(scan_mode)
+ return web.json_response({"success": True})
+ except Exception as e:
+ error_msg = f"Download model info failed: {str(e)}"
+ utils.print_error(error_msg)
+ return web.json_response({"success": False, "error": error_msg})
+
+
@routes.get("/model-manager/preview/{type}/{index}/{filename:.*}")
async def read_model_preview(request):
"""
@@ -236,6 +282,20 @@ async def read_download_preview(request):
return web.FileResponse(preview_path)
+@routes.post("/model-manager/migrate")
+async def migrate_legacy_information(request):
+ """
+ Migrate legacy information.
+ """
+ try:
+ await services.migrate_legacy_information()
+ return web.json_response({"success": True})
+ except Exception as e:
+ error_msg = f"Download model info failed: {str(e)}"
+ utils.print_error(error_msg)
+ return web.json_response({"success": False, "error": error_msg})
+
+
WEB_DIRECTORY = "web"
NODE_CLASS_MAPPINGS = {}
__all__ = ["WEB_DIRECTORY", "NODE_CLASS_MAPPINGS"]
diff --git a/demo/scan-model-info.png b/demo/scan-model-info.png
new file mode 100755
index 0000000000000000000000000000000000000000..7a26a3e9d19be5d8993b37776319ea1cffbc6595
GIT binary patch
literal 95567
zcmeFZWl)^Yw=Oyf5g;K6?hxD|*ubC(&fqf)?(Xgo_$LInz~D2GU<1tHHaG!-TX2Wq
z!5u=dlYLL!y=#9sANJW*_g3xt_50EGU-!i(ZAF^Rb`8`h
zcX4&b{dJX`T{y&U+mzJexAU~Lg~H-N&iof!5Ai^llSr9_sSquO#1Gu8(^{AG?V=r+
zP_BmVHju=NhH)x;E{%;j ;0!NAnRziU%@%thL+kOAOcA33Hk3nB^swmnHvI+7tX%q_!$obQBTw
z?0a%xvE7ctT>nl=>5U=pVOEm0u>^zlqGHV<`H;lB%s9kl%xaPPg3lR&?Yd-P>@92k
zV$igWIc=4Vc@76DmtcM5mG{m@rl%y6ICDE5aCp|g)*^?*E|unMlT%3*XUSr_R)_!8
z3xouG5t+DU(~`QVi^WFaXBW=C`oYy07aGmQ%KPKpZi&AgZZ9fE%mW)1@iNUNZyFD1
zmo!kM(EBr?P;PI#ONaAFR9Oc0eE@l|BD=_~(iDcT H-d5+?4{&7
zGfbQOIl|sf@ule*B
z$PFC?NkndIQlcfV9Nw+6Z$0)QXF}U*>kew
zN}bcHXh|QI;c?IBrRUa@{y7>;1e=ZNmQG2>;w;ks>C;fZe*SX@4<&s_#%DCOd&gEI
zgZNXi%6p_2Skoh$TD~EztWus$Hzyo1cuyT>2hP%QtJjm__!=JJ7D1D9biA7V7en$0
zjR5PTv1xR@cM|HpmHPeW=y?#pV|t)Cwx@m|1q3KKa9E*Tb8vH|6YFhV@`U`BiS&`1
zYW=>;+J1p*=WM|-C_B&rBllVD-<8)Unqa%rz88UhrD_db{kX6Rq9X=VNi*e-rP^pS
zPKI9>$)2_@tRU^J#3nWTQd1N2q{C`hhYg15*Cq(o1jO2f+dt;%oRP8wobO2F#-r>@&>>~TS*;-9Bk$eoUW
zwY5Ghkj=UGy{$v7