fix: resolve gallery crash when thumbnails exist and prevent thumbnail-as-image linking

- Fix AttributeError: 'str' has no attribute 'as_posix' on thumbnail_rel_path
  in get_output_images and find_duplicates (thumbnail_rel_path is already a
  string from f-string construction, not a Path object)
- Fix NameError: total_images undefined in generate_thumbnails (was defined as
  total_media, causing progress logging and response to fail)
- Add URL encoding for paths in scan_output_dir for filenames with spaces
- Exclude thumbnails directory from image monitor to prevent linking thumbnail
  files to prompts via fallback mechanism
- Bump version to 3.0.31
This commit is contained in:
Vito Sansevero
2026-02-03 14:07:23 -08:00
parent 9e575ab48c
commit f485825bfb
3 changed files with 24 additions and 17 deletions
+15 -12
View File
@@ -1068,8 +1068,8 @@ class PromptManagerAPI:
if thumbnail_abs_path.exists():
from urllib.parse import quote
thumbnail_url = f'/prompt_manager/images/serve/{quote(thumbnail_rel_path.as_posix(), safe="/")}'
thumbnail_url = f'/prompt_manager/images/serve/{quote(thumbnail_rel_path, safe="/")}'
image_info = {
'id': str(hash(str(media_path))),
'filename': media_path.name,
@@ -2029,8 +2029,8 @@ class PromptManagerAPI:
if thumbnail_abs_path.exists():
from urllib.parse import quote
thumbnail_url = f'/prompt_manager/images/serve/{quote(thumbnail_rel_path.as_posix(), safe="/")}'
thumbnail_url = f'/prompt_manager/images/serve/{quote(thumbnail_rel_path, safe="/")}'
images.append({
'id': str(hash(str(media_path))), # Simple hash for ID
'filename': media_path.name,
@@ -2251,10 +2251,10 @@ class PromptManagerAPI:
if any(file.lower().endswith(ext) for ext in media_extensions):
media_files.append(Path(root) / file)
total_media = len(media_files)
self.logger.info(f"Found {total_media} media files to process for thumbnails")
if total_media == 0:
total_images = len(media_files)
self.logger.info(f"Found {total_images} media files to process for thumbnails")
if total_images == 0:
return web.json_response({
'success': True,
'count': 0,
@@ -4883,15 +4883,18 @@ class PromptManagerAPI:
if thumbnails_dir.exists():
# Preserve subdirectory structure in thumbnail path
rel_path_no_ext = rel_path.with_suffix('')
thumbnail_path = thumbnails_dir / f"{rel_path_no_ext.as_posix()}_thumb{image_path.suffix}"
if thumbnail_path.exists():
thumbnail_url = f'/prompt_manager/images/serve/thumbnails/{rel_path_no_ext.as_posix()}_thumb{image_path.suffix}'
thumbnail_rel_path = f"thumbnails/{rel_path_no_ext.as_posix()}_thumb{image_path.suffix}"
thumbnail_abs_path = thumbnails_dir / f"{rel_path_no_ext.as_posix()}_thumb{image_path.suffix}"
if thumbnail_abs_path.exists():
from urllib.parse import quote
thumbnail_url = f'/prompt_manager/images/serve/{quote(thumbnail_rel_path, safe="/")}'
from urllib.parse import quote as url_quote
images.append({
'filename': image_path.name,
'path': str(image_path),
'relative_path': str(rel_path),
'url': f'/prompt_manager/images/serve/{rel_path.as_posix()}',
'url': f'/prompt_manager/images/serve/{url_quote(rel_path.as_posix(), safe="/")}',
'thumbnail_url': thumbnail_url
})
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "promptmanager"
description = "A powerful ComfyUI custom node that extends the standard text encoder with persistent prompt storage, advanced search capabilities, and an automatic image gallery system using SQLite."
version = "3.0.30"
version = "3.0.31"
license = {file = "LICENSE"}
dependencies = ["# Core dependencies for PromptManager", "# Note: Most dependencies are already included with ComfyUI", "# Already included with Python standard library:", "# - sqlite3", "# - hashlib", "# - json", "# - datetime", "# - os", "# - typing", "# - threading", "# - uuid", "# Required for gallery functionality:", "watchdog>=2.1.0 # For file system monitoring", "Pillow>=8.0.0 # For image metadata extraction (usually included with ComfyUI)", "# Optional dependencies for enhanced search functionality:", "# fuzzywuzzy[speedup]>=0.18.0 # For fuzzy string matching (optional)", "# sqlalchemy>=1.4.0 # For advanced ORM features (optional)", "# Development dependencies (optional):", "# pytest>=6.0.0 # For running tests", "# black>=22.0.0 # For code formatting", "# flake8>=4.0.0 # For linting", "# mypy>=0.910 # For type checking"]
+8 -4
View File
@@ -84,14 +84,18 @@ class ImageGenerationHandler(FileSystemEventHandler):
).start()
def is_image_file(self, filepath: str) -> bool:
"""Check if file is a supported image format.
"""Check if file is a supported image format and not a thumbnail.
Args:
filepath: Path to the file to check
Returns:
True if the file has a supported image extension, False otherwise
True if the file has a supported image extension and is not
inside a thumbnails directory, False otherwise
"""
# Skip files in thumbnails directory - those are derivatives, not generated images
if '/thumbnails/' in filepath or '\\thumbnails\\' in filepath:
return False
return filepath.lower().endswith(('.png', '.jpg', '.jpeg', '.webp', '.gif'))
def process_new_image(self, image_path: str):