Add CivitaiApiMetadataParser and improve recipe parsing logic for Civitai images. Also fixes #197

Additional info: Now prioritizes using the Civitai Images API to fetch image and generation metadata. Even NSFW images can now be imported via URL.
This commit is contained in:
Will Miao
2025-06-03 14:58:43 +08:00
parent e151a19fcf
commit 2d39b84806
7 changed files with 383 additions and 23 deletions

View File

@@ -5,7 +5,8 @@ from .parsers import (
RecipeFormatParser,
ComfyMetadataParser,
MetaFormatParser,
AutomaticMetadataParser
AutomaticMetadataParser,
CivitaiApiMetadataParser
)
from .base import RecipeMetadataParser
@@ -15,29 +16,49 @@ class RecipeParserFactory:
"""Factory for creating recipe metadata parsers"""
@staticmethod
def create_parser(user_comment: str) -> RecipeMetadataParser:
def create_parser(metadata) -> RecipeMetadataParser:
"""
Create appropriate parser based on the user comment content
Create appropriate parser based on the metadata content
Args:
user_comment: The EXIF UserComment string from the image
metadata: The metadata from the image (dict or str)
Returns:
Appropriate RecipeMetadataParser implementation
"""
# Try ComfyMetadataParser first since it requires valid JSON
# First, try CivitaiApiMetadataParser for dict input
if isinstance(metadata, dict):
try:
if CivitaiApiMetadataParser().is_metadata_matching(metadata):
return CivitaiApiMetadataParser()
except Exception as e:
logger.debug(f"CivitaiApiMetadataParser check failed: {e}")
pass
# Convert dict to string for other parsers that expect string input
try:
import json
metadata_str = json.dumps(metadata)
except Exception as e:
logger.debug(f"Failed to convert dict to JSON string: {e}")
return None
else:
metadata_str = metadata
# Try ComfyMetadataParser which requires valid JSON
try:
if ComfyMetadataParser().is_metadata_matching(user_comment):
if ComfyMetadataParser().is_metadata_matching(metadata_str):
return ComfyMetadataParser()
except Exception:
# If JSON parsing fails, move on to other parsers
pass
if RecipeFormatParser().is_metadata_matching(user_comment):
# Check other parsers that expect string input
if RecipeFormatParser().is_metadata_matching(metadata_str):
return RecipeFormatParser()
elif AutomaticMetadataParser().is_metadata_matching(user_comment):
elif AutomaticMetadataParser().is_metadata_matching(metadata_str):
return AutomaticMetadataParser()
elif MetaFormatParser().is_metadata_matching(user_comment):
elif MetaFormatParser().is_metadata_matching(metadata_str):
return MetaFormatParser()
else:
return None