diff --git a/py/api.py b/py/api.py index 6a6d308..0d754c8 100644 --- a/py/api.py +++ b/py/api.py @@ -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 }) diff --git a/pyproject.toml b/pyproject.toml index 222da40..a5aa150 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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"] diff --git a/utils/image_monitor.py b/utils/image_monitor.py index 168ccb5..271330f 100644 --- a/utils/image_monitor.py +++ b/utils/image_monitor.py @@ -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):