mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 13:12:12 -03:00
Make preview file discovery case-insensitive so files with uppercase extensions like .WEBP are found on case-sensitive filesystems. Also explicitly list image/webp in the file picker accept attribute for broader browser compatibility. https://claude.ai/code/session_01SgT2pkisi27bEQELX5EeXZ
99 lines
3.2 KiB
Python
99 lines
3.2 KiB
Python
|
|
import hashlib
|
|
import logging
|
|
import os
|
|
|
|
from .constants import (
|
|
CARD_PREVIEW_WIDTH,
|
|
DEFAULT_HASH_CHUNK_SIZE_MB,
|
|
PREVIEW_EXTENSIONS,
|
|
)
|
|
from .exif_utils import ExifUtils
|
|
from ..services.settings_manager import get_settings_manager
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _get_hash_chunk_size_bytes() -> int:
|
|
"""Return the chunk size used for hashing, in bytes."""
|
|
|
|
settings_manager = get_settings_manager()
|
|
chunk_size_mb = settings_manager.get("hash_chunk_size_mb", DEFAULT_HASH_CHUNK_SIZE_MB)
|
|
try:
|
|
chunk_size_value = float(chunk_size_mb)
|
|
except (TypeError, ValueError):
|
|
chunk_size_value = float(DEFAULT_HASH_CHUNK_SIZE_MB)
|
|
|
|
if chunk_size_value <= 0:
|
|
chunk_size_value = float(DEFAULT_HASH_CHUNK_SIZE_MB)
|
|
|
|
return max(1, int(chunk_size_value * 1024 * 1024))
|
|
|
|
|
|
async def calculate_sha256(file_path: str) -> str:
|
|
"""Calculate SHA256 hash of a file"""
|
|
sha256_hash = hashlib.sha256()
|
|
chunk_size = _get_hash_chunk_size_bytes()
|
|
with open(file_path, "rb") as f:
|
|
for byte_block in iter(lambda: f.read(chunk_size), b""):
|
|
sha256_hash.update(byte_block)
|
|
return sha256_hash.hexdigest()
|
|
|
|
def find_preview_file(base_name: str, dir_path: str) -> str:
|
|
"""Find preview file for given base name in directory.
|
|
|
|
Performs an exact-case check first (fast path), then falls back to a
|
|
case-insensitive scan so that files like ``model.WEBP`` or ``model.Png``
|
|
are discovered on case-sensitive filesystems.
|
|
"""
|
|
|
|
temp_extensions = PREVIEW_EXTENSIONS.copy()
|
|
# Add example extension for compatibility
|
|
# https://github.com/willmiao/ComfyUI-Lora-Manager/issues/225
|
|
# The preview image will be optimized to lora-name.webp, so it won't affect other logic
|
|
temp_extensions.append(".example.0.jpeg")
|
|
|
|
# Fast path: exact-case match
|
|
for ext in temp_extensions:
|
|
full_pattern = os.path.join(dir_path, f"{base_name}{ext}")
|
|
if os.path.exists(full_pattern):
|
|
return full_pattern.replace(os.sep, "/")
|
|
|
|
# Slow path: case-insensitive match for systems with mixed-case extensions
|
|
# (e.g. .WEBP, .Png, .JPG placed manually or by external tools)
|
|
try:
|
|
dir_entries = os.listdir(dir_path)
|
|
except OSError:
|
|
return ""
|
|
|
|
base_lower = base_name.lower()
|
|
for ext in temp_extensions:
|
|
target = f"{base_lower}{ext}" # ext is already lowercase
|
|
for entry in dir_entries:
|
|
if entry.lower() == target:
|
|
return os.path.join(dir_path, entry).replace(os.sep, "/")
|
|
|
|
return ""
|
|
|
|
def get_preview_extension(preview_path: str) -> str:
|
|
"""Get the complete preview extension from a preview file path
|
|
|
|
Args:
|
|
preview_path: Path to the preview file
|
|
|
|
Returns:
|
|
str: The complete extension (e.g., '.preview.png', '.png', '.webp')
|
|
"""
|
|
preview_path_lower = preview_path.lower()
|
|
|
|
# Check for compound extensions first (longer matches first)
|
|
for ext in sorted(PREVIEW_EXTENSIONS, key=len, reverse=True):
|
|
if preview_path_lower.endswith(ext.lower()):
|
|
return ext
|
|
|
|
return os.path.splitext(preview_path)[1]
|
|
|
|
def normalize_path(path: str) -> str:
|
|
"""Normalize file path to use forward slashes"""
|
|
return path.replace(os.sep, "/") if path else path
|