mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-10-03 08:45:31 -03:00
fix(example-images): support importing for Other models and pending hashes
Two gaps kept 'import example images' from working on the Other page:
- import_images/delete_custom_image/set_example_image_nsfw_level only
searched the lora/checkpoint/embedding scanners, so Other-category
models were never found ('Model with hash ... not found in cache').
All three now go through a shared scanner list that includes the
Other scanner.
- Other models (and fresh checkpoints) carry hash_status=pending with
an empty sha256, so the frontend sent an empty model_hash and the
import was rejected with 'Missing model_hash parameter'. The modal
now also sends the model's file path, and the import use case
resolves the hash on demand via the scanner's lazy-hash calculation.
The resolved hash is returned to the UI and persisted on the
showcase element so follow-up operations target the same
hash-keyed folder.
This commit is contained in:
@@ -146,6 +146,8 @@ class StubExampleImagesProcessor(ExampleImagesProcessor):
|
||||
self.calls: List[Dict[str, Any]] = []
|
||||
self.error: Optional[str] = None
|
||||
self.response: Dict[str, Any] = {"success": True}
|
||||
self.resolved_hash: Optional[str] = None
|
||||
self.resolve_calls: List[str] = []
|
||||
|
||||
async def import_images(self, model_hash: str, files: List[str]) -> Dict[str, Any]: # pyright: ignore[reportIncompatibleMethodOverride]
|
||||
self.calls.append({"model_hash": model_hash, "files": files})
|
||||
@@ -155,6 +157,10 @@ class StubExampleImagesProcessor(ExampleImagesProcessor):
|
||||
raise ExampleImagesImportError("boom")
|
||||
return self.response
|
||||
|
||||
async def resolve_hash_for_file_path(self, file_path: str) -> str:
|
||||
self.resolve_calls.append(file_path)
|
||||
return self.resolved_hash or ""
|
||||
|
||||
|
||||
async def test_auto_organize_use_case_executes_with_lock() -> None:
|
||||
file_service = StubFileService()
|
||||
@@ -506,6 +512,34 @@ async def test_import_example_images_use_case_propagates_generic_error() -> None
|
||||
await use_case.execute(request) # pyright: ignore[reportArgumentType]
|
||||
|
||||
|
||||
async def test_import_example_images_use_case_resolves_hash_from_model_path() -> None:
|
||||
"""Models with a deferred hash (checkpoints, Other) send model_path
|
||||
instead of model_hash; the use case must resolve the hash on demand."""
|
||||
processor = StubExampleImagesProcessor()
|
||||
processor.resolved_hash = "f" * 64
|
||||
use_case = ImportExampleImagesUseCase(processor=processor)
|
||||
|
||||
request = DummyJsonRequest(
|
||||
{"model_path": "/models/vae/x.safetensors", "file_paths": ["/tmp/file"]}
|
||||
)
|
||||
result = await use_case.execute(request) # pyright: ignore[reportArgumentType]
|
||||
|
||||
assert processor.resolve_calls == ["/models/vae/x.safetensors"]
|
||||
assert processor.calls == [{"model_hash": "f" * 64, "files": ["/tmp/file"]}]
|
||||
assert result == {"success": True}
|
||||
|
||||
|
||||
async def test_import_example_images_use_case_rejects_unresolvable_model_path() -> None:
|
||||
processor = StubExampleImagesProcessor()
|
||||
use_case = ImportExampleImagesUseCase(processor=processor)
|
||||
request = DummyJsonRequest(
|
||||
{"model_path": "/models/unknown.safetensors", "file_paths": []}
|
||||
)
|
||||
|
||||
with pytest.raises(ImportExampleImagesValidationError):
|
||||
await use_case.execute(request) # pyright: ignore[reportArgumentType]
|
||||
|
||||
|
||||
class StubLifecycleService:
|
||||
def __init__(self, scanner: Optional[MockScanner] = None) -> None:
|
||||
self.renames: List[Dict[str, str]] = []
|
||||
|
||||
Reference in New Issue
Block a user