mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-09-21 03:01:27 -03:00
Support re-import for recipes without a source URL
Recipes imported by drag & drop / file-picker record no source_path and were rejected by re-import. Fall back to the recipe's own saved image, which still carries the original embedded generation metadata. Re-import now re-parses that original metadata instead of the appended recipe JSON block, so parser upgrades produce fresh results. The already-optimized preview image is kept verbatim: only its WebP EXIF chunk is rewritten in place to replace the recipe metadata block, and the recipe JSON is rewritten with the new analysis plus carried-over user edits.
This commit is contained in:
@@ -368,6 +368,7 @@ class RecipeAnalysisService:
|
||||
*,
|
||||
file_path: str | None,
|
||||
recipe_scanner,
|
||||
ignore_recipe_metadata: bool = False,
|
||||
) -> AnalysisResult:
|
||||
"""Analyze a file already present on disk."""
|
||||
|
||||
@@ -389,6 +390,22 @@ class RecipeAnalysisService:
|
||||
}
|
||||
return result
|
||||
|
||||
if ignore_recipe_metadata:
|
||||
# Re-import: re-parse the original embedded generation metadata
|
||||
# instead of the recipe JSON block LoRA Manager appended on save.
|
||||
from ...recipes.parsers.recipe_format import strip_recipe_metadata
|
||||
|
||||
metadata = strip_recipe_metadata(metadata)
|
||||
if not metadata:
|
||||
result = self._metadata_not_found_response(normalized_path)
|
||||
result.payload["diagnostics"] = {
|
||||
"channel": "local",
|
||||
"exif_present": True,
|
||||
"ignore_recipe_metadata": True,
|
||||
"reason": "only_recipe_metadata",
|
||||
}
|
||||
return result
|
||||
|
||||
result = await self._parse_metadata(
|
||||
metadata,
|
||||
recipe_scanner=recipe_scanner,
|
||||
|
||||
@@ -58,6 +58,7 @@ class RecipePersistenceService:
|
||||
extension: str | None = None,
|
||||
recipe_id: str | None = None,
|
||||
target_dir: str | None = None,
|
||||
skip_optimize: bool = False,
|
||||
) -> PersistenceResult:
|
||||
"""Persist a user uploaded recipe.
|
||||
|
||||
@@ -67,6 +68,11 @@ class RecipePersistenceService:
|
||||
target_dir: If provided, save recipe files to this directory instead
|
||||
of the default recipes_dir. Used by re-import to preserve the
|
||||
original folder location.
|
||||
skip_optimize: If True, store the image bytes verbatim without
|
||||
resizing/re-encoding (recipe metadata is still embedded via a
|
||||
byte-level EXIF update that leaves the pixels untouched). Used
|
||||
by local re-import, where the source is the recipe's own
|
||||
already-optimized preview image.
|
||||
"""
|
||||
|
||||
missing_fields = []
|
||||
@@ -87,9 +93,12 @@ class RecipePersistenceService:
|
||||
|
||||
recipe_id = recipe_id or str(uuid.uuid4())
|
||||
|
||||
# Handle video formats by bypassing optimization and metadata embedding
|
||||
# Handle video formats by bypassing optimization and metadata embedding.
|
||||
# Local re-import also bypasses optimization: the source is the
|
||||
# recipe's own already-optimized preview image, so re-compressing it
|
||||
# would only degrade quality.
|
||||
is_video = extension in [".mp4", ".webm"]
|
||||
if is_video:
|
||||
if is_video or skip_optimize:
|
||||
optimized_image = resolved_image_bytes
|
||||
# extension is already set
|
||||
else:
|
||||
@@ -175,7 +184,11 @@ class RecipePersistenceService:
|
||||
json.dump(recipe_data, file_obj, indent=4, ensure_ascii=False)
|
||||
|
||||
if not is_video:
|
||||
self._exif_utils.append_recipe_metadata(normalized_image_path, recipe_data)
|
||||
self._exif_utils.append_recipe_metadata(
|
||||
normalized_image_path,
|
||||
recipe_data,
|
||||
pixel_preserving=skip_optimize,
|
||||
)
|
||||
|
||||
matching_recipes = await self._find_matching_recipes(recipe_scanner, fingerprint, exclude_id=recipe_id)
|
||||
await recipe_scanner.add_recipe(recipe_data)
|
||||
|
||||
Reference in New Issue
Block a user