mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-10-12 12:32:11 -03:00
fix(sidebar): let a ghost folder be cleared from the UI (#1145)
Deleting a folder a file manager had already moved away answered "Folder no longer
exists" and stopped there: `remove_known_folder()` only ran after `shutil.rmtree()`
succeeded, so the records keeping the node in the tree could never be dropped, and
the modal's missing state hid its confirm button. The sidebar was a dead end for
exactly the case the folder list cannot self-heal.
* `ModelMoveService.forget_folder()` drops a folder's records (the recorded entry
plus the cached models under it) and refuses with `code: "exists"` while any root
still holds the directory, because then the caller wants a delete.
* `delete_folder()` forgets the records instead of failing when the directory is
already gone. The dry run stays a pure read and keeps answering `missing`, which
is what makes the dialog offer the removal. `POST`/`GET
/api/lm/{prefix}/forget-folder` is the endpoint for a node that maps to no
directory at all (the GET form is for the browser extension, which is GET-only).
* The sidebar falls back to it from the delete flow, offers "Remove from list" in
the missing state, and reports the folder as removed from the sidebar rather than
as a delete that never happened. An `exists` conflict says the directory is back
and should be deleted instead.
Verified: 3811 backend tests, 1543 JS tests, 96 Vue tests, 20 i18n tests.
This commit is contained in:
@@ -2629,6 +2629,39 @@ class ModelMoveHandler:
|
||||
self._logger.error("Error deleting folder: %s", exc, exc_info=True)
|
||||
return web.json_response({"success": False, "error": str(exc)}, status=500)
|
||||
|
||||
async def forget_folder(self, request: web.Request) -> web.Response:
|
||||
"""Drop the records of a folder that no longer exists on disk (#1145).
|
||||
|
||||
The sidebar's delete flow reaches this when the node it holds maps to no
|
||||
directory any more: there is nothing to delete, so the only cleanup left
|
||||
is forgetting the folder entry and the cached models under it.
|
||||
"""
|
||||
data: Dict[str, Any] = {}
|
||||
if request.method == "POST":
|
||||
try:
|
||||
data = await request.json()
|
||||
except Exception:
|
||||
data = {}
|
||||
folder = str(data.get("folder") or request.query.get("folder") or "").strip()
|
||||
if not folder:
|
||||
return web.json_response(
|
||||
{"success": False, "error": "Folder is required"}, status=400
|
||||
)
|
||||
|
||||
try:
|
||||
result = await self._move_service.forget_folder(folder)
|
||||
if result.get("success"):
|
||||
_broadcast_models_changed()
|
||||
return web.json_response(result, status=200)
|
||||
|
||||
# `exists` is a conflict between the tree the client rendered and the
|
||||
# on-disk truth: the folder is still there, so it must be deleted.
|
||||
status = 409 if result.get("code") == "exists" else 400
|
||||
return web.json_response(result, status=status)
|
||||
except Exception as exc:
|
||||
self._logger.error("Error forgetting folder: %s", exc, exc_info=True)
|
||||
return web.json_response({"success": False, "error": str(exc)}, status=500)
|
||||
|
||||
async def rename_folder(self, request: web.Request) -> web.Response:
|
||||
try:
|
||||
data = await request.json()
|
||||
@@ -3701,6 +3734,7 @@ class ModelHandlerSet:
|
||||
"create_folder": self.move.create_folder,
|
||||
"resolve_folder": self.move.resolve_folder,
|
||||
"delete_folder": self.move.delete_folder,
|
||||
"forget_folder": self.move.forget_folder,
|
||||
"rename_folder": self.move.rename_folder,
|
||||
"auto_organize_models": self.auto_organize.auto_organize_models,
|
||||
"get_auto_organize_progress": self.auto_organize.get_auto_organize_progress,
|
||||
|
||||
Reference in New Issue
Block a user